mirror of
https://github.com/mackron/miniaudio.git
synced 2026-04-22 00:06:59 +02:00
Get full-duplex working with DirectSound.
This commit is contained in:
@@ -2089,7 +2089,8 @@ MAL_ALIGNED_STRUCT(MAL_SIMD_ALIGNMENT) mal_device
|
|||||||
/*LPDIRECTSOUNDBUFFER*/ mal_ptr pPlaybackBuffer;
|
/*LPDIRECTSOUNDBUFFER*/ mal_ptr pPlaybackBuffer;
|
||||||
/*LPDIRECTSOUNDCAPTURE*/ mal_ptr pCapture;
|
/*LPDIRECTSOUNDCAPTURE*/ mal_ptr pCapture;
|
||||||
/*LPDIRECTSOUNDCAPTUREBUFFER*/ mal_ptr pCaptureBuffer;
|
/*LPDIRECTSOUNDCAPTUREBUFFER*/ mal_ptr pCaptureBuffer;
|
||||||
mal_uint32 iNextPeriod; /* Circular. Keeps track of the next period that's due for an update. */
|
mal_uint32 iNextPeriodPlayback; /* Circular. Keeps track of the next period that's due for an update. */
|
||||||
|
mal_uint32 iNextPeriodCapture;
|
||||||
void* pMappedBufferPlayback;
|
void* pMappedBufferPlayback;
|
||||||
void* pMappedBufferCapture;
|
void* pMappedBufferCapture;
|
||||||
mal_uint32 mappedBufferFramesRemainingPlayback;
|
mal_uint32 mappedBufferFramesRemainingPlayback;
|
||||||
@@ -8912,7 +8913,7 @@ mal_result mal_device_get_current_frame__dsound(mal_device* pDevice, mal_device_
|
|||||||
mal_result mal_device_map_next_playback_buffer__dsound(mal_device* pDevice)
|
mal_result mal_device_map_next_playback_buffer__dsound(mal_device* pDevice)
|
||||||
{
|
{
|
||||||
DWORD periodSizeInBytes = (pDevice->bufferSizeInFrames / pDevice->periods) * mal_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
|
DWORD periodSizeInBytes = (pDevice->bufferSizeInFrames / pDevice->periods) * mal_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
|
||||||
DWORD lockOffset = (pDevice->dsound.iNextPeriod * periodSizeInBytes);
|
DWORD lockOffset = (pDevice->dsound.iNextPeriodPlayback * periodSizeInBytes);
|
||||||
DWORD mappedSizeInBytes;
|
DWORD mappedSizeInBytes;
|
||||||
HRESULT hr = mal_IDirectSoundBuffer_Lock((mal_IDirectSoundBuffer*)pDevice->dsound.pPlaybackBuffer, lockOffset, periodSizeInBytes, &pDevice->dsound.pMappedBufferPlayback, &mappedSizeInBytes, NULL, NULL, 0);
|
HRESULT hr = mal_IDirectSoundBuffer_Lock((mal_IDirectSoundBuffer*)pDevice->dsound.pPlaybackBuffer, lockOffset, periodSizeInBytes, &pDevice->dsound.pMappedBufferPlayback, &mappedSizeInBytes, NULL, NULL, 0);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
@@ -8967,7 +8968,7 @@ mal_result mal_device_write__dsound(mal_device* pDevice, const void* pPCMFrames,
|
|||||||
pDevice->dsound.pMappedBufferPlayback = NULL;
|
pDevice->dsound.pMappedBufferPlayback = NULL;
|
||||||
pDevice->dsound.mappedBufferFramesRemainingPlayback = 0;
|
pDevice->dsound.mappedBufferFramesRemainingPlayback = 0;
|
||||||
pDevice->dsound.mappedBufferFramesCapacityPlayback = 0;
|
pDevice->dsound.mappedBufferFramesCapacityPlayback = 0;
|
||||||
pDevice->dsound.iNextPeriod = (pDevice->dsound.iNextPeriod + 1) % pDevice->periods;
|
pDevice->dsound.iNextPeriodPlayback = (pDevice->dsound.iNextPeriodPlayback + 1) % pDevice->periods;
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
result = MAL_FAILED_TO_UNMAP_DEVICE_BUFFER;
|
result = MAL_FAILED_TO_UNMAP_DEVICE_BUFFER;
|
||||||
@@ -9008,8 +9009,8 @@ mal_result mal_device_write__dsound(mal_device* pDevice, const void* pPCMFrames,
|
|||||||
break; /* Failed to get the current frame. */
|
break; /* Failed to get the current frame. */
|
||||||
}
|
}
|
||||||
|
|
||||||
mal_uint32 periodSizeInFrames = pDevice->bufferSizeInFrames/pDevice->periods;
|
mal_uint32 periodSizeInFrames = pDevice->playback.internalBufferSizeInFrames / pDevice->playback.internalPeriods;
|
||||||
if ((currentPos - (pDevice->dsound.iNextPeriod * periodSizeInFrames)) >= periodSizeInFrames) {
|
if ((currentPos - (pDevice->dsound.iNextPeriodPlayback * periodSizeInFrames)) >= periodSizeInFrames) {
|
||||||
break; /* There's enough room. */
|
break; /* There's enough room. */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9042,7 +9043,7 @@ mal_result mal_device_write__dsound(mal_device* pDevice, const void* pPCMFrames,
|
|||||||
mal_result mal_device_map_next_capture_buffer__dsound(mal_device* pDevice)
|
mal_result mal_device_map_next_capture_buffer__dsound(mal_device* pDevice)
|
||||||
{
|
{
|
||||||
DWORD periodSizeInBytes = (pDevice->bufferSizeInFrames / pDevice->periods) * mal_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels);
|
DWORD periodSizeInBytes = (pDevice->bufferSizeInFrames / pDevice->periods) * mal_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels);
|
||||||
DWORD lockOffset = (pDevice->dsound.iNextPeriod * periodSizeInBytes);
|
DWORD lockOffset = (pDevice->dsound.iNextPeriodCapture * periodSizeInBytes);
|
||||||
DWORD mappedSizeInBytes;
|
DWORD mappedSizeInBytes;
|
||||||
HRESULT hr = mal_IDirectSoundCaptureBuffer_Lock((mal_IDirectSoundCaptureBuffer*)pDevice->dsound.pCaptureBuffer, lockOffset, periodSizeInBytes, &pDevice->dsound.pMappedBufferCapture, &mappedSizeInBytes, NULL, NULL, 0);
|
HRESULT hr = mal_IDirectSoundCaptureBuffer_Lock((mal_IDirectSoundCaptureBuffer*)pDevice->dsound.pCaptureBuffer, lockOffset, periodSizeInBytes, &pDevice->dsound.pMappedBufferCapture, &mappedSizeInBytes, NULL, NULL, 0);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
@@ -9094,7 +9095,7 @@ mal_result mal_device_read__dsound(mal_device* pDevice, void* pPCMFrames, mal_ui
|
|||||||
pDevice->dsound.pMappedBufferCapture = NULL;
|
pDevice->dsound.pMappedBufferCapture = NULL;
|
||||||
pDevice->dsound.mappedBufferFramesRemainingCapture = 0;
|
pDevice->dsound.mappedBufferFramesRemainingCapture = 0;
|
||||||
pDevice->dsound.mappedBufferFramesCapacityCapture = 0;
|
pDevice->dsound.mappedBufferFramesCapacityCapture = 0;
|
||||||
pDevice->dsound.iNextPeriod = (pDevice->dsound.iNextPeriod + 1) % pDevice->periods;
|
pDevice->dsound.iNextPeriodCapture = (pDevice->dsound.iNextPeriodCapture + 1) % pDevice->periods;
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
result = MAL_FAILED_TO_UNMAP_DEVICE_BUFFER;
|
result = MAL_FAILED_TO_UNMAP_DEVICE_BUFFER;
|
||||||
@@ -9120,8 +9121,8 @@ mal_result mal_device_read__dsound(mal_device* pDevice, void* pPCMFrames, mal_ui
|
|||||||
break; /* Failed to get the current frame. */
|
break; /* Failed to get the current frame. */
|
||||||
}
|
}
|
||||||
|
|
||||||
mal_uint32 periodSizeInFrames = pDevice->bufferSizeInFrames/pDevice->periods;
|
mal_uint32 periodSizeInFrames = pDevice->capture.internalBufferSizeInFrames / pDevice->capture.internalPeriods;
|
||||||
if ((currentPos - (pDevice->dsound.iNextPeriod * periodSizeInFrames)) >= periodSizeInFrames) {
|
if ((currentPos - (pDevice->dsound.iNextPeriodCapture * periodSizeInFrames)) >= periodSizeInFrames) {
|
||||||
break; /* There's enough room. */
|
break; /* There's enough room. */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9831,8 +9832,13 @@ mal_result mal_device_init__winmm(mal_context* pContext, const mal_device_config
|
|||||||
mal_zero_memory(pDevice->winmm._pHeapData, heapSize);
|
mal_zero_memory(pDevice->winmm._pHeapData, heapSize);
|
||||||
|
|
||||||
if (pConfig->deviceType == mal_device_type_capture || pConfig->deviceType == mal_device_type_duplex) {
|
if (pConfig->deviceType == mal_device_type_capture || pConfig->deviceType == mal_device_type_duplex) {
|
||||||
|
if (pConfig->deviceType == mal_device_type_capture) {
|
||||||
pDevice->winmm.pWAVEHDRCapture = pDevice->winmm._pHeapData;
|
pDevice->winmm.pWAVEHDRCapture = pDevice->winmm._pHeapData;
|
||||||
pDevice->winmm.pIntermediaryBufferCapture = pDevice->winmm._pHeapData + (sizeof(WAVEHDR)*pDevice->capture.internalPeriods);
|
pDevice->winmm.pIntermediaryBufferCapture = pDevice->winmm._pHeapData + (sizeof(WAVEHDR)*(pDevice->capture.internalPeriods));
|
||||||
|
} else {
|
||||||
|
pDevice->winmm.pWAVEHDRCapture = pDevice->winmm._pHeapData;
|
||||||
|
pDevice->winmm.pIntermediaryBufferCapture = pDevice->winmm._pHeapData + (sizeof(WAVEHDR)*(pDevice->capture.internalPeriods + pDevice->playback.internalPeriods));
|
||||||
|
}
|
||||||
|
|
||||||
/* Prepare headers. */
|
/* Prepare headers. */
|
||||||
for (mal_uint32 iPeriod = 0; iPeriod < pDevice->capture.internalPeriods; ++iPeriod) {
|
for (mal_uint32 iPeriod = 0; iPeriod < pDevice->capture.internalPeriods; ++iPeriod) {
|
||||||
@@ -9856,8 +9862,8 @@ mal_result mal_device_init__winmm(mal_context* pContext, const mal_device_config
|
|||||||
pDevice->winmm.pWAVEHDRPlayback = pDevice->winmm._pHeapData;
|
pDevice->winmm.pWAVEHDRPlayback = pDevice->winmm._pHeapData;
|
||||||
pDevice->winmm.pIntermediaryBufferPlayback = pDevice->winmm._pHeapData + (sizeof(WAVEHDR)*pDevice->playback.internalPeriods);
|
pDevice->winmm.pIntermediaryBufferPlayback = pDevice->winmm._pHeapData + (sizeof(WAVEHDR)*pDevice->playback.internalPeriods);
|
||||||
} else {
|
} else {
|
||||||
pDevice->winmm.pWAVEHDRPlayback = pDevice->winmm._pHeapData + (sizeof(WAVEHDR)*(pDevice->playback.internalPeriods));
|
pDevice->winmm.pWAVEHDRPlayback = pDevice->winmm._pHeapData + (sizeof(WAVEHDR)*(pDevice->capture.internalPeriods));
|
||||||
pDevice->winmm.pIntermediaryBufferPlayback = pDevice->winmm._pHeapData + (sizeof(WAVEHDR)*(pDevice->playback.internalPeriods + pDevice->playback.internalPeriods)) + (pDevice->playback.internalBufferSizeInFrames*mal_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels));
|
pDevice->winmm.pIntermediaryBufferPlayback = pDevice->winmm._pHeapData + (sizeof(WAVEHDR)*(pDevice->capture.internalPeriods + pDevice->playback.internalPeriods)) + (pDevice->playback.internalBufferSizeInFrames*mal_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prepare headers. */
|
/* Prepare headers. */
|
||||||
@@ -20784,6 +20790,10 @@ mal_thread_result MAL_THREADCALL mal_worker_thread(void* pData)
|
|||||||
if (result != MAL_SUCCESS) {
|
if (result != MAL_SUCCESS) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (playbackDeviceFramesCount < playbackDeviceDataCapInFrames) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (capturedFramesToProcess < capturedFramesToTryProcessing) {
|
if (capturedFramesToProcess < capturedFramesToTryProcessing) {
|
||||||
@@ -20801,7 +20811,7 @@ mal_thread_result MAL_THREADCALL mal_worker_thread(void* pData)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mal_uint8 buffer[4096];
|
mal_uint8 buffer[4096];
|
||||||
mal_uint32 bufferSizeInFrames;// = sizeof(buffer) / mal_get_bytes_per_frame(pDevice->internalFormat, pDevice->internalChannels);
|
mal_uint32 bufferSizeInFrames;
|
||||||
if (pDevice->type == mal_device_type_capture) {
|
if (pDevice->type == mal_device_type_capture) {
|
||||||
bufferSizeInFrames = sizeof(buffer) / mal_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels);
|
bufferSizeInFrames = sizeof(buffer) / mal_get_bytes_per_frame(pDevice->capture.internalFormat, pDevice->capture.internalChannels);
|
||||||
} else {
|
} else {
|
||||||
@@ -27950,7 +27960,6 @@ mal_uint32 mal_decoder_internal_on_read_pcm_frames__flac(mal_pcm_converter* pDSP
|
|||||||
|
|
||||||
mal_decoder* pDecoder = (mal_decoder*)pUserData;
|
mal_decoder* pDecoder = (mal_decoder*)pUserData;
|
||||||
mal_assert(pDecoder != NULL);
|
mal_assert(pDecoder != NULL);
|
||||||
mal_assert(pDecoder->internalFormat == mal_format_s32);
|
|
||||||
|
|
||||||
drflac* pFlac = (drflac*)pDecoder->pInternalDecoder;
|
drflac* pFlac = (drflac*)pDecoder->pInternalDecoder;
|
||||||
mal_assert(pFlac != NULL);
|
mal_assert(pFlac != NULL);
|
||||||
|
|||||||
+6
-6
@@ -38,10 +38,10 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
drwav_data_format wavFormat;
|
drwav_data_format wavFormat;
|
||||||
wavFormat.container = drwav_container_riff;
|
wavFormat.container = drwav_container_riff;
|
||||||
wavFormat.format = DR_WAVE_FORMAT_IEEE_FLOAT;
|
wavFormat.format = DR_WAVE_FORMAT_PCM;
|
||||||
wavFormat.channels = 2;
|
wavFormat.channels = 2;
|
||||||
wavFormat.sampleRate = 44100;
|
wavFormat.sampleRate = 44100;
|
||||||
wavFormat.bitsPerSample = 32;
|
wavFormat.bitsPerSample = 16;
|
||||||
|
|
||||||
drwav wav;
|
drwav wav;
|
||||||
if (drwav_init_file_write(&wav, "output.wav", &wavFormat) == DRWAV_FALSE) {
|
if (drwav_init_file_write(&wav, "output.wav", &wavFormat) == DRWAV_FALSE) {
|
||||||
@@ -64,14 +64,14 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
mal_device_config deviceConfig = mal_device_config_init(mal_device_type_duplex);
|
mal_device_config deviceConfig = mal_device_config_init(mal_device_type_duplex);
|
||||||
deviceConfig.capture.pDeviceID = NULL;
|
deviceConfig.capture.pDeviceID = NULL;
|
||||||
deviceConfig.capture.format = mal_format_f32;
|
deviceConfig.capture.format = mal_format_s16;
|
||||||
deviceConfig.capture.channels = 2;
|
deviceConfig.capture.channels = 2;
|
||||||
deviceConfig.playback.pDeviceID = NULL;
|
deviceConfig.playback.pDeviceID = NULL;
|
||||||
deviceConfig.playback.format = mal_format_f32;
|
deviceConfig.playback.format = mal_format_s16;
|
||||||
deviceConfig.playback.channels = 2;
|
deviceConfig.playback.channels = 2;
|
||||||
deviceConfig.sampleRate = 44100;
|
deviceConfig.sampleRate = 44100;
|
||||||
deviceConfig.bufferSizeInMilliseconds = 50;
|
deviceConfig.bufferSizeInMilliseconds = 100;
|
||||||
deviceConfig.periods = 3;
|
deviceConfig.periods = 2;
|
||||||
deviceConfig.dataCallback = data_callback;
|
deviceConfig.dataCallback = data_callback;
|
||||||
deviceConfig.stopCallback = stop_callback;
|
deviceConfig.stopCallback = stop_callback;
|
||||||
deviceConfig.pUserData = &wav;
|
deviceConfig.pUserData = &wav;
|
||||||
|
|||||||
Reference in New Issue
Block a user