PASDK-71:Add PFP component to ARM & DSP.
[processor-sdk/performance-audio-sr.git] / pasdk / common / asp0.c
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 UInt32 gAspCurCount = 0;                    // ASP number in chain starting from 0
96 #endif // _TMS320C6X
99 //
100 // Audio Stream Processing Chain Function - Initialization
101 //
102 //   Name:      PAF_ASP_chainInit_
103 //   Purpose:   Initialize an ASP Chain by linking all elements of an
104 //              initialization array onto it. If this is the first audio
105 //              stream, perform base initialization of the ASP Chain, but 
106 //              otherwise do not.
107 //   From:      AST Parameter Chain Function -> chainInit
108 //   Uses:      AST Parameter Chain Function -> chainLink
109 //   States:    None.
110 //   Return:    ASP Chain.
111 //   Trace:     None.
112 //
114 PAF_ASP_Chain *
115 PAF_ASP_chainInit_ (
116     PAF_ASP_Chain *this,
117     const struct PAF_ASP_ChainFxns *fxns,
118     HeapMem_Handle heap, //int heap,
119     Uns stream,
120     ACP_Handle acp,
121     LOG_Obj *log,
122     const PAF_ASP_LinkInit *pInit,
123     PAF_ASP_Chain *from,
124     IALG_MemRec *common,
125     PAF_IALG_Config *pafConfig)
127     if (stream) {
128         this->fxns = fxns;
129         this->head = NULL;
130         this->stream = stream;
131         this->acp = acp;
132         this->log = log;
133     }
135     for ( ; pInit && pInit->thisCode.full; pInit++)
136         if (! this->fxns->chainLink (this, heap, pInit, from, common, pafConfig))
137             return NULL;
139     return this;
142 //
143 // Audio Stream Processing Chain Function - Link
144 //
145 //   Name:      PAF_ASP_chainLink_
146 //   Purpose:   Link an element onto an ASP Chain:
147 //              (1) Allocate memory for the link, and
148 //              (2) For the first gear, create the data for the link, but
149 //              (3) For other than the first gear, simply link the data already
150 //                  created in the previous gear.
151 //   From:      AST Parameter Chain Function -> chainInit
152 //   Uses:      See code.
153 //   States:    None.
154 //   Return:    Success: ASP Chain.
155 //              Failure: Null.
156 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
157 //              * Memory allocation errors.
158 //              * Data creation errors.
159 //              * Data linking errors.
160 //
163 PAF_ASP_Chain *
164 PAF_ASP_chainLink_ (
165     PAF_ASP_Chain *this,
166     HeapMem_Handle heap, //int heap,
167     const PAF_ASP_LinkInit *pInit,
168     PAF_ASP_Chain *from,
169     IALG_MemRec *common,
170     PAF_IALG_Config *pafConfig)
172     PAF_ASP_Link *pLink;
173     Error_Block    eb;
175     if (! this || ! pInit)
176         return this;
178     // Initialize error block
179     Error_init(&eb); 
181     //if (! (pLink = MEM_alloc (heap, sizeof(PAF_ASP_Link), 4))) {
182     if (!(pLink = Memory_alloc((IHeap_Handle)heap, sizeof(PAF_ASP_Link), 4, &eb))) {
183         if (this->log)
184             LOG_printf(this->log, "AS%d: ASP code 0x%08x alloc failure", 
185                 this->stream, pInit->thisCode.full);
186         return NULL;
187     }
189     if (! from) {
190         if (! this->fxns->linkData(pLink, pInit, this->stream, this->acp, 
191             this->log,common, pafConfig)) {
192             if (this->log)
193                 LOG_printf(this->log, "AS%d: ASP code 0x%08x link-init failure",
194                     this->stream, pInit->thisCode.full);
195             return NULL;
196         }
197     }
198     else {
199         if (! this->fxns->linkCopy(pLink, pInit, from->head)) {
200             if (this->log)
201                 LOG_printf(this->log, "AS%d: ASP code 0x%08x link-copy failure",
202                     this->stream, pInit->thisCode.full);
203             return NULL;
204         }
205     }
207     {
208         PAF_ASP_Link **ppLink;
209         for (ppLink=&this->head; *ppLink; ppLink=&(*ppLink)->next)
210             if ((*ppLink)->code.full == pInit->linkCode.full)
211                 break;
212         pLink->next = *ppLink;
213         *ppLink = pLink;
214     }
216     return this;
219 //
220 // Audio Stream Processing Chain Function - Find
221 //
222 //   Name:      PAF_ASP_chainFind_
223 //   Purpose:   Find an element in an ASP Chain.
224 //   From:      AST Parameter Chain Function -> chainFind
225 //   Uses:      None.
226 //   States:    None.
227 //   Return:    Success (found): Pointer to element.
228 //              Failure (not found): Null.
229 //   Trace:     None.
230 //
232 PAF_ASP_Link *
233 PAF_ASP_chainFind_ (
234     PAF_ASP_Chain *this,
235     PAF_ASP_AlphaCode code)
237     PAF_ASP_Link *that = this->head;
239     for ( ; that; that = that->next) {
240         if (that->code.full == code.full)
241             break;
242     }
244     return that;
247 //
248 // Audio Stream Processing Chain Function - Reset
249 //
250 //   Name:      PAF_ASP_chainReset_
251 //   Purpose:   Reset an ASP Chain by invoking for each element:
252 //              (1) The algorithm activation function (NOT PERFORMED), and
253 //              (2) The algorithm reset function.
254 //   From:      AST Parameter Chain Function -> chainReset
255 //   Uses:      See code.
256 //   States:    None.
257 //   Return:    0 on success.
258 //              Error number reported by ASP Reset Function on failure.
259 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
260 //              * ASP Reset Function errors.
261 //
263 Int
264 PAF_ASP_chainReset_ (PAF_ASP_Chain *this, PAF_AudioFrame *pAudioFrame)
266     Int errno;
268     PAF_ASP_Link *pLink;
270     for (pLink=this->head; pLink; pLink=pLink->next) {
271         ASP_Handle alg = pLink->alg;
272 #if 0
273         /* ASP Algorithms are self-activating and not framework-activated */
274         if (((ALG_Handle )alg)->fxns->algActivate)
275             ((ALG_Handle )alg)->fxns->algActivate (((ALG_Handle )alg));
276 #endif
277         if (alg->fxns->reset && (errno = alg->fxns->reset(alg, pAudioFrame))) {
278             if (this->log) {
279                 LOG_printf(this->log, "AS%d: ASP code 0x%08x reset error",
280                     this->stream, pLink->code.full);
281                 LOG_printf(this->log, "AS%d: errno = 0x%08x", 
282                     this->stream, errno);
283             }
284             return errno;
285         }
286     }
288     return 0;
291 //
292 // Audio Stream Processing Chain Function - Apply
293 //
294 //   Name:      PAF_ASP_chainApply_
295 //   Purpose:   Apply an ASP Chain by invoking for each:
296 //              (1) The algorithm apply function.
297 //   From:      AST Parameter Chain Function -> chainApply
298 //   Uses:      See code.
299 //   States:    None.
300 //   Return:    0 on success.
301 //              Error number reported by ASP Apply Function on failure.
302 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
303 //              * ASP Apply Function errors.
304 //
306 Int
307 PAF_ASP_chainApply_ (PAF_ASP_Chain *this, PAF_AudioFrame *pAudioFrame)
309     Int errno;
310     int i = 0;
311     PAF_ASP_Link *pLink;
313     for (pLink=this->head; pLink; pLink=pLink->next)
314     {
315         ASP_Handle alg = pLink->alg;
317         i++;
318         if (this->log)
319         {
320             LOG_printf(&trace, "PAF_ASP_chainApply_: AS_%d. link %d.  alg: 0x%x.",
321                        this->stream, i, alg);
322         }
323         Log_info3("PAF_ASP_chainApply_: AS_%d. link %d.  alg: 0x%x.", this->stream, i, (IArg)alg);
325         if (alg->fxns->apply /*&& (errno = alg->fxns->apply(alg, pAudioFrame))*/)
326         {
327 #ifdef PROFILER
328             if (aspNumberToProfile == currentAspCount)  // only profile the selected ASP
329             {
330                 time32_1 = Timestamp_get32();
331             }
332 #endif
334 #ifdef _TMS320C6X
335             if ((gAspProfileEnable == 1) && (gAspNumProfile == gAspCurCount))  // only profile the selected ASP
336             {                
337                 pfpBegin(PFP_ID_TASK1_2, Task_self());
338             }
339 #endif            
341             errno = alg->fxns->apply(alg, pAudioFrame);
342             
343 #ifdef _TMS320C6X
344             if ((gAspProfileEnable == 1) && (gAspNumProfile == gAspCurCount))  // only profile the selected ASP
345             {
346                 pfpEnd(PFP_ID_TASK1_2, PFP_FINISH_MEAS);
347             }
348             gAspCurCount++;
349 #endif            
351 #ifdef PROFILER
352             if (aspNumberToProfile == currentAspCount)  // only profile the selected ASP
353             {
354                 time32_2 = Timestamp_get32();
355                 //Load_Stat stat;
356                 //Load_getTaskLoad (Task_getIdleTask(), &stat);
357                 //UInt32 intLoad = Load_calculateLoad (&stat);
358                 if (start_profiling == 1)
359                 {
360                     if (profile_index < MAX_NUM)
361                     {
362                         profile_array_dsp_cycles[profile_index] = (time32_2 - time32_1);
363                         //profile_array_dsp_cpuload[profile_index] = (100   - intLoad);
364                         profile_array_dsp_cpuload[profile_index] =  Load_getCPULoad();
365                         profile_index++;
366                     }
367                     else
368                     {
369                         //SW_BREAKPOINT;
370                     }
371                 }
373                 //TRACE_TERSE1("profiler: Timestamp_get32() cycles: %u", (time32_2 - time32_1) * factor);
374                 //TRACE_TERSE2("profiler: CPU load: idle: %d other: %d", intLoad, (100 - intLoad));
375             }
376             // increase ASP count
377             currentAspCount++;
378 #endif
380             if (errno && this->log)
381             {
382                 LOG_printf(this->log, "AS%d: ASP code 0x%08x apply error 0x%x.",
383                     this->stream, pLink->code.full, errno);
384                 LOG_printf(&trace, "AS%d: ASP code 0x%08x apply error 0x%x.",
385                     this->stream, pLink->code.full, errno);
387 #ifdef _TMS320C6X
388                 // Reset ASP count for next frame
389                 gAspCurCount = 0;
390 #endif
391 #ifdef PROFILER
392                 // Reset ASP count for next frame
393                 currentAspCount = 0;
394 #endif
396                 return errno;
397             }
398         }
399     }
400     
401 #ifdef _TMS320C6X    
402     // Reset ASP count for next frame
403     gAspCurCount = 0;
404 #endif    
405 #ifdef PROFILER
406     // Reset ASP count for next frame
407     currentAspCount = 0;
408 #endif
410     return 0;
413 //
414 // Audio Stream Processing Chain Function - Final
415 //
416 //   Name:      PAF_ASP_chainFinal_
417 //   Purpose:   Finalize an ASP Chain by invoking for each:
418 //              (1) The algorithm final function (NOT PERFORMED), and
419 //              (2) The algorithm deactivation function.
420 //   From:      AST Parameter Chain Function -> chainFinal
421 //   Uses:      See code.
422 //   States:    None.
423 //   Return:    0 on success.
424 //              Error number reported by ASP Final Function on failure.
425 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
426 //              * ASP Final Function errors.
427 //
428 //   Note:      In Audio Framework #2, PAF_ASP_FINAL is not defined and there
429 //              are no Final Functions supplied with ASP Algorithms.
431 Int
432 PAF_ASP_chainFinal_ (PAF_ASP_Chain *this, PAF_AudioFrame *pAudioFrame)
434 #ifdef PAF_ASP_FINAL
435     Int errno;
436 #endif /* PAF_ASP_FINAL */
438     PAF_ASP_Link *pLink;
440     for (pLink=this->head; pLink; pLink=pLink->next) {
441         ASP_Handle alg = pLink->alg;
442 #ifdef PAF_ASP_FINAL
443         if (alg->fxns->final && (errno = alg->fxns->final(alg, pAudioFrame))) {
444             if (this->log) {
445                 LOG_printf(this->log, "AS%d: ASP code 0x%08x final error",
446                     this->stream, pLink->code.full);
447                 LOG_printf(this->log, "AS%d: errno = 0x%08x", 
448                     this->stream, errno);
449             }
450             return errno;
451         }
452 #endif /* PAF_ASP_FINAL */
453 #if 1
454         /* ASP Algorithms are self-deactivating and framework-deactivated */
455         if (((ALG_Handle )alg)->fxns->algDeactivate)
456             ((ALG_Handle )alg)->fxns->algDeactivate (((ALG_Handle )alg));
457 #endif
458     }
460     return 0;
463 //
464 // Audio Stream Processing Chain Function - Link Data
465 //
466 //   Name:      PAF_ASP_linkData
467 //   Purpose:   Create the data for a chain link:
468 //              (1) Perform beta unit relocation,
469 //              (2) Instantiate an algorithm, and
470 //              (3) Attach the beta unit(s) of an algorithm to an ACP Algorithm
471 //                  instance.
472 //   From:      AST Parameter Chain Function -> linkData
473 //   Uses:      See code.
474 //   States:    None.
475 //   Return:    Null pointer on failure.
476 //              Pointer to the chain link on success.
477 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
478 //              * Algorithm instance creation failure message.
479 //              * Beta Unit initialization success message.
480 //
482 PAF_ASP_Link *
483 PAF_ASP_linkData (
484     PAF_ASP_Link *this,
485     const PAF_ASP_LinkInit *pInit,
486     Uns stream,
487     ACP_Handle acp,
488     LOG_Obj *log,
489     IALG_MemRec *common,
490     PAF_IALG_Config *pafConfig) 
492     IALG_Status *pStatus;
493     
494     ALG_Handle alg;
495     
496     Int beta = pInit->thisCode.part.beta;
497         
498     if (log)
499         LOG_printf(log, "AS%d: beta 0x%x initialization begins.", stream, beta);
500     {
501         ALG_Handle acpAlg = (ALG_Handle) acp;
502         Int betaPrimeBase;
503         Int betaPrimeOffset;
504         acpAlg->fxns->algControl (acpAlg, ACP_GETBETAPRIMEBASE, 
505             (IALG_Status *) &betaPrimeBase);
506         acpAlg->fxns->algControl (acpAlg, ACP_GETBETAPRIMEOFFSET, 
507             (IALG_Status *) &betaPrimeOffset);
508         if (beta >= betaPrimeBase)
509             beta += (stream - 1) * betaPrimeOffset;
510     }
511     
512     this->next = NULL;
513     this->code = pInit->thisCode;
515     if (pInit->ialg_fxns) {
517         if (pInit->init_func)
518             (*pInit->init_func)();
520         if (! (alg = PAF_ALG_create(pInit->ialg_fxns,NULL,(IALG_Params *)pInit->ialg_prms,
521                      common, pafConfig))) {
522             if (log) {
523                 LOG_printf(log,
524                     "AS%d: beta 0x%x algorithm instance creation failed",
525                     stream, beta);
526             }
527             return NULL;
528         }
529     }
530     else
531         return NULL;
533     this->alg = (ASP_Handle )alg;
535     if (alg->fxns->algControl) {
536         if (! alg->fxns->algControl (alg, ACP_GETSTATUSADDRESS1, (IALG_Status *)&pStatus))
537             acp->fxns->attach (acp, pInit->thisCode.part.series, beta, pStatus);
538         if (! alg->fxns->algControl (alg, ACP_GETSTATUSADDRESS2, (IALG_Status *)&pStatus))
539             acp->fxns->attach (acp, pInit->thisCode.part.series, beta+1, pStatus);
540     }
542     if (log)
543         LOG_printf(log, "AS%d: beta 0x%x processing initialized", stream, beta);
545     return this;
548 //
549 // Audio Stream Processing Chain Function - Link Copy
550 //
551 //   Name:      PAF_ASP_linkCopy
552 //   Purpose:   Copy the data for a chain link:
553 //              (1) Find an element on a chain, and
554 //              (2) Copy the reference to the data of the link.
555 //   From:      AST Parameter Chain Function -> linkCopy
556 //   Uses:      See code.
557 //   States:    None.
558 //   Return:    Null pointer on failure.
559 //              Pointer to the chain link on success.
560 //   Trace:     None.
561 //
563 PAF_ASP_Link *
564 PAF_ASP_linkCopy (
565     PAF_ASP_Link *this,
566     const PAF_ASP_LinkInit *pInit,
567     PAF_ASP_Link *from)
569     for ( ; from; from = from->next) {
570         if (from->code.full == pInit->thisCode.full)
571             break;
572     }
574     if (! from)
575         return NULL;
577     this->next = NULL;
578     this->code = pInit->thisCode;
579     this->alg = from->alg;
581     return this;
584 //
585 // Audio Stream Processing Chain Functions
586 //
587 //   Name:      PAF_ASP_chainFxns
588 //   Purpose:   Collect the chain functions that embody the implementation 
589 //              of Audio Framework Number 2 for use as a jump table.
590 //   From:      PAF_AST_Params
591 //   Uses:      See contents.
592 //   States:    N.A.
593 //   Return:    N.A.
594 //   Trace:     None.
595 //
597 const struct PAF_ASP_ChainFxns PAF_ASP_chainFxns =
599     PAF_ASP_chainInit_,
600     PAF_ASP_chainLink_,
601     PAF_ASP_chainFind_,
602     {
603         PAF_ASP_chainReset_,
604         PAF_ASP_chainApply_,
605         PAF_ASP_chainFinal_,
606     },
607     PAF_ASP_linkData,
608     PAF_ASP_linkCopy,
609 };