ecaa84c1dbe8a946ae80e423766acb8087cbaa36
2 /*
3 Copyright (c) 2016, Texas Instruments Incorporated - http://www.ti.com/
4 All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the
16 * distribution.
17 *
18 * Neither the name of Texas Instruments Incorporated nor the names of
19 * its contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *
34 */
36 //
37 //
38 // Performance Audio Framework Series 3 -- Audio Stream Processing Definitions
39 //
40 //
41 //
43 #include "fwkPort.h"
45 #include <xdc/std.h>
47 //#include <mem.h>
48 #include <xdc/runtime/Log.h>
49 #include <xdc/runtime/Memory.h>
50 #include <xdc/runtime/Error.h>
51 #include <xdc/runtime/IHeap.h>
52 #include <ti/sysbios/heaps/HeapMem.h>
55 #define PROFILER
57 #ifdef PROFILER
58 #include <ti/sysbios/knl/Task.h>
59 #include "ti/sysbios/knl/Clock.h"
60 #include "xdc/runtime/Timestamp.h"
61 #include "ti/sysbios/utils/Load.h"
63 #ifndef MAX_NUM
64 #define MAX_NUM 28515
65 #define NUM_ASP_PROFILE 0 // Profile CAR; As we have PCM->SRC(0)->CAR(1)->PCE
66 #endif
67 UInt32 profile_array_dsp_cycles[MAX_NUM];
68 UInt32 profile_array_dsp_cpuload[MAX_NUM];
69 UInt32 profile_index = 0; // Array index
70 UInt32 start_profiling = 0; // Flag
71 UInt32 currentAspCount = 0; // ASP number in chain starting from 0
72 UInt32 aspNumberToProfile = NUM_ASP_PROFILE; // ASP number in chain starting from 0
73 volatile UInt32 time32_1, time32_2;
74 #endif
76 //
77 #include "asp0.h"
78 //#include <paf_alg.h>
79 //#include <pafhjt.h>
81 #include <acp.h>
83 #include "logp.h"
85 //
86 // Audio Stream Processing Chain Function - Initialization
87 //
88 // Name: PAF_ASP_chainInit_
89 // Purpose: Initialize an ASP Chain by linking all elements of an
90 // initialization array onto it. If this is the first audio
91 // stream, perform base initialization of the ASP Chain, but
92 // otherwise do not.
93 // From: AST Parameter Chain Function -> chainInit
94 // Uses: AST Parameter Chain Function -> chainLink
95 // States: None.
96 // Return: ASP Chain.
97 // Trace: None.
98 //
100 PAF_ASP_Chain *
101 PAF_ASP_chainInit_ (
102 PAF_ASP_Chain *this,
103 const struct PAF_ASP_ChainFxns *fxns,
104 HeapMem_Handle heap, //int heap,
105 Uns stream,
106 ACP_Handle acp,
107 LOG_Obj *log,
108 const PAF_ASP_LinkInit *pInit,
109 PAF_ASP_Chain *from,
110 IALG_MemRec *common,
111 PAF_IALG_Config *pafConfig)
112 {
113 if (stream) {
114 this->fxns = fxns;
115 this->head = NULL;
116 this->stream = stream;
117 this->acp = acp;
118 this->log = log;
119 }
121 for ( ; pInit && pInit->thisCode.full; pInit++)
122 if (! this->fxns->chainLink (this, heap, pInit, from, common, pafConfig))
123 return NULL;
125 return this;
126 }
128 //
129 // Audio Stream Processing Chain Function - Link
130 //
131 // Name: PAF_ASP_chainLink_
132 // Purpose: Link an element onto an ASP Chain:
133 // (1) Allocate memory for the link, and
134 // (2) For the first gear, create the data for the link, but
135 // (3) For other than the first gear, simply link the data already
136 // created in the previous gear.
137 // From: AST Parameter Chain Function -> chainInit
138 // Uses: See code.
139 // States: None.
140 // Return: Success: ASP Chain.
141 // Failure: Null.
142 // Trace: Message Log "trace" in Debug Project Configuration reports:
143 // * Memory allocation errors.
144 // * Data creation errors.
145 // * Data linking errors.
146 //
149 PAF_ASP_Chain *
150 PAF_ASP_chainLink_ (
151 PAF_ASP_Chain *this,
152 HeapMem_Handle heap, //int heap,
153 const PAF_ASP_LinkInit *pInit,
154 PAF_ASP_Chain *from,
155 IALG_MemRec *common,
156 PAF_IALG_Config *pafConfig)
157 {
158 PAF_ASP_Link *pLink;
159 Error_Block eb;
161 if (! this || ! pInit)
162 return this;
164 // Initialize error block
165 Error_init(&eb);
167 //if (! (pLink = MEM_alloc (heap, sizeof(PAF_ASP_Link), 4))) {
168 if (!(pLink = Memory_alloc((IHeap_Handle)heap, sizeof(PAF_ASP_Link), 4, &eb))) {
169 if (this->log)
170 LOG_printf(this->log, "AS%d: ASP code 0x%08x alloc failure",
171 this->stream, pInit->thisCode.full);
172 return NULL;
173 }
175 if (! from) {
176 if (! this->fxns->linkData(pLink, pInit, this->stream, this->acp,
177 this->log,common, pafConfig)) {
178 if (this->log)
179 LOG_printf(this->log, "AS%d: ASP code 0x%08x link-init failure",
180 this->stream, pInit->thisCode.full);
181 return NULL;
182 }
183 }
184 else {
185 if (! this->fxns->linkCopy(pLink, pInit, from->head)) {
186 if (this->log)
187 LOG_printf(this->log, "AS%d: ASP code 0x%08x link-copy failure",
188 this->stream, pInit->thisCode.full);
189 return NULL;
190 }
191 }
193 {
194 PAF_ASP_Link **ppLink;
195 for (ppLink=&this->head; *ppLink; ppLink=&(*ppLink)->next)
196 if ((*ppLink)->code.full == pInit->linkCode.full)
197 break;
198 pLink->next = *ppLink;
199 *ppLink = pLink;
200 }
202 return this;
203 }
205 //
206 // Audio Stream Processing Chain Function - Find
207 //
208 // Name: PAF_ASP_chainFind_
209 // Purpose: Find an element in an ASP Chain.
210 // From: AST Parameter Chain Function -> chainFind
211 // Uses: None.
212 // States: None.
213 // Return: Success (found): Pointer to element.
214 // Failure (not found): Null.
215 // Trace: None.
216 //
218 PAF_ASP_Link *
219 PAF_ASP_chainFind_ (
220 PAF_ASP_Chain *this,
221 PAF_ASP_AlphaCode code)
222 {
223 PAF_ASP_Link *that = this->head;
225 for ( ; that; that = that->next) {
226 if (that->code.full == code.full)
227 break;
228 }
230 return that;
231 }
233 //
234 // Audio Stream Processing Chain Function - Reset
235 //
236 // Name: PAF_ASP_chainReset_
237 // Purpose: Reset an ASP Chain by invoking for each element:
238 // (1) The algorithm activation function (NOT PERFORMED), and
239 // (2) The algorithm reset function.
240 // From: AST Parameter Chain Function -> chainReset
241 // Uses: See code.
242 // States: None.
243 // Return: 0 on success.
244 // Error number reported by ASP Reset Function on failure.
245 // Trace: Message Log "trace" in Debug Project Configuration reports:
246 // * ASP Reset Function errors.
247 //
249 Int
250 PAF_ASP_chainReset_ (PAF_ASP_Chain *this, PAF_AudioFrame *pAudioFrame)
251 {
252 Int errno;
254 PAF_ASP_Link *pLink;
256 for (pLink=this->head; pLink; pLink=pLink->next) {
257 ASP_Handle alg = pLink->alg;
258 #if 0
259 /* ASP Algorithms are self-activating and not framework-activated */
260 if (((ALG_Handle )alg)->fxns->algActivate)
261 ((ALG_Handle )alg)->fxns->algActivate (((ALG_Handle )alg));
262 #endif
263 if (alg->fxns->reset && (errno = alg->fxns->reset(alg, pAudioFrame))) {
264 if (this->log) {
265 LOG_printf(this->log, "AS%d: ASP code 0x%08x reset error",
266 this->stream, pLink->code.full);
267 LOG_printf(this->log, "AS%d: errno = 0x%08x",
268 this->stream, errno);
269 }
270 return errno;
271 }
272 }
274 return 0;
275 }
277 //
278 // Audio Stream Processing Chain Function - Apply
279 //
280 // Name: PAF_ASP_chainApply_
281 // Purpose: Apply an ASP Chain by invoking for each:
282 // (1) The algorithm apply function.
283 // From: AST Parameter Chain Function -> chainApply
284 // Uses: See code.
285 // States: None.
286 // Return: 0 on success.
287 // Error number reported by ASP Apply Function on failure.
288 // Trace: Message Log "trace" in Debug Project Configuration reports:
289 // * ASP Apply Function errors.
290 //
292 Int
293 PAF_ASP_chainApply_ (PAF_ASP_Chain *this, PAF_AudioFrame *pAudioFrame)
294 {
295 Int errno;
296 int i = 0;
298 PAF_ASP_Link *pLink;
300 for (pLink=this->head; pLink; pLink=pLink->next)
301 {
302 ASP_Handle alg = pLink->alg;
304 i++;
305 if (this->log)
306 {
307 LOG_printf(&trace, "PAF_ASP_chainApply_: AS_%d. link %d. alg: 0x%x.",
308 this->stream, i, alg);
309 }
310 Log_info3("PAF_ASP_chainApply_: AS_%d. link %d. alg: 0x%x.", this->stream, i, (IArg)alg);
312 if (alg->fxns->apply /*&& (errno = alg->fxns->apply(alg, pAudioFrame))*/)
313 {
315 #ifdef PROFILER
316 if (aspNumberToProfile == currentAspCount) // only profile the selected ASP
317 {
318 time32_1 = Timestamp_get32();
319 }
320 #endif
321 errno = alg->fxns->apply(alg, pAudioFrame);
323 #ifdef PROFILER
324 if (aspNumberToProfile == currentAspCount) // only profile the selected ASP
325 {
326 time32_2 = Timestamp_get32();
327 //Load_Stat stat;
328 //Load_getTaskLoad (Task_getIdleTask(), &stat);
329 //UInt32 intLoad = Load_calculateLoad (&stat);
330 if (start_profiling == 1)
331 {
332 if (profile_index < MAX_NUM)
333 {
334 profile_array_dsp_cycles[profile_index] = (time32_2 - time32_1);
335 //profile_array_dsp_cpuload[profile_index] = (100 - intLoad);
336 profile_array_dsp_cpuload[profile_index] = Load_getCPULoad();
337 profile_index++;
338 }
339 else
340 {
341 //SW_BREAKPOINT;
342 }
343 }
345 //TRACE_TERSE1("profiler: Timestamp_get32() cycles: %u", (time32_2 - time32_1) * factor);
346 //TRACE_TERSE2("profiler: CPU load: idle: %d other: %d", intLoad, (100 - intLoad));
347 }
348 // increase ASP count
349 currentAspCount++;
350 #endif
352 if (errno && this->log)
353 {
354 LOG_printf(this->log, "AS%d: ASP code 0x%08x apply error 0x%x.",
355 this->stream, pLink->code.full, errno);
356 LOG_printf(&trace, "AS%d: ASP code 0x%08x apply error 0x%x.",
357 this->stream, pLink->code.full, errno);
358 #ifdef PROFILER
359 // Reset ASP count for next frame
360 currentAspCount = 0;
361 #endif
362 return errno;
363 }
364 }
365 }
366 #ifdef PROFILER
367 // Reset ASP count for next frame
368 currentAspCount = 0;
369 #endif
371 return 0;
372 }
374 //
375 // Audio Stream Processing Chain Function - Final
376 //
377 // Name: PAF_ASP_chainFinal_
378 // Purpose: Finalize an ASP Chain by invoking for each:
379 // (1) The algorithm final function (NOT PERFORMED), and
380 // (2) The algorithm deactivation function.
381 // From: AST Parameter Chain Function -> chainFinal
382 // Uses: See code.
383 // States: None.
384 // Return: 0 on success.
385 // Error number reported by ASP Final Function on failure.
386 // Trace: Message Log "trace" in Debug Project Configuration reports:
387 // * ASP Final Function errors.
388 //
389 // Note: In Audio Framework #2, PAF_ASP_FINAL is not defined and there
390 // are no Final Functions supplied with ASP Algorithms.
392 Int
393 PAF_ASP_chainFinal_ (PAF_ASP_Chain *this, PAF_AudioFrame *pAudioFrame)
394 {
395 #ifdef PAF_ASP_FINAL
396 Int errno;
397 #endif /* PAF_ASP_FINAL */
399 PAF_ASP_Link *pLink;
401 for (pLink=this->head; pLink; pLink=pLink->next) {
402 ASP_Handle alg = pLink->alg;
403 #ifdef PAF_ASP_FINAL
404 if (alg->fxns->final && (errno = alg->fxns->final(alg, pAudioFrame))) {
405 if (this->log) {
406 LOG_printf(this->log, "AS%d: ASP code 0x%08x final error",
407 this->stream, pLink->code.full);
408 LOG_printf(this->log, "AS%d: errno = 0x%08x",
409 this->stream, errno);
410 }
411 return errno;
412 }
413 #endif /* PAF_ASP_FINAL */
414 #if 1
415 /* ASP Algorithms are self-deactivating and framework-deactivated */
416 if (((ALG_Handle )alg)->fxns->algDeactivate)
417 ((ALG_Handle )alg)->fxns->algDeactivate (((ALG_Handle )alg));
418 #endif
419 }
421 return 0;
422 }
424 //
425 // Audio Stream Processing Chain Function - Link Data
426 //
427 // Name: PAF_ASP_linkData
428 // Purpose: Create the data for a chain link:
429 // (1) Perform beta unit relocation,
430 // (2) Instantiate an algorithm, and
431 // (3) Attach the beta unit(s) of an algorithm to an ACP Algorithm
432 // instance.
433 // From: AST Parameter Chain Function -> linkData
434 // Uses: See code.
435 // States: None.
436 // Return: Null pointer on failure.
437 // Pointer to the chain link on success.
438 // Trace: Message Log "trace" in Debug Project Configuration reports:
439 // * Algorithm instance creation failure message.
440 // * Beta Unit initialization success message.
441 //
443 PAF_ASP_Link *
444 PAF_ASP_linkData (
445 PAF_ASP_Link *this,
446 const PAF_ASP_LinkInit *pInit,
447 Uns stream,
448 ACP_Handle acp,
449 LOG_Obj *log,
450 IALG_MemRec *common,
451 PAF_IALG_Config *pafConfig)
452 {
453 IALG_Status *pStatus;
455 ALG_Handle alg;
457 Int beta = pInit->thisCode.part.beta;
459 if (log)
460 LOG_printf(log, "AS%d: beta 0x%x initialization begins.", stream, beta);
461 {
462 ALG_Handle acpAlg = (ALG_Handle) acp;
463 Int betaPrimeBase;
464 Int betaPrimeOffset;
465 acpAlg->fxns->algControl (acpAlg, ACP_GETBETAPRIMEBASE,
466 (IALG_Status *) &betaPrimeBase);
467 acpAlg->fxns->algControl (acpAlg, ACP_GETBETAPRIMEOFFSET,
468 (IALG_Status *) &betaPrimeOffset);
469 if (beta >= betaPrimeBase)
470 beta += (stream - 1) * betaPrimeOffset;
471 }
473 this->next = NULL;
474 this->code = pInit->thisCode;
476 if (pInit->ialg_fxns) {
478 if (pInit->init_func)
479 (*pInit->init_func)();
481 if (! (alg = PAF_ALG_create(pInit->ialg_fxns,NULL,(IALG_Params *)pInit->ialg_prms,
482 common, pafConfig))) {
483 if (log) {
484 LOG_printf(log,
485 "AS%d: beta 0x%x algorithm instance creation failed",
486 stream, beta);
487 }
488 return NULL;
489 }
490 }
491 else
492 return NULL;
494 this->alg = (ASP_Handle )alg;
496 if (alg->fxns->algControl) {
497 if (! alg->fxns->algControl (alg, ACP_GETSTATUSADDRESS1, (IALG_Status *)&pStatus))
498 acp->fxns->attach (acp, pInit->thisCode.part.series, beta, pStatus);
499 if (! alg->fxns->algControl (alg, ACP_GETSTATUSADDRESS2, (IALG_Status *)&pStatus))
500 acp->fxns->attach (acp, pInit->thisCode.part.series, beta+1, pStatus);
501 }
503 if (log)
504 LOG_printf(log, "AS%d: beta 0x%x processing initialized", stream, beta);
506 return this;
507 }
509 //
510 // Audio Stream Processing Chain Function - Link Copy
511 //
512 // Name: PAF_ASP_linkCopy
513 // Purpose: Copy the data for a chain link:
514 // (1) Find an element on a chain, and
515 // (2) Copy the reference to the data of the link.
516 // From: AST Parameter Chain Function -> linkCopy
517 // Uses: See code.
518 // States: None.
519 // Return: Null pointer on failure.
520 // Pointer to the chain link on success.
521 // Trace: None.
522 //
524 PAF_ASP_Link *
525 PAF_ASP_linkCopy (
526 PAF_ASP_Link *this,
527 const PAF_ASP_LinkInit *pInit,
528 PAF_ASP_Link *from)
529 {
530 for ( ; from; from = from->next) {
531 if (from->code.full == pInit->thisCode.full)
532 break;
533 }
535 if (! from)
536 return NULL;
538 this->next = NULL;
539 this->code = pInit->thisCode;
540 this->alg = from->alg;
542 return this;
543 }
545 //
546 // Audio Stream Processing Chain Functions
547 //
548 // Name: PAF_ASP_chainFxns
549 // Purpose: Collect the chain functions that embody the implementation
550 // of Audio Framework Number 2 for use as a jump table.
551 // From: PAF_AST_Params
552 // Uses: See contents.
553 // States: N.A.
554 // Return: N.A.
555 // Trace: None.
556 //
558 const struct PAF_ASP_ChainFxns PAF_ASP_chainFxns =
559 {
560 PAF_ASP_chainInit_,
561 PAF_ASP_chainLink_,
562 PAF_ASP_chainFind_,
563 {
564 PAF_ASP_chainReset_,
565 PAF_ASP_chainApply_,
566 PAF_ASP_chainFinal_,
567 },
568 PAF_ASP_linkData,
569 PAF_ASP_linkCopy,
570 };