]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/audio-preprocessing.git/blob - common/components/sys.c
realtime_demo_bios: update the demo using cmb to replace the cmbk2g
[processor-sdk/audio-preprocessing.git] / common / components / sys.c
1 /*
2  * Copyright (c) 2016, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  */
33 \r
34 /*=================================================================\r
35  *  sys.c: Basic system functions.\r
36  *=================================================================*/\r
37 \r
38 #include <string.h>\r
39 \r
40 #include <xdc/std.h>\r
41 #include <ti/sysbios/BIOS.h>\r
42 #include <xdc/runtime/System.h>\r
43 \r
44 #include <ti/mas/types/types.h>\r
45 #include <ti/mas/util/ecomem.h>\r
46 //#include <ti/mas/mhm/mhm.h>\r
47 \r
48 #include "mhm/mhm.h"\r
49 \r
50 #include "sys.h"\r
51 #include "syseram.h"\r
52 #include "sysiram.h"\r
53 #include "sysbfflt.h"\r
54 \r
55 /* Globals */\r
56 \r
57 /* Buffer descriptor array for memory allocations */\r
58 ecomemBuffer_t  sysCompBufs[SYS_COMP_MAXBUFS];\r
59 \r
60 /* Input sample buffer (dual) (align=8) */\r
61 #pragma DATA_ALIGN(sysInBuf,8)\r
62 tword sysInBuf[SYS_IN_SIZE];\r
63 \r
64 /* Virtual microphone frame outputs (align=8)*/\r
65 #pragma DATA_ALIGN(sysVmicFrame,8)\r
66 linSample sysVmicFrame[SYS_VMICS_MAX*SYS_FRAME_LENGTH];\r
67 \r
68 /* Virtual microphone angles to be used (default is all 12, every 30 degrees) */\r
69 tint sysBfVMicAngles[SYS_VMICS_MAX] = {\r
70   SYS_BF_ANGLE_P0,\r
71   SYS_BF_ANGLE_P30,\r
72   SYS_BF_ANGLE_P60,\r
73   SYS_BF_ANGLE_P90,\r
74   SYS_BF_ANGLE_P120,\r
75   SYS_BF_ANGLE_P150,\r
76   SYS_BF_ANGLE_P180,\r
77   SYS_BF_ANGLE_M150,\r
78   SYS_BF_ANGLE_M120,\r
79   SYS_BF_ANGLE_M90,\r
80   SYS_BF_ANGLE_M60,\r
81   SYS_BF_ANGLE_M30\r
82 };\r
83 \r
84 sysContext_t  sysContext;     /* Global System Context structure */\r
85 \r
86 #define max(a,b)  (((a)>(b))?(a):(b))\r
87 \r
88 /*=============================\r
89  * Functions\r
90  *=============================*/\r
91 \r
92 /*=================================================================\r
93  *  int sysAngleConfig(   Configure default virtual microphones\r
94  *    tint nvmics)        - Number of virtual mics to configure\r
95  *  \r
96  *    This function accespts only 4,6,8,12 virtual microphones.\r
97  *    If different number is used, manual configuration must be done\r
98  *    with potentially providing different microphone filters for the array.\r
99  *=================================================================*/\r
100 \r
101 int sysAngleConfig(tint nvmics)\r
102 {\r
103   int   err;\r
104 \r
105   err = SYS_ERR_SUCCESS;\r
106   nvmics = sysContext.nvmics;\r
107   switch (nvmics) {\r
108   case 4:\r
109     sysBfVMicAngles[0] = SYS_BF_ANGLE_P0;\r
110     sysBfVMicAngles[1] = SYS_BF_ANGLE_P90;\r
111     sysBfVMicAngles[2] = SYS_BF_ANGLE_P180;\r
112     sysBfVMicAngles[3] = SYS_BF_ANGLE_M90;\r
113     break;\r
114   case 6:\r
115     sysBfVMicAngles[0] = SYS_BF_ANGLE_P0;\r
116     sysBfVMicAngles[1] = SYS_BF_ANGLE_P60;\r
117     sysBfVMicAngles[2] = SYS_BF_ANGLE_P120;\r
118     sysBfVMicAngles[3] = SYS_BF_ANGLE_P180;\r
119     sysBfVMicAngles[4] = SYS_BF_ANGLE_M120;\r
120     sysBfVMicAngles[5] = SYS_BF_ANGLE_M60;\r
121     break;\r
122   case 8:\r
123     sysBfVMicAngles[0] = SYS_BF_ANGLE_P0;\r
124     sysBfVMicAngles[1] = SYS_BF_ANGLE_P45;\r
125     sysBfVMicAngles[2] = SYS_BF_ANGLE_P90;\r
126     sysBfVMicAngles[3] = SYS_BF_ANGLE_P135;\r
127     sysBfVMicAngles[4] = SYS_BF_ANGLE_P180;\r
128     sysBfVMicAngles[5] = SYS_BF_ANGLE_M135;\r
129     sysBfVMicAngles[6] = SYS_BF_ANGLE_M90;\r
130     sysBfVMicAngles[7] = SYS_BF_ANGLE_M45;\r
131     break;\r
132   case 12:\r
133     sysBfVMicAngles[0]  = SYS_BF_ANGLE_P0;\r
134     sysBfVMicAngles[1]  = SYS_BF_ANGLE_P30;\r
135     sysBfVMicAngles[2]  = SYS_BF_ANGLE_P60;\r
136     sysBfVMicAngles[3]  = SYS_BF_ANGLE_P90;\r
137     sysBfVMicAngles[4]  = SYS_BF_ANGLE_P120;\r
138     sysBfVMicAngles[5]  = SYS_BF_ANGLE_P150;\r
139     sysBfVMicAngles[6]  = SYS_BF_ANGLE_P180;\r
140     sysBfVMicAngles[7]  = SYS_BF_ANGLE_M150;\r
141     sysBfVMicAngles[8]  = SYS_BF_ANGLE_M120;\r
142     sysBfVMicAngles[9]  = SYS_BF_ANGLE_M90;\r
143     sysBfVMicAngles[10] = SYS_BF_ANGLE_M60;\r
144     sysBfVMicAngles[11] = SYS_BF_ANGLE_M30;\r
145     break;\r
146   default:\r
147     err = SYS_ERR_ANGLECONFIG;\r
148     break;\r
149   }\r
150   return(err);\r
151 } /* sysAngleConfig */\r
152 \r
153 /*=================================================================\r
154  *  int sysCreate(\r
155  *    sysConfig_t cfg);   - System configuration (see sys.h)\r
156  *=================================================================*/\r
157 \r
158 int sysCreate(sysConfig_t *cfg)\r
159 {\r
160   int       k, err, nvmics;\r
161   void      *heap_p;\r
162   linSample *x_p;\r
163 \r
164   if (cfg->nmics < 1 || cfg->nmics > SYS_MICS_MAX ||\r
165       cfg->nvmics < 1 || cfg->nvmics > SYS_VMICS_MAX) {\r
166     return(SYS_ERR_BADCONFIG);\r
167   }\r
168   sysContext.nmics           = cfg->nmics;        /* Store # of mics used */\r
169   nvmics = sysContext.nvmics = cfg->nvmics;       /* Store # of virtual mics used */\r
170   sysContext.use_fileio      = cfg->use_fileio;   /* probably FALSE since slow */\r
171   sysContext.eof             = FALSE;             /* no EOF reached yet */\r
172   sysContext.use_default     = cfg->use_default;  /* TRUE for default vmic angles */\r
173   for (k = 0; k < 3; k++) {\r
174     sysContext.asnr_attn[k] = cfg->asnr_attn[k];\r
175   }\r
176   sysContext.asnr_delay   = cfg->asnr_delay;\r
177   sysContext.asnr_enable  = cfg->asnr_enable;\r
178   sysContext.vad_enable   = cfg->vad_enable;\r
179   sysContext.drc_exp_knee = cfg->drc_exp_knee;\r
180   sysContext.drc_max_amp  = cfg->drc_max_amp;\r
181   sysContext.drc_enable   = cfg->drc_enable;\r
182 \r
183   /* Initialize input buffer pointers and read portion */\r
184   sysContext.in_lo = &sysInBuf[0];                /* Input buffer start (Low part) */\r
185   sysContext.in_hi = &sysInBuf[SYS_IN_SIZE/2];    /* High part of input buffer */\r
186   sysContext.in_w  = sysContext.in_lo;            /* Write pointer */\r
187   sysContext.in_r  = sysContext.in_hi;            /* Read pointer */\r
188   memset(sysContext.in_r, 0xBA, SYS_IN_SIZE/2);   /* Initialize the read portion */\r
189 \r
190   /* Clear instance pointers */\r
191   for (k = 0; k < SYS_VMICS_MAX; k++) {\r
192     sysContext.bfInst_p[k] = sysContext.asnrInst_p[k] = NULL;\r
193   }\r
194   sysContext.mssInst_p = sysContext.vauInst_p = NULL;\r
195 \r
196   /* Initialize virtual microphone frame pointers */\r
197 \r
198   /* First check to see if default configurations are used */\r
199   if (sysContext.use_default) {\r
200     err = sysAngleConfig(nvmics);\r
201     if (err != SYS_ERR_SUCCESS) {\r
202       return(err);\r
203     }\r
204   }\r
205   x_p = &sysVmicFrame[0];\r
206   for (k = 0; k < nvmics; k++) {\r
207     sysContext.vmicfrm[k]     = &x_p[k*SYS_FRAME_LENGTH];\r
208     sysContext.vmicangles[k]  = sysBfVMicAngles[k];\r
209   }\r
210   for ( ; k < SYS_VMICS_MAX; k++) {\r
211     sysContext.vmicfrm[k] = (linSample*)NULL;\r
212     sysContext.vmicangles[k] = 0;\r
213   }\r
214 \r
215   /* Create heaps */\r
216   heap_p = mhmCreate(sysEramPermanent,SYS_ERAM_PERMANENT_SIZE,0);\r
217   if (heap_p == NULL) {\r
218     return(SYS_ERR_HEAPINIT);\r
219   }\r
220   sysContext.heapEP = heap_p;\r
221 \r
222   heap_p = mhmCreate(sysEramScratch,SYS_ERAM_SCRATCH_SIZE,0);\r
223   if (heap_p == NULL) {\r
224     return(SYS_ERR_HEAPINIT);\r
225   }\r
226   sysContext.heapES = heap_p;\r
227 \r
228   heap_p = mhmCreate(sysIramPermanent,SYS_IRAM_PERMANENT_SIZE,0);\r
229   if (heap_p == NULL) {\r
230     return(SYS_ERR_HEAPINIT);\r
231   }\r
232   sysContext.heapIP = heap_p;\r
233 \r
234   heap_p = mhmCreate(sysIramScratch,SYS_IRAM_SCRATCH_SIZE,0);\r
235   if (heap_p == NULL) {\r
236     return(SYS_ERR_HEAPINIT);\r
237   }\r
238   sysContext.heapIS = heap_p;\r
239 \r
240   return(SYS_ERR_SUCCESS);\r
241 } /* sysCreate */\r
242 \r
243 /*=================================================================\r
244  *  void sysError(  Print error and exit\r
245  *    int err);     - System errror code (see sys.h)\r
246  *=================================================================*/\r
247 \r
248 void sysError(int err)\r
249 {\r
250   System_printf("*** ERROR: %d\n", err);\r
251   BIOS_exit(0);\r
252 } /* sysError */\r
253 \r
254 /*=================================================================\r
255  *  int sysHeapAlloc(     Allocate buffer from appropriate heap\r
256  *    void *bd,             - buffer descriptor\r
257  *    tint reset)           - 1: reset heap, 0: don't\r
258  *=================================================================*/\r
259 \r
260 int sysHeapAlloc(void *bd_in, tint reset)\r
261 {\r
262   int     err = SYS_ERR_SUCCESS;\r
263   tuint   size;\r
264   void    *handle;\r
265   tword   *base_w;\r
266   tulong  *used_p;\r
267 \r
268   ecomemBuffer_t *bd_p = (ecomemBuffer_t*) bd_in;\r
269 \r
270   if (bd_p->mclass == ecomem_CLASS_EXTERNAL) {\r
271     if (bd_p->volat) {\r
272       handle = sysContext.heapES;\r
273       used_p = &sysContext.heapES_used;\r
274     }\r
275     else {  /* permanent */\r
276       handle = sysContext.heapEP;\r
277       used_p = &sysContext.heapEP_used;\r
278     }\r
279   }\r
280   else if (bd_p->mclass == ecomem_CLASS_INTERNAL) {\r
281     if (bd_p->volat) {\r
282       handle = sysContext.heapIS;\r
283       used_p = &sysContext.heapIS_used;\r
284     }\r
285     else {  /* permanent */\r
286       handle = sysContext.heapIP;\r
287       used_p = &sysContext.heapIP_used;\r
288     }\r
289   }\r
290   else {\r
291     return(SYS_ERR_INVHEAPCLASS);\r
292   }\r
293 \r
294   if (reset != 0) {\r
295     mhmReset(handle);                 /* optionally reset the heap */\r
296     *used_p = 0;                      /* reset used size to zero */\r
297   }\r
298   size = bd_p->size;\r
299   base_w = (tword*)mhmAllocAligned(handle, size, bd_p->log2align);\r
300   *used_p += size;          /* update the used size */\r
301 \r
302   bd_p->base = base_w;      /* store the bsae address for a buffer */\r
303 \r
304   if (base_w == NULL) {\r
305     err = SYS_ERR_NOMEMORY;\r
306   }\r
307   return(err);\r
308 } /* sysHeapAlloc */\r
309 \r
310 /*=================================================================\r
311  *  int sysHeapAllocAll(  Allocate ALL buffers from appropriate heaps\r
312  *    tint nbufs,           - number of buffers\r
313  *    void *bdout,          - output buffer descriptors\r
314  *    void *bdin)           - input buffer descriptors\r
315  *=================================================================*/\r
316 \r
317 int sysHeapAllocAll(tint nbufs, void *bdout_p, const void *bdin_p)\r
318 {\r
319   int err;\r
320   tint k, volatile_found;\r
321   tulong es_used, is_used;    /* place to save scratch used sizes */\r
322   ecomemBuffer_t  *bdout  = bdout_p;\r
323   const ecomemBuffer_t  *bdin   = bdin_p;\r
324 \r
325   es_used = sysContext.heapES_used;     /* save in case scratch was reset */\r
326   is_used = sysContext.heapIS_used;\r
327 \r
328   /* Allocate memory for all buffers */\r
329   volatile_found = FALSE;\r
330   for (k = 0; k < nbufs; k++) {\r
331     bdout[k] = bdin[k];\r
332     if (bdout[k].volat && !volatile_found) { /* first volatile? */\r
333       err=sysHeapAlloc(&bdout[k], TRUE);          /* reset heap for the first volatile buffer */\r
334       if (err < 0) {\r
335         return(err);\r
336       }\r
337       volatile_found = TRUE;\r
338     }\r
339     else {  /* no need to reset heap */\r
340       err=sysHeapAlloc(&bdout[k], FALSE);\r
341       if (err < 0) {\r
342         return(err);\r
343       }\r
344     }\r
345   }\r
346 \r
347   /* fix the scratch heap used sizes if necessary */\r
348   sysContext.heapES_used = max(es_used,sysContext.heapES_used);\r
349   sysContext.heapIS_used = max(is_used,sysContext.heapIS_used);\r
350 \r
351   return(SYS_ERR_SUCCESS);\r
352 } /* sysHeapAllocAll */\r
353 \r
354 /*==================================================*/\r
355 /* The following was based on MHM implementation!!! */\r
356 /*==================================================*/\r
357 \r
358 /* Heap header that is placed at the beginning of a memory pool. */\r
359 typedef struct {\r
360   tuint  total_size;   /* total number of words in a memory pool */\r
361   tuint  used_size;    /* index of the first available word */\r
362 } sysMhmHead_t;\r
363 typedef tulong  sysMhmAddress_t;\r
364 \r
365 /*=================================================================\r
366  *  int sysPrintConfig(\r
367  *    tuint scope);     - SYSM_SCOPE_STATIC: Static configuration like default constants\r
368  *                        SYSM_SCOPE_DYNAMIC: Dynamic configuraiton like actual run-time values \r
369  *=================================================================*/\r
370 \r
371 int sysPrintConfig(tuint scope)\r
372 {\r
373   if (SYS_MASK_TEST(scope,SYSM_SCOPE_STATIC)) {\r
374     System_printf("\nStatic information:\n");\r
375     System_printf("tword: %d\n", sizeof(tword));\r
376     System_printf("tint:  %d\n", sizeof(tint));\r
377     System_printf("tlong: %d\n", sizeof(tlong));\r
378     System_printf("Max #mics:  %d\n", SYS_MICS_MAX);\r
379     System_printf("Max #vmics: %d\n", SYS_VMICS_MAX);\r
380     System_printf("Fs: %d [Hz]\n", SYS_FS_HZ);\r
381     System_printf("Frame duration: %d [ms]\n", SYS_FRAME_DURATION_MS);\r
382     System_printf("Frame length: %ld samples\n", SYS_FRAME_LENGTH);\r
383     System_printf("Frame size: %ld bytes\n", SYS_FRAME_SIZE);\r
384     System_printf("Input buffer length: %ld samples\n", SYS_IN_LENGTH);\r
385     System_printf("Frame buffer size: %ld bytes\n", SYS_IN_SIZE);\r
386   }\r
387   if (SYS_MASK_TEST(scope,SYSM_SCOPE_DYNAMIC)) {\r
388     System_printf("\nDynamic information:\n");\r
389     System_printf("#mics:  %d\n", sysContext.nmics);\r
390     System_printf("#vmics: %d\n", sysContext.nvmics);\r
391   }\r
392   return(SYS_ERR_SUCCESS);\r
393 } /* sysPrintConfig */\r
394 \r
395 /* nothing past this point */\r
396 \r