Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 37 additions & 30 deletions src/audio/src/src.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,8 @@ int src_buffer_lengths(struct src_param *a, int fs_in, int fs_out, int nch,
/* Check from stage1 parameter for a deleted in/out rate combination.*/
if (stage1->filter_length < 1) {
trace_src_error("src_buffer_lengths() error: "
"stage1->filter_length <"
" 1, fs_in: %u, fs_out: %u", fs_in, fs_out);
"Non-supported combination "
"fs_in = %d, fs_out = %d", fs_in, fs_out);
return -EINVAL;
}

Expand Down Expand Up @@ -603,9 +603,6 @@ static int src_params(struct comp_dev *dev)
return err;
}

trace_src("src_params(), blk_in = %u, blk_out = %u",
cd->param.blk_in, cd->param.blk_out);

delay_lines_size = sizeof(int32_t) * cd->param.total;
if (delay_lines_size == 0) {
trace_src_error("src_params() error: delay_lines_size = 0");
Expand Down Expand Up @@ -803,31 +800,6 @@ static int src_prepare(struct comp_dev *dev)
if (ret == COMP_STATUS_STATE_ALREADY_SET)
return PPL_STATUS_PATH_STOP;

/* SRC supports S16_LE, S24_4LE and S32_LE formats */
switch (dev->params.frame_fmt) {
case SOF_IPC_FRAME_S16_LE:
cd->data_shift = 0;
cd->polyphase_func = src_polyphase_stage_cir_s16;
/* Copy function is set by default in params() for 32 bit
* data. Change it to 16 bit version here if source and sink
* rates are equal.
*/
if (cd->source_rate == cd->sink_rate)
cd->src_func = src_copy_s16;
break;
case SOF_IPC_FRAME_S24_4LE:
cd->data_shift = 8;
cd->polyphase_func = src_polyphase_stage_cir;
break;
case SOF_IPC_FRAME_S32_LE:
cd->data_shift = 0;
cd->polyphase_func = src_polyphase_stage_cir;
break;
default:
trace_src_error("src_prepare() error: invalid dev->frame_fmt");
return -EINVAL;
}

/* SRC component will only ever have 1 source and 1 sink buffer */
sourceb = list_first_item(&dev->bsource_list,
struct comp_buffer, sink_list);
Expand Down Expand Up @@ -871,6 +843,41 @@ static int src_prepare(struct comp_dev *dev)
goto err;
}

/* SRC supports S16_LE, S24_4LE and S32_LE formats */
if (cd->source_format != cd->sink_format) {
trace_src_error("src_prepare() error: "
"Source fmt %d and sink fmt %d are different.",
cd->source_format, cd->sink_format);
ret = -EINVAL;
goto err;
}

switch (cd->source_format) {
case SOF_IPC_FRAME_S16_LE:
cd->data_shift = 0;
cd->polyphase_func = src_polyphase_stage_cir_s16;
/* Copy function is set by default in params() for 32 bit
* data. Change it to 16 bit version here if source and sink
* rates are equal.
*/
if (cd->source_rate == cd->sink_rate)
cd->src_func = src_copy_s16;
break;
case SOF_IPC_FRAME_S24_4LE:
cd->data_shift = 8;
cd->polyphase_func = src_polyphase_stage_cir;
break;
case SOF_IPC_FRAME_S32_LE:
cd->data_shift = 0;
cd->polyphase_func = src_polyphase_stage_cir;
break;
default:
trace_src_error("src_prepare() error: invalid format %d",
cd->source_format);
ret = -EINVAL;
goto err;
}

return 0;

err:
Expand Down
1 change: 1 addition & 0 deletions tools/topology/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ set(TPLGS
"sof-icl-nocodec\;sof-icl-nocodec"
"sof-apl-eq-pcm512x\;sof-apl-eq-pcm512x"
"sof-apl-eq-dmic\;sof-apl-eq-dmic"
"sof-apl-src-dmic\;sof-apl-src-dmic"
"sof-apl-dmic-a2ch\;sof-apl-dmic-a2ch"
"sof-apl-dmic-b2ch\;sof-apl-dmic-b2ch"
"sof-apl-dmic-a2ch-b2ch\;sof-apl-dmic-a2ch-b2ch"
Expand Down
104 changes: 104 additions & 0 deletions tools/topology/sof-apl-src-dmic.m4
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#
# Topology for Apollo Lake with direct attach digital microphones array
#

# Capture configuration
# DAI0 2ch 32b mic1-2
# DAI1 2ch 32b mic1-2

# Include topology builder
include(`utils.m4')
include(`dai.m4')
include(`pipeline.m4')

# Include TLV library
include(`common/tlv.m4')

# Include Token library
include(`sof/tokens.m4')

# Include Apollolake DSP configuration
include(`platform/intel/bxt.m4')
include(`platform/intel/dmic.m4')

DEBUG_START

#
# Define the pipelines
#
# PCM6 <--- Volume <--- SRC <--- DMIC6 (DMIC01)
# PCM7 <--- Volume <--- SRC <--- DMIC7 (DMIC16k)
#

dnl PIPELINE_PCM_DAI_ADD(pipeline,
dnl pipe id, pcm, max channels, format,
dnl period, priority, core,
dnl dai type, dai_index, dai format,
dnl dai periods, pcm_min_rate, pcm_max_rate,
dnl pipeline_rate, time_domain)

# SRC capture pipeline 6 on PCM 6 using max channels 2.
# Set 1000us deadline on core 0 with priority 0
PIPELINE_PCM_DAI_ADD(sof/pipe-src-volume-capture.m4,
6, 6, 2, s32le,
1000, 0, 0, DMIC, 0, s32le, 3,
8000, 48000, 48000)

# SRC capture pipeline 7 on PCM 7 using max channels 2.
# Set 1000us deadline on core 0 with priority 0
PIPELINE_PCM_DAI_ADD(sof/pipe-src-volume-capture.m4,
7, 7, 2, s32le,
1000, 0, 0, DMIC, 1, s32le, 3,
8000, 48000, 16000)

#
# DAIs configuration
#

dnl DAI_ADD(pipeline,
dnl pipe id, dai type, dai_index, dai_be,
dnl buffer, periods, format,
dnl deadline, priority, core, time_domain)

# capture DAI is DMIC 0 using 3 periods
# Buffers use s32le format, 1000us deadline on core 0 with priority 0
DAI_ADD(sof/pipe-dai-capture.m4,
6, DMIC, 0, NoCodec-6,
PIPELINE_SINK_6, 3, s32le,
1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER)

# capture DAI is DMIC 1 using 3 periods
# Buffers use s32le format, 1000us deadline on core 0 with priority 0
DAI_ADD(sof/pipe-dai-capture.m4,
7, DMIC, 1, NoCodec-7,
PIPELINE_SINK_7, 3, s32le,
1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER)

dnl PCM_DUPLEX_ADD(name, pcm_id, playback, capture)
dnl PCM_CAPTURE_ADD(name, pipeline, capture)
PCM_CAPTURE_ADD(DMIC01, 6, PIPELINE_PCM_6)
PCM_CAPTURE_ADD(DMIC16k, 7, PIPELINE_PCM_7)

#
# BE configurations - overrides config in ACPI if present
#

dnl DAI_CONFIG(type, dai_index, link_id, name, ssp_config/dmic_config)

DAI_CONFIG(DMIC, 0, 6, NoCodec-6,
dnl DMIC_CONFIG(driver_version, clk_min, clk_mac, duty_min, duty_max,
dnl sample_rate, fifo word length, unmute time, type,
dnl dai_index, pdm controller config)
DMIC_CONFIG(1, 500000, 4800000, 40, 60, 48000,
DMIC_WORD_LENGTH(s32le), 400, DMIC, 0,
PDM_CONFIG(DMIC, 0, STEREO_PDM0)))

DAI_CONFIG(DMIC, 1, 7, NoCodec-7,
dnl DMIC_CONFIG(driver_version, clk_min, clk_mac, duty_min, duty_max,
dnl sample_rate, fifo word length, unmute time, type,
dnl dai_index, pdm controller config)
DMIC_CONFIG(1, 500000, 4800000, 40, 60, 16000,
DMIC_WORD_LENGTH(s32le), 400, DMIC, 1,
PDM_CONFIG(DMIC, 1, STEREO_PDM0)))

DEBUG_END
50 changes: 33 additions & 17 deletions tools/topology/sof/pipe-src-capture.m4
Original file line number Diff line number Diff line change
@@ -1,48 +1,58 @@
# Low Latency Passthrough with volume Pipeline and PCM
# Capture pipeline with SRC and PCM
#
# Pipeline Endpoints for connection are :-
#
# host PCM_P --> SRC --> sink DAI0
# host PCM_C <-- B0 <-- SRC <-- B1 <-- sink DAI0

# Include topology builder
include(`pipeline.m4')
include(`buffer.m4')
include(`utils.m4')
include(`src.m4')
include(`buffer.m4')
include(`pcm.m4')
include(`dai.m4')
include(`pipeline.m4')

#
# Controls
#

#
# Components and Buffers
#

# Host "Passthrough Capture" PCM
# with 4 sink and 0 source periods
W_PCM_CAPTURE(PCM_ID, Passthrough Capture, 4, 0)
# with 0 sink and 3 source periods
W_PCM_CAPTURE(PCM_ID, SRC Capture, 0, 3)

#
# SRC Configuration
#

W_VENDORTUPLES(media_src_tokens, sof_src_tokens, LIST(` ', `SOF_TKN_SRC_RATE_IN "PIPELINE_RATE"'))
# Create unique names for data to allow several different input rate instances
define(MY_SRC_TOKENS, concat(`src_tokens_', PIPELINE_ID))
define(MY_SRC_CONF, concat(`src_conf_', PIPELINE_ID))
W_VENDORTUPLES(MY_SRC_TOKENS, sof_src_tokens,
LIST(` ', `SOF_TKN_SRC_RATE_IN "PIPELINE_RATE"'))

W_DATA(media_src_conf, media_src_tokens)
W_DATA(MY_SRC_CONF, MY_SRC_TOKENS)

# "SRC" has 4 source and 4 sink periods
W_SRC(0, PIPELINE_FORMAT, 4, 4, media_src_conf)
# "SRC" has x source and 3 sink periods
W_SRC(0, PIPELINE_FORMAT, DAI_PERIODS, 3, MY_SRC_CONF)

# Capture Buffers
W_BUFFER(0, COMP_BUFFER_SIZE(4,
COMP_SAMPLE_SIZE(PIPELINE_FORMAT), PIPELINE_CHANNELS, COMP_PERIOD_FRAMES(PCM_MAX_RATE, SCHEDULE_PERIOD)),
W_BUFFER(0, COMP_BUFFER_SIZE(3,
COMP_SAMPLE_SIZE(PIPELINE_FORMAT),
PIPELINE_CHANNELS, COMP_PERIOD_FRAMES(PCM_MAX_RATE, SCHEDULE_PERIOD)),
PLATFORM_HOST_MEM_CAP)
W_BUFFER(1, COMP_BUFFER_SIZE(4,
COMP_SAMPLE_SIZE(PIPELINE_FORMAT), PIPELINE_CHANNELS, COMP_PERIOD_FRAMES(PCM_MAX_RATE, SCHEDULE_PERIOD)),
W_BUFFER(1, COMP_BUFFER_SIZE(DAI_PERIODS,
COMP_SAMPLE_SIZE(PIPELINE_FORMAT), PIPELINE_CHANNELS,
COMP_PERIOD_FRAMES(PCM_MAX_RATE, SCHEDULE_PERIOD)),
PLATFORM_DAI_MEM_CAP)

#
# Pipeline Graph
#
# host PCM_P <-- B0 <-- SRC 0 <-- B1 <-- sink DAI0
# host PCM_C <-- B0 <-- SRC <-- B1 <-- sink DAI0

P_GRAPH(pipe-pass-src-capture-PIPELINE_ID, PIPELINE_ID,
LIST(` ',
Expand All @@ -54,10 +64,16 @@ P_GRAPH(pipe-pass-src-capture-PIPELINE_ID, PIPELINE_ID,
# Pipeline Source and Sinks
#
indir(`define', concat(`PIPELINE_SINK_', PIPELINE_ID), N_BUFFER(1))
indir(`define', concat(`PIPELINE_PCM_', PIPELINE_ID), Passthrough Capture PCM_ID)
indir(`define', concat(`PIPELINE_PCM_', PIPELINE_ID),
SRC Capture PCM_ID)

#
# PCM Configuration
#

PCM_CAPABILITIES(Passthrough Capture PCM_ID, `S32_LE,S24_LE,S16_LE', PCM_MIN_RATE, PCM_MAX_RATE, 2, PIPELINE_CHANNELS, 2, 16, 192, 16384, 65536, 65536)
PCM_CAPABILITIES(SRC Capture PCM_ID, `S32_LE,S24_LE,S16_LE',
PCM_MIN_RATE, PCM_MAX_RATE, 2, PIPELINE_CHANNELS,
2, 16, 192, 16384, 65536, 65536)

undefine(`MY_SRC_TOKENS')
undefine(`MY_SRC_CONF')
Loading