PASDK242: Added support for SRC4 and 96KHz.
[processor-sdk/performance-audio-sr.git] / pasdk / common / asp0.c
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  1  // 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)
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;
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)
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;
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)
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;
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)
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;
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)
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;
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)
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;
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) 
453     IALG_Status *pStatus;
454     
455     ALG_Handle alg;
456     
457     Int beta = pInit->thisCode.part.beta;
458         
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     }
472     
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;
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)
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;
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 =
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 };