summaryrefslogtreecommitdiff
path: root/lib/rbcodec/dsp/dsp_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/dsp/dsp_core.c')
-rw-r--r--lib/rbcodec/dsp/dsp_core.c342
1 files changed, 160 insertions, 182 deletions
diff --git a/lib/rbcodec/dsp/dsp_core.c b/lib/rbcodec/dsp/dsp_core.c
index 84a23a4c83..c54bda17a9 100644
--- a/lib/rbcodec/dsp/dsp_core.c
+++ b/lib/rbcodec/dsp/dsp_core.c
@@ -34,6 +34,13 @@
34#define DSP_PROC_DB_CREATE 34#define DSP_PROC_DB_CREATE
35#include "dsp_proc_entry.h" 35#include "dsp_proc_entry.h"
36 36
37#ifndef DSP_PROCESS_START
38/* These do nothing if not previously defined */
39#define DSP_PROCESS_START()
40#define DSP_PROCESS_LOOP()
41#define DSP_PROCESS_END()
42#endif /* !DSP_PROCESS_START */
43
37/* Linked lists give fewer loads in processing loop compared to some index 44/* Linked lists give fewer loads in processing loop compared to some index
38 * list, which is more important than keeping occasionally executed code 45 * list, which is more important than keeping occasionally executed code
39 * simple */ 46 * simple */
@@ -41,24 +48,23 @@
41struct dsp_config 48struct dsp_config
42{ 49{
43 /** General DSP-local data **/ 50 /** General DSP-local data **/
44 struct sample_io_data io_data; /* Sample input-output data (first) */ 51 struct sample_io_data io_data; /* Sample input-output data (first) */
45 uint32_t slot_free_mask; /* Mask of free slots for this DSP */ 52 uint32_t slot_free_mask; /* Mask of free slots for this DSP */
46 uint32_t proc_masks[2]; /* Mask of active/enabled stages */ 53 uint32_t proc_mask_enabled; /* Mask of enabled stages */
54 uint32_t proc_mask_active; /* Mask of active stages */
47 struct dsp_proc_slot 55 struct dsp_proc_slot
48 { 56 {
49 struct dsp_proc_entry proc_entry; /* This enabled stage */ 57 struct dsp_proc_entry proc_entry; /* This enabled stage */
50 struct dsp_proc_slot *next[2]; /* [0]=active next, [1]=enabled next */ 58 struct dsp_proc_slot *next; /* Next enabled slot */
51 const struct dsp_proc_db_entry *db_entry; 59 uint32_t mask; /* In place operation mask/flag */
52 } *proc_slots[2]; /* Pointer to first in list of 60 uint8_t version; /* Sample format version */
53 active/enabled stages */ 61 uint8_t db_index; /* Index in database array */
54 62 } *proc_slots; /* Pointer to first in list of enabled
55 /** Misc. extra stuff **/ 63 stages */
56#if 0 /* Not needed now but enable if something must know this */
57 bool processing; /* DSP is processing (to thwart inopportune
58 buffer moves) */
59#endif
60}; 64};
61 65
66#define NACT_BIT BIT_N(___DSP_PROC_ID_RESERVED)
67
62/* Pool of slots for stages - supports 32 or fewer combined as-is atm. */ 68/* Pool of slots for stages - supports 32 or fewer combined as-is atm. */
63static struct dsp_proc_slot 69static struct dsp_proc_slot
64dsp_proc_slot_arr[DSP_NUM_PROC_STAGES+DSP_VOICE_NUM_PROC_STAGES] IBSS_ATTR; 70dsp_proc_slot_arr[DSP_NUM_PROC_STAGES+DSP_VOICE_NUM_PROC_STAGES] IBSS_ATTR;
@@ -67,6 +73,11 @@ dsp_proc_slot_arr[DSP_NUM_PROC_STAGES+DSP_VOICE_NUM_PROC_STAGES] IBSS_ATTR;
67static struct dsp_config dsp_conf[DSP_COUNT] IBSS_ATTR; 73static struct dsp_config dsp_conf[DSP_COUNT] IBSS_ATTR;
68 74
69/** Processing stages support functions **/ 75/** Processing stages support functions **/
76static const struct dsp_proc_db_entry *
77proc_db_entry(const struct dsp_proc_slot *s)
78{
79 return dsp_proc_database[s->db_index];
80}
70 81
71/* Find the slot for a given enabled id */ 82/* Find the slot for a given enabled id */
72static struct dsp_proc_slot * find_proc_slot(struct dsp_config *dsp, 83static struct dsp_proc_slot * find_proc_slot(struct dsp_config *dsp,
@@ -74,17 +85,17 @@ static struct dsp_proc_slot * find_proc_slot(struct dsp_config *dsp,
74{ 85{
75 const uint32_t mask = BIT_N(id); 86 const uint32_t mask = BIT_N(id);
76 87
77 if ((dsp->proc_masks[1] & mask) == 0) 88 if (!(dsp->proc_mask_enabled & mask))
78 return NULL; /* Not enabled */ 89 return NULL; /* Not enabled */
79 90
80 struct dsp_proc_slot *s = dsp->proc_slots[1]; 91 struct dsp_proc_slot *s = dsp->proc_slots;
81 92
82 while (1) /* In proc_masks == it must be there */ 93 while (1) /* In proc_mask_enabled == it must be there */
83 { 94 {
84 if (BIT_N(s->db_entry->id) == mask) 95 if (BIT_N(proc_db_entry(s)->id) == mask)
85 return s; 96 return s;
86 97
87 s = s->next[1]; 98 s = s->next;
88 } 99 }
89} 100}
90 101
@@ -94,54 +105,23 @@ static intptr_t proc_broadcast(struct dsp_config *dsp, unsigned int setting,
94 intptr_t value) 105 intptr_t value)
95{ 106{
96 bool multi = setting < DSP_PROC_SETTING; 107 bool multi = setting < DSP_PROC_SETTING;
97 struct dsp_proc_slot *s = multi ? 108 struct dsp_proc_slot *s = multi ? dsp->proc_slots :
98 dsp->proc_slots[1] : find_proc_slot(dsp, setting - DSP_PROC_SETTING); 109 find_proc_slot(dsp, setting - DSP_PROC_SETTING);
99 110
100 while (s != NULL) 111 while (s != NULL)
101 { 112 {
102 intptr_t ret = s->db_entry->configure(&s->proc_entry, dsp, setting, 113 intptr_t ret = proc_db_entry(s)->configure(
103 value); 114 &s->proc_entry, dsp, setting, value);
115
104 if (!multi) 116 if (!multi)
105 return ret; 117 return ret;
106 118
107 s = s->next[1]; 119 s = s->next;
108 } 120 }
109 121
110 return multi ? 1 : 0; 122 return multi ? 1 : 0;
111} 123}
112 124
113/* Generic handler for this->process[0] */
114static void dsp_process_null(struct dsp_proc_entry *this,
115 struct dsp_buffer **buf_p)
116{
117 (void)this; (void)buf_p;
118}
119
120/* Generic handler for this->process[1] */
121static void dsp_format_change_process(struct dsp_proc_entry *this,
122 struct dsp_buffer **buf_p)
123{
124 enum dsp_proc_ids id =
125 TYPE_FROM_MEMBER(struct dsp_proc_slot, this, proc_entry)->db_entry->id;
126
127 DSP_PRINT_FORMAT(<Default Handler>, id, (*buf_p)->format);
128
129 /* We don't keep back references to the DSP, so just search for it */
130 struct dsp_config *dsp;
131 for (unsigned int i = 0; (dsp = dsp_get_config(i)); i++)
132 {
133 /* Found one with the id, check if it's this one
134 (NULL return doesn't matter) */
135 if (&find_proc_slot(dsp, id)->proc_entry == this)
136 {
137 if (dsp_proc_active(dsp, id))
138 dsp_proc_call(this, buf_p, 0);
139
140 break;
141 }
142 }
143}
144
145/* Add an item to the enabled list */ 125/* Add an item to the enabled list */
146static struct dsp_proc_slot * 126static struct dsp_proc_slot *
147dsp_proc_enable_enlink(struct dsp_config *dsp, uint32_t mask) 127dsp_proc_enable_enlink(struct dsp_config *dsp, uint32_t mask)
@@ -156,44 +136,42 @@ dsp_proc_enable_enlink(struct dsp_config *dsp, uint32_t mask)
156 return NULL; 136 return NULL;
157 } 137 }
158 138
159 const struct dsp_proc_db_entry *db_entry_prev = NULL; 139 unsigned int db_index = 0, db_index_prev = DSP_NUM_PROC_STAGES;
160 const struct dsp_proc_db_entry *db_entry;
161 140
162 /* Order of enabled list is same as DB array */ 141 /* Order of enabled list is same as DB array */
163 for (unsigned int i = 0;; i++) 142 while (1)
164 { 143 {
165 if (i >= DSP_NUM_PROC_STAGES) 144 uint32_t m = BIT_N(dsp_proc_database[db_index]->id);
166 return NULL;
167
168 db_entry = dsp_proc_database[i];
169
170 uint32_t m = BIT_N(db_entry->id);
171 145
172 if (m == mask) 146 if (m == mask)
173 break; /* This is the one */ 147 break; /* This is the one */
174 148
175 if (dsp->proc_masks[1] & m) 149 if (dsp->proc_mask_enabled & m)
176 db_entry_prev = db_entry; 150 db_index_prev = db_index;
151
152 if (++db_index >= DSP_NUM_PROC_STAGES)
153 return NULL;
177 } 154 }
178 155
179 struct dsp_proc_slot *s = &dsp_proc_slot_arr[slot]; 156 struct dsp_proc_slot *s = &dsp_proc_slot_arr[slot];
180 157
181 if (db_entry_prev != NULL) 158 if (db_index_prev < DSP_NUM_PROC_STAGES)
182 { 159 {
183 struct dsp_proc_slot *prev = find_proc_slot(dsp, db_entry_prev->id); 160 struct dsp_proc_slot *prev =
184 s->next[0] = prev->next[0]; 161 find_proc_slot(dsp, dsp_proc_database[db_index_prev]->id);
185 s->next[1] = prev->next[1]; 162 s->next = prev->next;
186 prev->next[1] = s; 163 prev->next = s;
187 } 164 }
188 else 165 else
189 { 166 {
190 s->next[0] = dsp->proc_slots[0]; 167 s->next = dsp->proc_slots;
191 s->next[1] = dsp->proc_slots[1]; 168 dsp->proc_slots = s;
192 dsp->proc_slots[1] = s;
193 } 169 }
194 170
195 s->db_entry = db_entry; /* record DB entry */ 171 s->mask = mask | NACT_BIT;
196 dsp->proc_masks[1] |= mask; 172 s->version = 0;
173 s->db_index = db_index;
174 dsp->proc_mask_enabled |= mask;
197 dsp->slot_free_mask &= ~BIT_N(slot); 175 dsp->slot_free_mask &= ~BIT_N(slot);
198 176
199 return s; 177 return s;
@@ -203,33 +181,33 @@ dsp_proc_enable_enlink(struct dsp_config *dsp, uint32_t mask)
203static struct dsp_proc_slot * 181static struct dsp_proc_slot *
204dsp_proc_enable_delink(struct dsp_config *dsp, uint32_t mask) 182dsp_proc_enable_delink(struct dsp_config *dsp, uint32_t mask)
205{ 183{
206 struct dsp_proc_slot *s = dsp->proc_slots[1]; 184 struct dsp_proc_slot *s = dsp->proc_slots;
207 struct dsp_proc_slot *prev = NULL; 185 struct dsp_proc_slot *prev = NULL;
208 186
209 while (1) /* In proc_masks == it must be there */ 187 while (1) /* In proc_mask_enabled == it must be there */
210 { 188 {
211 if (BIT_N(s->db_entry->id) == mask) 189 if (BIT_N(proc_db_entry(s)->id) == mask)
212 { 190 {
213 if (prev) 191 if (prev)
214 prev->next[1] = s->next[1]; 192 prev->next = s->next;
215 else 193 else
216 dsp->proc_slots[1] = s->next[1]; 194 dsp->proc_slots = s->next;
217 195
218 dsp->proc_masks[1] &= ~mask; 196 dsp->proc_mask_enabled &= ~mask;
219 dsp->slot_free_mask |= BIT_N(s - dsp_proc_slot_arr); 197 dsp->slot_free_mask |= BIT_N(s - dsp_proc_slot_arr);
220 return s; 198 return s;
221 } 199 }
222 200
223 prev = s; 201 prev = s;
224 s = s->next[1]; 202 s = s->next;
225 } 203 }
226} 204}
227 205
228void dsp_proc_enable(struct dsp_config *dsp, enum dsp_proc_ids id, 206void dsp_proc_enable(struct dsp_config *dsp, enum dsp_proc_ids id,
229 bool enable) 207 bool enable)
230{ 208{
231 uint32_t mask = BIT_N(id); 209 const uint32_t mask = BIT_N(id);
232 bool enabled = dsp->proc_masks[1] & mask; 210 bool enabled = dsp->proc_mask_enabled & mask;
233 211
234 if (enable) 212 if (enable)
235 { 213 {
@@ -247,13 +225,11 @@ void dsp_proc_enable(struct dsp_config *dsp, enum dsp_proc_ids id,
247 { 225 {
248 /* New entry - set defaults */ 226 /* New entry - set defaults */
249 s->proc_entry.data = 0; 227 s->proc_entry.data = 0;
250 s->proc_entry.ip_mask = mask; 228 s->proc_entry.process = NULL;
251 s->proc_entry.process[0] = dsp_process_null;
252 s->proc_entry.process[1] = dsp_format_change_process;
253 } 229 }
254 230
255 enabled = s->db_entry->configure(&s->proc_entry, dsp, DSP_PROC_INIT, 231 enabled = proc_db_entry(s)->configure(&s->proc_entry, dsp,
256 enabled) >= 0; 232 DSP_PROC_INIT, enabled) >= 0;
257 if (enabled) 233 if (enabled)
258 return; 234 return;
259 235
@@ -267,38 +243,7 @@ void dsp_proc_enable(struct dsp_config *dsp, enum dsp_proc_ids id,
267 243
268 dsp_proc_activate(dsp, id, false); /* Deactivate it first */ 244 dsp_proc_activate(dsp, id, false); /* Deactivate it first */
269 struct dsp_proc_slot *s = dsp_proc_enable_delink(dsp, mask); 245 struct dsp_proc_slot *s = dsp_proc_enable_delink(dsp, mask);
270 s->db_entry->configure(&s->proc_entry, dsp, DSP_PROC_CLOSE, 0); 246 proc_db_entry(s)->configure(&s->proc_entry, dsp, DSP_PROC_CLOSE, 0);
271}
272
273/* Maintain the list structure for the active list where each enabled entry
274 * has a link to the next active item, even if not active which facilitates
275 * switching out of format change mode by a stage during a format change.
276 * When that happens, the iterator must jump over inactive but enabled
277 * stages after its current position. */
278static struct dsp_proc_slot *
279dsp_proc_activate_link(struct dsp_config *dsp, uint32_t mask,
280 struct dsp_proc_slot *s)
281{
282 uint32_t m = BIT_N(s->db_entry->id);
283 uint32_t mor = m | mask;
284
285 if (mor == m) /* Only if same single bit in common */
286 {
287 dsp->proc_masks[0] |= mask;
288 return s;
289 }
290 else if (~mor == 0) /* Only if bits complement */
291 {
292 dsp->proc_masks[0] &= mask;
293 return s->next[0];
294 }
295
296 struct dsp_proc_slot *next = s->next[1];
297 next = dsp_proc_activate_link(dsp, mask, next);
298
299 s->next[0] = next;
300
301 return (m & dsp->proc_masks[0]) ? s : next;
302} 247}
303 248
304/* Activate or deactivate a stage */ 249/* Activate or deactivate a stage */
@@ -307,55 +252,109 @@ void dsp_proc_activate(struct dsp_config *dsp, enum dsp_proc_ids id,
307{ 252{
308 const uint32_t mask = BIT_N(id); 253 const uint32_t mask = BIT_N(id);
309 254
310 if (!(dsp->proc_masks[1] & mask)) 255 if (!(dsp->proc_mask_enabled & mask))
311 return; /* Not enabled */ 256 return; /* Not enabled */
312 257
313 if (activate != !(dsp->proc_masks[0] & mask)) 258 if (activate != !(dsp->proc_mask_active & mask))
314 return; /* No change in state */ 259 return; /* No change in state */
315 260
316 /* Send mask bit if activating and ones complement if deactivating */ 261 struct dsp_proc_slot *s = find_proc_slot(dsp, id);
317 dsp->proc_slots[0] = dsp_proc_activate_link( 262
318 dsp, activate ? mask : ~mask, dsp->proc_slots[1]); 263 if (activate)
264 {
265 dsp->proc_mask_active |= mask;
266 s->mask &= ~NACT_BIT;
267 }
268 else
269 {
270 dsp->proc_mask_active &= ~mask;
271 s->mask |= NACT_BIT;
272 }
319} 273}
320 274
321/* Is the stage specified by the id currently active? */ 275/* Is the stage specified by the id currently active? */
322bool dsp_proc_active(struct dsp_config *dsp, enum dsp_proc_ids id) 276bool dsp_proc_active(struct dsp_config *dsp, enum dsp_proc_ids id)
323{ 277{
324 return (dsp->proc_masks[0] & BIT_N(id)) != 0; 278 return (dsp->proc_mask_active & BIT_N(id)) != 0;
325} 279}
326 280
327/* Determine by the rules if the processing function should be called */ 281/* Force the specified stage to receive a format update before the next
328static FORCE_INLINE bool dsp_proc_should_call(struct dsp_proc_entry *this, 282 * buffer is sent to process() */
329 struct dsp_buffer *buf, 283void dsp_proc_want_format_update(struct dsp_config *dsp,
330 unsigned int fmt) 284 enum dsp_proc_ids id)
331{ 285{
332 uint32_t ip_mask = this->ip_mask; 286 struct dsp_proc_slot *s = find_proc_slot(dsp, id);
333 287
334 return UNLIKELY(fmt != 0) || /* Also pass override value */ 288 if (s)
335 ip_mask == 0 || /* Not in-place */ 289 s->version = 0; /* Set invalid */
336 ((ip_mask & buf->proc_mask) == 0 &&
337 (buf->proc_mask |= ip_mask, buf->remcount > 0));
338} 290}
339 291
340/* Call this->process[fmt] according to the rules (for external call) */ 292/* Set or unset in-place operation */
341bool dsp_proc_call(struct dsp_proc_entry *this, struct dsp_buffer **buf_p, 293void dsp_proc_set_in_place(struct dsp_config *dsp, enum dsp_proc_ids id,
342 unsigned int fmt) 294 bool in_place)
343{ 295{
344 if (dsp_proc_should_call(this, *buf_p, fmt)) 296 struct dsp_proc_slot *s = find_proc_slot(dsp, id);
297
298 if (!s)
299 return;
300
301 const uint32_t mask = BIT_N(id);
302
303 if (in_place)
304 s->mask |= mask;
305 else
306 s->mask &= ~mask;
307}
308
309/* Determine by the rules if the processing function should be called */
310static NO_INLINE bool dsp_proc_new_format(struct dsp_proc_slot *s,
311 struct dsp_config *dsp,
312 struct dsp_buffer *buf)
313{
314 struct dsp_proc_entry *this = &s->proc_entry;
315 struct sample_format *format = &buf->format;
316
317 switch (proc_db_entry(s)->configure(
318 this, dsp, DSP_PROC_NEW_FORMAT, (intptr_t)format))
345 { 319 {
346 this->process[fmt == (0u-1u) ? 0 : fmt](this, buf_p); 320 case PROC_NEW_FORMAT_OK:
321 s->version = format->version;
347 return true; 322 return true;
348 }
349 323
350 return false; 324 case PROC_NEW_FORMAT_TRANSITION:
325 return true;
326
327 case PROC_NEW_FORMAT_DEACTIVATED:
328 s->version = format->version;
329 return false;
330
331 default:
332 return false;
333 }
351} 334}
352 335
353#ifndef DSP_PROCESS_START 336static FORCE_INLINE void dsp_proc_call(struct dsp_proc_slot *s,
354/* These do nothing if not previously defined */ 337 struct dsp_config *dsp,
355#define DSP_PROCESS_START() 338 struct dsp_buffer **buf_p)
356#define DSP_PROCESS_LOOP() 339{
357#define DSP_PROCESS_END() 340 struct dsp_buffer *buf = *buf_p;
358#endif /* !DSP_PROCESS_START */ 341
342 if (UNLIKELY(buf->format.version != s->version))
343 {
344 if (!dsp_proc_new_format(s, dsp, buf))
345 return;
346 }
347
348 if (s->mask)
349 {
350 if ((s->mask & (buf->proc_mask | NACT_BIT)) || buf->remcount <= 0)
351 return;
352
353 buf->proc_mask |= s->mask;
354 }
355
356 s->proc_entry.process(&s->proc_entry, buf_p);
357}
359 358
360/** 359/**
361 * dsp_process: 360 * dsp_process:
@@ -411,9 +410,6 @@ void dsp_process(struct dsp_config *dsp, struct dsp_buffer *src,
411 } 410 }
412 411
413 DSP_PROCESS_START(); 412 DSP_PROCESS_START();
414#if 0 /* Not needed now but enable if something must know this */
415 dsp->processing = true;
416#endif
417 413
418 /* Tag input with codec-specified sample format */ 414 /* Tag input with codec-specified sample format */
419 src->format = dsp->io_data.format; 415 src->format = dsp->io_data.format;
@@ -423,36 +419,29 @@ void dsp_process(struct dsp_config *dsp, struct dsp_buffer *src,
423 /* Out-of-place-processing stages take the current buf as input 419 /* Out-of-place-processing stages take the current buf as input
424 * and switch the buffer to their own output buffer */ 420 * and switch the buffer to their own output buffer */
425 struct dsp_buffer *buf = src; 421 struct dsp_buffer *buf = src;
426 unsigned int fmt = buf->format.changed;
427 422
428 /* Convert input samples to internal format */ 423 if (UNLIKELY(buf->format.version != dsp->io_data.sample_buf.format.version))
429 dsp->io_data.input_samples[fmt](&dsp->io_data, &buf); 424 dsp_sample_input_format_change(&dsp->io_data, &buf->format);
430 fmt = buf->format.changed;
431 425
432 struct dsp_proc_slot *s = dsp->proc_slots[fmt]; 426 /* Convert input samples to internal format */
427 dsp->io_data.input_samples(&dsp->io_data, &buf);
433 428
434 /* Call all active/enabled stages depending if format is 429 /* Call all active/enabled stages depending if format is
435 same/changed on the last output buffer */ 430 same/changed on the last output buffer */
436 while (s != NULL) 431 for (struct dsp_proc_slot *s = dsp->proc_slots; s; s = s->next)
437 { 432 dsp_proc_call(s, dsp, &buf);
438 if (dsp_proc_should_call(&s->proc_entry, buf, fmt))
439 {
440 s->proc_entry.process[fmt](&s->proc_entry, &buf);
441 fmt = buf->format.changed;
442 }
443
444 /* The buffer may have changed along with the format flag */
445 s = s->next[fmt];
446 }
447 433
448 /* Don't overread/write src/destination */ 434 /* Don't overread/write src/destination */
449 int outcount = MIN(dst->bufcount, buf->remcount); 435 int outcount = MIN(dst->bufcount, buf->remcount);
450 436
451 if (fmt == 0 && outcount <= 0) 437 if (outcount <= 0)
452 break; /* Output full or purged internal buffers */ 438 break; /* Output full or purged internal buffers */
453 439
440 if (UNLIKELY(buf->format.version != dsp->io_data.output_version))
441 dsp_sample_output_format_change(&dsp->io_data, &buf->format);
442
454 dsp->io_data.outcount = outcount; 443 dsp->io_data.outcount = outcount;
455 dsp->io_data.output_samples[fmt](&dsp->io_data, buf, dst); 444 dsp->io_data.output_samples(&dsp->io_data, buf, dst);
456 445
457 /* Advance buffers by what output consumed and produced */ 446 /* Advance buffers by what output consumed and produced */
458 dsp_advance_buffer32(buf, outcount); 447 dsp_advance_buffer32(buf, outcount);
@@ -461,10 +450,6 @@ void dsp_process(struct dsp_config *dsp, struct dsp_buffer *src,
461 DSP_PROCESS_LOOP(); 450 DSP_PROCESS_LOOP();
462 } /* while */ 451 } /* while */
463 452
464#if 0 /* Not needed now but enable if something must know this */
465 dsp->process = false;
466#endif
467
468 DSP_PROCESS_END(); 453 DSP_PROCESS_END();
469} 454}
470 455
@@ -495,13 +480,6 @@ enum dsp_ids dsp_get_id(const struct dsp_config *dsp)
495 return (enum dsp_ids)id; 480 return (enum dsp_ids)id;
496} 481}
497 482
498#if 0 /* Not needed now but enable if something must know this */
499bool dsp_is_busy(const struct dsp_config *dsp)
500{
501 return dsp->processing;
502}
503#endif /* 0 */
504
505/* Do what needs initializing before enable/disable calls can be made. 483/* Do what needs initializing before enable/disable calls can be made.
506 * Must be done before changing settings for the first time. */ 484 * Must be done before changing settings for the first time. */
507void INIT_ATTR dsp_init(void) 485void INIT_ATTR dsp_init(void)