From 7a5ab6ae43f3fd4a3e9a09621753a5fe007d2a6e Mon Sep 17 00:00:00 2001 From: Pin-chih Lin Date: Fri, 10 Feb 2023 11:51:58 +0800 Subject: [PATCH 1/4] module_adapter: waves: fix unfreed rballoc memory block There is a rballoc() call during module_init() lacking the correspondent rfree() on module_free(). Replace it with module_allocate_memory() to ensure the memory to be freed by module_adapter. Signed-off-by: Pin-chih Lin (cherry picked from commit eedd76ae375e69f1845b57a34cab0ae5d5f41509) --- src/audio/module_adapter/module/waves.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/audio/module_adapter/module/waves.c b/src/audio/module_adapter/module/waves.c index ed8a3f9c219b..89e1e6b02551 100644 --- a/src/audio/module_adapter/module/waves.c +++ b/src/audio/module_adapter/module/waves.c @@ -622,7 +622,7 @@ static int waves_codec_init(struct processing_module *mod) struct module_config *setup_cfg = &waves_codec->setup_cfg; /* allocate memory for set up config */ - setup_cfg->data = rballoc(0, SOF_MEM_CAPS_RAM, codec->cfg.size); + setup_cfg->data = module_allocate_memory(mod, codec->cfg.size, 16); if (!setup_cfg->data) { comp_err(dev, "waves_codec_init(): failed to alloc setup config"); module_free_memory(mod, waves_codec); @@ -634,6 +634,7 @@ static int waves_codec_init(struct processing_module *mod) ret = memcpy_s(setup_cfg->data, setup_cfg->size, codec->cfg.data, setup_cfg->size); if (ret) { comp_err(dev, "waves_codec_init(): failed to copy setup config %d", ret); + module_free_memory(mod, setup_cfg->data); module_free_memory(mod, waves_codec); return ret; } From 3d8ac157bcd008ed4ab53be56c34ff6ca2a22ae8 Mon Sep 17 00:00:00 2001 From: Pin-chih Lin Date: Mon, 13 Feb 2023 06:29:04 +0800 Subject: [PATCH 2/4] topology1: add PDM1 version for sof-adl-max98360a-rt5682-2way Adds new topology build based on sof-adl-max98360a-rt5682-2way with appending arg `-DDMIC_DAI_LINK_16k_PDM=STEREO_PDM1` for existing ADL-P projects. Signed-off-by: Pin-chih Lin (cherry picked from commit feeb51f216d3f26a4e00eb1047f2583cd59b16bf) --- tools/topology/topology1/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/topology/topology1/CMakeLists.txt b/tools/topology/topology1/CMakeLists.txt index d4c652b4df14..15bfa738f759 100644 --- a/tools/topology/topology1/CMakeLists.txt +++ b/tools/topology/topology1/CMakeLists.txt @@ -149,6 +149,7 @@ set(TPLGS "sof-tgl-max98357a-rt5682\;sof-adl-max98360a-rt5682\;-DCODEC=MAX98360A\;-DFMT=s32le\;-DPLATFORM=adl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=1\;-DBT_OFFLOAD\;-DSPK_MIC_PERIOD_US=10000" "sof-tgl-max98357a-rt5682\;sof-adl-max98360a-rt5682-waves\;-DCODEC=MAX98360A\;-DFMT=s32le\;-DPLATFORM=adl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=1\;-DWAVES" "sof-tgl-max98357a-rt5682\;sof-adl-max98360a-rt5682-2way\;-DCODEC=MAX98360A_TDM\;-DFMT=s32le\;-DPLATFORM=adl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=1\;-D2CH_2WAY\;-DBT_OFFLOAD" + "sof-tgl-max98357a-rt5682\;sof-adl-max98360a-rt5682-2way-pdm1\;-DCODEC=MAX98360A_TDM\;-DFMT=s32le\;-DDMIC_DAI_LINK_16k_PDM=STEREO_PDM1\;-DPLATFORM=adl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=1\;-D2CH_2WAY\;-DBT_OFFLOAD" "sof-tgl-max98357a-rt5682\;sof-adl-max98360a-rt5682-4ch\;-DCODEC=MAX98360A_TDM\;-DFMT=s32le\;-DPLATFORM=adl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=1\;-D4CH_PASSTHROUGH\;-DBT_OFFLOAD" "sof-tgl-max98357a-rt5682\;sof-adl-max98360a-rt5682-rtnr\;-DCODEC=MAX98360A\;-DFMT=s32le\;-DPLATFORM=adl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=1\;-DCHANNELS=2\;-DRTNR" "sof-tgl-max98357a-rt5682\;sof-adl-max98360a-rt5682-rtnr-google-aec\;-DCODEC=MAX98360A\;-DFMT=s32le\;-DPLATFORM=adl\;-DLINUX_MACHINE_DRIVER=sof_rt5682\;-DAMP_SSP=1\;-DCHANNELS=2\;-DGOOGLE_RTC_AUDIO_PROCESSING\;-DRTNR\;-DNOHOTWORD\;-DNO16KDMIC" From a2c6e433f921081f472ec084b8140ae23541975c Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 13 Apr 2022 12:19:57 +0200 Subject: [PATCH 3/4] smart_amp: fix buffer acquisition Instead of acquiring and releasing buffers locally multiple times, do that once for .copy(), .trigger() and .prepare() methods. Signed-off-by: Guennadi Liakhovetski (cherry picked from commit 6c94904f3d130bae67f4f4897a4a7e2a9196c4b5) --- src/audio/smart_amp/smart_amp.c | 132 ++++++++++---------- src/audio/smart_amp/smart_amp_generic.c | 36 +++--- src/audio/smart_amp/smart_amp_maxim_dsm.c | 24 ++-- src/include/sof/audio/smart_amp/smart_amp.h | 14 +-- 4 files changed, 103 insertions(+), 103 deletions(-) diff --git a/src/audio/smart_amp/smart_amp.c b/src/audio/smart_amp/smart_amp.c index e5f617d6f56a..3be0d63babc1 100644 --- a/src/audio/smart_amp/smart_amp.c +++ b/src/audio/smart_amp/smart_amp.c @@ -25,8 +25,8 @@ DECLARE_TR_CTX(maxim_dsm_comp_tr, SOF_UUID(maxim_dsm_comp_uuid), #define SOF_SMART_AMP_MODEL 1 typedef int(*smart_amp_proc)(struct comp_dev *dev, - const struct audio_stream *source, - const struct audio_stream *sink, uint32_t frames, + const struct audio_stream __sparse_cache *source, + const struct audio_stream __sparse_cache *sink, uint32_t frames, int8_t *chan_map, bool is_feedback); struct smart_amp_data { @@ -516,8 +516,11 @@ static int smart_amp_trigger(struct comp_dev *dev, int cmd) switch (cmd) { case COMP_TRIGGER_START: case COMP_TRIGGER_RELEASE: - if (sad->feedback_buf) - buffer_zero(sad->feedback_buf); + if (sad->feedback_buf) { + struct comp_buffer __sparse_cache *buf = buffer_acquire(sad->feedback_buf); + buffer_zero(buf); + buffer_release(buf); + } break; case COMP_TRIGGER_PAUSE: case COMP_TRIGGER_STOP: @@ -530,8 +533,8 @@ static int smart_amp_trigger(struct comp_dev *dev, int cmd) } static int smart_amp_process(struct comp_dev *dev, - const struct audio_stream *source, - const struct audio_stream *sink, + const struct audio_stream __sparse_cache *source, + const struct audio_stream __sparse_cache *sink, uint32_t frames, int8_t *chan_map, bool is_feedback) { @@ -540,14 +543,14 @@ static int smart_amp_process(struct comp_dev *dev, if (!is_feedback) ret = smart_amp_ff_copy(dev, frames, - sad->source_buf, sad->sink_buf, + source, sink, chan_map, sad->mod_handle, sad->in_channels, sad->out_channels); else ret = smart_amp_fb_copy(dev, frames, - sad->feedback_buf, sad->sink_buf, + source, sink, chan_map, sad->mod_handle, - sad->feedback_buf->stream.channels); + source->channels); return ret; } @@ -569,83 +572,71 @@ static smart_amp_proc get_smart_amp_process(struct comp_dev *dev) static int smart_amp_copy(struct comp_dev *dev) { struct smart_amp_data *sad = comp_get_drvdata(dev); - struct comp_buffer *source_buf = sad->source_buf; - struct comp_buffer *sink_buf = sad->sink_buf; + struct comp_buffer __sparse_cache *source_buf = buffer_acquire(sad->source_buf); + struct comp_buffer __sparse_cache *sink_buf = buffer_acquire(sad->sink_buf); uint32_t avail_passthrough_frames; uint32_t avail_feedback_frames; uint32_t avail_frames; uint32_t source_bytes; uint32_t sink_bytes; uint32_t feedback_bytes; - int ret = 0; comp_dbg(dev, "smart_amp_copy()"); - source_buf = buffer_acquire(source_buf); - sink_buf = buffer_acquire(sink_buf); - /* available bytes and samples calculation */ - avail_passthrough_frames = - audio_stream_avail_frames(&sad->source_buf->stream, - &sad->sink_buf->stream); - - source_buf = buffer_release(source_buf); - sink_buf = buffer_release(sink_buf); + avail_passthrough_frames = audio_stream_avail_frames(&source_buf->stream, + &sink_buf->stream); avail_frames = avail_passthrough_frames; if (sad->feedback_buf) { - struct comp_buffer *buf = sad->feedback_buf; + struct comp_buffer __sparse_cache *feedback_buf = buffer_acquire(sad->feedback_buf); - buf = buffer_acquire(buf); - if (comp_get_state(dev, buf->source) == dev->state) { + if (comp_get_state(dev, feedback_buf->source) == dev->state) { /* feedback */ avail_feedback_frames = - audio_stream_get_avail_frames(&buf->stream); + audio_stream_get_avail_frames(&feedback_buf->stream); avail_frames = MIN(avail_passthrough_frames, avail_feedback_frames); feedback_bytes = avail_frames * - audio_stream_frame_bytes(&buf->stream); - - buffer_release(buf); + audio_stream_frame_bytes(&feedback_buf->stream); comp_dbg(dev, "smart_amp_copy(): processing %d feedback frames (avail_passthrough_frames: %d)", avail_frames, avail_passthrough_frames); /* perform buffer writeback after source_buf process */ - buffer_stream_invalidate(sad->feedback_buf, feedback_bytes); - sad->process(dev, &sad->feedback_buf->stream, - &sad->sink_buf->stream, avail_frames, + buffer_stream_invalidate(feedback_buf, feedback_bytes); + sad->process(dev, &feedback_buf->stream, + &sink_buf->stream, avail_frames, sad->config.feedback_ch_map, true); - comp_update_buffer_consume(sad->feedback_buf, feedback_bytes); - } else { - buffer_release(buf); + comp_update_buffer_cached_consume(feedback_buf, feedback_bytes); } + + buffer_release(feedback_buf); } /* bytes calculation */ - source_buf = buffer_acquire(source_buf); source_bytes = avail_frames * audio_stream_frame_bytes(&source_buf->stream); - source_buf = buffer_release(source_buf); - sink_buf = buffer_acquire(sink_buf); sink_bytes = avail_frames * audio_stream_frame_bytes(&sink_buf->stream); - sink_buf = buffer_release(sink_buf); /* process data */ - buffer_stream_invalidate(sad->source_buf, source_bytes); - sad->process(dev, &sad->source_buf->stream, &sad->sink_buf->stream, + buffer_stream_invalidate(source_buf, source_bytes); + sad->process(dev, &source_buf->stream, &sink_buf->stream, avail_frames, sad->config.source_ch_map, false); - buffer_stream_writeback(sad->sink_buf, sink_bytes); + buffer_stream_writeback(sink_buf, sink_bytes); /* source/sink buffer pointers update */ - comp_update_buffer_consume(sad->source_buf, source_bytes); - comp_update_buffer_produce(sad->sink_buf, sink_bytes); + comp_update_buffer_cached_consume(source_buf, source_bytes); + comp_update_buffer_cached_produce(sink_buf, sink_bytes); - return ret; + buffer_release(sink_buf); + buffer_release(source_buf); + + return 0; } static int smart_amp_reset(struct comp_dev *dev) @@ -666,7 +657,7 @@ static int smart_amp_reset(struct comp_dev *dev) static int smart_amp_prepare(struct comp_dev *dev) { struct smart_amp_data *sad = comp_get_drvdata(dev); - struct comp_buffer *source_buffer; + struct comp_buffer __sparse_cache *source_c, *buf_c; struct list_item *blist; int ret; int bitwidth; @@ -679,40 +670,47 @@ static int smart_amp_prepare(struct comp_dev *dev) /* searching for stream and feedback source buffers */ list_for_item(blist, &dev->bsource_list) { - source_buffer = container_of(blist, struct comp_buffer, - sink_list); - source_buffer = buffer_acquire(source_buffer); - if (source_buffer->source->ipc_config.type == SOF_COMP_DEMUX) + struct comp_buffer *source_buffer = container_of(blist, struct comp_buffer, + sink_list); + source_c = buffer_acquire(source_buffer); + + if (source_c->source->ipc_config.type == SOF_COMP_DEMUX) { sad->feedback_buf = source_buffer; - else + } else { sad->source_buf = source_buffer; - source_buffer = buffer_release(source_buffer); + sad->in_channels = source_c->stream.channels; + } + + buffer_release(source_c); } sad->sink_buf = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - sad->in_channels = sad->source_buf->stream.channels; - sad->out_channels = sad->sink_buf->stream.channels; + buf_c = buffer_acquire(sad->sink_buf); + sad->out_channels = buf_c->stream.channels; + buffer_release(buf_c); + + source_c = buffer_acquire(sad->source_buf); if (sad->feedback_buf) { - struct comp_buffer *buf = sad->feedback_buf; - - buf = buffer_acquire(buf); - buf->stream.channels = sad->config.feedback_channels; - buf->stream.rate = sad->source_buf->stream.rate; - buffer_release(buf); - ret = smart_amp_check_audio_fmt(sad->source_buf->stream.rate, - sad->source_buf->stream.channels); + buf_c = buffer_acquire(sad->feedback_buf); + + buf_c->stream.channels = sad->config.feedback_channels; + buf_c->stream.rate = source_c->stream.rate; + buffer_release(buf_c); + + ret = smart_amp_check_audio_fmt(source_c->stream.rate, + source_c->stream.channels); if (ret) { comp_err(dev, "[DSM] Format not supported, sample rate: %d, ch: %d", - sad->source_buf->stream.rate, - sad->source_buf->stream.channels); + source_c->stream.rate, + source_c->stream.channels); goto error; } } - switch (sad->source_buf->stream.frame_fmt) { + switch (source_c->stream.frame_fmt) { case SOF_IPC_FRAME_S16_LE: bitwidth = 16; break; @@ -724,9 +722,10 @@ static int smart_amp_prepare(struct comp_dev *dev) break; default: comp_err(dev, "[DSM] smart_amp_process() error: not supported frame format %d", - sad->source_buf->stream.frame_fmt); + source_c->stream.frame_fmt); goto error; } + if (sad->mod_handle->bitwidth != bitwidth) { sad->mod_handle->bitwidth = bitwidth; comp_info(dev, "[DSM] Re-initialized for %d bit processing", bitwidth); @@ -747,10 +746,11 @@ static int smart_amp_prepare(struct comp_dev *dev) if (!sad->process) { comp_err(dev, "smart_amp_prepare(): get_smart_amp_process failed"); ret = -EINVAL; - goto error; } error: + buffer_release(source_c); + smart_amp_flush(sad->mod_handle, dev); return ret; } diff --git a/src/audio/smart_amp/smart_amp_generic.c b/src/audio/smart_amp/smart_amp_generic.c index c9b79ff284d0..c969f66eadec 100644 --- a/src/audio/smart_amp/smart_amp_generic.c +++ b/src/audio/smart_amp/smart_amp_generic.c @@ -24,9 +24,9 @@ static void smart_amp_fb_generic(int32_t x) #if CONFIG_FORMAT_S16LE static void smart_amp_s16_ff_default(const struct comp_dev *dev, - const struct audio_stream *source, - const struct audio_stream *sink, - const struct audio_stream *feedback, + const struct audio_stream __sparse_cache *source, + const struct audio_stream __sparse_cache *sink, + const struct audio_stream __sparse_cache *feedback, uint32_t frames) { int16_t *x; @@ -52,9 +52,9 @@ static void smart_amp_s16_ff_default(const struct comp_dev *dev, #if CONFIG_FORMAT_S24LE static void smart_amp_s24_ff_default(const struct comp_dev *dev, - const struct audio_stream *source, - const struct audio_stream *sink, - const struct audio_stream *feedback, + const struct audio_stream __sparse_cache *source, + const struct audio_stream __sparse_cache *sink, + const struct audio_stream __sparse_cache *feedback, uint32_t frames) { int32_t *x; @@ -80,9 +80,9 @@ static void smart_amp_s24_ff_default(const struct comp_dev *dev, #if CONFIG_FORMAT_S32LE static void smart_amp_s32_ff_default(const struct comp_dev *dev, - const struct audio_stream *source, - const struct audio_stream *sink, - const struct audio_stream *feedback, + const struct audio_stream __sparse_cache *source, + const struct audio_stream __sparse_cache *sink, + const struct audio_stream __sparse_cache *feedback, uint32_t frames) { int32_t *x; @@ -106,9 +106,9 @@ static void smart_amp_s32_ff_default(const struct comp_dev *dev, #if CONFIG_FORMAT_S16LE static void smart_amp_s16_fb_default(const struct comp_dev *dev, - const struct audio_stream *source, - const struct audio_stream *sink, - const struct audio_stream *feedback, + const struct audio_stream __sparse_cache *source, + const struct audio_stream __sparse_cache *sink, + const struct audio_stream __sparse_cache *feedback, uint32_t frames) { int16_t *x; @@ -130,9 +130,9 @@ static void smart_amp_s16_fb_default(const struct comp_dev *dev, #if CONFIG_FORMAT_S24LE static void smart_amp_s24_fb_default(const struct comp_dev *dev, - const struct audio_stream *source, - const struct audio_stream *sink, - const struct audio_stream *feedback, + const struct audio_stream __sparse_cache *source, + const struct audio_stream __sparse_cache *sink, + const struct audio_stream __sparse_cache *feedback, uint32_t frames) { int32_t *x; @@ -154,9 +154,9 @@ static void smart_amp_s24_fb_default(const struct comp_dev *dev, #if CONFIG_FORMAT_S32LE static void smart_amp_s32_fb_default(const struct comp_dev *dev, - const struct audio_stream *source, - const struct audio_stream *sink, - const struct audio_stream *feedback, + const struct audio_stream __sparse_cache *source, + const struct audio_stream __sparse_cache *sink, + const struct audio_stream __sparse_cache *feedback, uint32_t frames) { int32_t *x; diff --git a/src/audio/smart_amp/smart_amp_maxim_dsm.c b/src/audio/smart_amp/smart_amp_maxim_dsm.c index 73ff38c38b89..14cf31119f65 100644 --- a/src/audio/smart_amp/smart_amp_maxim_dsm.c +++ b/src/audio/smart_amp/smart_amp_maxim_dsm.c @@ -579,7 +579,7 @@ int smart_amp_check_audio_fmt(int sample_rate, int ch_num) } static int smart_amp_get_buffer(int32_t *buf, uint32_t frames, - struct audio_stream *stream, + const struct audio_stream __sparse_cache *stream, int8_t *chan_map, uint32_t num_ch) { int idx, ch; @@ -629,7 +629,7 @@ static int smart_amp_get_buffer(int32_t *buf, uint32_t frames, } static int smart_amp_put_buffer(int32_t *buf, uint32_t frames, - struct audio_stream *stream, + const struct audio_stream __sparse_cache *stream, int8_t *chan_map, uint32_t num_ch_in, uint32_t num_ch_out) { @@ -681,8 +681,8 @@ static int smart_amp_put_buffer(int32_t *buf, uint32_t frames, } int smart_amp_ff_copy(struct comp_dev *dev, uint32_t frames, - struct comp_buffer *source, - struct comp_buffer *sink, int8_t *chan_map, + const struct audio_stream __sparse_cache *source, + const struct audio_stream __sparse_cache *sink, int8_t *chan_map, struct smart_amp_mod_struct_t *hspk, uint32_t num_ch_in, uint32_t num_ch_out) { @@ -703,12 +703,12 @@ int smart_amp_ff_copy(struct comp_dev *dev, uint32_t frames, num_ch_out = MIN(num_ch_out, SMART_AMP_FF_OUT_MAX_CH_NUM); ret = smart_amp_get_buffer(hspk->buf.frame_in, - frames, &source->stream, chan_map, + frames, source, chan_map, num_ch_in); if (ret) goto err; - switch (source->stream.frame_fmt) { + switch (source->frame_fmt) { case SOF_IPC_FRAME_S16_LE: maxim_dsm_ff_proc(hspk, dev, hspk->buf.frame_in, @@ -728,7 +728,7 @@ int smart_amp_ff_copy(struct comp_dev *dev, uint32_t frames, } ret = smart_amp_put_buffer(hspk->buf.frame_out, - frames, &sink->stream, chan_map, + frames, sink, chan_map, MIN(num_ch_in, SMART_AMP_FF_MAX_CH_NUM), MIN(num_ch_out, SMART_AMP_FF_OUT_MAX_CH_NUM)); if (ret) @@ -741,8 +741,8 @@ int smart_amp_ff_copy(struct comp_dev *dev, uint32_t frames, } int smart_amp_fb_copy(struct comp_dev *dev, uint32_t frames, - struct comp_buffer *source, - struct comp_buffer *sink, int8_t *chan_map, + const struct audio_stream __sparse_cache *source, + const struct audio_stream __sparse_cache *sink, int8_t *chan_map, struct smart_amp_mod_struct_t *hspk, uint32_t num_ch) { @@ -762,12 +762,12 @@ int smart_amp_fb_copy(struct comp_dev *dev, uint32_t frames, num_ch = MIN(num_ch, SMART_AMP_FB_MAX_CH_NUM); ret = smart_amp_get_buffer(hspk->buf.frame_iv, - frames, &source->stream, + frames, source, chan_map, num_ch); if (ret) goto err; - switch (source->stream.frame_fmt) { + switch (source->frame_fmt) { case SOF_IPC_FRAME_S16_LE: maxim_dsm_fb_proc(hspk, dev, hspk->buf.frame_iv, frames * num_ch, sizeof(int16_t)); @@ -784,6 +784,6 @@ int smart_amp_fb_copy(struct comp_dev *dev, uint32_t frames, return 0; err: comp_err(dev, "[DSM] Not supported frame format : %d", - source->stream.frame_fmt); + source->frame_fmt); return ret; } diff --git a/src/include/sof/audio/smart_amp/smart_amp.h b/src/include/sof/audio/smart_amp/smart_amp.h index 14e372f1122f..6438d7f082bc 100644 --- a/src/include/sof/audio/smart_amp/smart_amp.h +++ b/src/include/sof/audio/smart_amp/smart_amp.h @@ -136,9 +136,9 @@ struct smart_amp_mod_struct_t { }; typedef void (*smart_amp_func)(const struct comp_dev *dev, - const struct audio_stream *source, - const struct audio_stream *sink, - const struct audio_stream *feedback, + const struct audio_stream __sparse_cache *source, + const struct audio_stream __sparse_cache *sink, + const struct audio_stream __sparse_cache *feedback, uint32_t frames); struct smart_amp_func_map { uint16_t frame_fmt; @@ -151,14 +151,14 @@ int smart_amp_init(struct smart_amp_mod_struct_t *hspk, struct comp_dev *dev); int smart_amp_flush(struct smart_amp_mod_struct_t *hspk, struct comp_dev *dev); /* Feed forward processing function */ int smart_amp_ff_copy(struct comp_dev *dev, uint32_t frames, - struct comp_buffer *source, - struct comp_buffer *sink, int8_t *chan_map, + const struct audio_stream __sparse_cache *source, + const struct audio_stream __sparse_cache *sink, int8_t *chan_map, struct smart_amp_mod_struct_t *hspk, uint32_t num_ch_in, uint32_t num_ch_out); /* Feedback processing function */ int smart_amp_fb_copy(struct comp_dev *dev, uint32_t frames, - struct comp_buffer *source, - struct comp_buffer *sink, int8_t *chan_map, + const struct audio_stream __sparse_cache *source, + const struct audio_stream __sparse_cache *sink, int8_t *chan_map, struct smart_amp_mod_struct_t *hspk, uint32_t num_ch); /* memory usage calculation for the component */ From ad1c720cc33e8adb9b1d9e18df0f284fc436314a Mon Sep 17 00:00:00 2001 From: Long Wang Date: Tue, 7 Feb 2023 00:44:01 -0800 Subject: [PATCH 4/4] smart_amp: eliminat pops when switch device between speaker and headphone. There are two pops caused by SOF Firmware. Pop occurs when switch from headphone to speaker: When switch to headphone, audio playback data still remains in DSM internal processing buffer and not consumed by DMA. So when switch back to speaker, the DSM processing buffer is not clean, then pop noise occurs. We can clean and reset the point for DSM internal processing buffer by called this function 'smart_amp_init' in function 'smart_amp_prepare'. Pop occurs when switch from speaker to headphone: The feedback and feed-forward buffer processing should be independent. But the number of frames processed by DSM feedforward is corrupted by feedback buffer calculation. When capture pipeline exists, the number of frames for feedforward is always same as feedback. And the number of frames for feedback is zero at the first time when the capture pipeline setup. Then the number of frames processed by DSM feed forward is also zero though there are many frames in playback buffer. So the available frames will become larger. It is easy to exceed the limit size of DSM input. Then it will cause the buffer overflow and we could hear obvious pop noise from speaker. We fix it by calculating the number of frames for feedforward and feedback respectively. Signed-off-by: Long Wang (cherry picked from commit 8a1798e4e843a2a3c8f29387c091e105b4bc4810) --- src/audio/smart_amp/smart_amp.c | 35 +++++++++++++++------------------ 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/src/audio/smart_amp/smart_amp.c b/src/audio/smart_amp/smart_amp.c index 3be0d63babc1..eeea155a7f3d 100644 --- a/src/audio/smart_amp/smart_amp.c +++ b/src/audio/smart_amp/smart_amp.c @@ -597,19 +597,19 @@ static int smart_amp_copy(struct comp_dev *dev) avail_feedback_frames = audio_stream_get_avail_frames(&feedback_buf->stream); - avail_frames = MIN(avail_passthrough_frames, - avail_feedback_frames); + avail_feedback_frames = MIN(avail_passthrough_frames, + avail_feedback_frames); - feedback_bytes = avail_frames * + feedback_bytes = avail_feedback_frames * audio_stream_frame_bytes(&feedback_buf->stream); comp_dbg(dev, "smart_amp_copy(): processing %d feedback frames (avail_passthrough_frames: %d)", - avail_frames, avail_passthrough_frames); + avail_feedback_frames, avail_passthrough_frames); /* perform buffer writeback after source_buf process */ buffer_stream_invalidate(feedback_buf, feedback_bytes); sad->process(dev, &feedback_buf->stream, - &sink_buf->stream, avail_frames, + &sink_buf->stream, avail_feedback_frames, sad->config.feedback_ch_map, true); comp_update_buffer_cached_consume(feedback_buf, feedback_bytes); @@ -620,7 +620,6 @@ static int smart_amp_copy(struct comp_dev *dev) /* bytes calculation */ source_bytes = avail_frames * audio_stream_frame_bytes(&source_buf->stream); - sink_bytes = avail_frames * audio_stream_frame_bytes(&sink_buf->stream); /* process data */ @@ -726,20 +725,18 @@ static int smart_amp_prepare(struct comp_dev *dev) goto error; } - if (sad->mod_handle->bitwidth != bitwidth) { - sad->mod_handle->bitwidth = bitwidth; - comp_info(dev, "[DSM] Re-initialized for %d bit processing", bitwidth); + sad->mod_handle->bitwidth = bitwidth; + comp_info(dev, "[DSM] Re-initialized for %d bit processing", bitwidth); - ret = smart_amp_init(sad->mod_handle, dev); - if (ret) { - comp_err(dev, "[DSM] Re-initialization error."); - goto error; - } - ret = maxim_dsm_restore_param(sad->mod_handle, dev); - if (ret) { - comp_err(dev, "[DSM] Restoration error."); - goto error; - } + ret = smart_amp_init(sad->mod_handle, dev); + if (ret) { + comp_err(dev, "[DSM] Re-initialization error."); + goto error; + } + ret = maxim_dsm_restore_param(sad->mod_handle, dev); + if (ret) { + comp_err(dev, "[DSM] Restoration error."); + goto error; } sad->process = get_smart_amp_process(dev);