]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/performance-audio-sr.git/blob - pasdk/common/asp0.c
Merge branch 'dev_pasdk' of ssh://bitbucket.itg.ti.com/pasdk/pasdk_sr into dev_pasdk
[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 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)
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;
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)
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;
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)
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;
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)
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;
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)
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);
326   
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);
353             
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     }
415     
416 #ifdef PROFILER
417     // Reset ASP count for next frame
418     currentAspCount = 0;
419 #endif
421     return 0;
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)
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;
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) 
503     IALG_Status *pStatus;
504     
505     ALG_Handle alg;
506     
507     Int beta = pInit->thisCode.part.beta;
508         
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     }
522     
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;
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)
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;
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 =
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 };