mirror of
https://github.com/mackron/miniaudio.git
synced 2026-04-22 00:06:59 +02:00
Add a basic single-threaded test to deviceio test.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
USAGE: deviceio [input/output file] [mode] [backend] [waveform] [noise] [--auto]
|
||||
USAGE: deviceio [input/output file] [mode] [backend] [waveform] [noise] [threading mode] [--auto]
|
||||
|
||||
In playback mode the input file is optional, in which case a waveform or noise source will be used instead. For capture and loopback modes
|
||||
it must specify an output parameter, and must be specified. In duplex mode it is optional, but if specified will be an output file that
|
||||
@@ -19,6 +19,7 @@ will receive the captured audio.
|
||||
sndio
|
||||
audio4
|
||||
oss
|
||||
pipewire
|
||||
pulseaudio or pulse
|
||||
alsa
|
||||
jack
|
||||
@@ -27,7 +28,6 @@ will receive the captured audio.
|
||||
webaudio
|
||||
null
|
||||
sdl2
|
||||
pipewire
|
||||
|
||||
"waveform" can be one of the following:
|
||||
sine
|
||||
@@ -40,6 +40,11 @@ will receive the captured audio.
|
||||
pink
|
||||
brownian or brown
|
||||
|
||||
"threading mode" can be one of the following:
|
||||
multi-threaded or multithreaded (default)
|
||||
single-threaded or singlethreaded
|
||||
|
||||
|
||||
If multiple backends are specified, the priority will be based on the order in which you specify them. If multiple waveform or noise types
|
||||
are specified the last one on the command line will have priority.
|
||||
*/
|
||||
@@ -256,6 +261,23 @@ ma_bool32 try_parse_noise(const char* arg, ma_noise_type* pNoiseType)
|
||||
return MA_FALSE;
|
||||
}
|
||||
|
||||
ma_bool32 try_parse_threading_mode(const char* arg, ma_threading_mode* pThreadingMode)
|
||||
{
|
||||
MA_ASSERT(arg != NULL);
|
||||
MA_ASSERT(pThreadingMode != NULL);
|
||||
|
||||
if (strcmp(arg, "multi-threaded") == 0 || strcmp(arg, "multithreaded") == 0) {
|
||||
*pThreadingMode = MA_THREADING_MODE_MULTI_THREADED;
|
||||
return MA_TRUE;
|
||||
}
|
||||
if (strcmp(arg, "single-threaded") == 0 || strcmp(arg, "singlethreaded") == 0) {
|
||||
*pThreadingMode = MA_THREADING_MODE_SINGLE_THREADED;
|
||||
return MA_TRUE;
|
||||
}
|
||||
|
||||
return MA_FALSE;
|
||||
}
|
||||
|
||||
void print_enabled_backends(void)
|
||||
{
|
||||
ma_device_backend_config pStockBackends[MA_MAX_STOCK_DEVICE_BACKENDS];
|
||||
@@ -449,6 +471,7 @@ int main(int argc, char** argv)
|
||||
ma_device_config deviceConfig;
|
||||
ma_waveform_type waveformType = ma_waveform_type_sine;
|
||||
ma_noise_type noiseType = ma_noise_type_white;
|
||||
ma_threading_mode threadingMode = MA_THREADING_MODE_MULTI_THREADED;
|
||||
const char* pFilePath = NULL; /* Input or output file path, depending on the mode. */
|
||||
ma_bool32 enumerate = MA_TRUE;
|
||||
ma_bool32 interactive = MA_TRUE;
|
||||
@@ -487,6 +510,11 @@ int main(int argc, char** argv)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* threading mode */
|
||||
if (try_parse_threading_mode(argv[iarg], &threadingMode)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Getting here means the argument should be considered the input or output file. */
|
||||
pFilePath = argv[iarg];
|
||||
g_State.sourceType = source_type_decoder;
|
||||
@@ -534,6 +562,7 @@ int main(int argc, char** argv)
|
||||
}
|
||||
|
||||
deviceConfig = ma_device_config_init(deviceType);
|
||||
deviceConfig.threadingMode = threadingMode;
|
||||
deviceConfig.playback.format = deviceFormat;
|
||||
deviceConfig.playback.channels = deviceChannels;
|
||||
deviceConfig.capture.format = deviceFormat;
|
||||
@@ -622,9 +651,14 @@ int main(int argc, char** argv)
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (ma_device_get_threading_mode(&g_State.device) == MA_THREADING_MODE_SINGLE_THREADED) {
|
||||
printf("Running in single-threaded mode. Press Ctrl+C to quit.\n");
|
||||
}
|
||||
|
||||
/* Now we just keep looping and wait for user input. */
|
||||
for (;;) {
|
||||
if (interactive) {
|
||||
if (ma_device_get_threading_mode(&g_State.device) == MA_THREADING_MODE_MULTI_THREADED) {
|
||||
int c;
|
||||
|
||||
if (ma_device_is_started(&g_State.device)) {
|
||||
@@ -657,12 +691,24 @@ int main(int argc, char** argv)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Single-threaded mode. Just sleep for a bit and check if we want to close. */
|
||||
ma_device_step(&g_State.device, MA_BLOCKING_MODE_BLOCKING);
|
||||
|
||||
if (g_State.wantsToClose) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Running in auto-close mode. Just sleep for a bit. The data callback will control when this loop aborts. */
|
||||
if (g_State.wantsToClose) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (ma_device_get_threading_mode(&g_State.device) == MA_THREADING_MODE_SINGLE_THREADED) {
|
||||
ma_device_step(&g_State.device, MA_BLOCKING_MODE_BLOCKING);
|
||||
}
|
||||
|
||||
/*
|
||||
Can't sleep with Emscripten. Just skip the sleeping part in this case. I don't run this test for Emscripten
|
||||
so it doesn't matter. Just fixing this for the sake of automated build tools.
|
||||
|
||||
Reference in New Issue
Block a user