2 /*
3 Copyright (c) 2017, 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>
54 #include "asp0.h"
55 //#include <paf_alg.h>
56 //#include <pafhjt.h>
57 #include <acp.h>
58 #include "logp.h"
60 #include "pfp/pfp.h"
61 #include "pfp_app.h" /* contains all PFP ID's */
64 #include "dbgBenchmark.h" // PCM high-sampling rate + SRC + CAR benchmarking
65 //
66 // Performing PCM high-sampling rate + SRC + CAR benchmarking
67 //
68 #ifdef _ENABLE_BENCHMARK_PCMHSR_SRC_CAR_
69 #define PROFILER
70 #endif
72 #ifdef PROFILER
73 #include <ti/sysbios/knl/Task.h>
74 #include "ti/sysbios/knl/Clock.h"
75 #include "xdc/runtime/Timestamp.h"
76 #include "ti/sysbios/utils/Load.h"
78 #ifndef MAX_NUM
79 #define MAX_NUM 28515
80 #define NUM_ASP_PROFILE 0 // Profile CAR; As we have PCM->SRC(0)->CAR(1)->PCE
81 #endif
82 UInt32 profile_array_dsp_cycles[MAX_NUM];
83 UInt32 profile_array_dsp_cpuload[MAX_NUM];
84 UInt32 profile_index = 0; // Array index
85 UInt32 start_profiling = 0; // Flag
86 UInt32 currentAspCount = 0; // ASP number in chain starting from 0
87 UInt32 aspNumberToProfile = NUM_ASP_PROFILE; // ASP number in chain starting from 0
88 volatile UInt32 time32_1, time32_2;
89 #endif
91 #ifdef _TMS320C6X
92 #define ASP_NUM_PROFILE ( 0 ) // Profile CAR; As we have DEC->CAR(0)->OAR(1)->BMDA(2)->ENC
93 UInt32 gAspProfileEnable = 0; // ASP profile enable flag
94 //UInt32 gAspNumProfile = ASP_NUM_PROFILE; // ASP number in chain starting from 0
95 Int32 gAspNumProfile = -1; // Number of ASP in chain to profile or -1 to indicate all ASPs
96 //UInt32 gAspCurCount = 0; // ASP number in chain starting from 0
97 Int32 gAspPfpId; // Number of ASP in chain to profile or -1 to indicate all ASPs
98 #endif // _TMS320C6X
101 //
102 // Audio Stream Processing Chain Function - Initialization
103 //
104 // Name: PAF_ASP_chainInit_
105 // Purpose: Initialize an ASP Chain by linking all elements of an
106 // initialization array onto it. If this is the first audio
107 // stream, perform base initialization of the ASP Chain, but
108 // otherwise do not.
109 // From: AST Parameter Chain Function -> chainInit
110 // Uses: AST Parameter Chain Function -> chainLink
111 // States: None.
112 // Return: ASP Chain.
113 // Trace: None.
114 //
116 PAF_ASP_Chain *
117 PAF_ASP_chainInit_ (
118 PAF_ASP_Chain *this,
119 const struct PAF_ASP_ChainFxns *fxns,
120 HeapMem_Handle heap, //int heap,
121 Uns stream,
122 ACP_Handle acp,
123 LOG_Obj *log,
124 const PAF_ASP_LinkInit *pInit,
125 PAF_ASP_Chain *from,
126 IALG_MemRec *common,
127 PAF_IALG_Config *pafConfig)
128 {
129 if (stream) {
130 this->fxns = fxns;
131 this->head = NULL;
132 this->stream = stream;
133 this->acp = acp;
134 this->log = log;
135 }
137 for ( ; pInit && pInit->thisCode.full; pInit++)
138 if (! this->fxns->chainLink (this, heap, pInit, from, common, pafConfig))
139 return NULL;
141 return this;
142 }
144 //
145 // Audio Stream Processing Chain Function - Link
146 //
147 // Name: PAF_ASP_chainLink_
148 // Purpose: Link an element onto an ASP Chain:
149 // (1) Allocate memory for the link, and
150 // (2) For the first gear, create the data for the link, but
151 // (3) For other than the first gear, simply link the data already
152 // created in the previous gear.
153 // From: AST Parameter Chain Function -> chainInit
154 // Uses: See code.
155 // States: None.
156 // Return: Success: ASP Chain.
157 // Failure: Null.
158 // Trace: Message Log "trace" in Debug Project Configuration reports:
159 // * Memory allocation errors.
160 // * Data creation errors.
161 // * Data linking errors.
162 //
165 PAF_ASP_Chain *
166 PAF_ASP_chainLink_ (
167 PAF_ASP_Chain *this,
168 HeapMem_Handle heap, //int heap,
169 const PAF_ASP_LinkInit *pInit,
170 PAF_ASP_Chain *from,
171 IALG_MemRec *common,
172 PAF_IALG_Config *pafConfig)
173 {
174 PAF_ASP_Link *pLink;
175 Error_Block eb;
177 if (! this || ! pInit)
178 return this;
180 // Initialize error block
181 Error_init(&eb);
183 //if (! (pLink = MEM_alloc (heap, sizeof(PAF_ASP_Link), 4))) {
184 if (!(pLink = Memory_alloc((IHeap_Handle)heap, sizeof(PAF_ASP_Link), 4, &eb))) {
185 if (this->log)
186 LOG_printf(this->log, "AS%d: ASP code 0x%08x alloc failure",
187 this->stream, pInit->thisCode.full);
188 return NULL;
189 }
191 if (! from) {
192 if (! this->fxns->linkData(pLink, pInit, this->stream, this->acp,
193 this->log,common, pafConfig)) {
194 if (this->log)
195 LOG_printf(this->log, "AS%d: ASP code 0x%08x link-init failure",
196 this->stream, pInit->thisCode.full);
197 return NULL;
198 }
199 }
200 else {
201 if (! this->fxns->linkCopy(pLink, pInit, from->head)) {
202 if (this->log)
203 LOG_printf(this->log, "AS%d: ASP code 0x%08x link-copy failure",
204 this->stream, pInit->thisCode.full);
205 return NULL;
206 }
207 }
209 {
210 PAF_ASP_Link **ppLink;
211 for (ppLink=&this->head; *ppLink; ppLink=&(*ppLink)->next)
212 if ((*ppLink)->code.full == pInit->linkCode.full)
213 break;
214 pLink->next = *ppLink;
215 *ppLink = pLink;
216 }
218 return this;
219 }
221 //
222 // Audio Stream Processing Chain Function - Find
223 //
224 // Name: PAF_ASP_chainFind_
225 // Purpose: Find an element in an ASP Chain.
226 // From: AST Parameter Chain Function -> chainFind
227 // Uses: None.
228 // States: None.
229 // Return: Success (found): Pointer to element.
230 // Failure (not found): Null.
231 // Trace: None.
232 //
234 PAF_ASP_Link *
235 PAF_ASP_chainFind_ (
236 PAF_ASP_Chain *this,
237 PAF_ASP_AlphaCode code)
238 {
239 PAF_ASP_Link *that = this->head;
241 for ( ; that; that = that->next) {
242 if (that->code.full == code.full)
243 break;
244 }
246 return that;
247 }
249 //
250 // Audio Stream Processing Chain Function - Reset
251 //
252 // Name: PAF_ASP_chainReset_
253 // Purpose: Reset an ASP Chain by invoking for each element:
254 // (1) The algorithm activation function (NOT PERFORMED), and
255 // (2) The algorithm reset function.
256 // From: AST Parameter Chain Function -> chainReset
257 // Uses: See code.
258 // States: None.
259 // Return: 0 on success.
260 // Error number reported by ASP Reset Function on failure.
261 // Trace: Message Log "trace" in Debug Project Configuration reports:
262 // * ASP Reset Function errors.
263 //
265 Int
266 PAF_ASP_chainReset_ (PAF_ASP_Chain *this, PAF_AudioFrame *pAudioFrame)
267 {
268 Int errno;
270 PAF_ASP_Link *pLink;
272 for (pLink=this->head; pLink; pLink=pLink->next) {
273 ASP_Handle alg = pLink->alg;
274 #if 0
275 /* ASP Algorithms are self-activating and not framework-activated */
276 if (((ALG_Handle )alg)->fxns->algActivate)
277 ((ALG_Handle )alg)->fxns->algActivate (((ALG_Handle )alg));
278 #endif
279 if (alg->fxns->reset && (errno = alg->fxns->reset(alg, pAudioFrame))) {
280 if (this->log) {
281 LOG_printf(this->log, "AS%d: ASP code 0x%08x reset error",
282 this->stream, pLink->code.full);
283 LOG_printf(this->log, "AS%d: errno = 0x%08x",
284 this->stream, errno);
285 }
286 return errno;
287 }
288 }
290 return 0;
291 }
293 //
294 // Audio Stream Processing Chain Function - Apply
295 //
296 // Name: PAF_ASP_chainApply_
297 // Purpose: Apply an ASP Chain by invoking for each:
298 // (1) The algorithm apply function.
299 // From: AST Parameter Chain Function -> chainApply
300 // Uses: See code.
301 // States: None.
302 // Return: 0 on success.
303 // Error number reported by ASP Apply Function on failure.
304 // Trace: Message Log "trace" in Debug Project Configuration reports:
305 // * ASP Apply Function errors.
306 //
308 Int
309 PAF_ASP_chainApply_ (PAF_ASP_Chain *this, PAF_AudioFrame *pAudioFrame)
310 {
311 Int errno;
312 int i = 0;
313 PAF_ASP_Link *pLink;
315 for (pLink=this->head; pLink; pLink=pLink->next)
316 {
317 ASP_Handle alg = pLink->alg;
319 i++;
320 if (this->log)
321 {
322 LOG_printf(&trace, "PAF_ASP_chainApply_: AS_%d. link %d. alg: 0x%x.",
323 this->stream, i, alg);
324 }
325 Log_info3("PAF_ASP_chainApply_: AS_%d. link %d. alg: 0x%x.", this->stream, i, (IArg)alg);
327 if (alg->fxns->apply /*&& (errno = alg->fxns->apply(alg, pAudioFrame))*/)
328 {
329 #ifdef PROFILER
330 if (aspNumberToProfile == currentAspCount) // only profile the selected ASP
331 {
332 time32_1 = Timestamp_get32();
333 }
334 #endif
336 #ifdef _TMS320C6X
337 if (gAspProfileEnable == 1)
338 {
339 if (gAspNumProfile == (i-1))
340 {
341 // only profile the selected ASP
342 pfpBegin(PFP_ID_ASOT_ASP_0, Task_self());
343 }
344 else if ((gAspNumProfile == -1) && (i <= PFP_MAX_ASP))
345 {
346 // profile current ASP
347 pfpBegin(PFP_ID_ASOT_ASP_0+(i-1), Task_self());
348 }
349 }
350 #endif
352 errno = alg->fxns->apply(alg, pAudioFrame);
354 #ifdef _TMS320C6X
355 if (gAspProfileEnable == 1)
356 {
357 if (gAspNumProfile == (i-1))
358 {
359 // only profile the selected ASP
360 pfpEnd(PFP_ID_ASOT_ASP_0, PFP_FINISH_MEAS);
361 }
362 else if ((gAspNumProfile == -1) && (i <= PFP_MAX_ASP))
363 {
364 // profile current ASP
365 pfpEnd(PFP_ID_ASOT_ASP_0+(i-1), PFP_FINISH_MEAS);
366 }
367 }
368 #endif
370 #ifdef PROFILER
371 if (aspNumberToProfile == currentAspCount) // only profile the selected ASP
372 {
373 time32_2 = Timestamp_get32();
374 //Load_Stat stat;
375 //Load_getTaskLoad (Task_getIdleTask(), &stat);
376 //UInt32 intLoad = Load_calculateLoad (&stat);
377 if (start_profiling == 1)
378 {
379 if (profile_index < MAX_NUM)
380 {
381 profile_array_dsp_cycles[profile_index] = (time32_2 - time32_1);
382 //profile_array_dsp_cpuload[profile_index] = (100 - intLoad);
383 profile_array_dsp_cpuload[profile_index] = Load_getCPULoad();
384 profile_index++;
385 }
386 else
387 {
388 //SW_BREAKPOINT;
389 }
390 }
392 //TRACE_TERSE1("profiler: Timestamp_get32() cycles: %u", (time32_2 - time32_1) * factor);
393 //TRACE_TERSE2("profiler: CPU load: idle: %d other: %d", intLoad, (100 - intLoad));
394 }
395 // increase ASP count
396 currentAspCount++;
397 #endif
399 if (errno && this->log)
400 {
401 LOG_printf(this->log, "AS%d: ASP code 0x%08x apply error 0x%x.",
402 this->stream, pLink->code.full, errno);
403 LOG_printf(&trace, "AS%d: ASP code 0x%08x apply error 0x%x.",
404 this->stream, pLink->code.full, errno);
406 #ifdef PROFILER
407 // Reset ASP count for next frame
408 currentAspCount = 0;
409 #endif
411 return errno;
412 }
413 }
414 }
416 #ifdef PROFILER
417 // Reset ASP count for next frame
418 currentAspCount = 0;
419 #endif
421 return 0;
422 }
424 //
425 // Audio Stream Processing Chain Function - Final
426 //
427 // Name: PAF_ASP_chainFinal_
428 // Purpose: Finalize an ASP Chain by invoking for each:
429 // (1) The algorithm final function (NOT PERFORMED), and
430 // (2) The algorithm deactivation function.
431 // From: AST Parameter Chain Function -> chainFinal
432 // Uses: See code.
433 // States: None.
434 // Return: 0 on success.
435 // Error number reported by ASP Final Function on failure.
436 // Trace: Message Log "trace" in Debug Project Configuration reports:
437 // * ASP Final Function errors.
438 //
439 // Note: In Audio Framework #2, PAF_ASP_FINAL is not defined and there
440 // are no Final Functions supplied with ASP Algorithms.
442 Int
443 PAF_ASP_chainFinal_ (PAF_ASP_Chain *this, PAF_AudioFrame *pAudioFrame)
444 {
445 #ifdef PAF_ASP_FINAL
446 Int errno;
447 #endif /* PAF_ASP_FINAL */
449 PAF_ASP_Link *pLink;
451 for (pLink=this->head; pLink; pLink=pLink->next) {
452 ASP_Handle alg = pLink->alg;
453 #ifdef PAF_ASP_FINAL
454 if (alg->fxns->final && (errno = alg->fxns->final(alg, pAudioFrame))) {
455 if (this->log) {
456 LOG_printf(this->log, "AS%d: ASP code 0x%08x final error",
457 this->stream, pLink->code.full);
458 LOG_printf(this->log, "AS%d: errno = 0x%08x",
459 this->stream, errno);
460 }
461 return errno;
462 }
463 #endif /* PAF_ASP_FINAL */
464 #if 1
465 /* ASP Algorithms are self-deactivating and framework-deactivated */
466 if (((ALG_Handle )alg)->fxns->algDeactivate)
467 ((ALG_Handle )alg)->fxns->algDeactivate (((ALG_Handle )alg));
468 #endif
469 }
471 return 0;
472 }
474 //
475 // Audio Stream Processing Chain Function - Link Data
476 //
477 // Name: PAF_ASP_linkData
478 // Purpose: Create the data for a chain link:
479 // (1) Perform beta unit relocation,
480 // (2) Instantiate an algorithm, and
481 // (3) Attach the beta unit(s) of an algorithm to an ACP Algorithm
482 // instance.
483 // From: AST Parameter Chain Function -> linkData
484 // Uses: See code.
485 // States: None.
486 // Return: Null pointer on failure.
487 // Pointer to the chain link on success.
488 // Trace: Message Log "trace" in Debug Project Configuration reports:
489 // * Algorithm instance creation failure message.
490 // * Beta Unit initialization success message.
491 //
493 PAF_ASP_Link *
494 PAF_ASP_linkData (
495 PAF_ASP_Link *this,
496 const PAF_ASP_LinkInit *pInit,
497 Uns stream,
498 ACP_Handle acp,
499 LOG_Obj *log,
500 IALG_MemRec *common,
501 PAF_IALG_Config *pafConfig)
502 {
503 IALG_Status *pStatus;
505 ALG_Handle alg;
507 Int beta = pInit->thisCode.part.beta;
509 if (log)
510 LOG_printf(log, "AS%d: beta 0x%x initialization begins.", stream, beta);
511 {
512 ALG_Handle acpAlg = (ALG_Handle) acp;
513 Int betaPrimeBase;
514 Int betaPrimeOffset;
515 acpAlg->fxns->algControl (acpAlg, ACP_GETBETAPRIMEBASE,
516 (IALG_Status *) &betaPrimeBase);
517 acpAlg->fxns->algControl (acpAlg, ACP_GETBETAPRIMEOFFSET,
518 (IALG_Status *) &betaPrimeOffset);
519 if (beta >= betaPrimeBase)
520 beta += (stream - 1) * betaPrimeOffset;
521 }
523 this->next = NULL;
524 this->code = pInit->thisCode;
526 if (pInit->ialg_fxns) {
528 if (pInit->init_func)
529 (*pInit->init_func)();
531 if (! (alg = PAF_ALG_create(pInit->ialg_fxns,NULL,(IALG_Params *)pInit->ialg_prms,
532 common, pafConfig))) {
533 if (log) {
534 LOG_printf(log,
535 "AS%d: beta 0x%x algorithm instance creation failed",
536 stream, beta);
537 }
538 return NULL;
539 }
540 }
541 else
542 return NULL;
544 this->alg = (ASP_Handle )alg;
546 if (alg->fxns->algControl) {
547 if (! alg->fxns->algControl (alg, ACP_GETSTATUSADDRESS1, (IALG_Status *)&pStatus))
548 acp->fxns->attach (acp, pInit->thisCode.part.series, beta, pStatus);
549 if (! alg->fxns->algControl (alg, ACP_GETSTATUSADDRESS2, (IALG_Status *)&pStatus))
550 acp->fxns->attach (acp, pInit->thisCode.part.series, beta+1, pStatus);
551 }
553 if (log)
554 LOG_printf(log, "AS%d: beta 0x%x processing initialized", stream, beta);
556 return this;
557 }
559 //
560 // Audio Stream Processing Chain Function - Link Copy
561 //
562 // Name: PAF_ASP_linkCopy
563 // Purpose: Copy the data for a chain link:
564 // (1) Find an element on a chain, and
565 // (2) Copy the reference to the data of the link.
566 // From: AST Parameter Chain Function -> linkCopy
567 // Uses: See code.
568 // States: None.
569 // Return: Null pointer on failure.
570 // Pointer to the chain link on success.
571 // Trace: None.
572 //
574 PAF_ASP_Link *
575 PAF_ASP_linkCopy (
576 PAF_ASP_Link *this,
577 const PAF_ASP_LinkInit *pInit,
578 PAF_ASP_Link *from)
579 {
580 for ( ; from; from = from->next) {
581 if (from->code.full == pInit->thisCode.full)
582 break;
583 }
585 if (! from)
586 return NULL;
588 this->next = NULL;
589 this->code = pInit->thisCode;
590 this->alg = from->alg;
592 return this;
593 }
595 //
596 // Audio Stream Processing Chain Functions
597 //
598 // Name: PAF_ASP_chainFxns
599 // Purpose: Collect the chain functions that embody the implementation
600 // of Audio Framework Number 2 for use as a jump table.
601 // From: PAF_AST_Params
602 // Uses: See contents.
603 // States: N.A.
604 // Return: N.A.
605 // Trace: None.
606 //
608 const struct PAF_ASP_ChainFxns PAF_ASP_chainFxns =
609 {
610 PAF_ASP_chainInit_,
611 PAF_ASP_chainLink_,
612 PAF_ASP_chainFind_,
613 {
614 PAF_ASP_chainReset_,
615 PAF_ASP_chainApply_,
616 PAF_ASP_chainFinal_,
617 },
618 PAF_ASP_linkData,
619 PAF_ASP_linkCopy,
620 };