edb1213914e4db36bdc459ba43252b1eb5bd43f3
[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 "dbgBenchmark.h" // PCM high-sampling rate + SRC + CAR benchmarking
55 //
56 // Performing PCM high-sampling rate + SRC + CAR benchmarking
57 //
58 #ifdef _ENABLE_BENCHMARK_PCMHSR_SRC_CAR_
59 #define PROFILER
60 #endif
62 #ifdef PROFILER
63 #include <ti/sysbios/knl/Task.h>
64 #include "ti/sysbios/knl/Clock.h"
65 #include "xdc/runtime/Timestamp.h"
66 #include "ti/sysbios/utils/Load.h"
68 #ifndef MAX_NUM
69 #define MAX_NUM 28515
70 #define NUM_ASP_PROFILE  0  // Profile CAR; As we have PCM->SRC(0)->CAR(1)->PCE
71 #endif
72 UInt32 profile_array_dsp_cycles[MAX_NUM];
73 UInt32 profile_array_dsp_cpuload[MAX_NUM];
74 UInt32 profile_index = 0;      // Array index
75 UInt32 start_profiling = 0;    // Flag
76 UInt32 currentAspCount = 0;    // ASP number in chain starting from 0
77 UInt32 aspNumberToProfile = NUM_ASP_PROFILE; // ASP number in chain starting from 0
78 volatile UInt32 time32_1, time32_2;
79 #endif
81 //
82 #include "asp0.h"
83 //#include <paf_alg.h>
84 //#include <pafhjt.h>
86 #include <acp.h>
88 #include "logp.h"
92 //
93 // Audio Stream Processing Chain Function - Initialization
94 //
95 //   Name:      PAF_ASP_chainInit_
96 //   Purpose:   Initialize an ASP Chain by linking all elements of an
97 //              initialization array onto it. If this is the first audio
98 //              stream, perform base initialization of the ASP Chain, but 
99 //              otherwise do not.
100 //   From:      AST Parameter Chain Function -> chainInit
101 //   Uses:      AST Parameter Chain Function -> chainLink
102 //   States:    None.
103 //   Return:    ASP Chain.
104 //   Trace:     None.
105 //
107 PAF_ASP_Chain *
108 PAF_ASP_chainInit_ (
109     PAF_ASP_Chain *this,
110     const struct PAF_ASP_ChainFxns *fxns,
111     HeapMem_Handle heap, //int heap,
112     Uns stream,
113     ACP_Handle acp,
114     LOG_Obj *log,
115     const PAF_ASP_LinkInit *pInit,
116     PAF_ASP_Chain *from,
117     IALG_MemRec *common,
118     PAF_IALG_Config *pafConfig)
120     if (stream) {
121         this->fxns = fxns;
122         this->head = NULL;
123         this->stream = stream;
124         this->acp = acp;
125         this->log = log;
126     }
128     for ( ; pInit && pInit->thisCode.full; pInit++)
129         if (! this->fxns->chainLink (this, heap, pInit, from, common, pafConfig))
130             return NULL;
132     return this;
135 //
136 // Audio Stream Processing Chain Function - Link
137 //
138 //   Name:      PAF_ASP_chainLink_
139 //   Purpose:   Link an element onto an ASP Chain:
140 //              (1) Allocate memory for the link, and
141 //              (2) For the first gear, create the data for the link, but
142 //              (3) For other than the first gear, simply link the data already
143 //                  created in the previous gear.
144 //   From:      AST Parameter Chain Function -> chainInit
145 //   Uses:      See code.
146 //   States:    None.
147 //   Return:    Success: ASP Chain.
148 //              Failure: Null.
149 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
150 //              * Memory allocation errors.
151 //              * Data creation errors.
152 //              * Data linking errors.
153 //
156 PAF_ASP_Chain *
157 PAF_ASP_chainLink_ (
158     PAF_ASP_Chain *this,
159     HeapMem_Handle heap, //int heap,
160     const PAF_ASP_LinkInit *pInit,
161     PAF_ASP_Chain *from,
162     IALG_MemRec *common,
163     PAF_IALG_Config *pafConfig)
165     PAF_ASP_Link *pLink;
166     Error_Block    eb;
168     if (! this || ! pInit)
169         return this;
171     // Initialize error block
172     Error_init(&eb); 
174     //if (! (pLink = MEM_alloc (heap, sizeof(PAF_ASP_Link), 4))) {
175     if (!(pLink = Memory_alloc((IHeap_Handle)heap, sizeof(PAF_ASP_Link), 4, &eb))) {
176         if (this->log)
177             LOG_printf(this->log, "AS%d: ASP code 0x%08x alloc failure", 
178                 this->stream, pInit->thisCode.full);
179         return NULL;
180     }
182     if (! from) {
183         if (! this->fxns->linkData(pLink, pInit, this->stream, this->acp, 
184             this->log,common, pafConfig)) {
185             if (this->log)
186                 LOG_printf(this->log, "AS%d: ASP code 0x%08x link-init failure",
187                     this->stream, pInit->thisCode.full);
188             return NULL;
189         }
190     }
191     else {
192         if (! this->fxns->linkCopy(pLink, pInit, from->head)) {
193             if (this->log)
194                 LOG_printf(this->log, "AS%d: ASP code 0x%08x link-copy failure",
195                     this->stream, pInit->thisCode.full);
196             return NULL;
197         }
198     }
200     {
201         PAF_ASP_Link **ppLink;
202         for (ppLink=&this->head; *ppLink; ppLink=&(*ppLink)->next)
203             if ((*ppLink)->code.full == pInit->linkCode.full)
204                 break;
205         pLink->next = *ppLink;
206         *ppLink = pLink;
207     }
209     return this;
212 //
213 // Audio Stream Processing Chain Function - Find
214 //
215 //   Name:      PAF_ASP_chainFind_
216 //   Purpose:   Find an element in an ASP Chain.
217 //   From:      AST Parameter Chain Function -> chainFind
218 //   Uses:      None.
219 //   States:    None.
220 //   Return:    Success (found): Pointer to element.
221 //              Failure (not found): Null.
222 //   Trace:     None.
223 //
225 PAF_ASP_Link *
226 PAF_ASP_chainFind_ (
227     PAF_ASP_Chain *this,
228     PAF_ASP_AlphaCode code)
230     PAF_ASP_Link *that = this->head;
232     for ( ; that; that = that->next) {
233         if (that->code.full == code.full)
234             break;
235     }
237     return that;
240 //
241 // Audio Stream Processing Chain Function - Reset
242 //
243 //   Name:      PAF_ASP_chainReset_
244 //   Purpose:   Reset an ASP Chain by invoking for each element:
245 //              (1) The algorithm activation function (NOT PERFORMED), and
246 //              (2) The algorithm reset function.
247 //   From:      AST Parameter Chain Function -> chainReset
248 //   Uses:      See code.
249 //   States:    None.
250 //   Return:    0 on success.
251 //              Error number reported by ASP Reset Function on failure.
252 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
253 //              * ASP Reset Function errors.
254 //
256 Int
257 PAF_ASP_chainReset_ (PAF_ASP_Chain *this, PAF_AudioFrame *pAudioFrame)
259     Int errno;
261     PAF_ASP_Link *pLink;
263     for (pLink=this->head; pLink; pLink=pLink->next) {
264         ASP_Handle alg = pLink->alg;
265 #if 0
266         /* ASP Algorithms are self-activating and not framework-activated */
267         if (((ALG_Handle )alg)->fxns->algActivate)
268             ((ALG_Handle )alg)->fxns->algActivate (((ALG_Handle )alg));
269 #endif
270         if (alg->fxns->reset && (errno = alg->fxns->reset(alg, pAudioFrame))) {
271             if (this->log) {
272                 LOG_printf(this->log, "AS%d: ASP code 0x%08x reset error",
273                     this->stream, pLink->code.full);
274                 LOG_printf(this->log, "AS%d: errno = 0x%08x", 
275                     this->stream, errno);
276             }
277             return errno;
278         }
279     }
281     return 0;
284 //
285 // Audio Stream Processing Chain Function - Apply
286 //
287 //   Name:      PAF_ASP_chainApply_
288 //   Purpose:   Apply an ASP Chain by invoking for each:
289 //              (1) The algorithm apply function.
290 //   From:      AST Parameter Chain Function -> chainApply
291 //   Uses:      See code.
292 //   States:    None.
293 //   Return:    0 on success.
294 //              Error number reported by ASP Apply Function on failure.
295 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
296 //              * ASP Apply Function errors.
297 //
299 Int
300 PAF_ASP_chainApply_ (PAF_ASP_Chain *this, PAF_AudioFrame *pAudioFrame)
302     Int errno;
303     int i = 0;
305     PAF_ASP_Link *pLink;
307     for (pLink=this->head; pLink; pLink=pLink->next)
308     {
309         ASP_Handle alg = pLink->alg;
311         i++;
312         if (this->log)
313         {
314             LOG_printf(&trace, "PAF_ASP_chainApply_: AS_%d. link %d.  alg: 0x%x.",
315                        this->stream, i, alg);
316         }
317         Log_info3("PAF_ASP_chainApply_: AS_%d. link %d.  alg: 0x%x.", this->stream, i, (IArg)alg);
319         if (alg->fxns->apply /*&& (errno = alg->fxns->apply(alg, pAudioFrame))*/)
320         {
322 #ifdef PROFILER
323         if (aspNumberToProfile == currentAspCount)  // only profile the selected ASP
324         {
325             time32_1 = Timestamp_get32();
326         }
327 #endif
328             errno = alg->fxns->apply(alg, pAudioFrame);
330 #ifdef PROFILER
331         if (aspNumberToProfile == currentAspCount)  // only profile the selected ASP
332         {
333             time32_2 = Timestamp_get32();
334             //Load_Stat stat;
335             //Load_getTaskLoad (Task_getIdleTask(), &stat);
336             //UInt32 intLoad = Load_calculateLoad (&stat);
337             if (start_profiling == 1)
338             {
339                 if (profile_index < MAX_NUM)
340                 {
341                     profile_array_dsp_cycles[profile_index] = (time32_2 - time32_1);
342                     //profile_array_dsp_cpuload[profile_index] = (100   - intLoad);
343                     profile_array_dsp_cpuload[profile_index] =  Load_getCPULoad();
344                     profile_index++;
345                 }
346                 else
347                 {
348                     //SW_BREAKPOINT;
349                 }
350             }
352             //TRACE_TERSE1("profiler: Timestamp_get32() cycles: %u", (time32_2 - time32_1) * factor);
353             //TRACE_TERSE2("profiler: CPU load: idle: %d other: %d", intLoad, (100 - intLoad));
354         }
355         // increase ASP count
356         currentAspCount++;
357 #endif
359             if (errno && this->log)
360             {
361                 LOG_printf(this->log, "AS%d: ASP code 0x%08x apply error 0x%x.",
362                     this->stream, pLink->code.full, errno);
363                 LOG_printf(&trace, "AS%d: ASP code 0x%08x apply error 0x%x.",
364                     this->stream, pLink->code.full, errno);
365                 #ifdef PROFILER
366                 // Reset ASP count for next frame
367                 currentAspCount = 0;
368                 #endif
369                 return errno;
370             }
371         }
372     }
373 #ifdef PROFILER
374     // Reset ASP count for next frame
375     currentAspCount = 0;
376 #endif
378     return 0;
381 //
382 // Audio Stream Processing Chain Function - Final
383 //
384 //   Name:      PAF_ASP_chainFinal_
385 //   Purpose:   Finalize an ASP Chain by invoking for each:
386 //              (1) The algorithm final function (NOT PERFORMED), and
387 //              (2) The algorithm deactivation function.
388 //   From:      AST Parameter Chain Function -> chainFinal
389 //   Uses:      See code.
390 //   States:    None.
391 //   Return:    0 on success.
392 //              Error number reported by ASP Final Function on failure.
393 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
394 //              * ASP Final Function errors.
395 //
396 //   Note:      In Audio Framework #2, PAF_ASP_FINAL is not defined and there
397 //              are no Final Functions supplied with ASP Algorithms.
399 Int
400 PAF_ASP_chainFinal_ (PAF_ASP_Chain *this, PAF_AudioFrame *pAudioFrame)
402 #ifdef PAF_ASP_FINAL
403     Int errno;
404 #endif /* PAF_ASP_FINAL */
406     PAF_ASP_Link *pLink;
408     for (pLink=this->head; pLink; pLink=pLink->next) {
409         ASP_Handle alg = pLink->alg;
410 #ifdef PAF_ASP_FINAL
411         if (alg->fxns->final && (errno = alg->fxns->final(alg, pAudioFrame))) {
412             if (this->log) {
413                 LOG_printf(this->log, "AS%d: ASP code 0x%08x final error",
414                     this->stream, pLink->code.full);
415                 LOG_printf(this->log, "AS%d: errno = 0x%08x", 
416                     this->stream, errno);
417             }
418             return errno;
419         }
420 #endif /* PAF_ASP_FINAL */
421 #if 1
422         /* ASP Algorithms are self-deactivating and framework-deactivated */
423         if (((ALG_Handle )alg)->fxns->algDeactivate)
424             ((ALG_Handle )alg)->fxns->algDeactivate (((ALG_Handle )alg));
425 #endif
426     }
428     return 0;
431 //
432 // Audio Stream Processing Chain Function - Link Data
433 //
434 //   Name:      PAF_ASP_linkData
435 //   Purpose:   Create the data for a chain link:
436 //              (1) Perform beta unit relocation,
437 //              (2) Instantiate an algorithm, and
438 //              (3) Attach the beta unit(s) of an algorithm to an ACP Algorithm
439 //                  instance.
440 //   From:      AST Parameter Chain Function -> linkData
441 //   Uses:      See code.
442 //   States:    None.
443 //   Return:    Null pointer on failure.
444 //              Pointer to the chain link on success.
445 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
446 //              * Algorithm instance creation failure message.
447 //              * Beta Unit initialization success message.
448 //
450 PAF_ASP_Link *
451 PAF_ASP_linkData (
452     PAF_ASP_Link *this,
453     const PAF_ASP_LinkInit *pInit,
454     Uns stream,
455     ACP_Handle acp,
456     LOG_Obj *log,
457     IALG_MemRec *common,
458     PAF_IALG_Config *pafConfig) 
460     IALG_Status *pStatus;
461     
462     ALG_Handle alg;
463     
464     Int beta = pInit->thisCode.part.beta;
465         
466     if (log)
467         LOG_printf(log, "AS%d: beta 0x%x initialization begins.", stream, beta);
468     {
469         ALG_Handle acpAlg = (ALG_Handle) acp;
470         Int betaPrimeBase;
471         Int betaPrimeOffset;
472         acpAlg->fxns->algControl (acpAlg, ACP_GETBETAPRIMEBASE, 
473             (IALG_Status *) &betaPrimeBase);
474         acpAlg->fxns->algControl (acpAlg, ACP_GETBETAPRIMEOFFSET, 
475             (IALG_Status *) &betaPrimeOffset);
476         if (beta >= betaPrimeBase)
477             beta += (stream - 1) * betaPrimeOffset;
478     }
479     
480     this->next = NULL;
481     this->code = pInit->thisCode;
483     if (pInit->ialg_fxns) {
485         if (pInit->init_func)
486             (*pInit->init_func)();
488         if (! (alg = PAF_ALG_create(pInit->ialg_fxns,NULL,(IALG_Params *)pInit->ialg_prms,
489                      common, pafConfig))) {
490             if (log) {
491                 LOG_printf(log,
492                     "AS%d: beta 0x%x algorithm instance creation failed",
493                     stream, beta);
494             }
495             return NULL;
496         }
497     }
498     else
499         return NULL;
501     this->alg = (ASP_Handle )alg;
503     if (alg->fxns->algControl) {
504         if (! alg->fxns->algControl (alg, ACP_GETSTATUSADDRESS1, (IALG_Status *)&pStatus))
505             acp->fxns->attach (acp, pInit->thisCode.part.series, beta, pStatus);
506         if (! alg->fxns->algControl (alg, ACP_GETSTATUSADDRESS2, (IALG_Status *)&pStatus))
507             acp->fxns->attach (acp, pInit->thisCode.part.series, beta+1, pStatus);
508     }
510     if (log)
511         LOG_printf(log, "AS%d: beta 0x%x processing initialized", stream, beta);
513     return this;
516 //
517 // Audio Stream Processing Chain Function - Link Copy
518 //
519 //   Name:      PAF_ASP_linkCopy
520 //   Purpose:   Copy the data for a chain link:
521 //              (1) Find an element on a chain, and
522 //              (2) Copy the reference to the data of the link.
523 //   From:      AST Parameter Chain Function -> linkCopy
524 //   Uses:      See code.
525 //   States:    None.
526 //   Return:    Null pointer on failure.
527 //              Pointer to the chain link on success.
528 //   Trace:     None.
529 //
531 PAF_ASP_Link *
532 PAF_ASP_linkCopy (
533     PAF_ASP_Link *this,
534     const PAF_ASP_LinkInit *pInit,
535     PAF_ASP_Link *from)
537     for ( ; from; from = from->next) {
538         if (from->code.full == pInit->thisCode.full)
539             break;
540     }
542     if (! from)
543         return NULL;
545     this->next = NULL;
546     this->code = pInit->thisCode;
547     this->alg = from->alg;
549     return this;
552 //
553 // Audio Stream Processing Chain Functions
554 //
555 //   Name:      PAF_ASP_chainFxns
556 //   Purpose:   Collect the chain functions that embody the implementation 
557 //              of Audio Framework Number 2 for use as a jump table.
558 //   From:      PAF_AST_Params
559 //   Uses:      See contents.
560 //   States:    N.A.
561 //   Return:    N.A.
562 //   Trace:     None.
563 //
565 const struct PAF_ASP_ChainFxns PAF_ASP_chainFxns =
567     PAF_ASP_chainInit_,
568     PAF_ASP_chainLink_,
569     PAF_ASP_chainFind_,
570     {
571         PAF_ASP_chainReset_,
572         PAF_ASP_chainApply_,
573         PAF_ASP_chainFinal_,
574     },
575     PAF_ASP_linkData,
576     PAF_ASP_linkCopy,
577 };