Files
miniaudio/examples/simple_duplex.c
T
David Reid 766a155fb3 Stop using MA_ASSERT in examples.
This is useful because MA_ASSERT is only defined in the implementation
section of miniaudio.h which can cause issues when people copy/paste
the code and use it in a file that does not have visibility of the
implementation.

Note that there are still more references to implementation-defined
macros, but these have been moved to the public section in the dev-0.12
branch so I'm not bothering to change those just yet.

Public issue https://github.com/mackron/miniaudio/issues/787
2023-12-17 08:42:19 +10:00

74 lines
2.5 KiB
C

/*
Demonstrates duplex mode which is where data is captured from a microphone and then output to a speaker device.
This example captures audio from the default microphone and then outputs it straight to the default playback device
without any kind of modification. If you wanted to, you could also apply filters and effects to the input stream
before outputting to the playback device.
Note that the microphone and playback device must run in lockstep. Any kind of timing deviation will result in audible
glitching which the backend may not be able to recover from. For this reason, miniaudio forces you to use the same
sample rate for both capture and playback. If internally the native sample rates differ, miniaudio will perform the
sample rate conversion for you automatically.
*/
#define MINIAUDIO_IMPLEMENTATION
#include "../miniaudio.h"
#include <stdio.h>
#ifdef __EMSCRIPTEN__
void main_loop__em()
{
}
#endif
void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
{
/* This example assumes the playback and capture sides use the same format and channel count. */
if (pDevice->capture.format != pDevice->playback.format || pDevice->capture.channels != pDevice->playback.channels) {
return;
}
/* In this example the format and channel count are the same for both input and output which means we can just memcpy(). */
MA_COPY_MEMORY(pOutput, pInput, frameCount * ma_get_bytes_per_frame(pDevice->capture.format, pDevice->capture.channels));
}
int main(int argc, char** argv)
{
ma_result result;
ma_device_config deviceConfig;
ma_device device;
deviceConfig = ma_device_config_init(ma_device_type_duplex);
deviceConfig.capture.pDeviceID = NULL;
deviceConfig.capture.format = ma_format_s16;
deviceConfig.capture.channels = 2;
deviceConfig.capture.shareMode = ma_share_mode_shared;
deviceConfig.playback.pDeviceID = NULL;
deviceConfig.playback.format = ma_format_s16;
deviceConfig.playback.channels = 2;
deviceConfig.dataCallback = data_callback;
result = ma_device_init(NULL, &deviceConfig, &device);
if (result != MA_SUCCESS) {
return result;
}
#ifdef __EMSCRIPTEN__
getchar();
#endif
ma_device_start(&device);
#ifdef __EMSCRIPTEN__
emscripten_set_main_loop(main_loop__em, 0, 1);
#else
printf("Press Enter to quit...\n");
getchar();
#endif
ma_device_uninit(&device);
(void)argc;
(void)argv;
return 0;
}