diff options
Diffstat (limited to 'lib/rbcodec/dsp/dsp_core.c')
-rw-r--r-- | lib/rbcodec/dsp/dsp_core.c | 342 |
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 @@ | |||
41 | struct dsp_config | 48 | struct 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. */ |
63 | static struct dsp_proc_slot | 69 | static struct dsp_proc_slot |
64 | dsp_proc_slot_arr[DSP_NUM_PROC_STAGES+DSP_VOICE_NUM_PROC_STAGES] IBSS_ATTR; | 70 | dsp_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; | |||
67 | static struct dsp_config dsp_conf[DSP_COUNT] IBSS_ATTR; | 73 | static struct dsp_config dsp_conf[DSP_COUNT] IBSS_ATTR; |
68 | 74 | ||
69 | /** Processing stages support functions **/ | 75 | /** Processing stages support functions **/ |
76 | static const struct dsp_proc_db_entry * | ||
77 | proc_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 */ |
72 | static struct dsp_proc_slot * find_proc_slot(struct dsp_config *dsp, | 83 | static 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] */ | ||
114 | static 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] */ | ||
121 | static 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 */ |
146 | static struct dsp_proc_slot * | 126 | static struct dsp_proc_slot * |
147 | dsp_proc_enable_enlink(struct dsp_config *dsp, uint32_t mask) | 127 | dsp_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) | |||
203 | static struct dsp_proc_slot * | 181 | static struct dsp_proc_slot * |
204 | dsp_proc_enable_delink(struct dsp_config *dsp, uint32_t mask) | 182 | dsp_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 | ||
228 | void dsp_proc_enable(struct dsp_config *dsp, enum dsp_proc_ids id, | 206 | void 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. */ | ||
278 | static struct dsp_proc_slot * | ||
279 | dsp_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? */ |
322 | bool dsp_proc_active(struct dsp_config *dsp, enum dsp_proc_ids id) | 276 | bool 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 |
328 | static FORCE_INLINE bool dsp_proc_should_call(struct dsp_proc_entry *this, | 282 | * buffer is sent to process() */ |
329 | struct dsp_buffer *buf, | 283 | void 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 */ |
341 | bool dsp_proc_call(struct dsp_proc_entry *this, struct dsp_buffer **buf_p, | 293 | void 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 */ | ||
310 | static 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 | 336 | static 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 */ | ||
499 | bool 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. */ |
507 | void INIT_ATTR dsp_init(void) | 485 | void INIT_ATTR dsp_init(void) |