diff --git a/src/audio/codec_adapter/codec/cadence.c b/src/audio/codec_adapter/codec/cadence.c index 0eac9162d388..0f92059a5bc4 100644 --- a/src/audio/codec_adapter/codec/cadence.c +++ b/src/audio/codec_adapter/codec/cadence.c @@ -399,10 +399,6 @@ int cadence_codec_prepare(struct comp_dev *dev) goto free; } - ret = cadence_codec_init_process(dev); - if (ret) - goto free; - comp_dbg(dev, "cadence_codec_prepare() done"); return 0; free: diff --git a/src/audio/codec_adapter/codec_adapter.c b/src/audio/codec_adapter/codec_adapter.c index 6413b42021e0..7d826e9381c8 100644 --- a/src/audio/codec_adapter/codec_adapter.c +++ b/src/audio/codec_adapter/codec_adapter.c @@ -245,7 +245,7 @@ static int codec_adapter_prepare(struct comp_dev *dev) } /* Allocate local buffer */ - buff_size = MAX(cd->period_bytes, codec->cpd.in_buff_size) * buff_periods; + buff_size = MAX(cd->period_bytes, codec->cpd.out_buff_size) * buff_periods; if (cd->local_buff) { ret = buffer_set_size(cd->local_buff, buff_size); if (ret < 0) { @@ -392,6 +392,7 @@ static int codec_adapter_copy(struct comp_dev *dev) return ret; bytes_to_process -= codec->cpd.consumed; + processed += codec->cpd.consumed; comp_update_buffer_consume(source, codec->cpd.consumed); } @@ -405,6 +406,13 @@ static int codec_adapter_copy(struct comp_dev *dev) break; } + /* TODO: remove magic number and use possible maximum output per + * decoding algorithm type + * 9216 is maximum frame length bytes for mp3 at 192Khz, 24bits, + */ + if (local_buff->stream.free < 9217) + goto db_verify; + buffer_invalidate(source, codec_buff_size); codec_adapter_copy_from_source_to_lib(&source->stream, &codec->cpd, codec_buff_size); @@ -426,18 +434,22 @@ static int codec_adapter_copy(struct comp_dev *dev) bytes_to_process -= codec->cpd.consumed; processed += codec->cpd.consumed; produced += codec->cpd.produced; + + audio_stream_produce(&local_buff->stream, codec->cpd.produced); + comp_update_buffer_consume(source, codec->cpd.consumed); } if (!produced && !cd->deep_buff_bytes) { comp_dbg(dev, "codec_adapter_copy(): nothing processed in this call"); - goto end; - } else if (!produced && cd->deep_buff_bytes) { - goto db_verify; + /* we haven't produced anything in this period but we + * still have data in the local buffer to copy to sink + */ + if (audio_stream_get_avail_bytes(&local_buff->stream) >= cd->period_bytes) + goto copy_period; + else + goto end; } - audio_stream_produce(&local_buff->stream, produced); - comp_update_buffer_consume(source, processed); - db_verify: if (cd->deep_buff_bytes) { if (cd->deep_buff_bytes >= audio_stream_get_avail_bytes(&local_buff->stream)) { @@ -450,6 +462,7 @@ static int codec_adapter_copy(struct comp_dev *dev) } } +copy_period: comp_get_copy_limits_with_lock(local_buff, sink, &cl); copy_bytes = cl.frames * cl.source_frame_bytes; audio_stream_copy(&local_buff->stream, 0, diff --git a/src/include/sof/audio/codec_adapter/interfaces.h b/src/include/sof/audio/codec_adapter/interfaces.h index 4787ef4d72f4..f333fef7334f 100644 --- a/src/include/sof/audio/codec_adapter/interfaces.h +++ b/src/include/sof/audio/codec_adapter/interfaces.h @@ -36,6 +36,7 @@ static struct codec_interface interfaces[] = { .id = CADENCE_ID, /**< Cadence interface */ .init = cadence_codec_init, .prepare = cadence_codec_prepare, + .init_process = cadence_codec_init_process, .process = cadence_codec_process, .apply_config = cadence_codec_apply_config, .reset = cadence_codec_reset, diff --git a/tools/topology/CMakeLists.txt b/tools/topology/CMakeLists.txt index cce80a38dcd9..2e7f309656bd 100644 --- a/tools/topology/CMakeLists.txt +++ b/tools/topology/CMakeLists.txt @@ -129,6 +129,7 @@ set(TPLGS "sof-jsl-da7219\;sof-jsl-da7219\;-DPLATFORM=jsl" "sof-jsl-da7219\;sof-jsl-da7219-mx98360a\;-DPLATFORM=jsl-dedede" "sof-imx8mp-wm8960\;sof-imx8mp-wm8960" + "sof-imx8-processing-wm8960\;sof-imx8-processing-wm8960\;-DPP_CORE=0" "sof-smart-amplifier-nocodec\;sof-smart-amplifier-nocodec" "sof-jsl-rt5682\;sof-jsl-rt5682-rt1015\;-DPLATFORM=jsl-rt1015" "sof-jsl-rt5682\;sof-jsl-rt5682-mx98360a\;-DPLATFORM=jsl-dedede" diff --git a/tools/topology/sof-imx8-processing-wm8960.m4 b/tools/topology/sof-imx8-processing-wm8960.m4 new file mode 100644 index 000000000000..ccf222d27eb1 --- /dev/null +++ b/tools/topology/sof-imx8-processing-wm8960.m4 @@ -0,0 +1,91 @@ +# +# Topology with codec_adapter processing component for i.MX8QM/i.MX8QXP +# + +# Include topology builder +include(`utils.m4') +include(`dai.m4') +include(`pipeline.m4') +include(`sai.m4') +include(`pcm.m4') +include(`buffer.m4') + +# Include TLV library +include(`common/tlv.m4') + +# Include Token library +include(`sof/tokens.m4') + +# Include DSP configuration +include(`platform/imx/imx8qxp.m4') + + +# Post process setup config + + #codec Post Process setup config +# +# Define the pipelines +# +# PCM0 <----> volume <-----> SAI3 (wm8960) +# + + ++# Post process setup config +define(`CA_SETUP_CONTROLBYTES', +`` bytes "0x53,0x4f,0x46,0x00,0x00,0x00,0x00,0x00,' +` 0x20,0x00,0x00,0x00,0x00,0x10,0x00,0x03,' +` 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,' +` 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,' +` 0x06,0x01,0xDE,0xCA,0x00,0x00,0x00,0x00,' +` 0x80,0xBB,0x00,0x00,0x20,0x00,0x00,0x00,' +` 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,' +` 0x0C,0x00,0x00,0x00,0x20,0x00,0x00,0x00"'' +) + +define(`CA_SETUP_CONTROLBYTES_MAX', 300) + +undefine(`DAI_PERIODS') +define(`DAI_PERIODS', 16) + +dnl PIPELINE_PCM_ADD(pipeline, +dnl pipe id, pcm, max channels, format, +dnl period, priority, core, +dnl pcm_min_rate, pcm_max_rate, pipeline_rate, +dnl time_domain, sched_comp) + +# Low Latency playback pipeline 1 on PCM 0 using max 2 channels of s32le. +# Set 1000us deadline on core 0 with priority 0 +PIPELINE_PCM_ADD(sof/pipe-codec-adapter-playback.m4, + 1, 0, 2, s32le, + 1000, 0, 0, + 48000, 48000, 48000) + +# +# DAIs configuration +# + +dnl DAI_ADD(pipeline, +dnl pipe id, dai type, dai_index, dai_be, +dnl buffer, periods, format, +dnl period, priority, core, time_domain) + +# playback DAI is SAI3 using 2 periods +# Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 +DAI_ADD(sof/pipe-dai-playback.m4, + 1, SAI, 1, sai1-wm8960-hifi, + PIPELINE_SOURCE_1, 2, s32le, + 1000, 0, 0, SCHEDULE_TIME_DOMAIN_DMA) + + +# PCM Low Latency, id 0 + +dnl PCM_DUPLEX_ADD(name, pcm_id, playback, capture) +COMPR_PLAYBACK_ADD(Port0, 0, PIPELINE_PCM_1) + +dnl DAI_CONFIG(type, idx, link_id, name, sai_config) +DAI_CONFIG(SAI, 1, 0, sai1-wm8960-hifi, + SAI_CONFIG(I2S, SAI_CLOCK(mclk, 12288000, codec_mclk_in), + SAI_CLOCK(bclk, 3072000, codec_master), + SAI_CLOCK(fsync, 48000, codec_master), + SAI_TDM(2, 32, 3, 3), + SAI_CONFIG_DATA(SAI, 1, 0))) diff --git a/tools/topology/sof/pipe-codec-adapter-playback.m4 b/tools/topology/sof/pipe-codec-adapter-playback.m4 index af3c5e4c1b98..9619fb1f16b4 100644 --- a/tools/topology/sof/pipe-codec-adapter-playback.m4 +++ b/tools/topology/sof/pipe-codec-adapter-playback.m4 @@ -115,10 +115,10 @@ W_CODEC_ADAPTER(0, PIPELINE_FORMAT, DAI_PERIODS, DAI_PERIODS, CA_SCHEDULE_CORE, LIST(` ', "CA_SETUP_CONTROLBYTES_NAME_PIPE", "CA_RUNTIME_CONTROLBYTES_NAME_PIPE")) # Playback Buffers -W_BUFFER(0, COMP_BUFFER_SIZE(DAI_PERIODS, +W_BUFFER(0, COMP_BUFFER_SIZE(8, COMP_SAMPLE_SIZE(PIPELINE_FORMAT), PIPELINE_CHANNELS, COMP_PERIOD_FRAMES(PCM_MAX_RATE, SCHEDULE_PERIOD)), PLATFORM_HOST_MEM_CAP, SCHEDULE_CORE) -W_BUFFER(1, COMP_BUFFER_SIZE(DAI_PERIODS, +W_BUFFER(1, COMP_BUFFER_SIZE(2, COMP_SAMPLE_SIZE(DAI_FORMAT), PIPELINE_CHANNELS, COMP_PERIOD_FRAMES(PCM_MAX_RATE, SCHEDULE_PERIOD)), PLATFORM_DAI_MEM_CAP, SCHEDULE_CORE)