11 Jan 2024 |
carbonacat | the annoying thing with having more than one buffer or a bigger buffer is that you're increasint the maximum audio latency that the user can experience | 22:35:29 |
tuxinator2009 | Interesting, I usually have the update perform the swap so that the interupt simply checks if (bufferPos == bufferEnd) bufferPos = bufferStart; thus simplifying it's code. | 22:36:22 |
tuxinator2009 | So it basically sends the current bufferPos value, increments bufferPos, then checks the pos and moves it accordingly. | 22:37:24 |
carbonacat | if you have more than 2 buffers of this kind, you will probably often be 1 buffer late so ~125-250 ms in normal cases | 22:38:31 |
carbonacat | in some case it can be weird for your SFX | 22:38:54 |
tuxinator2009 | Unless you have functions in place to fill the current buffer based on it's current position, but that can cause other race conditions that may be undesirable. | 22:39:16 |
carbonacat | yes | 22:39:29 |
carbonacat | it's also defeating the purpose of having two buffers | 22:39:51 |
tuxinator2009 | But yeah I think the smaller the buffer and the fewer buffers is definitely best. Doing a byte-for-byte read/write is too inefficient as opposed to reading/writing 512 bytes at once for example. | 22:40:18 |
carbonacat | theorically you could have a single circular buffer | 22:40:22 |
carbonacat | but yeah, reading/writing get more complicated | 22:40:52 |
tuxinator2009 | Yeah, you could simply have a 1024 ring-buffer which gets filled in X byte segments which would still create the same stuttering effect in the event of a stalled update loop. | 22:41:29 |
carbonacat | yeah and if you manipulated the libaudio code | 22:42:42 |
carbonacat | you'll see that the audio handlers generates their output on a sequence of 512 bytes at once | 22:43:10 |
carbonacat | (or 1024, can't remember) | 22:43:42 |
carbonacat | it's interesting to have because you can do a bunch of samples while not worrying about the varying lenght | 22:44:30 |
tuxinator2009 | In LibAudio it's 512 which I would guess is because that's one block of SD card data. | 22:44:50 |
carbonacat | with a circular buffer, you'd need a stack-allocated buffer of 512 to keep that, then a copy to the actual audio buffer | 22:44:59 |
carbonacat | so ... essentially, double buffer again 😛 | 22:45:13 |
tuxinator2009 | I think that's why a double buffer approach is good. The buffer still needs to be filled faster than it takes to play those 512 bytes. | 22:47:18 |
carbonacat | (so you'll end up with some "free samples" not filled in the end) | 22:47:22 |
carbonacat | yeah and it's much simpler to implement | 22:47:32 |
tuxinator2009 | So the higher the sample rate the faster it has to transfer that data. | 22:47:45 |
carbonacat | yes | 22:47:58 |
tuxinator2009 | 8Khz = 64ms and 22050 ~= 23ms. | 22:48:17 |
carbonacat | it'll also increase the cpu load too of course | 22:48:19 |
carbonacat | (since more samples have to be generated/read) | 22:48:32 |
carbonacat | increasing the interrupt rate also increase the cost of context switching that is associated to it | 22:49:07 |
tuxinator2009 | Yep, more samples needed per second which means more work to be done to get those samples and that additional work also has to be done much faster than that of a lower sample rate. | 22:49:11 |
carbonacat | (total cost, not individual) | 22:49:23 |