I'm having trouble with an AudioHandler in C. I've read through the discussion here: Tips and tricks for processing audio in C:
I'm writing a sound emulator for 8 bit game consoles. Right now I'm focusing on NES (NSF files)
My setup is as follows:
- User presses button, call from lua to c for "play_file". Which instantiates an emulator and sets a flag "playing" = true;
- Meanwhile in lua playdate.update() I have a call to emulator:update() (my c code). In emulator:update(), if "playing" = true, I fill a ring buffer of samples. Right now it is 500 arrays of 512 int16_t. Once the ring buffer is full, this method no-ops.
- emulator:update() binds a new sound source with "AudioSourceCallback" once it has a full ring buffer.
- The audio callbacks begin, samples are removed from the ring buffer and fed into the *left and *right arrays (256 pcm samples each) and audio plays. In the meantime, emulator:update() keeps on getting called so it can replenish the ring buffer.
- Eventually (after about 2 seconds) AudioSouceCallback reaches the end of the initial 500 elements of the buffer and needs to circle back to the front. When this happens audio stops playing on device, but it works in the simulator.
I've added debugging via LogToConsole statements to document where the error happens. The number of items in the buffer never drops below about 480 elements.
main.c:79:AudioSourceCallback(): Played a sample, writeIndex: 497, readIndex: 498, bufferLength: 499, audioSourceCallbackCount: 497
main.c:79:AudioSourceCallback(): Played a sample, writeIndex: 497, readIndex: 499, bufferLength: 498, audioSourceCallbackCount: 498
main.c:79:AudioSourceCallback(): Played a sample, writeIndex: 497, readIndex: 500, bufferLength: 497, audioSourceCallbackCount: 499
***** Audio playback dies here....I think ******
main.c:79:AudioSourceCallback(): Played a sample, writeIndex: 497, readIndex: 1, bufferLength: 496, audioSourceCallbackCount: 500
main.c:79:AudioSourceCallback(): Played a sample, writeIndex: 497, readIndex: 2, bufferLength: 495, audioSourceCallbackCount: 501
main.c:79:AudioSourceCallback(): Played a sample, writeIndex: 497, readIndex: 3, bufferLength: 494, audioSourceCallbackCount: 502
If I preload the enitre track, sound works great, but it needs about 15k samples and uses like 10MB of memory (and needs about 6 seconds CPU time to load the huge buffer). In theory, I think I can get away with a buffer of about 50 items or less as the buffer length never drops below 480 on device (on simulator the buffer stays at 495 or more) in my current code.
The audio issue always seems to be when the index wraps the ring and comes back to start. This all works fine on the simulator. Any ideas as to what's going on? Do I need to free memory in the buffer slot before I overwrite it?