mirror of
https://github.com/mackron/miniaudio.git
synced 2026-04-22 00:06:59 +02:00
Fix some full-duplex errors.
This commit is contained in:
@@ -4820,7 +4820,7 @@ static mal_result mal_device__handle_duplex_callback_capture(mal_device* pDevice
|
||||
mal_assert(pRB != NULL);
|
||||
|
||||
mal_result result;
|
||||
|
||||
|
||||
pDevice->capture._dspFrameCount = (mal_uint32)frameCount;
|
||||
pDevice->capture._dspFrames = (const mal_uint8*)pFramesInInternalFormat;
|
||||
|
||||
@@ -4836,7 +4836,9 @@ static mal_result mal_device__handle_duplex_callback_capture(mal_device* pDevice
|
||||
}
|
||||
|
||||
if (framesToProcess == 0) {
|
||||
break; /* Overrun. Not enough room in the ring buffer for input frame. Excess frames are dropped. */
|
||||
if (mal_pcm_rb_pointer_disance(pRB) == 0) {
|
||||
break; /* Overrun. Not enough room in the ring buffer for input frame. Excess frames are dropped. */
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert. */
|
||||
@@ -4862,7 +4864,7 @@ static mal_result mal_device__handle_duplex_callback_playback(mal_device* pDevic
|
||||
mal_assert(frameCount > 0);
|
||||
mal_assert(pFramesInInternalFormat != NULL);
|
||||
mal_assert(pRB != NULL);
|
||||
|
||||
|
||||
/*
|
||||
Sitting in the ring buffer should be captured data from the capture callback in external format. If there's not enough data in there for
|
||||
the whole frameCount frames we just use silence instead for the input data.
|
||||
@@ -4875,7 +4877,7 @@ static mal_result mal_device__handle_duplex_callback_playback(mal_device* pDevic
|
||||
/* We need to calculate how many output frames are required to be read from the client to completely fill frameCount internal frames. */
|
||||
mal_uint32 totalFramesToReadFromClient = (mal_uint32)mal_calculate_frame_count_after_src(pDevice->sampleRate, pDevice->playback.internalSampleRate, frameCount); // mal_pcm_converter_get_required_input_frame_count(&pDevice->playback.converter, (mal_uint32)frameCount);
|
||||
mal_uint32 totalFramesReadFromClient = 0;
|
||||
while (totalFramesReadFromClient < totalFramesToReadFromClient) {
|
||||
while (totalFramesReadFromClient < totalFramesToReadFromClient && mal_device_is_started(pDevice)) {
|
||||
mal_uint32 framesRemainingFromClient = (totalFramesToReadFromClient - totalFramesReadFromClient);
|
||||
mal_uint32 framesToProcessFromClient = sizeof(playbackFramesInExternalFormat) / mal_get_bytes_per_frame(pDevice->playback.format, pDevice->playback.channels);
|
||||
if (framesToProcessFromClient > framesRemainingFromClient) {
|
||||
@@ -4886,10 +4888,12 @@ static mal_result mal_device__handle_duplex_callback_playback(mal_device* pDevic
|
||||
mal_uint32 inputFrameCount = framesToProcessFromClient;
|
||||
void* pInputFrames;
|
||||
result = mal_pcm_rb_acquire_read(pRB, &inputFrameCount, &pInputFrames);
|
||||
if (result == MAL_SUCCESS && inputFrameCount > 0) {
|
||||
/* Use actual input frames. */
|
||||
pDevice->onData(pDevice, playbackFramesInExternalFormat, pInputFrames, inputFrameCount);
|
||||
|
||||
if (result == MAL_SUCCESS) {
|
||||
if (inputFrameCount > 0) {
|
||||
/* Use actual input frames. */
|
||||
pDevice->onData(pDevice, playbackFramesInExternalFormat, pInputFrames, inputFrameCount);
|
||||
}
|
||||
|
||||
/* We're done with the captured samples. */
|
||||
result = mal_pcm_rb_commit_read(pRB, inputFrameCount, pInputFrames);
|
||||
if (result != MAL_SUCCESS) {
|
||||
@@ -16509,7 +16513,12 @@ OSStatus mal_on_input__coreaudio(void* pUserData, AudioUnitRenderActionFlags* pA
|
||||
framesToSend = framesRemaining;
|
||||
}
|
||||
|
||||
mal_device__send_frames_to_client(pDevice, framesToSend, silentBuffer);
|
||||
if (pDevice->type == mal_device_type_duplex) {
|
||||
mal_device__handle_duplex_callback_capture(pDevice, framesToSend, silentBuffer, &pDevice->coreaudio.duplexRB);
|
||||
} else {
|
||||
mal_device__send_frames_to_client(pDevice, framesToSend, silentBuffer);
|
||||
}
|
||||
|
||||
framesRemaining -= framesToSend;
|
||||
}
|
||||
|
||||
@@ -17121,6 +17130,7 @@ mal_result mal_device_init__coreaudio(mal_context* pContext, const mal_device_co
|
||||
data.shareMode = pConfig->capture.shareMode;
|
||||
data.bufferSizeInFramesIn = pConfig->bufferSizeInFrames;
|
||||
data.bufferSizeInMillisecondsIn = pConfig->bufferSizeInMilliseconds;
|
||||
data.registerStopEvent = MAL_TRUE;
|
||||
|
||||
mal_result result = mal_device_init_internal__coreaudio(pDevice->pContext, mal_device_type_capture, pConfig->capture.pDeviceID, &data, (void*)pDevice);
|
||||
if (result != MAL_SUCCESS) {
|
||||
@@ -17172,10 +17182,12 @@ mal_result mal_device_init__coreaudio(mal_context* pContext, const mal_device_co
|
||||
if (pConfig->deviceType == mal_device_type_duplex) {
|
||||
data.bufferSizeInFramesIn = pDevice->capture.internalBufferSizeInFrames;
|
||||
data.periodsIn = pDevice->capture.internalPeriods;
|
||||
data.registerStopEvent = MAL_FALSE;
|
||||
} else {
|
||||
data.bufferSizeInFramesIn = pConfig->bufferSizeInFrames;
|
||||
data.bufferSizeInMillisecondsIn = pConfig->bufferSizeInMilliseconds;
|
||||
data.periodsIn = pConfig->periods;
|
||||
data.registerStopEvent = MAL_TRUE;
|
||||
}
|
||||
|
||||
mal_result result = mal_device_init_internal__coreaudio(pDevice->pContext, mal_device_type_playback, pConfig->playback.pDeviceID, &data, (void*)pDevice);
|
||||
|
||||
+6
-6
@@ -31,7 +31,7 @@ void data_callback(mal_device* pDevice, void* pOutput, const void* pInput, mal_u
|
||||
/* In this test the format and channel count are the same for both input and output which means we can just memcpy(). */
|
||||
mal_copy_memory(pOutput, pInput, frameCount * mal_get_bytes_per_frame(pDevice->capture.format, pDevice->capture.channels));
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
/* Also write to a wav file for debugging. */
|
||||
drwav* pWav = (drwav*)pDevice->pUserData;
|
||||
mal_assert(pWav != NULL);
|
||||
@@ -44,7 +44,7 @@ int main(int argc, char** argv)
|
||||
{
|
||||
mal_result result;
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
drwav_data_format wavFormat;
|
||||
wavFormat.container = drwav_container_riff;
|
||||
wavFormat.format = DR_WAVE_FORMAT_PCM;
|
||||
@@ -60,7 +60,7 @@ int main(int argc, char** argv)
|
||||
#endif
|
||||
|
||||
|
||||
mal_backend backend = mal_backend_webaudio;
|
||||
mal_backend backend = mal_backend_coreaudio;
|
||||
|
||||
mal_context_config contextConfig = mal_context_config_init();
|
||||
contextConfig.logCallback = log_callback;
|
||||
@@ -84,7 +84,7 @@ int main(int argc, char** argv)
|
||||
deviceConfig.periods = 2;
|
||||
deviceConfig.dataCallback = data_callback;
|
||||
deviceConfig.stopCallback = stop_callback;
|
||||
deviceConfig.pUserData = NULL; /*&wav;*/
|
||||
deviceConfig.pUserData = &wav;
|
||||
|
||||
mal_device device;
|
||||
result = mal_device_init(&context, &deviceConfig, &device);
|
||||
@@ -106,9 +106,9 @@ int main(int argc, char** argv)
|
||||
#endif
|
||||
|
||||
mal_device_uninit(&device);
|
||||
/*drwav_uninit(&wav);*/
|
||||
drwav_uninit(&wav);
|
||||
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user