diff --git a/mini_al.h b/mini_al.h index 779a6001..de94198f 100644 --- a/mini_al.h +++ b/mini_al.h @@ -1236,6 +1236,7 @@ mal_result mal_rb_commit_write(mal_rb* pRB, size_t sizeInBytes, void* pBufferOut mal_result mal_rb_seek_read(mal_rb* pRB, size_t offsetInBytes); mal_result mal_rb_seek_write(mal_rb* pRB, size_t offsetInBytes); mal_int32 mal_rb_pointer_distance(mal_rb* pRB); /* Returns the distance between the write pointer and the read pointer. Should never be negative for a correct program. */ +size_t mal_rb_get_subbuffer_size(mal_rb* pRB); size_t mal_rb_get_subbuffer_stride(mal_rb* pRB); size_t mal_rb_get_subbuffer_offset(mal_rb* pRB, size_t subbufferIndex); void* mal_rb_get_subbuffer_ptr(mal_rb* pRB, size_t subbufferIndex, void* pBuffer); @@ -1258,8 +1259,9 @@ mal_result mal_pcm_rb_commit_write(mal_pcm_rb* pRB, mal_uint32 sizeInFrames, voi mal_result mal_pcm_rb_seek_read(mal_pcm_rb* pRB, mal_uint32 offsetInFrames); mal_result mal_pcm_rb_seek_write(mal_pcm_rb* pRB, mal_uint32 offsetInFrames); mal_int32 mal_pcm_rb_pointer_disance(mal_pcm_rb* pRB); /* Return value is in frames. */ -size_t mal_pcm_rb_get_subbuffer_stride(mal_pcm_rb* pRB); -size_t mal_pcm_rb_get_subbuffer_offset(mal_pcm_rb* pRB, mal_uint32 subbufferIndex); +mal_uint32 mal_pcm_rb_get_subbuffer_size(mal_pcm_rb* pRB); +mal_uint32 mal_pcm_rb_get_subbuffer_stride(mal_pcm_rb* pRB); +mal_uint32 mal_pcm_rb_get_subbuffer_offset(mal_pcm_rb* pRB, mal_uint32 subbufferIndex); void* mal_pcm_rb_get_subbuffer_ptr(mal_pcm_rb* pRB, mal_uint32 subbufferIndex, void* pBuffer); @@ -4836,7 +4838,7 @@ static mal_result mal_device__handle_duplex_callback_capture(mal_device* pDevice } if (framesToProcess == 0) { - if (mal_pcm_rb_pointer_disance(pRB) == 0) { + if (mal_pcm_rb_pointer_disance(pRB) == (mal_int32)mal_pcm_rb_get_subbuffer_size(pRB)) { break; /* Overrun. Not enough room in the ring buffer for input frame. Excess frames are dropped. */ } } @@ -4892,6 +4894,10 @@ static mal_result mal_device__handle_duplex_callback_playback(mal_device* pDevic if (inputFrameCount > 0) { /* Use actual input frames. */ pDevice->onData(pDevice, playbackFramesInExternalFormat, pInputFrames, inputFrameCount); + } else { + if (mal_pcm_rb_pointer_disance(pRB) == 0) { + break; /* Underrun. */ + } } /* We're done with the captured samples. */ @@ -21442,7 +21448,7 @@ mal_result mal_device_init__webaudio(mal_context* pContext, const mal_device_con the external sample rate. */ if (pConfig->deviceType == mal_device_type_duplex) { - mal_uint32 rbSizeInFrames = (mal_uint32)mal_calculate_frame_count_after_src(pDevice->sampleRate, pDevice->capture.internalSampleRate, pDevice->capture.internalBufferSizeInFrames); + mal_uint32 rbSizeInFrames = (mal_uint32)mal_calculate_frame_count_after_src(pDevice->sampleRate, pDevice->capture.internalSampleRate, pDevice->capture.internalBufferSizeInFrames) * 2; result = mal_pcm_rb_init(pDevice->capture.format, pDevice->capture.channels, rbSizeInFrames, NULL, &pDevice->webaudio.duplexRB); if (result != MAL_SUCCESS) { if (pDevice->type == mal_device_type_capture || pDevice->type == mal_device_type_duplex) { @@ -28995,6 +29001,15 @@ mal_int32 mal_rb_pointer_distance(mal_rb* pRB) } } +size_t mal_rb_get_subbuffer_size(mal_rb* pRB) +{ + if (pRB == NULL) { + return 0; + } + + return pRB->subbufferSizeInBytes; +} + size_t mal_rb_get_subbuffer_stride(mal_rb* pRB) { if (pRB == NULL) { @@ -29157,7 +29172,16 @@ mal_int32 mal_pcm_rb_pointer_disance(mal_pcm_rb* pRB) return mal_rb_pointer_distance(&pRB->rb) / mal_pcm_rb_get_bpf(pRB); } -size_t mal_pcm_rb_get_subbuffer_stride(mal_pcm_rb* pRB) +mal_uint32 mal_pcm_rb_get_subbuffer_size(mal_pcm_rb* pRB) +{ + if (pRB == NULL) { + return 0; + } + + return mal_rb_get_subbuffer_size(&pRB->rb) / mal_pcm_rb_get_bpf(pRB); +} + +mal_uint32 mal_pcm_rb_get_subbuffer_stride(mal_pcm_rb* pRB) { if (pRB == NULL) { return 0; @@ -29166,7 +29190,7 @@ size_t mal_pcm_rb_get_subbuffer_stride(mal_pcm_rb* pRB) return mal_rb_get_subbuffer_stride(&pRB->rb) / mal_pcm_rb_get_bpf(pRB); } -size_t mal_pcm_rb_get_subbuffer_offset(mal_pcm_rb* pRB, mal_uint32 subbufferIndex) +mal_uint32 mal_pcm_rb_get_subbuffer_offset(mal_pcm_rb* pRB, mal_uint32 subbufferIndex) { if (pRB == NULL) { return 0; diff --git a/tests/mal_duplex.c b/tests/mal_duplex.c index b514d416..122ce4a4 100644 --- a/tests/mal_duplex.c +++ b/tests/mal_duplex.c @@ -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 1 +#if 0 /* 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 1 +#if 0 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_coreaudio; + mal_backend backend = mal_backend_webaudio; 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 = &wav; + deviceConfig.pUserData = NULL/*&wav*/; mal_device device; result = mal_device_init(&context, &deviceConfig, &device); @@ -106,7 +106,7 @@ int main(int argc, char** argv) #endif mal_device_uninit(&device); - drwav_uninit(&wav); + /*drwav_uninit(&wav);*/ (void)argc; (void)argv;