The default tone frequency of 997 Hz was updated to a proper Q16.16 value. Macros for tone frequency and gain were added to tone.h and a generic float to fractional value conversion macro to format.h. Also some common Q1.31 decibel constants were added. Tone function pointer set was moved to tone_new() since it is not modified later in this component.
Signed-off-by: Seppo Ingalsuo seppo.ingalsuo@linux.intel.com --- src/audio/tone.c | 29 +++++++++++++---------------- src/audio/tone.h | 7 ++++++- src/include/reef/audio/format.h | 17 ++++++++++++++++- 3 files changed, 35 insertions(+), 18 deletions(-)
diff --git a/src/audio/tone.c b/src/audio/tone.c index f45d8be..9499040 100644 --- a/src/audio/tone.c +++ b/src/audio/tone.c @@ -55,8 +55,8 @@ #define trace_tone_error(__e) trace_error(TRACE_CLASS_TONE, __e)
#define TONE_NUM_FS 13 /* Table size for 8-192 kHz range */ -#define TONE_AMPLITUDE_DEFAULT 2147484 /* -60 dB from full scale */ -#define TONE_FREQUENCY_DEFAULT 16334848 /* 997 in Q18.14 */ +#define TONE_AMPLITUDE_DEFAULT MINUS_60DB_Q1_31 /* -60 dB */ +#define TONE_FREQUENCY_DEFAULT TONE_FREQ(997.0) /* 997 Hz */
static int32_t tonegen(struct tone_state *sg); static void tonegen_control(struct tone_state *sg); @@ -80,7 +80,6 @@ struct comp_data { struct tone_state sg; void (*tone_func)(struct comp_dev *dev, struct comp_buffer *sink, struct comp_buffer *source, uint32_t frames); - };
/* @@ -129,7 +128,8 @@ static void tone_s32_default(struct comp_dev *dev, struct comp_buffer *sink, /* No need to check if past end_addr, * it is so just subtract buffer size. */ - dest = (int32_t *) ((size_t) dest - sink->alloc_size); + dest = (int32_t *) ((size_t) dest + - sink->ipc_buffer.size); } } sink->w_ptr = dest; @@ -381,7 +381,9 @@ static struct comp_dev *tone_new(struct sof_ipc_comp *comp)
comp_set_drvdata(dev, cd); comp_set_endpoint(dev); + cd->tone_func = tone_s32_default;
+ /* Reset tone generator and set channels volumes to default */ tonegen_reset(&cd->sg);
return dev; @@ -417,22 +419,19 @@ static int tone_params(struct comp_dev *dev, struct stream_params *params) static int tone_cmd(struct comp_dev *dev, int cmd, void *data) { struct comp_data *cd = comp_get_drvdata(dev); - struct sof_ipc_comp_tone *cv; + struct sof_ipc_comp_tone *ct; trace_tone("TCm");
switch (cmd) { case COMP_CMD_TONE: trace_tone("Tto"); - cv = (struct sof_ipc_comp_tone *) data; + ct = (struct sof_ipc_comp_tone *) data; /* Ignore channels while tone implementation is mono */ - tonegen_set_f(&cd->sg, cv->frequency); - tonegen_set_a(&cd->sg, cv->amplitude); - tonegen_set_sweep(&cd->sg, cv->freq_mult, cv->ampl_mult, - cv->length, cv->period, cv->repeats); - tonegen_set_linramp(&cd->sg, cv->ramp_step); - break; - case COMP_CMD_VOLUME: - trace_tone("TVo"); + tonegen_set_f(&cd->sg, ct->frequency); + tonegen_set_a(&cd->sg, ct->amplitude); + tonegen_set_sweep(&cd->sg, ct->freq_mult, ct->ampl_mult, + ct->length, ct->period, ct->repeats); + tonegen_set_linramp(&cd->sg, ct->ramp_step); break; case COMP_CMD_MUTE: trace_tone("TMu"); @@ -496,7 +495,6 @@ static int tone_copy(struct comp_dev *dev) */ need_sink = cframes * sink->params.pcm->frame_size; if (sink->free >= need_sink) { - /* create tone */ cd->tone_func(dev, sink, source, cframes); } @@ -517,7 +515,6 @@ static int tone_prepare(struct comp_dev *dev) trace_value(sink->params.pcm->channels); trace_value(sink->params.pcm->rate);
- cd->tone_func = tone_s32_default; f = tonegen_get_f(&cd->sg); a = tonegen_get_a(&cd->sg); if (tonegen_init(&cd->sg, sink->params.pcm->rate, f, a) < 0) diff --git a/src/audio/tone.h b/src/audio/tone.h index 861717c..fcaf404 100644 --- a/src/audio/tone.h +++ b/src/audio/tone.h @@ -30,6 +30,11 @@ * Keyon Jie yang.jie@linux.intel.com */
+/* Convert float frequency in Hz to Q16.16 fractional format */ +#define TONE_FREQ(f) Q_CONVERT_FLOAT(f, 16) + +/* Convert float gain to Q1.31 fractional format */ +#define TONE_GAIN(v) Q_CONVERT_FLOAT(v, 31)
struct tone_state { int mute; @@ -37,7 +42,7 @@ struct tone_state { int32_t a_target; /* Target amplitude Q1.31 */ int32_t ampl_coef; /* Amplitude multiplier Q2.30 */ int32_t c; /* Coefficient 2*pi/Fs Q1.31 */ - int32_t f; /* Frequency Q18.14 */ + int32_t f; /* Frequency Q16.16 */ int32_t freq_coef; /* Frequency multiplier Q2.30 */ int32_t fs; /* Sample rate in Hertz Q32.0 */ int32_t ramp_step; /* Amplitude ramp step Q1.31 */ diff --git a/src/include/reef/audio/format.h b/src/include/reef/audio/format.h index a1dae42..945a968 100644 --- a/src/include/reef/audio/format.h +++ b/src/include/reef/audio/format.h @@ -44,7 +44,22 @@ /* Collection of common fractional numbers */ #define ONE_Q2_30 1073741824 /* Q2.30 1.0 */ #define ONE_Q1_31 2147483647 /* Q1.31 ~1.0 */ - +#define MINUS_3DB_Q1_31 1520301996 /* 10^(-3/20) */ +#define MINUS_6DB_Q1_31 1076291389 /* 10^(-6/20) */ +#define MINUS_10DB_Q1_31 679093957 /* 10^(-10/20) */ +#define MINUS_20DB_Q1_31 214748365 /* 10^(-20/20) */ +#define MINUS_30DB_Q1_31 67909396 /* 10^(-30/20) */ +#define MINUS_40DB_Q1_31 21474836 /* 10^(-40/20) */ +#define MINUS_50DB_Q1_31 6790940 /* 10^(-50/20) */ +#define MINUS_60DB_Q1_31 2147484 /* 10^(-60/20) */ +#define MINUS_70DB_Q1_31 679094 /* 10^(-70/20) */ +#define MINUS_80DB_Q1_31 214748 /* 10^(-80/20) */ +#define MINUS_90DB_Q1_31 67909 /* 10^(-90/20) */ + +/* Convert a float number to fractional Qnx.ny format. Note that there is no + * check for nx+ny number of bits to fit the word length of int. + */ +#define Q_CONVERT_FLOAT(f, qy) ((int)((f) * (1 << qy) + 0.5)) /* f is float */
/* A more clever macro for Q-shifts */ #define Q_SHIFT(x, src_q, dst_q) ((x)>>((src_q)-(dst_q)))