[Sound-open-firmware] [PATCH 4/5] SRC: IPC updates and fixes v3
Seppo Ingalsuo
seppo.ingalsuo at linux.intel.com
Wed Jun 28 18:25:51 CEST 2017
SRC sets the sink and downstream pipeline PCM rate, period_count and
period_bytes in src_params() according to received out_rate via IPC.
Fail in delay lines allocation results to -ENOMEM error.
Function call comp_set_sink_params() is renamed to
comp_buffer_sink_params().
Added void to functions and corresponding headers without parameters.
Plus white space and long lines fixes for all SRC source files.
Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo at linux.intel.com>
---
src/audio/src.c | 71 +++++++++++++++++++++++++++++++++++---------------
src/audio/src_core.c | 40 ++++++++++++++++++----------
src/audio/src_core.h | 12 +++++----
src/include/uapi/ipc.h | 1 +
4 files changed, 84 insertions(+), 40 deletions(-)
diff --git a/src/audio/src.c b/src/audio/src.c
index c338220..4e46338 100644
--- a/src/audio/src.c
+++ b/src/audio/src.c
@@ -56,9 +56,13 @@
/* src component private data */
struct comp_data {
struct polyphase_src src[PLATFORM_MAX_CHANNELS];
+ /* Next two elements must be kept in this order since
+ * the end of pcm_params is a flexible array.
+ */
+ struct sof_ipc_pcm_params pcm_params;
+ enum sof_ipc_chmap channel_map[PLATFORM_MAX_CHANNELS];
int32_t *delay_lines;
int scratch_length;
- //int32_t z[STAGE_BUF_SIZE];
void (*src_func)(struct comp_dev *dev,
struct comp_buffer *source,
struct comp_buffer *sink,
@@ -149,7 +153,8 @@ static void src_2s_s32_default(struct comp_dev *dev,
int n_written = 0;
if (cd->src[0].mute) {
- src_muted_s32(source, sink, blk_in, blk_out, nch, source_frames);
+ src_muted_s32(source, sink, blk_in, blk_out, nch,
+ source_frames);
return;
}
@@ -214,14 +219,15 @@ static void src_1s_s32_default(struct comp_dev *dev,
int blk_out = cd->src[0].blk_out;
int n_times = cd->src[0].stage1_times;
int nch = sink->params.pcm->channels;
- int32_t *dest = (int32_t*) sink->w_ptr;
- int32_t *src = (int32_t*) source->r_ptr;
+ int32_t *dest = (int32_t *) sink->w_ptr;
+ int32_t *src = (int32_t *) source->r_ptr;
int n_read = 0;
int n_written = 0;
struct src_stage_prm s1;
if (cd->src[0].mute) {
- src_muted_s32(source, sink, blk_in, blk_out, nch, source_frames);
+ src_muted_s32(source, sink, blk_in, blk_out, nch,
+ source_frames);
return;
}
@@ -263,7 +269,7 @@ static struct comp_dev *src_new(struct sof_ipc_comp *comp)
{
struct comp_dev *dev;
struct sof_ipc_comp_src *src;
- struct sof_ipc_comp_src *ipc_src = (struct sof_ipc_comp_src *)comp;
+ struct sof_ipc_comp_src *ipc_src = (struct sof_ipc_comp_src *) comp;
struct comp_data *cd;
int i;
@@ -274,7 +280,7 @@ static struct comp_dev *src_new(struct sof_ipc_comp *comp)
if (dev == NULL)
return NULL;
- src = (struct sof_ipc_comp_src *)&dev->comp;
+ src = (struct sof_ipc_comp_src *) &dev->comp;
memcpy(src, ipc_src, sizeof(struct sof_ipc_comp_src));
cd = rmalloc(RZONE_RUNTIME, RFLAGS_NONE, sizeof(*cd));
@@ -317,6 +323,7 @@ static int src_params(struct comp_dev *dev, struct stream_params *params)
int32_t *buffer_start;
int n = 0;
struct comp_data *cd = comp_get_drvdata(dev);
+ struct sof_ipc_comp_src *src = (struct sof_ipc_comp_src *) &dev->comp;
trace_src("SPa");
@@ -325,23 +332,45 @@ static int src_params(struct comp_dev *dev, struct stream_params *params)
|| (params->pcm->frame_fmt != SOF_IPC_FRAME_S32_LE))
return -EINVAL;
- /* No data transformation */
- comp_set_sink_params(dev, params);
+ comp_buffer_sink_params(dev, params);
- /* Allocate needed memory for delay lines */
source = list_first_item(&dev->bsource_list, struct comp_buffer,
sink_list);
sink = list_first_item(&dev->bsink_list, struct comp_buffer,
source_list);
- src_buffer_lengths(&need, source->params.pcm->rate,
- sink->params.pcm->rate, source->params.pcm->channels);
+
+ /* Copy PCM stream parameters and the channel map array */
+ memcpy(&cd->pcm_params, &(*params->pcm),
+ sizeof(struct sof_ipc_pcm_params));
+ for (i = 0; i < params->pcm->channels; i++)
+ cd->pcm_params.channel_map[i] = params->pcm->channel_map[i];
+
+ /* Point sink stream parameters to copy */
+ sink->params.pcm = &cd->pcm_params;
+
+ /* Stored IPC from src_new() contains the output rate for sink,
+ * set the new rate for sink.
+ */
+ sink->params.pcm->rate = src->out_rate;
+
+ /* Adjust sink buffer parameters to match fs_out/fs_in */
+ sink->params.pcm->period_count = sink->params.pcm->period_count
+ * sink->params.pcm->rate / source->params.pcm->rate;
+ sink->params.pcm->period_bytes = sink->params.pcm->period_bytes
+ * sink->params.pcm->rate / source->params.pcm->rate;
+
+ /* Allocate needed memory for delay lines */
+ if (src_buffer_lengths(&need, source->params.pcm->rate,
+ sink->params.pcm->rate, source->params.pcm->channels) < 0)
+ return -EINVAL;
+
delay_lines_size = sizeof(int32_t) * need.total;
if (cd->delay_lines != NULL)
rfree(cd->delay_lines);
cd->delay_lines = rmalloc(RZONE_RUNTIME, RFLAGS_NONE, delay_lines_size);
if (cd->delay_lines == NULL)
- return -EINVAL;
+ return -ENOMEM;
/* Clear all delay lines here */
memset(cd->delay_lines, 0, delay_lines_size);
@@ -369,18 +398,19 @@ static int src_params(struct comp_dev *dev, struct stream_params *params)
*/
trace_src("SFa");
cd->src_func = fallback_s32;
- return(-EINVAL);
- break;
+ return -EINVAL;
}
/* Check that src blk_in and blk_out are less than params.period_frames.
* Return an error if the period is too short.
*/
- if (src_polyphase_get_blk_in(&cd->src[0]) > source->params.pcm->period_count)
- return(-EINVAL);
+ if (src_polyphase_get_blk_in(&cd->src[0])
+ > source->params.pcm->period_count)
+ return -EINVAL;
- if (src_polyphase_get_blk_out(&cd->src[0]) > sink->params.pcm->period_count)
- return(-EINVAL);
+ if (src_polyphase_get_blk_out(&cd->src[0])
+ > sink->params.pcm->period_count)
+ return -EINVAL;
return 0;
@@ -548,8 +578,7 @@ static int src_reset(struct comp_dev *dev)
struct comp_driver comp_src = {
.type = SOF_COMP_SRC,
- .ops =
- {
+ .ops = {
.new = src_new,
.free = src_free,
.params = src_params,
diff --git a/src/audio/src_core.c b/src/audio/src_core.c
index a9c503d..7deae14 100644
--- a/src/audio/src_core.c
+++ b/src/audio/src_core.c
@@ -65,7 +65,7 @@ int src_fir_delay_length(struct src_stage *s)
int src_out_delay_length(struct src_stage *s)
{
- return(s->num_of_subfilters - 1) * s->odm + 1;
+ return (s->num_of_subfilters - 1) * s->odm + 1;
}
/* Calculates the buffer length needed between two SRC stages */
@@ -86,6 +86,7 @@ int src_stage_buf_length(struct src_stage *s1, struct src_stage *s2)
int src_find_fs(int fs_list[], int list_length, int fs)
{
int i;
+
for (i = 0; i < list_length; i++) {
if (fs_list[i] == fs)
return i;
@@ -94,10 +95,11 @@ int src_find_fs(int fs_list[], int list_length, int fs)
}
/* Match SOF and defined SRC input rates into a bit mask */
-int32_t src_input_rates()
+int32_t src_input_rates(void)
{
int n, b;
int mask = 0;
+
for (n = SOF_RATES_LENGTH - 1; n >= 0; n--) {
b = (src_find_fs(src_in_fs, NUM_IN_FS, sof_rates[n]) >= 0)
? 1 : 0;
@@ -107,10 +109,11 @@ int32_t src_input_rates()
}
/* Match SOF and defined SRC output rates into a bit mask */
-int32_t src_output_rates()
+int32_t src_output_rates(void)
{
int n, b;
int mask = 0;
+
for (n = SOF_RATES_LENGTH - 1; n >= 0; n--) {
b = (src_find_fs(src_out_fs, NUM_OUT_FS, sof_rates[n]) >= 0)
? 1 : 0;
@@ -152,7 +155,7 @@ int src_buffer_lengths(struct src_alloc *a, int fs_in, int fs_out, int nch)
return 0;
}
-static void src_state_reset(struct src_state* state)
+static void src_state_reset(struct src_state *state)
{
state->fir_delay_size = 0;
@@ -316,7 +319,8 @@ static inline int32_t fir_filter(
n1 = fir->fir_ri + 1;
if (n1 > filter_length) {
/* No need to un-wrap fir read index, make sure fir_fi
- * is ge 0 after FIR computation */
+ * is ge 0 after FIR computation.
+ */
fir_part(&y, filter_length, coefs, coefi, fir->fir_delay,
&fir->fir_ri);
} else {
@@ -331,7 +335,7 @@ static inline int32_t fir_filter(
/* Q9.47 -> Q9.24, saturate to Q8.24 */
y = y >> (23 + shift);
- return(int32_t) sat_int32(y);
+ return (int32_t)sat_int32(y);
}
void src_polyphase_stage_cir(struct src_stage_prm *s)
@@ -377,7 +381,8 @@ void src_polyphase_stage_cir(struct src_stage_prm *s)
if (s->x_rptr >= s->x_end_addr)
s->x_rptr = (int32_t *)
((size_t) s->x_rptr - s->x_size);
- if (s->state->fir_wi == s->state->fir_delay_size)
+ if (s->state->fir_wi
+ == s->state->fir_delay_size)
s->state->fir_wi = 0;
}
}
@@ -416,14 +421,16 @@ void src_polyphase_stage_cir(struct src_stage_prm *s)
if (m < n_wrap_min) {
/* No circular wrap need */
while (m > 0) {
- *s->y_wptr = s->state->out_delay[s->state->out_ri++];
+ *s->y_wptr = s->state->out_delay[
+ s->state->out_ri++];
s->y_wptr += s->y_inc;
m -= s->y_inc;
}
} else {
/* Wrap in n_wrap_min/y_inc samples */
while (n_wrap_min > 0) {
- *s->y_wptr = s->state->out_delay[s->state->out_ri++];
+ *s->y_wptr = s->state->out_delay[
+ s->state->out_ri++];
s->y_wptr += s->y_inc;
n_wrap_min -= s->y_inc;
m -= s->y_inc;
@@ -434,7 +441,8 @@ void src_polyphase_stage_cir(struct src_stage_prm *s)
(int32_t *)
((size_t) s->y_wptr - s->y_size);
- if (s->state->out_ri == s->state->out_delay_size)
+ if (s->state->out_ri
+ == s->state->out_delay_size)
s->state->out_ri = 0;
}
}
@@ -460,7 +468,8 @@ void src_print_info(struct polyphase_src *src)
printf("SRC1 filter length %d\n", n1);
printf("SRC1 subfilter length %d\n", src->stage1->subfilter_length);
- printf("SRC1 number of subfilters %d\n", src->stage1->num_of_subfilters);
+ printf("SRC1 number of subfilters %d\n",
+ src->stage1->num_of_subfilters);
printf("SRC1 idm %d\n", src->stage1->idm);
printf("SRC1 odm %d\n", src->stage1->odm);
printf("SRC1 input blk %d\n", src->stage1->blk_in);
@@ -470,14 +479,16 @@ void src_print_info(struct polyphase_src *src)
if (n1 > 3) {
printf("SRC1 coef[1] %d\n", src->stage1->coefs[1]);
printf("SRC1 coef[2] %d\n", src->stage1->coefs[2]);
- printf("SRC1 coef[%d] %d\n", n1 - 1, src->stage1->coefs[n1 - 1]);
+ printf("SRC1 coef[%d] %d\n",
+ n1 - 1, src->stage1->coefs[n1 - 1]);
}
printf("SRC1 FIR delay %d\n", src->state1.fir_delay_size);
printf("SRC1 out delay %d\n", src->state1.out_delay_size);
printf("SRC2 filter length %d\n", n2);
printf("SRC2 subfilter length %d\n", src->stage2->subfilter_length);
- printf("SRC2 number of subfilters %d\n", src->stage2->num_of_subfilters);
+ printf("SRC2 number of subfilters %d\n",
+ src->stage2->num_of_subfilters);
printf("SRC2 idm %d\n", src->stage2->idm);
printf("SRC2 odm %d\n", src->stage2->odm);
printf("SRC2 input blk %d\n", src->stage2->blk_in);
@@ -487,7 +498,8 @@ void src_print_info(struct polyphase_src *src)
if (n2 > 3) {
printf("SRC2 coef[1] %d\n", src->stage2->coefs[1]);
printf("SRC2 coef[2] %d\n", src->stage2->coefs[2]);
- printf("SRC2 coef[%d] %d\n", n1 - 1, src->stage2->coefs[n2 - 1]);
+ printf("SRC2 coef[%d] %d\n",
+ n1 - 1, src->stage2->coefs[n2 - 1]);
}
printf("SRC2 FIR delay %d\n", src->state2.fir_delay_size);
printf("SRC2 out delay %d\n", src->state2.out_delay_size);
diff --git a/src/audio/src_core.h b/src/audio/src_core.h
index f7a9c67..0444215 100644
--- a/src/audio/src_core.h
+++ b/src/audio/src_core.h
@@ -32,7 +32,7 @@
#ifndef SRC_CORE_H
#define SRC_CORE_H
-#define MAX(a,b) ((a) > (b)) ? (a) : (b)
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
/* Include SRC min/max constants etc. */
#include <reef/audio/coefficients/src/src_int24_define.h>
@@ -125,17 +125,19 @@ static inline int src_polyphase_get_blk_out(struct polyphase_src *src)
void src_polyphase_reset(struct polyphase_src *src);
-int src_polyphase_init(struct polyphase_src *src, int fs1, int fs2, int32_t *delay_lines_start);
+int src_polyphase_init(struct polyphase_src *src, int fs1, int fs2,
+ int32_t *delay_lines_start);
-int src_polyphase(struct polyphase_src *src, int32_t x[], int32_t y[], int n_in);
+int src_polyphase(struct polyphase_src *src, int32_t x[], int32_t y[],
+ int n_in);
void src_polyphase_stage_cir(struct src_stage_prm *s);
int src_buffer_lengths(struct src_alloc *a, int fs_in, int fs_out, int nch);
-int32_t src_input_rates();
+int32_t src_input_rates(void);
-int32_t src_output_rates();
+int32_t src_output_rates(void);
#ifdef MODULE_TEST
void src_print_info(struct polyphase_src *src);
diff --git a/src/include/uapi/ipc.h b/src/include/uapi/ipc.h
index 5af07f2..9d5fa80 100644
--- a/src/include/uapi/ipc.h
+++ b/src/include/uapi/ipc.h
@@ -490,6 +490,7 @@ struct sof_ipc_comp_src {
struct sof_ipc_pcm_comp pcm;
uint32_t in_mask; /* SOF_RATE_ supported input rates */
uint32_t out_mask; /* SOF_RATE_ supported output rates */
+ int32_t out_rate;
} __attribute__((packed));
/* generic MUX component */
--
2.11.0
More information about the Sound-open-firmware
mailing list