#55325 - GPFerror - Tue Sep 27, 2005 7:26 pm
Need some help with how to do this or some examples please.
right now I am calling my function that generates a sound buffer on the arm9 with a set size and then calling playGenericSound on the buffer, right now I have no syncing up being done and the calcsoundbuffer and playsound functions im sure are being called before or late therefore sounding like crap. How can I calculate the buffersize so its in sync?
I was thinking of somekind of ringbuffer but dont know how to implement this on the DS.
I understand the general concept but not the implementation. I'v been looking through different released source code of different projects but there is usually so much other code that it makes it difficult to pick out and use what I need.
So anyone give me code, how to calculate buffersize based off timer/interupts ect on both arm7 and arm9 . and how to sync it up.
Thanks,
Troy(GPF)
#55377 - GPFerror - Wed Sep 28, 2005 2:33 am
actually its for something else because I knew you were working on FrodoDS but I didnt get your email could you send it again please. Or send me a link by pm and I will download it.
Thanks
#55398 - DekuTree64 - Wed Sep 28, 2005 6:18 am
The way I've done it before is by playing a looping buffer on ARM7, and using hardware timers on ARM9 to keep track of where it is in the buffer. The only tricky thing is getting the sound channel and the timers started at close to the same time.
Make sure the channel starts a little sooner though, so you never fill past where it currently is.
The actual ring buffering is just a matter of splitting up a load of samples if you're going to hit the end before it's done.
For example, say your buffer is 1000 samples long, your current position is 900, and you need to mix 500 samples. 900 + 500 would go past 1000, so it needs split up. Your first batch will be
bufferLength - bufferPos = 1000 - 900 = 100 samples.
After that's done, set the position back to 0, and since you've mixed 100 samples so far, you need to mix 400 more to get to your total 500. So mix them, update the buffer position to 400, and you're done.
For the sample counting, you can use a timer that triggers an interrupt every x samples, and in the interrupt update a variable telling how many samples need to be mixed. Then in your game loop or VBlank or something, mix however many samples have accumulated in that variable, and reset it to 0.
If I remember right, sound channel timers run at half the frequency of the CPU hardware timers, so set your counting timer's overflow period to 2*soundChannelTimerPeriod*x, where x is the number of samples you want to wait between each interrupt (I used 256).
The actual REG_TMxD value will be 65536 - period.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku
#59497 - LiraNuna - Wed Nov 02, 2005 6:49 am
Off topic: What emulator is it?
#59673 - gladius - Thu Nov 03, 2005 6:38 am
The general architecture I chose for streaming sound requires a custom arm7 binary. It sets the sound system up as normal to play a looped buffer, which is essentially a timer IRQ that plays the new buffers.
Then when that timer irq occurs on the arm7 side, it plays the current buffer, and sets the toBeMixed buffer to the next one. It then sends a FIFO message to the arm9 saying "hey, i just started started playing your samples, start mixing the ones for next time right now".
The arm9 then recieves this message and goes ahead and does the mixing into shared ram at the toBeMixed buffer location.
Then the next time the irq happens on the arm7 it plays the toBeMixed buffer and sets the toBeMixed buffer to the old location. This cycle is repeated forever.