[Sound-open-firmware] [PATCH v2 0/6] Tone pipeline related patches
This patches includes some changes to enable the hostless tone pipeline. The main changes are:
1. skip host page table for hostless pipelines 2. read tone sample_rate from topology 3. Fix period bytes calculation 4. change tone default frequency/gain to adhere to AES17 requirements
Ranjani Sridharan (6): ipc: skip host page table set up for hostless tone pipeline tone: add get command handler to return tone state ipc: add sample_rate member to ipc tone comp def tone: set sample rate from topology tone: fix calculation for period_bytes tone: fix default frequency and gain to match AES17 requirement
src/audio/tone.c | 43 +++++++++++++++++++----- src/include/uapi/ipc.h | 1 + src/ipc/handler.c | 76 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 110 insertions(+), 10 deletions(-)
Hostless pipelines such as the tone pipeline do not need host page table while setting up pcm params. Walk pipeline in both directions to ensure it is hostless.
Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com --- src/ipc/handler.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-)
diff --git a/src/ipc/handler.c b/src/ipc/handler.c index a83ef69..9737141 100644 --- a/src/ipc/handler.c +++ b/src/ipc/handler.c @@ -34,6 +34,7 @@ * */
+#include <stdbool.h> #include <sof/debug.h> #include <sof/timer.h> #include <sof/interrupt.h> @@ -86,6 +87,71 @@ static inline struct sof_ipc_hdr *mailbox_validate(void) return hdr; }
+/* check if a pipeline is hostless when walking downstream */ +static bool is_hostless_downstream(struct comp_dev *current) +{ + struct list_item *clist; + + /* check if current is a HOST comp */ + if (current->comp.type == SOF_COMP_HOST || + current->comp.type == SOF_COMP_SG_HOST) + return false; + + /* check if the pipeline has a HOST comp downstream */ + list_for_item(clist, ¤t->bsink_list) { + struct comp_buffer *buffer; + + buffer = container_of(clist, struct comp_buffer, source_list); + + /* don't go downstream if this component is not connected */ + if (!buffer->connected) + continue; + + /* dont go downstream if this comp belongs to another pipe */ + if (buffer->sink->comp.pipeline_id != current->comp.pipeline_id) + continue; + + /* return if there's a host comp downstream */ + if (!is_hostless_downstream(buffer->sink)) + return false; + } + + return true; +} + +/* check if a pipeline is hostless when walking upstream */ +static bool is_hostless_upstream(struct comp_dev *current) +{ + struct list_item *clist; + + /* check if current is a HOST comp */ + if (current->comp.type == SOF_COMP_HOST || + current->comp.type == SOF_COMP_SG_HOST) + return false; + + /* check if the pipeline has a HOST comp upstream */ + list_for_item(clist, ¤t->bsource_list) { + struct comp_buffer *buffer; + + buffer = container_of(clist, struct comp_buffer, sink_list); + + /* don't go upstream if this component is not connected */ + if (!buffer->connected) + continue; + + /* dont go upstream if this comp belongs to another pipeline */ + if (buffer->source->comp.pipeline_id != + current->comp.pipeline_id) + continue; + + /* return if there is a host comp upstream */ + if (!is_hostless_upstream(buffer->source)) + return false; + } + + return true; +} + /* * Stream IPC Operations. */ @@ -134,8 +200,14 @@ static int ipc_stream_pcm_params(uint32_t stream) cd = pcm_dev->cd; cd->params = pcm_params->params;
-#ifdef CONFIG_HOST_PTABLE + /* + * walk in both directions to check if the pipeline is hostless + * skip page table set up if it is + */ + if (is_hostless_downstream(cd) && is_hostless_upstream(cd)) + goto pipe_params;
+#ifdef CONFIG_HOST_PTABLE list_init(&elem_list);
/* use DMA to read in compressed page table ringbuffer from host */ @@ -172,6 +244,8 @@ static int ipc_stream_pcm_params(uint32_t stream) } #endif
+pipe_params: + /* configure pipeline audio params */ err = pipeline_params(pcm_dev->cd->pipeline, pcm_dev->cd, pcm_params); if (err < 0) {
This patch adds the get() handler to respond to requests for the current tone state.
Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com --- src/audio/tone.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
diff --git a/src/audio/tone.c b/src/audio/tone.c index eee6091..d02e35f 100644 --- a/src/audio/tone.c +++ b/src/audio/tone.c @@ -462,6 +462,25 @@ static int tone_params(struct comp_dev *dev) return 0; }
+static int tone_cmd_get_value(struct comp_dev *dev, + struct sof_ipc_ctrl_data *cdata) +{ + struct comp_data *cd = comp_get_drvdata(dev); + int j; + + trace_tone("mgt"); + + if (cdata->cmd == SOF_CTRL_CMD_SWITCH) { + for (j = 0; j < cdata->num_elems; j++) { + cdata->chanv[j].channel = j; + cdata->chanv[j].value = !cd->sg[j].mute; + trace_value(j); + trace_value(cd->sg[j].mute); + } + } + return 0; +} + static int tone_cmd_set_value(struct comp_dev *dev, struct sof_ipc_ctrl_data *cdata) { struct comp_data *cd = comp_get_drvdata(dev); @@ -480,6 +499,7 @@ static int tone_cmd_set_value(struct comp_dev *dev, struct sof_ipc_ctrl_data *cd trace_tone_error("che"); return -EINVAL; } + if (val) tonegen_unmute(&cd->sg[ch]); else @@ -583,6 +603,9 @@ static int tone_cmd(struct comp_dev *dev, int cmd, void *data) case COMP_CMD_SET_VALUE: ret = tone_cmd_set_value(dev, cdata); break; + case COMP_CMD_GET_VALUE: + ret = tone_cmd_get_value(dev, cdata); + break; }
return ret;
add sample_rate memeber in tone ipc comp def to read in the value from topology.
Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com --- src/include/uapi/ipc.h | 1 + 1 file changed, 1 insertion(+)
diff --git a/src/include/uapi/ipc.h b/src/include/uapi/ipc.h index 912926f..a5f4649 100644 --- a/src/include/uapi/ipc.h +++ b/src/include/uapi/ipc.h @@ -715,6 +715,7 @@ struct sof_ipc_comp_mux { struct sof_ipc_comp_tone { struct sof_ipc_comp comp; struct sof_ipc_comp_config config; + int32_t sample_rate; int32_t frequency; int32_t amplitude; int32_t freq_mult;
set the sample rate from the value set in topology.
Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com --- src/audio/tone.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/audio/tone.c b/src/audio/tone.c index d02e35f..eb060bd 100644 --- a/src/audio/tone.c +++ b/src/audio/tone.c @@ -422,6 +422,8 @@ static struct comp_dev *tone_new(struct sof_ipc_comp *comp) comp_set_drvdata(dev, cd); cd->tone_func = tone_s32_default;
+ cd->rate = ipc_tone->sample_rate; + /* Reset tone generator and set channels volumes to default */ for (i = 0; i < PLATFORM_MAX_CHANNELS; i++) tonegen_reset(&cd->sg[i]); @@ -664,7 +666,6 @@ static int tone_prepare(struct comp_dev * dev) return ret;
cd->channels = dev->params.channels; - cd->rate = dev->params.rate; tracev_value(cd->channels); tracev_value(cd->rate);
period bytes depends on the frame_fmt and the number of channels set in topology. So fix calculation accordingly.
Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com --- src/audio/tone.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/src/audio/tone.c b/src/audio/tone.c index eb060bd..68a78f3 100644 --- a/src/audio/tone.c +++ b/src/audio/tone.c @@ -450,17 +450,19 @@ static int tone_params(struct comp_dev *dev)
trace_tone("par");
+ /* Tone supports only S32_LE PCM format atm */ + if (config->frame_fmt != SOF_IPC_FRAME_S32_LE) + return -EINVAL; + + trace_value(config->frame_fmt); + dev->params.frame_fmt = config->frame_fmt; + /* Need to compute this in non-host endpoint */ - dev->frame_bytes = - dev->params.sample_container_bytes * dev->params.channels; + dev->frame_bytes = comp_frame_bytes(dev);
/* calculate period size based on config */ cd->period_bytes = dev->frames * dev->frame_bytes;
- /* EQ supports only S32_LE PCM format */ - if (config->frame_fmt != SOF_IPC_FRAME_S32_LE) - return -EINVAL; - return 0; }
Fix frequenyc to 997Hz and gain to -20dB to match AES17 single tone test case requirement
Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com --- src/audio/tone.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/audio/tone.c b/src/audio/tone.c index 68a78f3..f98e5e0 100644 --- a/src/audio/tone.c +++ b/src/audio/tone.c @@ -63,9 +63,8 @@ #define TONE_GAIN(v) Q_CONVERT_FLOAT(v, 31)
/* Set default tone amplitude and frequency */ -#define TONE_AMPLITUDE_DEFAULT TONE_GAIN(0.5) /* -6 dB */ -#define TONE_FREQUENCY_DEFAULT TONE_FREQ(82.41) /* E2 note */ - +#define TONE_AMPLITUDE_DEFAULT TONE_GAIN(0.1) /* -20 dB */ +#define TONE_FREQUENCY_DEFAULT TONE_FREQ(997.0) #define TONE_NUM_FS 13 /* Table size for 8-192 kHz range */
/* 2*pi/Fs lookup tables in Q1.31 for each Fs */
participants (1)
-
Ranjani Sridharan