Merge branch 'dev_pasdk_frank_pasdk516AsotRefactoring' into dev_pasdk_pasdk29Integration
[processor-sdk/performance-audio-sr.git] / pasdk / test_dsp / framework / as0.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 // Framework support function (implementation)
38 //
41 #include <xdc/std.h> //<std.h>
42 #include <xdc/runtime/Error.h>
43 #include <xdc/runtime/Log.h>
44 #include <xdc/runtime/Memory.h>
45 #include <ti/sysbios/BIOS.h>
46 #include <ti/sysbios/heaps/HeapMem.h>
47 #include <ti/ipc/MessageQ.h>
48 #include <ti/ipc/MultiProc.h>
50 //#include <ti/procsdk_audio/procsdk_audio_typ.h>
51 #include <procsdk_audio_typ.h>
53 #include <sio.h>
55 #include "as0.h"
57 #include "inpbuf.h"
58 #include <pafdec.h>
59 #include <pafenc.h>
60 #include "outbuf.h"
62 #include <asperr.h> /* ASPERR_*OUT_* */
63 #include <pafsio.h>
64 //#include "pafhjt.h"
66 #include "common.h"
67 #include "paf_heapMgr.h"
68 #include "aspMsg_common.h"
69 #include "aspMsg_master.h"
70 #include "audioStreamProc_common.h"
72 #define PAF_DEVICE_VERSION (PAF_DEVICE & 0xffff)
73 #if PAF_DEVICE_VERSION == 0xE000
74 #define _DEBUG // This is to enable log_printfs
75 #endif /* PAF_DEVICE_VERSION */
76 #include <logp.h>
78 // allows you to set a different trace module in pa.cfg
79 #define TR_MOD  trace
81 // Allow a developer to selectively enable tracing.
82 // For release, set mask to 1 to make it easier to catch any errors.
83 #define CURRENT_TRACE_MASK  1   // terse only
85 #define TRACE_MASK_TERSE    1   // only flag errors
86 #define TRACE_MASK_GENERAL  2   // log a half dozen lines per loop
87 #define TRACE_MASK_VERBOSE  4   // trace full operation
89 #if (CURRENT_TRACE_MASK & TRACE_MASK_TERSE)
90  #define TRACE_TERSE(a) LOG_printf a
91 #else
92  #define TRACE_TERSE(a)
93 #endif
95 #if (CURRENT_TRACE_MASK & TRACE_MASK_GENERAL)
96  #define TRACE_GEN(a) LOG_printf a
97 #else
98  #define TRACE_GEN(a)
99 #endif
101 #if (CURRENT_TRACE_MASK & TRACE_MASK_VERBOSE)
102  #define TRACE_VERBOSE(a) LOG_printf a
103 #else
104  #define TRACE_VERBOSE(a)
105 #endif
107 //
108 // Audio Stream Task / Decode Processing - Device Allocation Function
109 //
110 //   Name:      PAF_DEC_deviceAllocate
111 //   Purpose:   Decode Function for "device allocation" to
112 //              (1) allocate buffer memory, and
113 //              (2) initialize a Buffer Configuration, including pointers
114 //                  to that buffer memory.
115 //   From:      AST Parameter Function -> deviceAllocate
116 //   Uses:      None.
117 //   States:    None.
118 //   Return:    0 on success.
119 //              1 on MEM_calloc failure.
120 //   Trace:     None.
121 //
123 Int
124 PAF_DEC_deviceAllocate(
125     SIO_Handle *pHandle,
126     int mode,
127     int heapID,
128     int bufSize,
129     Ptr pBufCfg )
131     Ptr pBuf;
132     Error_Block    eb;
134     *pHandle = NULL;
136     // Initialize error block
137     Error_init(&eb); 
139 //#ifdef _TMS320C6X
140 //#warn Changed back to MEM_calloc until Mantis ID 81 resolved -- mwatson
141 //#endif
142 //    if (! (pBuf = (Ptr )MEM_alloc (heapID, bufSize, 128)))
143     //if (! (pBuf = (Ptr )MEM_calloc (heapID, bufSize, 128)))
144     if (!(pBuf = (Ptr )Memory_calloc((IHeap_Handle)pafHeapMgr_readHeapHandle(heapID), bufSize, 128, &eb)))
145         return (SYS_EALLOC);        
147     if( mode ==     SIO_OUTPUT ) {
148         PAF_OutBufConfig *pConfig = (PAF_OutBufConfig *)pBufCfg;
150         pConfig->base.pVoid = pBuf;
151         pConfig->pntr.pVoid = pBuf;
152         pConfig->head.pVoid = pBuf;
153         pConfig->allocation = bufSize;
154         pConfig->precision = 24;
155     }
156     else {
157         PAF_InpBufConfig *pConfig = (PAF_InpBufConfig *)pBufCfg;
159         pConfig->base.pVoid = pBuf;
160         pConfig->pntr.pVoid = pBuf;
161         pConfig->head.pVoid = pBuf;
162         pConfig->allocation = bufSize;
163         pConfig->precision = 16;
164     }
166     return SYS_OK;
167 } /* PAF_DEC_deviceAllocate */
169 //
170 // Audio Stream Task / Decode Processing - Device Selection Function
171 //
172 //   Name:      PAF_DEC_deviceSelect
173 //   Purpose:   Decode Function for "device selection" which
174 //              (1) "closes" any open device on that handle, and
175 //              (2) "opens" a new device on that handle if not None.
176 //   From:      AST Parameter Function -> deviceSelect
177 //   Uses:      See code.
178 //   States:    None.
179 //   Return:    0 on success.
180 //              1 on error in device create.
181 //              2 on error in device open.
182 //              3 on error in device close.
183 //              4 on error in device idle.
184 //   Trace:     None.
185 //
187 Int
188 PAF_DEC_deviceSelect(
189     SIO_Handle *pHandle,
190     int mode,
191     int heapID,
192     Ptr pParams )
194     // Device must be idled, closed, and freed to select new:
195     if (*pHandle) {
196         if (SIO_idle (*pHandle))
197             return ASPERR_DEVINP_IDLE-ASPERR_DEVINP;
198         if (SIO_ctrl (*pHandle, PAF_SIO_CONTROL_CLOSE, 0))
199             return ASPERR_DEVINP_CLOSE-ASPERR_DEVINP;
200         PAF_SIO_free (*pHandle, mode );
201             /* For consistency, should return integer. --Kurt */
202     }
204     // Select new device:
205     if (! pParams) {
206         /* input/output device None */
207         *pHandle = NULL;
208     }
209     else if (! (*pHandle = PAF_SIO_recreate (pParams, mode, &trace, heapID)))
210         return ASPERR_DEVINP_CREATE-ASPERR_DEVINP;
211     else if (SIO_ctrl (*pHandle, PAF_SIO_CONTROL_OPEN, (Arg) pParams))
212                 return ASPERR_DEVINP_OPEN-ASPERR_DEVINP;
214     return 0;
215 } /* PAF_DEC_deviceSelect */
217 //
218 // Audio Stream Task / Decode Processing - Frame Length Computation Function
219 //
220 //   Name:      PAF_DEC_computeFrameLength
221 //   Purpose:   Compute frame length to be generated by a decode algorithm,
222 //              including effects of the "buffer ratio" which is used to
223 //              indicate possible subsequent up-sampling by 2 or 4 (-2 or
224 //              -4) or down-sampling by 2 or 4 (2 or 4).
225 //   From:      AST Parameter Function -> computeFrameLength
226 //   Uses:      See code.
227 //   States:    None.
228 //   Return:    Frame length.
229 //   Trace:     None.
230 //
232 #include <pcm.h>
233 #if 0 /* commenting IP component header file inclusion */
234 #include <ac3.h>
235 #include <dts.h>
236 #include <aac.h>
238 #define DEC_MINSAMGEN PCM_MINSAMGEN
240 #if DEC_MINSAMGEN != AC3_MINSAMGEN
241 #error internal error
242 #elif DEC_MINSAMGEN != DTS_MINSAMGEN
243 #error internal error
244 #elif DEC_MINSAMGEN != AAC_MINSAMGEN
245 #error internal error
246 #endif /* DEC_MINSAMGEN */
248 #define DEC_MAXSAMGEN PCM_MAXSAMGEN
250 #if DEC_MAXSAMGEN != AC3_MAXSAMGEN
251 #error internal error
252 #elif DEC_MAXSAMGEN != DTS_MAXSAMGEN
253 #error internal error
254 #elif defined (AAC_SUPPORT) && DEC_MAXSAMGEN != AAC_MAXSAMGEN
255 #error internal error
256 #endif /* DEC_MAXSAMGEN */
257 #else
258 #define DEC_MINSAMGEN PCM_MINSAMGEN
259 #define DEC_MAXSAMGEN PCM_MAXSAMGEN
260 #endif
262 Int
263 PAF_DEC_computeFrameLength(
264     Int decIdx, 
265     Int frameLength, 
266     Int bufferRatio
269     Int m, n, o, p;
270     // Messaging
271     Int argIdx;
272     char decMsgBuf[ASP_MSG_BUF_LEN];
274     // dec control message to slave
275     argIdx = 0; //  set decIdx
276     *(Int *)&decMsgBuf[argIdx] = decIdx;
277     argIdx += sizeof(Int); // set decCtrlCmd
278     *(IALG_Cmd *)&decMsgBuf[argIdx] = DEC_MINSAMGEN;
279     if(AspMsgSend(ASP_SLAVE_DEC_CONTROL, ASP_MASTER_DEC_CONTROL_DONE,
280                   decMsgBuf, decMsgBuf) != ASP_MSG_NO_ERR)
281     {
282         SW_BREAKPOINT; // temporary
283         return -1; // temporary        
284     }    
285     else 
286     {
287         argIdx = 0; // get decCtrlRet
288         m = *(Int *)&decMsgBuf[argIdx];
289         TRACE_TERSE1("decCtrlRet (m)=%d", m);        
290     }
292     // dec control message to slave
293     argIdx = 0; // set decIdx
294     *(Int *)&decMsgBuf[argIdx] = decIdx;
295     argIdx += sizeof(Int); // set decCtrlCmd
296     *(IALG_Cmd *)&decMsgBuf[argIdx] = DEC_MAXSAMGEN;
297     if(AspMsgSend(ASP_SLAVE_DEC_CONTROL, ASP_MASTER_DEC_CONTROL_DONE,
298                   decMsgBuf, decMsgBuf) != ASP_MSG_NO_ERR)
299     {
300         SW_BREAKPOINT; // temporary
301         return -1; // temporary        
302     }    
303     else 
304     {
305         argIdx = 0; // get decCtrlRet
306         n = *(Int *)&decMsgBuf[argIdx];
307         TRACE_TERSE1("decCtrlRet (n)=%d", n);        
308     }
309     
310     if (m != n) {
311         o = n < frameLength ? n : frameLength;
312         o = o / m * m;
313         if (bufferRatio > 0) {
314             if (bufferRatio == 4 && (p = o / 4) > m && p % 8 == 0)
315                 return p;
316             else if (bufferRatio == 4 && (p = o / 2) > m && p % 8 == 0)
317                 return p;
318             else if (bufferRatio == 2 && (p = o / 2) > m && p % 8 == 0)
319                 return p;
320         }
321         else if (bufferRatio < 0) {
322             if (bufferRatio == -4 && (p = o * 4) > m && p % 8 == 0)
323                 return p;
324             else if (bufferRatio == -4 && (p = o * 2) > m && p % 8 == 0)
325                 return p;
326             else if (bufferRatio == -2 && (p = o * 2) > m && p % 8 == 0)
327                 return p;
328         }
329         if (o % 8 == 0)
330             return o;
331     }
333     return m;
334 } /* PAF_DEC_computeFrameLength */
336 //
337 // Audio Stream Task / Decode Processing - Input Status Update
338 //
339 //   Name:      PAF_DEC_updateInputStatus
340 //   Purpose:   Decode Function for maintaining Input Status.
341 //   From:      AST Parameter Function -> updateInputStatus
342 //   Uses:      See code.
343 //   States:    None.
344 //   Return:    0 on success.
345 //              Other on SIO Control failure (using SIO error numbers).
346 //   Trace:     None.
347 //
349 Int
350 PAF_DEC_updateInputStatus(
351     SIO_Handle hSio,
352     PAF_InpBufStatus *pStatus,
353     PAF_InpBufConfig *pConfig)
355     Int errno;
358     PAF_SIO_InputStatus inputStatus;
360     // initialize all values to unknown so that device specific
361     //   driver layer need only fill in those entries that it is aware of.
362     //   This allows extensibility of the structure without requiring users
363     //   to re-code.
364     inputStatus.lock = 0;
365     inputStatus.sampleRateData = PAF_SAMPLERATE_UNKNOWN;
366     inputStatus.sampleRateMeasured = PAF_SAMPLERATE_UNKNOWN;
367     inputStatus.nonaudio = PAF_IEC_AUDIOMODE_UNKNOWN;
368     inputStatus.emphasis = PAF_IEC_PREEMPHASIS_UNKNOWN;
370     errno = SIO_ctrl (hSio, (Uns)PAF_SIO_CONTROL_GET_INPUT_STATUS, (Arg) &inputStatus);
371     if (errno)
372         return errno;
373     pStatus->sampleRateData = inputStatus.sampleRateData;
374     pStatus->sampleRateMeasured = inputStatus.sampleRateMeasured;
375     pStatus->nonaudio = inputStatus.nonaudio;
376     pStatus->emphasisData = inputStatus.emphasis;
378     // if MSB of override clear then use as reported lock
379     // if = 0x80 then use default [0x81]
380     // if = 0x81 then use measured (from device)
381     // others not defined or implemented
382     if ((pStatus->lockOverride & (XDAS_Int8)0x80) == 0)
383         pStatus->lock = pStatus->lockOverride;
384     else if (pStatus->lockOverride == (XDAS_Int8)0x80)
385         pStatus->lock = inputStatus.lock;
386     else if (pStatus->lockOverride == (XDAS_Int8)0x81)
387         pStatus->lock = inputStatus.lock;
389     // if MSB of override clear then use it as sample rate for system,
390     // if = 0x80 then use default [0x82]
391     // if = 0x81 then use data
392     // if = 0x82 then use measured
393     // others not defined or implemented
394     if ((pStatus->sampleRateOverride & (XDAS_Int8)0x80) == 0)
395         pStatus->sampleRateStatus = pStatus->sampleRateOverride;
396     else if (pStatus->sampleRateOverride == (XDAS_Int8)0x80)
397         pStatus->sampleRateStatus = pStatus->sampleRateMeasured;
398     else if (pStatus->sampleRateOverride == (XDAS_Int8)0x81)
399         pStatus->sampleRateStatus = pStatus->sampleRateData;
400     else if (pStatus->sampleRateOverride == (XDAS_Int8)0x82)
401         pStatus->sampleRateStatus = pStatus->sampleRateMeasured;
403     // Update emphasis status:
404     if ((pStatus->emphasisOverride & (XDAS_Int8)0x80) == 0) {
405         if (pStatus->emphasisData == PAF_IEC_PREEMPHASIS_YES)
406             pStatus->emphasisStatus = PAF_IEC_PREEMPHASIS_YES;
407         else
408             pStatus->emphasisStatus = PAF_IEC_PREEMPHASIS_NO;
409     }
410     else if (pStatus->emphasisOverride ==
411              (XDAS_Int8 )(0x80+PAF_IEC_PREEMPHASIS_YES))
412         pStatus->emphasisStatus = PAF_IEC_PREEMPHASIS_YES;
413     else /* IBEmphasisOverrideNo or other */
414         pStatus->emphasisStatus = PAF_IEC_PREEMPHASIS_NO;
416     // Update precision control
417     pConfig->precision = pStatus->precisionInput =
418         pStatus->precisionOverride < 0
419         ? pStatus->precisionDefault
420         : pStatus->precisionOverride > 0
421         ? pStatus->precisionOverride
422         : pStatus->precisionDetect > 0
423         ? pStatus->precisionDetect
424         : pStatus->precisionDefault;
426     return 0;
428 } /* PAF_DEC_updateInputStatus */
430 // ----------------------------------------------------------------------------
432 #if 0
433 #ifndef HSE
435 // ............................................................................
437 //
438 // Audio Stream Task / Asynchronous Rate Conversion (ARC) - Control
439 //
440 //   Name:      PAF_ARC_controlRate
441 //   Purpose:   Control ARC conversion rate
442 //   From:      AST Parameter Function -> controlRate
443 //   Uses:      See code.
444 //   States:    None.
445 //   Return:    0 on success.
446 //              Other on SIO Control failure (using SIO error numbers).
447 //   Trace:     None.
448 //
450 #include <math.h>    /* ldexp() */
452 #include <acp.h>
454 #include <arc_a.h>
456 Int
457 PAF_ARC_controlRate(
458     SIO_Handle hRxSio,
459     SIO_Handle hTxSio,
460     ACP_Handle acp,
461     double arcRatio)  // KR032013
463     Int errno;
466     if (hRxSio && hTxSio) {
467         PAF_SIO_Stats *pRxStats, *pTxStats;
468       //extern double arcRatio;    // output / input rate  // KR032013
469         XDAS_UInt32 inputsPerOutputQ24 = (XDAS_UInt32) ldexp( arcRatio, 24);
471         static const ACP_Unit
472             readARCOutputsRemainingQ24_s[] = { readARCOutputsRemainingQ24 },
473             wroteARCInputsPerOutputQ24_s[] = { wroteARCInputsPerOutputQ24 };
475         ACP_Unit y4[4];
478         if (errno = SIO_ctrl (hRxSio, PAF_SIO_CONTROL_GET_STATS, (Arg) &pRxStats)) {
479             TRACE_TERSE ((&TR_MOD, "ARC: Error retrieving Rx xfer stats"
480                 " (0x%04x)", errno));
481             return errno;
482         }
484         if (errno = SIO_ctrl (hTxSio, PAF_SIO_CONTROL_GET_STATS, (Arg) &pTxStats)) {
485             TRACE_TERSE ((&TR_MOD, "ARC: Error retrieving Tx xfer stats"
486                 " (0x%04x)", errno));
487             return errno;
488         }
490         y4[0] = wroteARCInputsPerOutputQ24_s[0];
491         y4[1] = wroteARCInputsPerOutputQ24_s[1];
492         y4[2] = (MdInt) inputsPerOutputQ24;
493         y4[3] = (MdInt)(inputsPerOutputQ24 >> 16);
495         if (errno = acp->fxns->apply (acp, y4, NULL)) {
496             TRACE_TERSE ((&TR_MOD, "ARC: Error sending ARC rate ratio"
497                 " (0x%04x)", errno));
498             return errno;
499         }
501         if (errno = acp->fxns->apply (acp, readARCOutputsRemainingQ24_s, y4)) {
502             TRACE_TERSE ((&TR_MOD, "ARC: Error retrieving ARC timing"
503                 " (0x%04x)", errno));
504             return errno;
505         }
507         {
508         static XDAS_UInt32 outputsRemainingQ24[2];
510         const double arcDiff = pRxStats->dpll.v
511                             - (pTxStats->dpll.v + ldexp( outputsRemainingQ24[1], -24) * pTxStats->dpll.dv);
512         outputsRemainingQ24[1] = outputsRemainingQ24[0];
513         outputsRemainingQ24[0] = ((XDAS_UInt32) y4[3] << 16) + y4[2];
515         TRACE_GEN ((&TR_MOD, "time dif %d.%08d",
516             (int) arcDiff, (int) (1.e8 * (arcDiff - (int) arcDiff))));
518         }
519     }
521     return 0;
524 // ............................................................................
525 #else
526 Int
527 PAF_ARC_controlRate(
528     SIO_Handle hRxSio,
529     SIO_Handle hTxSio,
530     ACP_Handle acp,
531     double arcRatio) // KR032013
533     return 1;
535 #endif //HSE
536 #endif
538 // ----------------------------------------------------------------------------
540 //
541 // Audio Stream Task / Pass Processing - Buffer Copy
542 //
543 //   Name:      PAF_BUF_copy
544 //   Purpose:   Decode Function for copying the data in the input buffer
545 //              to the output buffer.
546 //   From:      AST Parameter Function -> copy
547 //   Uses:      None.
548 //   States:    None.
549 //   Return:    0 on success.
550 //              0x80000000 for errors in required arguments.
551 //   Trace:     None.
552 //
554 #define min(a, b)  (((a) < (b)) ? (a) : (b))
556 #include <pafdec.h>
557 #include <pafenc.h>
559 /* DO NOT REMOVE THIS CODE_SECTION. --Kurt */
560 #pragma CODE_SECTION(PAF_BUF_copy,".text:_PAF_BUF_copy")
562 Int
563 PAF_BUF_copy(
564     Uns inpChan,
565     PAF_InpBufConfig *pInpCfg,
566     Uns outChan,
567     PAF_OutBufConfig *pOutCfg)
569     Int i;
570     Int *pInBuf, *pOutBuf;
571     Int numSamples;
573 #ifndef __TI_EABI__
574     asm (" .clink");
575 #endif    
577     if( (pInpCfg == NULL) || (pOutCfg == NULL) )
578         return ASPERR_UNSPECIFIED;
580     if( (inpChan > pInpCfg->stride) || (outChan > pOutCfg->stride) )
581         return ASPERR_UNSPECIFIED;
583     //for now assume =32bit words
584     if( (pInpCfg->sizeofElement != 4) ||
585         (pInpCfg->sizeofElement != pOutCfg->sizeofElement) )
586         return ASPERR_UNSPECIFIED;
588     pInBuf = pInpCfg->pntr.pLgInt;
589     pOutBuf = pOutCfg->pntr.pLgInt;
591     numSamples = min(pInpCfg->frameLength, pOutCfg->lengthofFrame);
592     pInBuf += inpChan;
593     pOutBuf += outChan;
594     for( i=0; i < numSamples; i++ )
595     {
596         *pOutBuf = *pInBuf;
597         pInBuf += pInpCfg->stride;
598         pOutBuf += pOutCfg->stride;
599     }
601     return 0;
602 } /* PAF_BUF_copy */
604 // EOF