From 02ccade2b1a92e79efd5893be2382b79455e301e Mon Sep 17 00:00:00 2001 From: habibialireza Date: Thu, 2 Jul 2026 02:00:30 +0200 Subject: [PATCH] Fix microphone source switching while streaming --- src/audio/audio_system.c | 15 +++++++++++++-- src/audio/sw_codec_select.c | 38 ++++++++++++++++++++++++++++++------- src/audio/sw_codec_select.h | 9 +++++++++ 3 files changed, 53 insertions(+), 9 deletions(-) diff --git a/src/audio/audio_system.c b/src/audio/audio_system.c index c27d4cfd..493ee96f 100644 --- a/src/audio/audio_system.c +++ b/src/audio/audio_system.c @@ -587,9 +587,20 @@ SHELL_CMD_REGISTER(audio_system, &audio_system_cmd, "Audio system commands", NUL int audio_system_set_encoder_channel(uint8_t channel) { - encoder_channel = channel; + if (channel >= AUDIO_CH_NUM) { + LOG_ERR("Invalid microphone channel: %d", channel); + return -EINVAL; + } + + encoder_channel = channel; + sw_codec_cfg.encoder.audio_ch = channel; + + if (sw_codec_cfg.initialized && sw_codec_is_initialized()) { + return sw_codec_encoder_channel_set((enum audio_channel)channel); + } + LOG_INF("Microphone channel set to %d", channel); - return 0; + return 0; } uint8_t audio_system_get_encoder_channel() diff --git a/src/audio/sw_codec_select.c b/src/audio/sw_codec_select.c index 83fa76db..f1564206 100644 --- a/src/audio/sw_codec_select.c +++ b/src/audio/sw_codec_select.c @@ -83,6 +83,19 @@ bool sw_codec_is_initialized(void) return m_config.initialized; } +int sw_codec_encoder_channel_set(enum audio_channel channel) +{ + if (channel >= AUDIO_CH_NUM) { + LOG_ERR("Invalid encoder channel: %d", channel); + return -EINVAL; + } + + m_config.encoder.audio_ch = channel; + LOG_INF("Microphone channel set to %d", channel); + + return 0; +} + int sw_codec_encode(void *pcm_data, size_t pcm_size, uint8_t **encoded_data, size_t *encoded_size) { int ret; @@ -106,7 +119,7 @@ int sw_codec_encode(void *pcm_data, size_t pcm_size, uint8_t **encoded_data, siz case SW_CODEC_LC3: { #if (CONFIG_SW_CODEC_LC3) uint16_t encoded_bytes_written; - char *pcm_data_mono_ptrs[m_config.encoder.channel_mode]; + char *pcm_data_mono_ptrs[AUDIO_CH_NUM] = {0}; /* Since LC3 is a single channel codec, we must split the * stereo PCM stream @@ -121,19 +134,26 @@ int sw_codec_encode(void *pcm_data, size_t pcm_size, uint8_t **encoded_data, siz switch (m_config.encoder.channel_mode) { case SW_CODEC_MONO: { + enum audio_channel audio_ch = m_config.encoder.audio_ch; + + if (audio_ch >= AUDIO_CH_NUM) { + LOG_ERR("Invalid encoder channel: %d", audio_ch); + return -EINVAL; + } + ret = sw_codec_sample_rate_convert( - &encoder_converters[m_config.encoder.audio_ch], CONFIG_AUDIO_SAMPLE_RATE_HZ, + &encoder_converters[audio_ch], CONFIG_AUDIO_SAMPLE_RATE_HZ, m_config.encoder.sample_rate_hz, - pcm_data_mono_system_sample_rate[m_config.encoder.audio_ch], + pcm_data_mono_system_sample_rate[audio_ch], pcm_block_size_mono_system_sample_rate, - pcm_data_mono_converted_buf[m_config.encoder.audio_ch], &pcm_data_mono_ptrs[m_config.encoder.audio_ch], + pcm_data_mono_converted_buf[audio_ch], &pcm_data_mono_ptrs[audio_ch], &pcm_block_size_mono); if (ret) { - LOG_ERR("Sample rate conversion failed for channel %d: %d", m_config.encoder.audio_ch, ret); + LOG_ERR("Sample rate conversion failed for channel %d: %d", audio_ch, ret); return ret; } - ret = sw_codec_lc3_enc_run(pcm_data_mono_ptrs[m_config.encoder.audio_ch], + ret = sw_codec_lc3_enc_run(pcm_data_mono_ptrs[audio_ch], pcm_block_size_mono, LC3_USE_BITRATE_FROM_INIT, 0, sizeof(m_encoded_data), m_encoded_data, &encoded_bytes_written); @@ -446,7 +466,11 @@ int sw_codec_init(struct sw_codec_config sw_codec_cfg) } if (sw_codec_cfg.encoder.enabled && IS_ENABLED(SAMPLE_RATE_CONVERTER)) { - for (int i = 0; i < sw_codec_cfg.encoder.channel_mode; i++) { + int converter_count = (sw_codec_cfg.encoder.channel_mode == SW_CODEC_MONO) ? + AUDIO_CH_NUM : + sw_codec_cfg.encoder.channel_mode; + + for (int i = 0; i < converter_count; i++) { ret = sample_rate_converter_open(&encoder_converters[i]); if (ret) { LOG_ERR("Failed to initialize the sample rate converter for " diff --git a/src/audio/sw_codec_select.h b/src/audio/sw_codec_select.h index 3771fa79..6240a7f7 100644 --- a/src/audio/sw_codec_select.h +++ b/src/audio/sw_codec_select.h @@ -77,6 +77,15 @@ struct sw_codec_config { */ bool sw_codec_is_initialized(void); +/** + * @brief Set the encoder input channel used for mono encoding. + * + * @param[in] channel Audio channel to encode. + * + * @return 0 on success, error otherwise. + */ +int sw_codec_encoder_channel_set(enum audio_channel channel); + /** * @brief Encode PCM data and output encoded data. *