From 4980fcf3c5c0a8f489a406ff26bf85f84326dd6e Mon Sep 17 00:00:00 2001 From: David Reid Date: Sat, 12 Jan 2019 11:04:11 +1000 Subject: [PATCH] Reorder parameters in the callback. This swaps the order of the input and output pointers so that it's consistent with the order used by memcpy(). --- examples/simple_capture.c | 4 ++-- examples/simple_playback.c | 3 +-- mini_al.h | 12 +++++----- tests/mal_dithering.c | 4 ++-- tests/mal_duplex.c | 47 ++++++++++++++++++++++++++++++++++++++ tests/mal_stop.c | 2 +- tests/mal_test_0.c | 2 +- tests/mal_test_0.vcxproj | 21 +++++++++++------ tests/mal_unplugging.c | 4 ++-- 9 files changed, 76 insertions(+), 23 deletions(-) create mode 100644 tests/mal_duplex.c diff --git a/examples/simple_capture.c b/examples/simple_capture.c index 19745876..5d0ad577 100644 --- a/examples/simple_capture.c +++ b/examples/simple_capture.c @@ -12,7 +12,7 @@ mal_uint32 capturedSampleCount = 0; mal_int16* pCapturedSamples = NULL; mal_uint32 playbackSample = 0; -void on_recv_frames(mal_device* pDevice, const void* pInput, void* pOutput, mal_uint32 frameCount) +void on_recv_frames(mal_device* pDevice, void* pOutput, const void* pInput, mal_uint32 frameCount) { mal_uint32 sampleCount = frameCount * pDevice->channels; @@ -30,7 +30,7 @@ void on_recv_frames(mal_device* pDevice, const void* pInput, void* pOutput, mal_ (void)pOutput; } -void on_send_frames(mal_device* pDevice, const void* pInput, void* pOutput, mal_uint32 frameCount) +void on_send_frames(mal_device* pDevice, void* pOutput, const void* pInput, mal_uint32 frameCount) { mal_uint32 samplesToRead = frameCount * pDevice->channels; if (samplesToRead > capturedSampleCount-playbackSample) { diff --git a/examples/simple_playback.c b/examples/simple_playback.c index 6e6f7386..5b60ad79 100644 --- a/examples/simple_playback.c +++ b/examples/simple_playback.c @@ -10,8 +10,7 @@ #include -// This is the function that's used for sending more data to the device for playback. -void on_send_frames_to_device(mal_device* pDevice, const void* pInput, void* pOutput, mal_uint32 frameCount) +void on_send_frames_to_device(mal_device* pDevice, void* pOutput, const void* pInput, mal_uint32 frameCount) { mal_decoder* pDecoder = (mal_decoder*)pDevice->pUserData; if (pDecoder == NULL) { diff --git a/mini_al.h b/mini_al.h index f3a96ce1..1e5fbdd8 100644 --- a/mini_al.h +++ b/mini_al.h @@ -1391,19 +1391,19 @@ typedef struct /* The callback for processing audio data from the device. -pInput is a pointer to a buffer containing input data from the device. This will be non-null for a capture or full-duplex device, and -null for a playback device. - pOutput is a pointer to a buffer that will receive audio data that will later be played back through the speakers. This will be non-null for a playback or full-duplex device and null for a capture device. +pInput is a pointer to a buffer containing input data from the device. This will be non-null for a capture or full-duplex device, and +null for a playback device. + frameCount is the number of PCM frames to process. If an output buffer is provided (pOutput is not null), applications should write out to the entire output buffer. Do _not_ call any mini_al APIs from the callback. Attempting the stop the device can result in a deadlock. The proper way to stop the device is to call mal_device_stop() from a different thread, normally the main application thread. */ -typedef void (* mal_device_callback_proc)(mal_device* pDevice, const void* pInput, void* pOutput, mal_uint32 frameCount); +typedef void (* mal_device_callback_proc)(mal_device* pDevice, void* pOutput, const void* pInput, mal_uint32 frameCount); /* The callback for when the device has been stopped. @@ -4505,7 +4505,7 @@ mal_uint32 mal_device__on_read_from_client(mal_pcm_converter* pDSP, mal_uint32 f mal_device_callback_proc onData = pDevice->onData; if (onData) { - onData(pDevice, NULL, pFramesOut, frameCount); + onData(pDevice, pFramesOut, NULL, frameCount); return frameCount; } @@ -4576,7 +4576,7 @@ static MAL_INLINE void mal_device__send_frames_to_client(mal_device* pDevice, ma break; } - onData(pDevice, chunkBuffer, NULL, framesJustRead); + onData(pDevice, NULL, chunkBuffer, framesJustRead); if (framesJustRead < chunkFrameCount) { break; diff --git a/tests/mal_dithering.c b/tests/mal_dithering.c index d4c1924a..876f367a 100644 --- a/tests/mal_dithering.c +++ b/tests/mal_dithering.c @@ -30,7 +30,7 @@ mal_uint32 on_convert_samples_out(mal_format_converter* pConverter, mal_uint32 f return (mal_uint32)mal_format_converter_read(pConverterIn, frameCount, pFrames, NULL); } -void on_send_to_device__original(mal_device* pDevice, const void* pInput, void* pOutput, mal_uint32 frameCount) +void on_send_to_device__original(mal_device* pDevice, void* pOutput, const void* pInput, mal_uint32 frameCount) { mal_assert(pDevice->format == mal_format_f32); mal_assert(pDevice->channels == 1); @@ -41,7 +41,7 @@ void on_send_to_device__original(mal_device* pDevice, const void* pInput, void* (void)pInput; } -void on_send_to_device__dithered(mal_device* pDevice, const void* pInput, void* pOutput, mal_uint32 frameCount) +void on_send_to_device__dithered(mal_device* pDevice, void* pOutput, const void* pInput, mal_uint32 frameCount) { mal_assert(pDevice->channels == 1); diff --git a/tests/mal_duplex.c b/tests/mal_duplex.c new file mode 100644 index 00000000..b00a167d --- /dev/null +++ b/tests/mal_duplex.c @@ -0,0 +1,47 @@ +#include + +#define MINI_AL_IMPLEMENTATION +#include "../mini_al.h" + +void on_stop(mal_device* pDevice) +{ + (void)pDevice; + printf("STOPPED\n"); +} + +void data_callback(mal_device* pDevice, void* pOutput, const void* pInput, mal_uint32 frameCount) +{ + /* In our this test the format and channel count is 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->format, pDevice->channels)); +} + +int main(int argc, char** argv) +{ + mal_result result; + + (void)argc; + (void)argv; + + mal_backend backend = mal_backend_wasapi; + + mal_device_config config = mal_device_config_init_default(data_callback, NULL); + config.format = mal_format_f32; + config.channels = 2; + config.sampleRate = 44100; + config.onStopCallback = on_stop; + config.bufferSizeInFrames = 16384*4; + + mal_device device; + result = mal_device_init_ex(&backend, 1, NULL, mal_device_type_playback, NULL, &config, &device); + if (result != MAL_SUCCESS) { + return result; + } + + mal_device_start(&device); + + printf("Press Enter to quit...\n"); + getchar(); + + mal_device_uninit(&device); + return 0; +} \ No newline at end of file diff --git a/tests/mal_stop.c b/tests/mal_stop.c index 8b450609..3ea9b78c 100644 --- a/tests/mal_stop.c +++ b/tests/mal_stop.c @@ -14,7 +14,7 @@ void on_stop(mal_device* pDevice) printf("STOPPED\n"); } -void data_callback(mal_device* pDevice, const void* pInput, void* pOutput, mal_uint32 frameCount) +void data_callback(mal_device* pDevice, void* pOutput, const void* pInput, mal_uint32 frameCount) { (void)pInput; /* Not used yet. */ diff --git a/tests/mal_test_0.c b/tests/mal_test_0.c index 44f96e1e..aaeb4c60 100644 --- a/tests/mal_test_0.c +++ b/tests/mal_test_0.c @@ -2232,7 +2232,7 @@ typedef struct mal_event endOfPlaybackEvent; } playback_test_callback_data; -void on_send__playback_test(mal_device* pDevice, const void* pInput, void* pOutput, mal_uint32 frameCount) +void on_send__playback_test(mal_device* pDevice, void* pOutput, const void* pInput, mal_uint32 frameCount) { playback_test_callback_data* pData = (playback_test_callback_data*)pDevice->pUserData; mal_assert(pData != NULL); diff --git a/tests/mal_test_0.vcxproj b/tests/mal_test_0.vcxproj index 6346189a..a72f593b 100644 --- a/tests/mal_test_0.vcxproj +++ b/tests/mal_test_0.vcxproj @@ -319,12 +319,12 @@ true - true - true - true - true - true - true + false + false + false + false + false + false true @@ -350,7 +350,14 @@ true true - + + true + true + true + true + true + true + true true diff --git a/tests/mal_unplugging.c b/tests/mal_unplugging.c index 8fe857c3..faaab073 100644 --- a/tests/mal_unplugging.c +++ b/tests/mal_unplugging.c @@ -23,12 +23,12 @@ void on_stop(mal_device* pDevice) mal_event_signal(&g_stopEvent); } -mal_uint32 on_send(mal_device* pDevice, mal_uint32 frameCount, void* pFramesOut) +void on_send(mal_device* pDevice, void* pFramesOut, const void* pFramesIn, mal_uint32 frameCount) { mal_assert(pDevice != NULL); //printf("TESTING: %d\n", frameCount); - return (mal_uint32)mal_sine_wave_read_f32_ex(&g_sineWave, frameCount, pDevice->channels, mal_stream_layout_interleaved, (float**)&pFramesOut); + mal_sine_wave_read_f32_ex(&g_sineWave, frameCount, pDevice->channels, mal_stream_layout_interleaved, (float**)&pFramesOut); } int main()