Commit 212e750d authored by David Reid's avatar David Reid

Fix bug where the data callback's output buffer is not pre-silenced.

parent 915f480c
/* /*
Audio playback and capture library. Choice of public domain or MIT-0. See license statements at the end of this file. Audio playback and capture library. Choice of public domain or MIT-0. See license statements at the end of this file.
miniaudio (formerly mini_al) - v0.9 - 2019-03-06 miniaudio (formerly mini_al) - v0.9.1 - 2019-03-17
David Reid - davidreidsoftware@gmail.com David Reid - davidreidsoftware@gmail.com
*/ */
...@@ -4917,7 +4917,15 @@ static MA_INLINE void ma_device__read_frames_from_client(ma_device* pDevice, ma_ ...@@ -4917,7 +4917,15 @@ static MA_INLINE void ma_device__read_frames_from_client(ma_device* pDevice, ma_
ma_assert(frameCount > 0); ma_assert(frameCount > 0);
ma_assert(pSamples != NULL); ma_assert(pSamples != NULL);
ma_pcm_converter_read(&pDevice->playback.converter, pSamples, frameCount); ma_device_callback_proc onData = pDevice->onData;
if (onData) {
if (pDevice->playback.converter.isPassthrough) {
ma_zero_pcm_frames(pSamples, frameCount, pDevice->playback.format, pDevice->playback.channels);
onData(pDevice, pSamples, NULL, frameCount);
} else {
ma_pcm_converter_read(&pDevice->playback.converter, pSamples, frameCount);
}
}
} }
// A helper for sending sample data to the client. // A helper for sending sample data to the client.
...@@ -4929,22 +4937,26 @@ static MA_INLINE void ma_device__send_frames_to_client(ma_device* pDevice, ma_ui ...@@ -4929,22 +4937,26 @@ static MA_INLINE void ma_device__send_frames_to_client(ma_device* pDevice, ma_ui
ma_device_callback_proc onData = pDevice->onData; ma_device_callback_proc onData = pDevice->onData;
if (onData) { if (onData) {
pDevice->capture._dspFrameCount = frameCount; if (pDevice->capture.converter.isPassthrough) {
pDevice->capture._dspFrames = (const ma_uint8*)pSamples; onData(pDevice, NULL, pSamples, frameCount);
} else {
pDevice->capture._dspFrameCount = frameCount;
pDevice->capture._dspFrames = (const ma_uint8*)pSamples;
ma_uint8 chunkBuffer[4096]; ma_uint8 chunkBuffer[4096];
ma_uint32 chunkFrameCount = sizeof(chunkBuffer) / ma_get_bytes_per_frame(pDevice->capture.format, pDevice->capture.channels); ma_uint32 chunkFrameCount = sizeof(chunkBuffer) / ma_get_bytes_per_frame(pDevice->capture.format, pDevice->capture.channels);
for (;;) { for (;;) {
ma_uint32 framesJustRead = (ma_uint32)ma_pcm_converter_read(&pDevice->capture.converter, chunkBuffer, chunkFrameCount); ma_uint32 framesJustRead = (ma_uint32)ma_pcm_converter_read(&pDevice->capture.converter, chunkBuffer, chunkFrameCount);
if (framesJustRead == 0) { if (framesJustRead == 0) {
break; break;
} }
onData(pDevice, NULL, chunkBuffer, framesJustRead); onData(pDevice, NULL, chunkBuffer, framesJustRead);
if (framesJustRead < chunkFrameCount) { if (framesJustRead < chunkFrameCount) {
break; break;
}
} }
} }
} }
...@@ -8160,12 +8172,8 @@ ma_result ma_device_main_loop__wasapi(ma_device* pDevice) ...@@ -8160,12 +8172,8 @@ ma_result ma_device_main_loop__wasapi(ma_device* pDevice)
break; break;
} }
/* We should have a buffer at this point. If we are running a passthrough pipeline we can send it straight to the callback. Otherwise we need to convert. */ /* We should have a buffer at this point. */
if (pDevice->capture.converter.isPassthrough) { ma_device__send_frames_to_client(pDevice, mappedBufferSizeInFramesCapture, pMappedBufferCapture);
pDevice->onData(pDevice, NULL, pMappedBufferCapture, mappedBufferSizeInFramesCapture);
} else {
ma_device__send_frames_to_client(pDevice, mappedBufferSizeInFramesCapture, pMappedBufferCapture);
}
/* At this point we're done with the buffer. */ /* At this point we're done with the buffer. */
hr = ma_IAudioCaptureClient_ReleaseBuffer((ma_IAudioCaptureClient*)pDevice->wasapi.pCaptureClient, mappedBufferSizeInFramesCapture); hr = ma_IAudioCaptureClient_ReleaseBuffer((ma_IAudioCaptureClient*)pDevice->wasapi.pCaptureClient, mappedBufferSizeInFramesCapture);
...@@ -8209,11 +8217,8 @@ ma_result ma_device_main_loop__wasapi(ma_device* pDevice) ...@@ -8209,11 +8217,8 @@ ma_result ma_device_main_loop__wasapi(ma_device* pDevice)
break; break;
} }
if (pDevice->playback.converter.isPassthrough) { /* We should have a buffer at this point. */
pDevice->onData(pDevice, pMappedBufferPlayback, NULL, framesAvailablePlayback); ma_device__read_frames_from_client(pDevice, framesAvailablePlayback, pMappedBufferPlayback);
} else {
ma_device__read_frames_from_client(pDevice, framesAvailablePlayback, pMappedBufferPlayback);
}
/* At this point we're done writing to the device and we just need to release the buffer. */ /* At this point we're done writing to the device and we just need to release the buffer. */
hr = ma_IAudioRenderClient_ReleaseBuffer((ma_IAudioRenderClient*)pDevice->wasapi.pRenderClient, framesAvailablePlayback, 0); hr = ma_IAudioRenderClient_ReleaseBuffer((ma_IAudioRenderClient*)pDevice->wasapi.pRenderClient, framesAvailablePlayback, 0);
...@@ -9776,14 +9781,7 @@ ma_result ma_device_main_loop__dsound(ma_device* pDevice) ...@@ -9776,14 +9781,7 @@ ma_result ma_device_main_loop__dsound(ma_device* pDevice)
} }
#endif #endif
/* Optimization: If we are running as a passthrough we can pass the mapped pointer to the callback directly. */ ma_device__send_frames_to_client(pDevice, mappedSizeInBytesCapture/bpfCapture, pMappedBufferCapture);
if (pDevice->capture.converter.isPassthrough) {
/* Passthrough. */
pDevice->onData(pDevice, NULL, pMappedBufferCapture, mappedSizeInBytesCapture/bpfCapture);
} else {
/* Not a passthrough. */
ma_device__send_frames_to_client(pDevice, mappedSizeInBytesCapture/bpfCapture, pMappedBufferCapture);
}
hr = ma_IDirectSoundCaptureBuffer_Unlock((ma_IDirectSoundCaptureBuffer*)pDevice->dsound.pCaptureBuffer, pMappedBufferCapture, mappedSizeInBytesCapture, NULL, 0); hr = ma_IDirectSoundCaptureBuffer_Unlock((ma_IDirectSoundCaptureBuffer*)pDevice->dsound.pCaptureBuffer, pMappedBufferCapture, mappedSizeInBytesCapture, NULL, 0);
if (FAILED(hr)) { if (FAILED(hr)) {
...@@ -9872,17 +9870,8 @@ ma_result ma_device_main_loop__dsound(ma_device* pDevice) ...@@ -9872,17 +9870,8 @@ ma_result ma_device_main_loop__dsound(ma_device* pDevice)
break; break;
} }
/* /* At this point we have a buffer for output. */
At this point we have a buffer for output. If we don't need to do any data conversion we can pass the mapped pointer to the buffer directly. Otherwise ma_device__read_frames_from_client(pDevice, (mappedSizeInBytesPlayback/bpfPlayback), pMappedBufferPlayback);
we need to convert the data.
*/
if (pDevice->playback.converter.isPassthrough) {
/* Passthrough. */
pDevice->onData(pDevice, pMappedBufferPlayback, NULL, (mappedSizeInBytesPlayback/bpfPlayback));
} else {
/* Conversion. */
ma_device__read_frames_from_client(pDevice, (mappedSizeInBytesPlayback/bpfPlayback), pMappedBufferPlayback);
}
hr = ma_IDirectSoundBuffer_Unlock((ma_IDirectSoundBuffer*)pDevice->dsound.pPlaybackBuffer, pMappedBufferPlayback, mappedSizeInBytesPlayback, NULL, 0); hr = ma_IDirectSoundBuffer_Unlock((ma_IDirectSoundBuffer*)pDevice->dsound.pPlaybackBuffer, pMappedBufferPlayback, mappedSizeInBytesPlayback, NULL, 0);
if (FAILED(hr)) { if (FAILED(hr)) {
...@@ -31395,6 +31384,13 @@ Device ...@@ -31395,6 +31384,13 @@ Device
REVISION HISTORY REVISION HISTORY
================ ================
v0.9.1 - 2019-03-17
- Fix a bug where the output buffer is not getting zeroed out before calling the data callback. This happens when
the device is running in passthrough mode (not doing any data conversion).
- Fix an issue where the data callback is getting called too frequently on the WASAPI and DirectSound backends.
- Fix error on the UWP build.
- Fix a build error on Apple platforms.
v0.9 - 2019-03-06 v0.9 - 2019-03-06
- Rebranded to "miniaudio". All namespaces have been renamed from "mal" to "ma". - Rebranded to "miniaudio". All namespaces have been renamed from "mal" to "ma".
- API CHANGE: ma_device_init() and ma_device_config_init() have changed significantly: - API CHANGE: ma_device_init() and ma_device_config_init() have changed significantly:
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment