diff options
Diffstat (limited to 'lib/rbcodec/dsp/lin_resample.c')
-rw-r--r-- | lib/rbcodec/dsp/lin_resample.c | 97 |
1 files changed, 45 insertions, 52 deletions
diff --git a/lib/rbcodec/dsp/lin_resample.c b/lib/rbcodec/dsp/lin_resample.c index 34dc35b2dd..20bb78e68d 100644 --- a/lib/rbcodec/dsp/lin_resample.c +++ b/lib/rbcodec/dsp/lin_resample.c | |||
@@ -51,9 +51,8 @@ static struct resample_data | |||
51 | int32_t last_sample[2]; /* 08h: Last samples for interpolation (L+R) */ | 51 | int32_t last_sample[2]; /* 08h: Last samples for interpolation (L+R) */ |
52 | /* 10h */ | 52 | /* 10h */ |
53 | int32_t frequency; /* Virtual samplerate */ | 53 | int32_t frequency; /* Virtual samplerate */ |
54 | struct dsp_config *dsp; /* The DSP for this resampler */ | ||
55 | struct dsp_buffer resample_buf; /* Buffer descriptor for resampled data */ | 54 | struct dsp_buffer resample_buf; /* Buffer descriptor for resampled data */ |
56 | int32_t *resample_buf_arr[2]; /* Actual output data pointers */ | 55 | int32_t *resample_out_p[2]; /* Actual output buffer pointers */ |
57 | } resample_data[DSP_COUNT] IBSS_ATTR; | 56 | } resample_data[DSP_COUNT] IBSS_ATTR; |
58 | 57 | ||
59 | /* Actual worker function. Implemented here or in target assembly code. */ | 58 | /* Actual worker function. Implemented here or in target assembly code. */ |
@@ -75,9 +74,9 @@ static void lin_resample_flush(struct dsp_proc_entry *this) | |||
75 | } | 74 | } |
76 | 75 | ||
77 | static bool lin_resample_new_delta(struct resample_data *data, | 76 | static bool lin_resample_new_delta(struct resample_data *data, |
78 | struct dsp_buffer *buf) | 77 | struct sample_format *format) |
79 | { | 78 | { |
80 | int32_t frequency = buf->format.frequency; /* virtual samplerate */ | 79 | int32_t frequency = format->frequency; /* virtual samplerate */ |
81 | 80 | ||
82 | data->frequency = frequency; | 81 | data->frequency = frequency; |
83 | data->delta = fp_div(frequency, NATIVE_FREQUENCY, 16); | 82 | data->delta = fp_div(frequency, NATIVE_FREQUENCY, 16); |
@@ -169,8 +168,8 @@ static void lin_resample_process(struct dsp_proc_entry *this, | |||
169 | return; /* data still remains */ | 168 | return; /* data still remains */ |
170 | 169 | ||
171 | dst->remcount = 0; | 170 | dst->remcount = 0; |
172 | dst->p32[0] = data->resample_buf_arr[0]; | 171 | dst->p32[0] = data->resample_out_p[0]; |
173 | dst->p32[1] = data->resample_buf_arr[1]; | 172 | dst->p32[1] = data->resample_out_p[1]; |
174 | 173 | ||
175 | if (src->remcount > 0) | 174 | if (src->remcount > 0) |
176 | { | 175 | { |
@@ -189,63 +188,44 @@ static void lin_resample_process(struct dsp_proc_entry *this, | |||
189 | } | 188 | } |
190 | 189 | ||
191 | /* Finish draining old samples then switch format or shut off */ | 190 | /* Finish draining old samples then switch format or shut off */ |
192 | static void lin_resample_new_format(struct dsp_proc_entry *this, | 191 | static intptr_t lin_resample_new_format(struct dsp_proc_entry *this, |
193 | struct dsp_buffer **buf_p) | 192 | struct dsp_config *dsp, |
193 | struct sample_format *format) | ||
194 | { | 194 | { |
195 | struct resample_data *data = (void *)this->data; | 195 | struct resample_data *data = (void *)this->data; |
196 | struct dsp_buffer *src = *buf_p; | ||
197 | struct dsp_buffer *dst = &data->resample_buf; | 196 | struct dsp_buffer *dst = &data->resample_buf; |
198 | 197 | ||
199 | if (dst->remcount > 0) | 198 | if (dst->remcount > 0) |
200 | { | 199 | return PROC_NEW_FORMAT_TRANSITION; |
201 | *buf_p = dst; | ||
202 | return; /* data still remains */ | ||
203 | } | ||
204 | 200 | ||
205 | DSP_PRINT_FORMAT(DSP_PROC_RESAMPLE, DSP_PROC_RESAMPLE, src->format); | 201 | DSP_PRINT_FORMAT(DSP_PROC_RESAMPLE, *format); |
206 | 202 | ||
207 | struct dsp_config *dsp = data->dsp; | ||
208 | int32_t frequency = data->frequency; | 203 | int32_t frequency = data->frequency; |
209 | bool active = dsp_proc_active(dsp, DSP_PROC_RESAMPLE); | 204 | bool active = dsp_proc_active(dsp, DSP_PROC_RESAMPLE); |
210 | 205 | ||
211 | if (src->format.frequency != frequency) | 206 | if (format->frequency != frequency) |
212 | { | 207 | { |
213 | DEBUGF(" DSP_PROC_RESAMPLE- new delta\n"); | 208 | DEBUGF(" DSP_PROC_RESAMPLE- new delta\n"); |
214 | active = lin_resample_new_delta(data, src); | 209 | active = lin_resample_new_delta(data, format); |
215 | dsp_proc_activate(dsp, DSP_PROC_RESAMPLE, active); | 210 | dsp_proc_activate(dsp, DSP_PROC_RESAMPLE, active); |
216 | } | 211 | } |
217 | 212 | ||
218 | /* Everything after us is NATIVE_FREQUENCY */ | 213 | /* Everything after us is NATIVE_FREQUENCY */ |
219 | struct sample_format f = src->format; | 214 | dst->format = *format; |
220 | f.frequency = NATIVE_FREQUENCY; | 215 | dst->format.frequency = NATIVE_FREQUENCY; |
221 | f.codec_frequency = NATIVE_FREQUENCY; | 216 | dst->format.codec_frequency = NATIVE_FREQUENCY; |
222 | |||
223 | if (!active) | ||
224 | { | ||
225 | DEBUGF(" DSP_PROC_RESAMPLE- not active\n"); | ||
226 | dst->format = f; /* Keep track */ | ||
227 | return; /* No resampling required */ | ||
228 | } | ||
229 | |||
230 | format_change_ack(&src->format); | ||
231 | 217 | ||
232 | if (EQU_SAMPLE_FORMAT(f, dst->format)) | 218 | if (active) |
233 | { | 219 | return PROC_NEW_FORMAT_OK; |
234 | DEBUGF(" DSP_PROC_RESAMPLE- same dst format\n"); | ||
235 | format_change_ack(&f); /* Nothing changed that matters downstream */ | ||
236 | } | ||
237 | 220 | ||
238 | dst->format = f; | 221 | /* No longer needed */ |
239 | dsp_proc_call(this, buf_p, 0); | 222 | DEBUGF(" DSP_PROC_RESAMPLE- deactivated\n"); |
223 | return PROC_NEW_FORMAT_DEACTIVATED; | ||
240 | } | 224 | } |
241 | 225 | ||
242 | static void lin_resample_init(struct dsp_config *dsp, | 226 | static void INIT_ATTR lin_resample_dsp_init(struct dsp_config *dsp, |
243 | enum dsp_ids dsp_id) | 227 | enum dsp_ids dsp_id) |
244 | { | 228 | { |
245 | /* Always enable resampler so that format changes may be monitored and | ||
246 | * it self-activated when required */ | ||
247 | dsp_proc_enable(dsp, DSP_PROC_RESAMPLE, true); | ||
248 | |||
249 | int32_t *lbuf, *rbuf; | 229 | int32_t *lbuf, *rbuf; |
250 | 230 | ||
251 | switch (dsp_id) | 231 | switch (dsp_id) |
@@ -265,8 +245,19 @@ static void lin_resample_init(struct dsp_config *dsp, | |||
265 | return; | 245 | return; |
266 | } | 246 | } |
267 | 247 | ||
268 | resample_data[dsp_id].resample_buf_arr[0] = lbuf; | 248 | /* Always enable resampler so that format changes may be monitored and |
269 | resample_data[dsp_id].resample_buf_arr[1] = rbuf; | 249 | * it self-activated when required */ |
250 | dsp_proc_enable(dsp, DSP_PROC_RESAMPLE, true); | ||
251 | resample_data[dsp_id].resample_out_p[0] = lbuf; | ||
252 | resample_data[dsp_id].resample_out_p[1] = rbuf; | ||
253 | } | ||
254 | |||
255 | static void INIT_ATTR lin_resample_proc_init(struct dsp_proc_entry *this, | ||
256 | struct dsp_config *dsp) | ||
257 | { | ||
258 | dsp_proc_set_in_place(dsp, DSP_PROC_RESAMPLE, false); | ||
259 | this->data = (intptr_t)&resample_data[dsp_get_id(dsp)]; | ||
260 | this->process = lin_resample_process; | ||
270 | } | 261 | } |
271 | 262 | ||
272 | /* DSP message hook */ | 263 | /* DSP message hook */ |
@@ -275,10 +266,12 @@ static intptr_t lin_resample_configure(struct dsp_proc_entry *this, | |||
275 | unsigned int setting, | 266 | unsigned int setting, |
276 | intptr_t value) | 267 | intptr_t value) |
277 | { | 268 | { |
269 | intptr_t retval = 0; | ||
270 | |||
278 | switch (setting) | 271 | switch (setting) |
279 | { | 272 | { |
280 | case DSP_INIT: | 273 | case DSP_INIT: |
281 | lin_resample_init(dsp, (enum dsp_ids)value); | 274 | lin_resample_dsp_init(dsp, (enum dsp_ids)value); |
282 | break; | 275 | break; |
283 | 276 | ||
284 | case DSP_FLUSH: | 277 | case DSP_FLUSH: |
@@ -286,21 +279,21 @@ static intptr_t lin_resample_configure(struct dsp_proc_entry *this, | |||
286 | break; | 279 | break; |
287 | 280 | ||
288 | case DSP_PROC_INIT: | 281 | case DSP_PROC_INIT: |
289 | this->data = (intptr_t)&resample_data[dsp_get_id(dsp)]; | 282 | lin_resample_proc_init(this, dsp); |
290 | this->ip_mask = 0; /* Not in-place */ | ||
291 | this->process[0] = lin_resample_process; | ||
292 | this->process[1] = lin_resample_new_format; | ||
293 | ((struct resample_data *)this->data)->dsp = dsp; | ||
294 | break; | 283 | break; |
295 | 284 | ||
296 | case DSP_PROC_CLOSE: | 285 | case DSP_PROC_CLOSE: |
297 | /* This stage should be enabled at all times */ | 286 | /* This stage should be enabled at all times */ |
298 | DEBUGF("DSP_PROC_RESAMPLE- Error: Closing!\n"); | 287 | DEBUGF("DSP_PROC_RESAMPLE- Error: Closing!\n"); |
299 | break; | 288 | break; |
289 | |||
290 | case DSP_PROC_NEW_FORMAT: | ||
291 | retval = lin_resample_new_format(this, dsp, | ||
292 | (struct sample_format *)value); | ||
293 | break; | ||
300 | } | 294 | } |
301 | 295 | ||
302 | return 1; | 296 | return retval; |
303 | (void)value; | ||
304 | } | 297 | } |
305 | 298 | ||
306 | /* Database entry */ | 299 | /* Database entry */ |