-
Notifications
You must be signed in to change notification settings - Fork 70
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rework audio wave channel #562
Conversation
- Rename the callback for more consistency - Pass the channel to the callback - Stop doing << 8 on samples - Make the callback optional
Should we also make some short playback buffer on 32blit hardware instead of generating 1 sample per interupt? Currently a 22k Hz interrupt for sound system is too frequent. A ~50Hz interupt for filling playback DMA call would make the sound playback more accurate and stable. |
@zenodante probably - yes - although we'd need - I guess - to size the wave buffer appropriately (441 samples?) and the output buffer appropriately. IIRC an earlier build I had a buffer set up with a memory -> peripheral DMA, and would run the audio engine on the DMA-half-complete callback. My reasoning for switching to a 22050Hz native sample rate with the audio engine invoked on every sample (IIRC) is due to wanting to mirror the capabilities of retro audio engines in the hands of expert composers. IE: you can mash the audio channel settings at high frequencies to create new effects and sounds that the sound system designer may not have anticipated. That said I'm not sure this is how - for example - the more advanced C64 SID tunes actually worked. Is a 50Hz "Vblank" interrupt equivalent actually... fine? This then begs the question- how does the end-user control the audio engine. If we're dealing with a sample buffer and a 50Hz update rate then a majority of changes to the engine in |
Currently you can only really have 100Hz updates anyway. You could try to do precise timing within (I guess for more advanced stuff you'd want the game to be able to refill the output buffer directly, instead of using a single WAVE channel and a double-copy.) |
If we use the timer event to provide the DMA tick and use double buffer for DMA transfer to DAC, we could set the buffer size to any number you would like. 100 means (22050/100 = 220.5 hz buffer update rate) and we will call the sound generation function 100 times to fill the next buffer in interrupt. As the buffer refreashing is done in the DMA finished interrupt, user would not notice any difference. (Just like Daft Freak mentioned, user could only update the channel statement in less than ~100Hz) It would reduce the interrupt frequency, increase system performance and make the code more I-cache friendly. (Otherwise the sound signal function would be moved into I-cache 22k times per second and replaced by game code after return back from interrupt) |
Hmm, you can use the callback on a WAVE channel as as fast-ish timer to mess with audio stuff... Anyway, using a buffer or not for the output wouldn't really affect this PR as it's just changing the user-visible part. (and SDL already works like that...) |
True, getting hung up on a separate issue here- discussion can continue here -> #568 |
Update for the API changes in 32blit/32blit-sdk#562
Update for the API changes in 32blit/32blit-sdk#562
Update for the API changes in 32blit/32blit-sdk#562
Update for the API changes in 32blit/32blit-sdk#562
wave_callback_arg
is now a genericuser_data
pointer.Changes for users are...
Old:
New:
Also, if you're using 8-bit samples you need to multiply them by 256 now. (If you're using 16-bit samples you can stop dividing your volume by 256).
This will also cause API breakage, but will only affect games that use the WAVE waveform (callback arg will be wrong).