On Jul 1, 2014, at 2:53 PM, Andrew Eikum wrote:
try2: Resample outside of the callback thread. Actually try to use the given format in IsFormatSupported.
Well, the resampling has been moved off of the callback thread, but it happens with the spin lock held. So, it can still block the callback thread for the duration. Ideally, there wouldn't be a need for the spin lock; some sort of lockless data structure could be used to move buffers into and out of buffer lists. Given that a spin lock is used, we should try hard to keep the work done while it's held to a minimum.
My first thought was that it should be possible to use a sort of double-buffering scheme. Within the lock, just swap some pointers so the callback thread can work with a different buffer. Then the resampling can be done outside of the lock.
My second thought is that's exactly what the GetBuffer() / ReleaseBuffer() scheme is about. I think that Core Audio should map pretty cleanly to DirectSound. It should not be necessary to use a wrap buffer or a temp buffer. It should be possible to preallocate all buffers at the right size during Initialize (you can query the device, audio unit, and converter for the information necessary to compute the buffer size). We should be able to return the actual "device" period. It should be possible to avoid copying audio data.
If we can't implement a lockless buffer list, then the spin lock would only be used to move buffers in and out of lists.
Once the buffers are in the right list, the resampling can be done without the lock being held.
All of that said, I seem to recall you tried to achieve something like that with the AudioQueue approach and kept hitting problems that prevented it. So, if I'm talking out of my ass, please disregard.
One last thing: if no sample rate conversion is required (requested sample rate matches the device sample rate), it would be ideal to avoid using the converter.
-Ken
On Jul 2, 2014, at 1:13 PM, Ken Thomases wrote:
My second thought is that's exactly what the GetBuffer() / ReleaseBuffer() scheme is about. I think that Core Audio should map pretty cleanly to DirectSound. It should not be necessary to use a wrap buffer or a temp buffer. It should be possible to preallocate all buffers at the right size during Initialize (you can query the device, audio unit, and converter for the information necessary to compute the buffer size). We should be able to return the actual "device" period. It should be possible to avoid copying audio data.
Just to be clear, I'm not suggesting that an overhaul on these lines must be done before anything can get done. I do think it's important to get the resampling operation to happen outside of the spin lock. The above is one possible approach to achieving that.
-Ken