/src/adhd/cras/src/dsp/eq2.c
Line | Count | Source |
1 | | /* Copyright 2013 The ChromiumOS Authors |
2 | | * Use of this source code is governed by a BSD-style license that can be |
3 | | * found in the LICENSE file. |
4 | | */ |
5 | | |
6 | | #include "cras/src/dsp/eq2.h" |
7 | | |
8 | | #include <errno.h> |
9 | | #include <stdlib.h> |
10 | | |
11 | | #include "cras/src/dsp/biquad.h" |
12 | | #include "cras/src/dsp/rust/dsp.h" |
13 | | #include "user/eq.h" |
14 | | |
15 | | int eq2_convert_channel_response(const struct eq2* eq2, |
16 | | int32_t* bq_cfg, |
17 | 0 | int channel) { |
18 | 0 | float accumulated_gain = 1.0; |
19 | 0 | int ret; |
20 | |
|
21 | 0 | for (int i = 0; i < eq2_len(eq2, channel); i++) { |
22 | 0 | const struct biquad* bq = eq2_get_bq(eq2, channel, i); |
23 | | |
24 | | /* For i = 0..(n-2), accumulated_gain is kept accumulating in loop. |
25 | | * For i = n-1, the last biquad element, accumulated_gain is dumped to the |
26 | | * converted blob by calling biquad_convert_blob() with dump_gain = 1. |
27 | | * To prevent the sample saturation on each node across the series of biquad |
28 | | * as the channel response intermediate nodes, considering that DSP EQ is |
29 | | * the fixed-point design. |
30 | | */ |
31 | 0 | ret = biquad_convert_blob(bq, bq_cfg, &accumulated_gain, |
32 | 0 | (i == eq2_len(eq2, channel) - 1) /* dump_gain */); |
33 | 0 | if (ret < 0) { |
34 | 0 | return ret; |
35 | 0 | } |
36 | 0 | bq_cfg += SOF_EQ_IIR_NBIQUAD; |
37 | 0 | } |
38 | 0 | return 0; |
39 | 0 | } |
40 | | |
41 | | int eq2_convert_params_to_blob(const struct eq2* eq2, |
42 | | uint32_t** config, |
43 | 0 | size_t* config_size) { |
44 | 0 | const size_t biquad_size = sizeof(struct sof_eq_iir_biquad); |
45 | 0 | const size_t eq_iir_hdr_size = sizeof(struct sof_eq_iir_header); |
46 | 0 | const size_t eq_cfg_hdr_size = sizeof(struct sof_eq_iir_config); |
47 | |
|
48 | 0 | if (!eq2) { |
49 | 0 | return -ENOENT; |
50 | 0 | } |
51 | | |
52 | 0 | if (eq2_len(eq2, 0) <= 0 || eq2_len(eq2, 1) <= 0) { |
53 | 0 | return -ENODATA; |
54 | 0 | } |
55 | | |
56 | 0 | size_t response_config_size[EQ2_NUM_CHANNELS] = { |
57 | 0 | eq_iir_hdr_size + eq2_len(eq2, 0) * biquad_size, /* response of ch-0 */ |
58 | 0 | eq_iir_hdr_size + eq2_len(eq2, 1) * biquad_size /* response of ch-1 */ |
59 | 0 | }; |
60 | |
|
61 | 0 | size_t size = |
62 | 0 | eq_cfg_hdr_size + /* sof_eq_iir_config header */ |
63 | 0 | EQ2_NUM_CHANNELS * sizeof(uint32_t) + /* assign_response[channels] */ |
64 | 0 | response_config_size[0] + /* 1st response config data */ |
65 | 0 | response_config_size[1]; /* 2nd response config data */ |
66 | |
|
67 | 0 | struct sof_eq_iir_config* eq_config = |
68 | 0 | (struct sof_eq_iir_config*)calloc(1, size); |
69 | 0 | if (!eq_config) { |
70 | 0 | return -ENOMEM; |
71 | 0 | } |
72 | | |
73 | | /* Fill sof_eq_iir_config header. */ |
74 | 0 | eq_config->size = size; |
75 | 0 | eq_config->channels_in_config = EQ2_NUM_CHANNELS; |
76 | 0 | eq_config->number_of_responses = EQ2_NUM_CHANNELS; |
77 | | |
78 | | /* Fill assign_response[channels]. */ |
79 | 0 | eq_config->data[0] = 0; /* assign response-0 to ch-0 */ |
80 | 0 | eq_config->data[1] = 1; /* assign response-1 to ch-1 */ |
81 | | |
82 | | /* Fill config data per response. */ |
83 | 0 | struct sof_eq_iir_header* eq_hdr = |
84 | 0 | (struct sof_eq_iir_header*)(&eq_config->data[2]); |
85 | 0 | int ret; |
86 | 0 | for (int channel = 0; channel < EQ2_NUM_CHANNELS; channel++) { |
87 | | /* Fill the header information. */ |
88 | 0 | eq_hdr->num_sections = eq2_len(eq2, channel); |
89 | 0 | eq_hdr->num_sections_in_series = eq2_len(eq2, channel); |
90 | | |
91 | | /* Fill sof_eq_iir_biquad for biquads in one channel. */ |
92 | 0 | ret = eq2_convert_channel_response(eq2, eq_hdr->biquads, channel); |
93 | 0 | if (ret < 0) { |
94 | 0 | free(eq_config); |
95 | 0 | return ret; |
96 | 0 | } |
97 | | |
98 | | /* Move the address to the next sof_eq_iir_header element. */ |
99 | 0 | eq_hdr = (struct sof_eq_iir_header*)((uint8_t*)eq_hdr + |
100 | 0 | response_config_size[channel]); |
101 | 0 | } |
102 | | |
103 | 0 | *config = (uint32_t*)eq_config; |
104 | 0 | *config_size = size; |
105 | 0 | return 0; |
106 | 0 | } |