portaudio: allow to select sink/source audio device

This commit is contained in:
Matthias Ringwald 2024-05-14 12:19:55 +02:00
parent 14200bb85a
commit 409f627cf8
2 changed files with 70 additions and 18 deletions

View File

@ -64,6 +64,9 @@ static int num_channels_source;
static int num_bytes_per_sample_sink; static int num_bytes_per_sample_sink;
static int num_bytes_per_sample_source; static int num_bytes_per_sample_source;
static const char * sink_device_name;
static const char * source_device_name = "4-chan";
// portaudio // portaudio
static int portaudio_initialized; static int portaudio_initialized;
@ -227,24 +230,42 @@ static int btstack_audio_portaudio_sink_init(
portaudio_initialized = 1; portaudio_initialized = 1;
} }
/* -- setup output -- */ /* -- find output device by name if requested -- */
PaStreamParameters theOutputParameters; PaDeviceIndex device_index = -1;
theOutputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */ const PaDeviceInfo *output_device_info;
theOutputParameters.channelCount = channels; if (sink_device_name != NULL){
theOutputParameters.sampleFormat = PA_SAMPLE_TYPE; int num_devices = Pa_GetDeviceCount();
theOutputParameters.suggestedLatency = Pa_GetDeviceInfo( theOutputParameters.device )->defaultHighOutputLatency; for (int i = 0; i < num_devices; i++) {
theOutputParameters.hostApiSpecificStreamInfo = NULL; output_device_info = Pa_GetDeviceInfo(i);
// Match device by prefix
if (strncmp(output_device_info->name, sink_device_name, strlen(sink_device_name)) == 0) {
device_index = i;
break;
}
}
}
const PaDeviceInfo *outputDeviceInfo; /* -- use default device otherwise -- */
outputDeviceInfo = Pa_GetDeviceInfo( theOutputParameters.device ); if (device_index < 0){
log_info("PortAudio: sink device: %s", outputDeviceInfo->name); device_index = Pa_GetDefaultOutputDevice();
UNUSED(outputDeviceInfo); output_device_info = Pa_GetDeviceInfo(device_index );
}
/* -- setup output -- */
PaStreamParameters output_parameters;
output_parameters.device = device_index;
output_parameters.channelCount = channels;
output_parameters.sampleFormat = PA_SAMPLE_TYPE;
output_parameters.suggestedLatency = output_device_info->defaultHighOutputLatency;
output_parameters.hostApiSpecificStreamInfo = NULL;
log_info("PortAudio: sink device: %s", output_device_info->name);
UNUSED(output_device_info);
/* -- setup stream -- */ /* -- setup stream -- */
err = Pa_OpenStream( err = Pa_OpenStream(
&stream_sink, &stream_sink,
NULL, NULL,
&theOutputParameters, &output_parameters,
samplerate, samplerate,
NUM_FRAMES_PER_PA_BUFFER, NUM_FRAMES_PER_PA_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */ paClipOff, /* we won't output out of range samples so don't bother clipping them */
@ -300,18 +321,37 @@ static int btstack_audio_portaudio_source_init(
portaudio_initialized = 1; portaudio_initialized = 1;
} }
/* -- find input device by name if requested -- */
PaDeviceIndex device_index = -1;
const PaDeviceInfo *input_device_info;
if (source_device_name != NULL){
int num_devices = Pa_GetDeviceCount();
for (int i = 0; i < num_devices; i++) {
input_device_info = Pa_GetDeviceInfo(i);
// Match device by prefix
if (strncmp(input_device_info->name, source_device_name, strlen(source_device_name)) == 0) {
device_index = i;
break;
}
}
}
/* -- use default device otherwise -- */
if (device_index < 0){
device_index = Pa_GetDefaultInputDevice();
input_device_info = Pa_GetDeviceInfo(device_index );
}
/* -- setup input -- */ /* -- setup input -- */
PaStreamParameters theInputParameters; PaStreamParameters theInputParameters;
theInputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */ theInputParameters.device = device_index;
theInputParameters.channelCount = channels; theInputParameters.channelCount = channels;
theInputParameters.sampleFormat = PA_SAMPLE_TYPE; theInputParameters.sampleFormat = PA_SAMPLE_TYPE;
theInputParameters.suggestedLatency = Pa_GetDeviceInfo( theInputParameters.device )->defaultHighInputLatency; theInputParameters.suggestedLatency = input_device_info->defaultHighInputLatency;
theInputParameters.hostApiSpecificStreamInfo = NULL; theInputParameters.hostApiSpecificStreamInfo = NULL;
const PaDeviceInfo *inputDeviceInfo; log_info("PortAudio: source device: %s", input_device_info->name);
inputDeviceInfo = Pa_GetDeviceInfo( theInputParameters.device ); UNUSED(input_device_info);
log_info("PortAudio: source device: %s", inputDeviceInfo->name);
UNUSED(inputDeviceInfo);
/* -- setup stream -- */ /* -- setup stream -- */
err = Pa_OpenStream( err = Pa_OpenStream(
@ -512,4 +552,12 @@ const btstack_audio_source_t * btstack_audio_portaudio_source_get_instance(void)
return &btstack_audio_portaudio_source; return &btstack_audio_portaudio_source;
} }
void btstack_audio_portaudio_sink_set_device(const char * device_name){
sink_device_name = device_name;
}
void btstack_audio_portaudio_source_set_device(const char * device_name){
source_device_name = device_name;
}
#endif #endif

View File

@ -177,6 +177,10 @@ const btstack_audio_source_t * btstack_audio_embedded_source_get_instance(void);
const btstack_audio_sink_t * btstack_audio_esp32_sink_get_instance(void); const btstack_audio_sink_t * btstack_audio_esp32_sink_get_instance(void);
const btstack_audio_source_t * btstack_audio_esp32_source_get_instance(void); const btstack_audio_source_t * btstack_audio_esp32_source_get_instance(void);
// platform-specific extension
void btstack_audio_portaudio_sink_set_device(const char * device_name);
void btstack_audio_portaudio_source_set_device(const char * device_name);
/* API_END */ /* API_END */
#if defined __cplusplus #if defined __cplusplus