diff --git a/doc/manual/docs-template/how_to.md b/doc/manual/docs-template/how_to.md index 993ce44f3..cadb10816 100644 --- a/doc/manual/docs-template/how_to.md +++ b/doc/manual/docs-template/how_to.md @@ -50,6 +50,8 @@ Embedded platform properties: -----------------------------------|------------------------------------ HAVE_EMBEDDED_TIME_MS | System provides time in milliseconds HAVE_EMBEDDED_TICK | System provides tick interrupt +HAVE_HAL_AUDIO | Audio HAL is available +HAVE_HAL_AUDIO_SINK_STEREO_ONLY | Duplicate samples for mono playback FreeRTOS platform properties: diff --git a/platform/embedded/btstack_audio_embedded.c b/platform/embedded/btstack_audio_embedded.c index 867a9b2d6..cbb0323b0 100644 --- a/platform/embedded/btstack_audio_embedded.c +++ b/platform/embedded/btstack_audio_embedded.c @@ -71,10 +71,16 @@ static unsigned int output_buffer_samples; static volatile int input_buffer_ready; static volatile const int16_t * input_buffer_samples; static volatile uint16_t input_buffer_num_samples; +static unsigned int output_channels; static int source_active; static int sink_active; +// Support for stereo-only audio hal +#ifdef HAVE_HAL_AUDIO_SINK_STEREO_ONLY +static bool output_duplicate_samples; +#endif + static void btstack_audio_audio_played(uint8_t buffer_index){ output_buffer_to_play = (buffer_index + 1) % output_buffer_count; } @@ -92,6 +98,18 @@ static void driver_timer_handler_sink(btstack_timer_source_t * ts){ int16_t * buffer = hal_audio_sink_get_output_buffer(output_buffer_to_fill); (*playback_callback)(buffer, output_buffer_samples); +#ifdef HAVE_HAL_AUDIO_SINK_STEREO_ONLY + if (output_duplicate_samples){ + unsigned int i = output_buffer_samples; + do { + i--; + int16_t sample = buffer[i]; + buffer[2*i + 0] = sample; + buffer[2*i + 1] = sample; + } while ( i > 0 ); + } +#endif + // next output_buffer_to_fill = (output_buffer_to_fill + 1 ) % output_buffer_count; } @@ -118,10 +136,14 @@ static int btstack_audio_embedded_sink_init( uint32_t samplerate, void (*playback)(int16_t * buffer, uint16_t num_samples) ){ - if (!playback){ - log_error("No playback callback"); - return 1; - } + btstack_assert(playback != NULL); + btstack_assert(channels != 0); + +#ifdef HAVE_HAL_AUDIO_SINK_STEREO_ONLY + // always use stereo from hal, duplicate samples if needed + output_duplicate_samples = num_channels != 2; + channels = 2; +#endif playback_callback = playback; @@ -159,6 +181,8 @@ static void btstack_audio_embedded_sink_start_stream(void){ output_buffer_count = hal_audio_sink_get_num_output_buffers(); output_buffer_samples = hal_audio_sink_get_num_output_buffer_samples(); + btstack_assert(output_buffer_samples > 0); + // pre-fill HAL buffers uint16_t i; for (i=0;i