diff --git a/src/audio/drc/drc.c b/src/audio/drc/drc.c index 888a2718f32e..95bc73ffc194 100644 --- a/src/audio/drc/drc.c +++ b/src/audio/drc/drc.c @@ -401,12 +401,8 @@ static int drc_prepare(struct comp_dev *dev) goto err; } } else { - cd->drc_func = drc_find_proc_func_pass(cd->source_format); - if (!cd->drc_func) { - comp_err(dev, "drc_prepare(), No proc func passthrough"); - ret = -EINVAL; - goto err; - } + /* Generic function for all formats */ + cd->drc_func = drc_default_pass; } comp_info(dev, "drc_prepare(), DRC is configured."); diff --git a/src/audio/drc/drc_generic.c b/src/audio/drc/drc_generic.c index 94dfabca5b18..2d3c878e9624 100644 --- a/src/audio/drc/drc_generic.c +++ b/src/audio/drc/drc_generic.c @@ -465,255 +465,253 @@ static void drc_process_one_division(struct drc_state *state, drc_compress_output(state, p, nbyte, nch); } -#if CONFIG_FORMAT_S16LE -static void drc_s16_default_pass(const struct comp_dev *dev, - const struct audio_stream *source, - struct audio_stream *sink, - uint32_t frames) +void drc_default_pass(const struct comp_dev *dev, const struct audio_stream *source, + struct audio_stream *sink, uint32_t frames) { - int16_t *x; - int16_t *y; - int i; - int n = source->channels * frames; + audio_stream_copy(source, 0, sink, 0, frames * source->channels); +} - for (i = 0; i < n; i++) { - x = audio_stream_read_frag_s16(source, i); - y = audio_stream_write_frag_s16(sink, i); - *y = *x; - } +static inline void drc_pre_delay_index_inc(int *idx, int increment) +{ + *idx = (*idx + increment) & DRC_MAX_PRE_DELAY_FRAMES_MASK; } -#endif /* CONFIG_FORMAT_S16LE */ -#if CONFIG_FORMAT_S24LE || CONFIG_FORMAT_S32LE -static void drc_s32_default_pass(const struct comp_dev *dev, - const struct audio_stream *source, - struct audio_stream *sink, - uint32_t frames) +#if CONFIG_FORMAT_S16LE +static void drc_delay_input_sample_s16(struct drc_state *state, const struct audio_stream *source, + struct audio_stream *sink, int16_t **x, int16_t **y, + int samples) { - int32_t *x; - int32_t *y; + int16_t *x1; + int16_t *y1; + int16_t *pd; + int pd_write_index, pd_read_index; + int nbuf, npcm, nfrm; + int ch; int i; - int n = source->channels * frames; + int16_t *x0 = *x; + int16_t *y0 = *y; + int remaining_samples = samples; + int nch = source->channels; - for (i = 0; i < n; i++) { - x = audio_stream_read_frag_s32(source, i); - y = audio_stream_write_frag_s32(sink, i); - *y = *x; + while (remaining_samples) { + nbuf = audio_stream_samples_without_wrap_s16(source, x0); + npcm = MIN(remaining_samples, nbuf); + nbuf = audio_stream_samples_without_wrap_s16(sink, y0); + npcm = MIN(npcm, nbuf); + nfrm = npcm / nch; + for (ch = 0; ch < nch; ++ch) { + pd = (int16_t *)state->pre_delay_buffers[ch]; + x1 = x0 + ch; + y1 = y0 + ch; + pd_write_index = state->pre_delay_write_index; + pd_read_index = state->pre_delay_read_index; + for (i = 0; i < nfrm; i++) { + *(pd + pd_write_index) = *x1; + *y1 = *(pd + pd_read_index); + drc_pre_delay_index_inc(&pd_write_index, 1); + drc_pre_delay_index_inc(&pd_read_index, 1); + x1 += nch; + y1 += nch; + } + } + remaining_samples -= npcm; + x0 = audio_stream_wrap(source, x0 + npcm); + y0 = audio_stream_wrap(sink, y0 + npcm); + drc_pre_delay_index_inc(&state->pre_delay_write_index, nfrm); + drc_pre_delay_index_inc(&state->pre_delay_read_index, nfrm); } + + *x = x0; + *y = y0; } -#endif /* CONFIG_FORMAT_S24LE || CONFIG_FORMAT_S32LE */ -#if CONFIG_FORMAT_S16LE static void drc_s16_default(const struct comp_dev *dev, const struct audio_stream *source, struct audio_stream *sink, uint32_t frames) { - int16_t *x; - int16_t *y; - int16_t *pd_write; - int16_t *pd_read; - int offset; - int i = 0; - int ch; - int idx; - int f; - int fragment; - int pd_write_index; - int pd_read_index; + int16_t *x = source->r_ptr; + int16_t *y = sink->w_ptr; int nch = source->channels; - + int samples = frames * nch; struct drc_comp_data *cd = comp_get_drvdata(dev); struct drc_state *state = &cd->state; const struct sof_drc_params *p = &cd->config->params; /* Read-only */ + int fragment_samples; + int fragment; if (!p->enabled) { /* Delay the input sample only and don't do other processing. This is used when the * DRC is disabled. We want to do this to match the processing delay of other bands * in multi-band DRC kernel case. */ - for (ch = 0; ch < nch; ++ch) { - pd_write_index = state->pre_delay_write_index; - pd_read_index = state->pre_delay_read_index; - pd_write = (int16_t *)state->pre_delay_buffers[ch] + pd_write_index; - pd_read = (int16_t *)state->pre_delay_buffers[ch] + pd_read_index; - idx = ch; - for (i = 0; i < frames; ++i) { - x = audio_stream_read_frag_s16(source, idx); - y = audio_stream_write_frag_s16(sink, idx); - *pd_write = *x; - *y = *pd_read; - if (++pd_write_index == CONFIG_DRC_MAX_PRE_DELAY_FRAMES) { - pd_write_index = 0; - pd_write = (int16_t *)state->pre_delay_buffers[ch]; - } else { - pd_write++; - } - if (++pd_read_index == CONFIG_DRC_MAX_PRE_DELAY_FRAMES) { - pd_read_index = 0; - pd_read = (int16_t *)state->pre_delay_buffers[ch]; - } else { - pd_read++; - } - idx += nch; - } - } - - state->pre_delay_write_index += frames; - state->pre_delay_write_index &= DRC_MAX_PRE_DELAY_FRAMES_MASK; - state->pre_delay_read_index += frames; - state->pre_delay_read_index &= DRC_MAX_PRE_DELAY_FRAMES_MASK; + drc_delay_input_sample_s16(state, source, sink, &x, &y, samples); return; } if (!state->processed) { drc_update_envelope(state, p); - drc_compress_output(state, p, 2, nch); + drc_compress_output(state, p, sizeof(int16_t), nch); state->processed = 1; } - offset = state->pre_delay_write_index & DRC_DIVISION_FRAMES_MASK; - while (i < frames) { - /* Copy fragment data from source to pre-delay buffers, and copy the output fragment - * to sink. - */ - fragment = MIN(DRC_DIVISION_FRAMES - offset, frames - i); - pd_write_index = state->pre_delay_write_index; - pd_read_index = state->pre_delay_read_index; + while (samples) { + fragment = DRC_DIVISION_FRAMES - + (state->pre_delay_write_index & DRC_DIVISION_FRAMES_MASK); + fragment_samples = fragment * nch; + fragment_samples = MIN(samples, fragment_samples); + drc_delay_input_sample_s16(state, source, sink, &x, &y, fragment_samples); + samples -= fragment_samples; + + /* Process the input division (32 frames). */ + if ((state->pre_delay_write_index & DRC_DIVISION_FRAMES_MASK) == 0) + drc_process_one_division(state, p, sizeof(int16_t), nch); + } +} +#endif /* CONFIG_FORMAT_S16LE */ + +#if CONFIG_FORMAT_S24LE || CONFIG_FORMAT_S32LE +static void drc_delay_input_sample_s32(struct drc_state *state, const struct audio_stream *source, + struct audio_stream *sink, int32_t **x, int32_t **y, + int samples) +{ + int32_t *x1; + int32_t *y1; + int32_t *pd; + int pd_write_index, pd_read_index; + int nbuf, npcm, nfrm; + int ch; + int i; + int32_t *x0 = *x; + int32_t *y0 = *y; + int remaining_samples = samples; + int nch = source->channels; + + while (remaining_samples) { + nbuf = audio_stream_samples_without_wrap_s32(source, x0); + npcm = MIN(remaining_samples, nbuf); + nbuf = audio_stream_samples_without_wrap_s32(sink, y0); + npcm = MIN(npcm, nbuf); + nfrm = npcm / nch; for (ch = 0; ch < nch; ++ch) { - pd_write = (int16_t *)state->pre_delay_buffers[ch] + pd_write_index; - pd_read = (int16_t *)state->pre_delay_buffers[ch] + pd_read_index; - idx = i * nch + ch; - for (f = 0; f < fragment; ++f) { - x = audio_stream_read_frag_s16(source, idx); - y = audio_stream_write_frag_s16(sink, idx); - *pd_write = *x; - *y = *pd_read; - pd_write++; - pd_read++; - idx += nch; + pd = (int32_t *)state->pre_delay_buffers[ch]; + x1 = x0 + ch; + y1 = y0 + ch; + pd_write_index = state->pre_delay_write_index; + pd_read_index = state->pre_delay_read_index; + for (i = 0; i < nfrm; i++) { + *(pd + pd_write_index) = *x1; + *y1 = *(pd + pd_read_index); + drc_pre_delay_index_inc(&pd_write_index, 1); + drc_pre_delay_index_inc(&pd_read_index, 1); + x1 += nch; + y1 += nch; } } - state->pre_delay_write_index = - (pd_write_index + fragment) & DRC_MAX_PRE_DELAY_FRAMES_MASK; - state->pre_delay_read_index = - (pd_read_index + fragment) & DRC_MAX_PRE_DELAY_FRAMES_MASK; + remaining_samples -= npcm; + x0 = audio_stream_wrap(source, x0 + npcm); + y0 = audio_stream_wrap(sink, y0 + npcm); + drc_pre_delay_index_inc(&state->pre_delay_write_index, nfrm); + drc_pre_delay_index_inc(&state->pre_delay_read_index, nfrm); + } - i += fragment; - offset = (offset + fragment) & DRC_DIVISION_FRAMES_MASK; + *x = x0; + *y = y0; +} +#endif - /* Process the input division (32 frames). */ - if (offset == 0) - drc_process_one_division(state, p, 2, nch); +#if CONFIG_FORMAT_S24LE +static void drc_delay_input_sample_s24(struct drc_state *state, const struct audio_stream *source, + struct audio_stream *sink, int32_t **x, int32_t **y, + int samples) +{ + int32_t *x1; + int32_t *y1; + int32_t *pd; + int pd_write_index, pd_read_index; + int nbuf, npcm, nfrm; + int ch; + int i; + int32_t *x0 = *x; + int32_t *y0 = *y; + int remaining_samples = samples; + int nch = source->channels; + + while (remaining_samples) { + nbuf = audio_stream_samples_without_wrap_s24(source, x0); + npcm = MIN(remaining_samples, nbuf); + nbuf = audio_stream_samples_without_wrap_s24(sink, y0); + npcm = MIN(npcm, nbuf); + nfrm = npcm / nch; + for (ch = 0; ch < nch; ++ch) { + pd = (int32_t *)state->pre_delay_buffers[ch]; + x1 = x0 + ch; + y1 = y0 + ch; + pd_write_index = state->pre_delay_write_index; + pd_read_index = state->pre_delay_read_index; + for (i = 0; i < nfrm; i++) { + *(pd + pd_write_index) = *x1 << 8; + *y1 = sat_int24(Q_SHIFT_RND(*(pd + pd_read_index), 31, 23)); + drc_pre_delay_index_inc(&pd_write_index, 1); + drc_pre_delay_index_inc(&pd_read_index, 1); + x1 += nch; + y1 += nch; + } + } + remaining_samples -= npcm; + x0 = audio_stream_wrap(source, x0 + npcm); + y0 = audio_stream_wrap(sink, y0 + npcm); + drc_pre_delay_index_inc(&state->pre_delay_write_index, nfrm); + drc_pre_delay_index_inc(&state->pre_delay_read_index, nfrm); } + + *x = x0; + *y = y0; } -#endif /* CONFIG_FORMAT_S16LE */ -#if CONFIG_FORMAT_S24LE static void drc_s24_default(const struct comp_dev *dev, const struct audio_stream *source, struct audio_stream *sink, uint32_t frames) { - int32_t *x; - int32_t *y; - int32_t *pd_write; - int32_t *pd_read; - int offset; - int i = 0; - int ch; - int idx; - int f; - int fragment; - int pd_write_index; - int pd_read_index; + int32_t *x = source->r_ptr; + int32_t *y = sink->w_ptr; int nch = source->channels; - + int samples = frames * nch; struct drc_comp_data *cd = comp_get_drvdata(dev); struct drc_state *state = &cd->state; const struct sof_drc_params *p = &cd->config->params; /* Read-only */ + int fragment_samples; + int fragment; if (!p->enabled) { /* Delay the input sample only and don't do other processing. This is used when the * DRC is disabled. We want to do this to match the processing delay of other bands - * in multi-band DRC kernel case. + * in multi-band DRC kernel case. Note: use 32 bit delay function. */ - for (ch = 0; ch < nch; ++ch) { - pd_write_index = state->pre_delay_write_index; - pd_read_index = state->pre_delay_read_index; - pd_write = (int32_t *)state->pre_delay_buffers[ch] + pd_write_index; - pd_read = (int32_t *)state->pre_delay_buffers[ch] + pd_read_index; - idx = ch; - for (i = 0; i < frames; ++i) { - x = audio_stream_read_frag_s32(source, idx); - y = audio_stream_write_frag_s32(sink, idx); - *pd_write = *x; - *y = *pd_read; - if (++pd_write_index == CONFIG_DRC_MAX_PRE_DELAY_FRAMES) { - pd_write_index = 0; - pd_write = (int32_t *)state->pre_delay_buffers[ch]; - } else { - pd_write++; - } - if (++pd_read_index == CONFIG_DRC_MAX_PRE_DELAY_FRAMES) { - pd_read_index = 0; - pd_read = (int32_t *)state->pre_delay_buffers[ch]; - } else { - pd_read++; - } - idx += nch; - } - } - - state->pre_delay_write_index += frames; - state->pre_delay_write_index &= DRC_MAX_PRE_DELAY_FRAMES_MASK; - state->pre_delay_read_index += frames; - state->pre_delay_read_index &= DRC_MAX_PRE_DELAY_FRAMES_MASK; + drc_delay_input_sample_s32(state, source, sink, &x, &y, samples); return; } if (!state->processed) { drc_update_envelope(state, p); - drc_compress_output(state, p, 4, nch); + drc_compress_output(state, p, sizeof(int32_t), nch); state->processed = 1; } - offset = state->pre_delay_write_index & DRC_DIVISION_FRAMES_MASK; - while (i < frames) { - /* Copy fragment data from source to pre-delay buffers, and copy the output fragment - * to sink. - */ - fragment = MIN(DRC_DIVISION_FRAMES - offset, frames - i); - pd_write_index = state->pre_delay_write_index; - pd_read_index = state->pre_delay_read_index; - for (ch = 0; ch < nch; ++ch) { - pd_write = (int32_t *)state->pre_delay_buffers[ch] + pd_write_index; - pd_read = (int32_t *)state->pre_delay_buffers[ch] + pd_read_index; - idx = i * nch + ch; - for (f = 0; f < fragment; ++f) { - x = audio_stream_read_frag_s32(source, idx); - y = audio_stream_write_frag_s32(sink, idx); - - /* Write/Read pre_delay_buffer as s32 format */ - *pd_write = *x << 8; - *y = sat_int24(Q_SHIFT_RND(*pd_read, 31, 23)); - - pd_write++; - pd_read++; - idx += nch; - } - } - state->pre_delay_write_index = - (pd_write_index + fragment) & DRC_MAX_PRE_DELAY_FRAMES_MASK; - state->pre_delay_read_index = - (pd_read_index + fragment) & DRC_MAX_PRE_DELAY_FRAMES_MASK; + while (samples) { + fragment = DRC_DIVISION_FRAMES - + (state->pre_delay_write_index & DRC_DIVISION_FRAMES_MASK); + fragment_samples = fragment * nch; + fragment_samples = MIN(samples, fragment_samples); - i += fragment; - offset = (offset + fragment) & DRC_DIVISION_FRAMES_MASK; + /* Use 24 bit delay function */ + drc_delay_input_sample_s24(state, source, sink, &x, &y, fragment_samples); + samples -= fragment_samples; /* Process the input division (32 frames). */ - if (offset == 0) - drc_process_one_division(state, p, 4, nch); + if ((state->pre_delay_write_index & DRC_DIVISION_FRAMES_MASK) == 0) + drc_process_one_division(state, p, sizeof(int32_t), nch); } } #endif /* CONFIG_FORMAT_S24LE */ @@ -724,102 +722,42 @@ static void drc_s32_default(const struct comp_dev *dev, struct audio_stream *sink, uint32_t frames) { - int32_t *x; - int32_t *y; - int32_t *pd_write; - int32_t *pd_read; - int offset; - int i = 0; - int ch; - int idx; - int f; - int fragment; - int pd_write_index; - int pd_read_index; + int32_t *x = source->r_ptr; + int32_t *y = sink->w_ptr; int nch = source->channels; - + int samples = frames * nch; struct drc_comp_data *cd = comp_get_drvdata(dev); struct drc_state *state = &cd->state; const struct sof_drc_params *p = &cd->config->params; /* Read-only */ + int fragment_samples; + int fragment; if (!p->enabled) { /* Delay the input sample only and don't do other processing. This is used when the * DRC is disabled. We want to do this to match the processing delay of other bands * in multi-band DRC kernel case. */ - for (ch = 0; ch < nch; ++ch) { - pd_write_index = state->pre_delay_write_index; - pd_read_index = state->pre_delay_read_index; - pd_write = (int32_t *)state->pre_delay_buffers[ch] + pd_write_index; - pd_read = (int32_t *)state->pre_delay_buffers[ch] + pd_read_index; - idx = ch; - for (i = 0; i < frames; ++i) { - x = audio_stream_read_frag_s32(source, idx); - y = audio_stream_write_frag_s32(sink, idx); - *pd_write = *x; - *y = *pd_read; - if (++pd_write_index == CONFIG_DRC_MAX_PRE_DELAY_FRAMES) { - pd_write_index = 0; - pd_write = (int32_t *)state->pre_delay_buffers[ch]; - } else { - pd_write++; - } - if (++pd_read_index == CONFIG_DRC_MAX_PRE_DELAY_FRAMES) { - pd_read_index = 0; - pd_read = (int32_t *)state->pre_delay_buffers[ch]; - } else { - pd_read++; - } - idx += nch; - } - } - - state->pre_delay_write_index += frames; - state->pre_delay_write_index &= DRC_MAX_PRE_DELAY_FRAMES_MASK; - state->pre_delay_read_index += frames; - state->pre_delay_read_index &= DRC_MAX_PRE_DELAY_FRAMES_MASK; + drc_delay_input_sample_s32(state, source, sink, &x, &y, samples); return; } if (!state->processed) { drc_update_envelope(state, p); - drc_compress_output(state, p, 4, nch); + drc_compress_output(state, p, sizeof(int32_t), nch); state->processed = 1; } - offset = state->pre_delay_write_index & DRC_DIVISION_FRAMES_MASK; - while (i < frames) { - /* Copy fragment data from source to pre-delay buffers, and copy the output fragment - * to sink. - */ - fragment = MIN(DRC_DIVISION_FRAMES - offset, frames - i); - pd_write_index = state->pre_delay_write_index; - pd_read_index = state->pre_delay_read_index; - for (ch = 0; ch < nch; ++ch) { - pd_write = (int32_t *)state->pre_delay_buffers[ch] + pd_write_index; - pd_read = (int32_t *)state->pre_delay_buffers[ch] + pd_read_index; - idx = i * nch + ch; - for (f = 0; f < fragment; ++f) { - x = audio_stream_read_frag_s32(source, idx); - y = audio_stream_write_frag_s32(sink, idx); - *pd_write = *x; - *y = *pd_read; - pd_write++; - pd_read++; - idx += nch; - } - } - state->pre_delay_write_index = - (pd_write_index + fragment) & DRC_MAX_PRE_DELAY_FRAMES_MASK; - state->pre_delay_read_index = - (pd_read_index + fragment) & DRC_MAX_PRE_DELAY_FRAMES_MASK; - - i += fragment; - offset = (offset + fragment) & DRC_DIVISION_FRAMES_MASK; + while (samples) { + fragment = DRC_DIVISION_FRAMES - + (state->pre_delay_write_index & DRC_DIVISION_FRAMES_MASK); + fragment_samples = fragment * nch; + fragment_samples = MIN(samples, fragment_samples); + drc_delay_input_sample_s32(state, source, sink, &x, &y, fragment_samples); + samples -= fragment_samples; /* Process the input division (32 frames). */ - if (offset == 0) - drc_process_one_division(state, p, 4, nch); + if ((state->pre_delay_write_index & DRC_DIVISION_FRAMES_MASK) == 0) + drc_process_one_division(state, p, sizeof(int32_t), nch); } } #endif /* CONFIG_FORMAT_S32LE */ @@ -839,19 +777,4 @@ const struct drc_proc_fnmap drc_proc_fnmap[] = { #endif /* CONFIG_FORMAT_S32LE */ }; -const struct drc_proc_fnmap drc_proc_fnmap_pass[] = { -/* { SOURCE_FORMAT , PROCESSING FUNCTION } */ -#if CONFIG_FORMAT_S16LE - { SOF_IPC_FRAME_S16_LE, drc_s16_default_pass }, -#endif /* CONFIG_FORMAT_S16LE */ - -#if CONFIG_FORMAT_S24LE - { SOF_IPC_FRAME_S24_4LE, drc_s32_default_pass }, -#endif /* CONFIG_FORMAT_S24LE */ - -#if CONFIG_FORMAT_S32LE - { SOF_IPC_FRAME_S32_LE, drc_s32_default_pass }, -#endif /* CONFIG_FORMAT_S32LE */ -}; - const size_t drc_proc_fncount = ARRAY_SIZE(drc_proc_fnmap); diff --git a/src/include/sof/audio/drc/drc.h b/src/include/sof/audio/drc/drc.h index 645d9546ea5d..1ed278ba7b0a 100644 --- a/src/include/sof/audio/drc/drc.h +++ b/src/include/sof/audio/drc/drc.h @@ -78,9 +78,11 @@ struct drc_proc_fnmap { }; extern const struct drc_proc_fnmap drc_proc_fnmap[]; -extern const struct drc_proc_fnmap drc_proc_fnmap_pass[]; extern const size_t drc_proc_fncount; +void drc_default_pass(const struct comp_dev *dev, const struct audio_stream *source, + struct audio_stream *sink, uint32_t frames); + /** * \brief Returns DRC processing function. */ @@ -96,19 +98,4 @@ static inline drc_func drc_find_proc_func(enum sof_ipc_frame src_fmt) return NULL; } -/** - * \brief Returns DRC passthrough functions. - */ -static inline drc_func drc_find_proc_func_pass(enum sof_ipc_frame src_fmt) -{ - int i; - - /* Find suitable processing function from map */ - for (i = 0; i < drc_proc_fncount; i++) - if (src_fmt == drc_proc_fnmap_pass[i].frame_fmt) - return drc_proc_fnmap_pass[i].drc_proc_func; - - return NULL; -} - #endif // __SOF_AUDIO_DRC_DRC_H__ diff --git a/tools/topology/topology1/development/CMakeLists.txt b/tools/topology/topology1/development/CMakeLists.txt index d7f39d5a4e6a..7c6ee829d073 100644 --- a/tools/topology/topology1/development/CMakeLists.txt +++ b/tools/topology/topology1/development/CMakeLists.txt @@ -50,6 +50,8 @@ set(TPLGS_UP "sof-hda-generic\;sof-hda-generic-4ch-loud\;-DCHANNELS=4\;-DHSPROC=eq-iir-eq-fir-volume\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DHSPROC_FILTER1=eq_iir_coef_pass.m4\;-DHSPROC_FILTER2=eq_fir_coef_loudness.m4\;-DDYNAMIC=1" "sof-hda-generic\;sof-hda-generic-multiband-drc\;-DCHANNELS=0\;-DHSPROC=multiband-drc\;-DDYNAMIC=1" "sof-hda-generic\;sof-hda-generic-2ch-multiband-drc\;-DCHANNELS=2\;-DHSPROC=multiband-drc\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DDYNAMIC=1" + "sof-hda-generic\;sof-hda-generic-drc\;-DCHANNELS=0\;-DHSPROC=drc\;-DDYNAMIC=1" + "sof-hda-generic\;sof-hda-generic-2ch-drc\;-DCHANNELS=2\;-DHSPROC=drc\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DDYNAMIC=1" "sof-tgl-rt711-rt1308\;sof-tgl-sdw-max98373-rt5682-dmic4ch-ampref\;-DCHANNELS=4\;-DEXT_AMP\;-DEXT_AMP_REF\;-DDMICPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_48khz.m4\;-DDMIC16KPROC_FILTER1=eq_iir_coef_highpass_40hz_20db_16khz.m4\;-DPLATFORM=tgl" ) diff --git a/tools/topology/topology1/sof/pipe-mixer-drc-dai-playback.m4 b/tools/topology/topology1/sof/pipe-mixer-drc-dai-playback.m4 new file mode 100644 index 000000000000..08edefef0c4c --- /dev/null +++ b/tools/topology/topology1/sof/pipe-mixer-drc-dai-playback.m4 @@ -0,0 +1,83 @@ +# Mixer DAI Playback connector +# +# DAI playback starting with a LL mixer +# +# Pipeline Endpoints for connection are :- +# +# LL Playback Mixer (Mixer) +# LL Playback Volume B1 (DAI buffer) +# +# DAI_BUF --> ll mixer(M) --> B0 --> DRC(LL) --> B1 --> sink DAI +# +# the ll mixer is connected to one DAI_BUF by default. Additional ones can be added later + +# Include topology builder +include(`utils.m4') +include(`mixer.m4') +include(`buffer.m4') +include(`dai.m4') +include(`pipeline.m4') +include(`bytecontrol.m4') +include(`drc.m4') + +# +# Controls +# + +# +# DRC Configuration +# + +define(DRC_priv, concat(`drc_bytes_', PIPELINE_ID)) +define(MY_DRC_CTRL, concat(`drc_control_', PIPELINE_ID)) +include(`drc_coef_default.m4') +C_CONTROLBYTES(MY_DRC_CTRL, PIPELINE_ID, + CONTROLBYTES_OPS(bytes, 258 binds the control to bytes get/put handlers, 258, 258), + CONTROLBYTES_EXTOPS(258 binds the control to bytes get/put handlers, 258, 258), + , , , + CONTROLBYTES_MAX(, 1024), + , + DRC_priv) + + +# Mixer 0 has 2 sink and source periods. +W_MIXER(0, PIPELINE_FORMAT, 2, 2, SCHEDULE_CORE) + +# "DRC" has 2 sink periods and 2 source periods +W_DRC(0, PIPELINE_FORMAT, DAI_PERIODS, 2, SCHEDULE_CORE, + LIST(` ', "MY_DRC_CTRL")) + +# +# DAI definitions +# +W_DAI_OUT(DAI_TYPE, DAI_INDEX, DAI_BE, DAI_FORMAT, 0, DAI_PERIODS, SCHEDULE_CORE) + +# +# DAI pipeline - always use 0 for DAIs - FIXME WHY 0? +# +W_PIPELINE(N_DAI_OUT, SCHEDULE_PERIOD, SCHEDULE_PRIORITY, SCHEDULE_CORE, SCHEDULE_TIME_DOMAIN, pipe_dai_schedule_plat) + +# Low Latency Buffers +W_BUFFER(0, COMP_BUFFER_SIZE(2, + COMP_SAMPLE_SIZE(DAI_FORMAT), DAI_CHANNELS, COMP_PERIOD_FRAMES(DAI_RATE, SCHEDULE_PERIOD)), + PLATFORM_COMP_MEM_CAP) +W_BUFFER(1, COMP_BUFFER_SIZE(2, + COMP_SAMPLE_SIZE(DAI_FORMAT), DAI_CHANNELS,COMP_PERIOD_FRAMES(DAI_RATE, SCHEDULE_PERIOD)), + PLATFORM_COMP_MEM_CAP) + +# +# Graph connections to pipelines +# we don't connect `dapm(N_MIXER(0), DAI_BUF)' due to forward dependencies +# +P_GRAPH(DAI_NAME, PIPELINE_ID, + LIST(` ', + `dapm(N_BUFFER(0), N_MIXER(0))', + `dapm(N_DRC(0), N_BUFFER(0))', + `dapm(N_BUFFER(1), N_DRC(0))' + `dapm(N_DAI_OUT, N_BUFFER(1))')) + +indir(`define', concat(`PIPELINE_PLAYBACK_SCHED_COMP_', PIPELINE_ID), N_DAI_OUT) +indir(`define', concat(`PIPELINE_MIXER_', PIPELINE_ID), N_MIXER(0)) + +undefine(`MY_DRC_CTRL') +undefine(`DRC_priv')