• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2004-2010 NXP Software
3  * Copyright (C) 2010 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 
19 /****************************************************************************************/
20 /*                                                                                        */
21 /*    Includes                                                                              */
22 /*                                                                                        */
23 /****************************************************************************************/
24 
25 #include "LVM_Private.h"
26 #include "VectorArithmetic.h"
27 
28 /****************************************************************************************/
29 /*                                                                                      */
30 /* FUNCTION:                 LVM_BufferManagedIn                                        */
31 /*                                                                                      */
32 /* DESCRIPTION:                                                                         */
33 /*    Full buffer management allowing the user to provide input and output buffers on   */
34 /*  any alignment and with any number of samples. The alignment is corrected within     */
35 /*  the buffer management and the samples are grouped in to blocks of the correct size  */
36 /*  before processing.                                                                  */
37 /*                                                                                      */
38 /* PARAMETERS:                                                                          */
39 /*    hInstance        -    Instance handle                                             */
40 /*    pInData            -    Pointer to the input data stream                          */
41 /*  *pToProcess        -    Pointer to pointer to the start of data processing          */
42 /*  *pProcessed        -    Pointer to pointer to the destination of the processed data */
43 /*    pNumSamples        -    Pointer to the number of samples to process               */
44 /*                                                                                      */
45 /* RETURNS:                                                                             */
46 /*    None                                                                              */
47 /*                                                                                      */
48 /* NOTES:                                                                               */
49 /*                                                                                      */
50 /****************************************************************************************/
51 #ifdef BUILD_FLOAT
LVM_BufferManagedIn(LVM_Handle_t hInstance,const LVM_FLOAT * pInData,LVM_FLOAT ** pToProcess,LVM_FLOAT ** pProcessed,LVM_UINT16 * pNumSamples)52 void LVM_BufferManagedIn(LVM_Handle_t       hInstance,
53                          const LVM_FLOAT    *pInData,
54                          LVM_FLOAT          **pToProcess,
55                          LVM_FLOAT          **pProcessed,
56                          LVM_UINT16         *pNumSamples)
57 {
58 
59     LVM_INT16        SampleCount;           /* Number of samples to be processed this call */
60     LVM_INT16        NumSamples;            /* Number of samples in scratch buffer */
61     LVM_FLOAT        *pStart;
62     LVM_Instance_t   *pInstance = (LVM_Instance_t  *)hInstance;
63     LVM_Buffer_t     *pBuffer;
64     LVM_FLOAT        *pDest;
65     LVM_INT16        NumChannels = 2;
66 
67 
68     /*
69      * Set the processing address pointers
70      */
71     pBuffer     = pInstance->pBufferManagement;
72     pDest       = pBuffer->pScratch;
73     *pToProcess = pBuffer->pScratch;
74     *pProcessed = pBuffer->pScratch;
75 
76     /*
77      * Check if it is the first call of a block
78      */
79     if (pInstance->SamplesToProcess == 0)
80     {
81         /*
82          * First call for a new block of samples
83          */
84         pInstance->SamplesToProcess = (LVM_INT16)(*pNumSamples + pBuffer->InDelaySamples);
85         pInstance->pInputSamples    = (LVM_FLOAT *)pInData;
86         pBuffer->BufferState        = LVM_FIRSTCALL;
87     }
88     pStart = pInstance->pInputSamples;                 /* Pointer to the input samples */
89     pBuffer->SamplesToOutput  = 0;                     /* Samples to output is same as
90                                                           number read for inplace processing */
91 
92 
93     /*
94      * Calculate the number of samples to process this call and update the buffer state
95      */
96     if (pInstance->SamplesToProcess > pInstance->InternalBlockSize)
97     {
98         /*
99          * Process the maximum bock size of samples.
100          */
101         SampleCount = pInstance->InternalBlockSize;
102         NumSamples  = pInstance->InternalBlockSize;
103     }
104     else
105     {
106         /*
107          * Last call for the block, so calculate how many frames and samples to process
108           */
109         LVM_INT16   NumFrames;
110 
111         NumSamples  = pInstance->SamplesToProcess;
112         NumFrames    = (LVM_INT16)(NumSamples >> MIN_INTERNAL_BLOCKSHIFT);
113         SampleCount = (LVM_INT16)(NumFrames << MIN_INTERNAL_BLOCKSHIFT);
114 
115         /*
116          * Update the buffer state
117          */
118         if (pBuffer->BufferState == LVM_FIRSTCALL)
119         {
120             pBuffer->BufferState = LVM_FIRSTLASTCALL;
121         }
122         else
123         {
124             pBuffer->BufferState = LVM_LASTCALL;
125         }
126     }
127     *pNumSamples = (LVM_UINT16)SampleCount;  /* Set the number of samples to process this call */
128 
129 
130     /*
131      * Copy samples from the delay buffer as required
132      */
133     if (((pBuffer->BufferState == LVM_FIRSTCALL) ||
134         (pBuffer->BufferState == LVM_FIRSTLASTCALL)) &&
135         (pBuffer->InDelaySamples != 0))
136     {
137         Copy_Float(&pBuffer->InDelayBuffer[0],                             /* Source */
138                    pDest,                                                  /* Destination */
139                    (LVM_INT16)(NumChannels * pBuffer->InDelaySamples));    /* Number of delay \
140                                                                        samples, left and right */
141         NumSamples = (LVM_INT16)(NumSamples - pBuffer->InDelaySamples); /* Update sample count */
142         pDest += NumChannels * pBuffer->InDelaySamples;      /* Update the destination pointer */
143     }
144 
145 
146     /*
147      * Copy the rest of the samples for this call from the input buffer
148      */
149     if (NumSamples > 0)
150     {
151         Copy_Float(pStart,                                      /* Source */
152                    pDest,                                       /* Destination */
153                    (LVM_INT16)(NumChannels * NumSamples));      /* Number of input samples */
154         pStart += NumChannels * NumSamples;                     /* Update the input pointer */
155 
156         /*
157          * Update the input data pointer and samples to output
158          */
159         /* Update samples to output */
160         pBuffer->SamplesToOutput = (LVM_INT16)(pBuffer->SamplesToOutput + NumSamples);
161     }
162 
163 
164     /*
165       * Update the sample count and input pointer
166      */
167     /* Update the count of samples */
168     pInstance->SamplesToProcess  = (LVM_INT16)(pInstance->SamplesToProcess - SampleCount);
169     pInstance->pInputSamples     = pStart; /* Update input sample pointer */
170 
171 
172     /*
173      * Save samples to the delay buffer if any left unprocessed
174      */
175     if ((pBuffer->BufferState == LVM_FIRSTLASTCALL) ||
176         (pBuffer->BufferState == LVM_LASTCALL))
177     {
178         NumSamples = pInstance->SamplesToProcess;
179         pStart     = pBuffer->pScratch;                             /* Start of the buffer */
180         pStart    += NumChannels * SampleCount; /* Offset by the number of processed samples */
181         if (NumSamples != 0)
182         {
183             Copy_Float(pStart,                                         /* Source */
184                        &pBuffer->InDelayBuffer[0],                     /* Destination */
185                        (LVM_INT16)(NumChannels * NumSamples));   /* Number of input samples */
186         }
187 
188 
189         /*
190          * Update the delay sample count
191          */
192         pBuffer->InDelaySamples     = NumSamples;       /* Number of delay sample pairs */
193         pInstance->SamplesToProcess = 0;                            /* All Samples used */
194     }
195 }
196 #else
LVM_BufferManagedIn(LVM_Handle_t hInstance,const LVM_INT16 * pInData,LVM_INT16 ** pToProcess,LVM_INT16 ** pProcessed,LVM_UINT16 * pNumSamples)197 void LVM_BufferManagedIn(LVM_Handle_t       hInstance,
198                          const LVM_INT16    *pInData,
199                          LVM_INT16          **pToProcess,
200                          LVM_INT16          **pProcessed,
201                          LVM_UINT16         *pNumSamples)
202 {
203 
204     LVM_INT16        SampleCount;           /* Number of samples to be processed this call */
205     LVM_INT16        NumSamples;            /* Number of samples in scratch buffer */
206     LVM_INT16        *pStart;
207     LVM_Instance_t   *pInstance = (LVM_Instance_t  *)hInstance;
208     LVM_Buffer_t     *pBuffer;
209     LVM_INT16        *pDest;
210     LVM_INT16        NumChannels =2;
211 
212 
213     /*
214      * Set the processing address pointers
215      */
216     pBuffer     = pInstance->pBufferManagement;
217     pDest       = pBuffer->pScratch;
218     *pToProcess = pBuffer->pScratch;
219     *pProcessed = pBuffer->pScratch;
220 
221     /*
222      * Check if it is the first call of a block
223      */
224     if (pInstance->SamplesToProcess == 0)
225     {
226         /*
227          * First call for a new block of samples
228          */
229         pInstance->SamplesToProcess = (LVM_INT16)(*pNumSamples + pBuffer->InDelaySamples);
230         pInstance->pInputSamples    = (LVM_INT16 *)pInData;
231         pBuffer->BufferState        = LVM_FIRSTCALL;
232     }
233     pStart = pInstance->pInputSamples;                       /* Pointer to the input samples */
234     pBuffer->SamplesToOutput  = 0;                           /* Samples to output is same as number read for inplace processing */
235 
236 
237     /*
238      * Calculate the number of samples to process this call and update the buffer state
239      */
240     if (pInstance->SamplesToProcess > pInstance->InternalBlockSize)
241     {
242         /*
243          * Process the maximum bock size of samples.
244          */
245         SampleCount = pInstance->InternalBlockSize;
246         NumSamples  = pInstance->InternalBlockSize;
247     }
248     else
249     {
250         /*
251          * Last call for the block, so calculate how many frames and samples to process
252           */
253         LVM_INT16   NumFrames;
254 
255         NumSamples  = pInstance->SamplesToProcess;
256         NumFrames    = (LVM_INT16)(NumSamples >> MIN_INTERNAL_BLOCKSHIFT);
257         SampleCount = (LVM_INT16)(NumFrames << MIN_INTERNAL_BLOCKSHIFT);
258 
259         /*
260          * Update the buffer state
261          */
262         if (pBuffer->BufferState == LVM_FIRSTCALL)
263         {
264             pBuffer->BufferState = LVM_FIRSTLASTCALL;
265         }
266         else
267         {
268             pBuffer->BufferState = LVM_LASTCALL;
269         }
270     }
271     *pNumSamples = (LVM_UINT16)SampleCount;                        /* Set the number of samples to process this call */
272 
273 
274     /*
275      * Copy samples from the delay buffer as required
276      */
277     if (((pBuffer->BufferState == LVM_FIRSTCALL) ||
278         (pBuffer->BufferState == LVM_FIRSTLASTCALL)) &&
279         (pBuffer->InDelaySamples != 0))
280     {
281         Copy_16(&pBuffer->InDelayBuffer[0],                             /* Source */
282                 pDest,                                                  /* Destination */
283                 (LVM_INT16)(NumChannels*pBuffer->InDelaySamples));      /* Number of delay samples, left and right */
284         NumSamples = (LVM_INT16)(NumSamples - pBuffer->InDelaySamples); /* Update sample count */
285         pDest += NumChannels * pBuffer->InDelaySamples;                 /* Update the destination pointer */
286     }
287 
288 
289     /*
290      * Copy the rest of the samples for this call from the input buffer
291      */
292     if (NumSamples > 0)
293     {
294         Copy_16(pStart,                                             /* Source */
295                 pDest,                                              /* Destination */
296                 (LVM_INT16)(NumChannels*NumSamples));               /* Number of input samples */
297         pStart += NumChannels * NumSamples;                         /* Update the input pointer */
298 
299         /*
300          * Update the input data pointer and samples to output
301          */
302         pBuffer->SamplesToOutput = (LVM_INT16)(pBuffer->SamplesToOutput + NumSamples); /* Update samples to output */
303     }
304 
305 
306     /*
307       * Update the sample count and input pointer
308      */
309     pInstance->SamplesToProcess  = (LVM_INT16)(pInstance->SamplesToProcess - SampleCount);      /* Update the count of samples */
310     pInstance->pInputSamples     = pStart;                                                      /* Update input sample pointer */
311 
312 
313     /*
314      * Save samples to the delay buffer if any left unprocessed
315      */
316     if ((pBuffer->BufferState == LVM_FIRSTLASTCALL) ||
317         (pBuffer->BufferState == LVM_LASTCALL))
318     {
319         NumSamples = pInstance->SamplesToProcess;
320         pStart     = pBuffer->pScratch;                             /* Start of the buffer */
321         pStart    += NumChannels*SampleCount;                       /* Offset by the number of processed samples */
322         if (NumSamples != 0)
323         {
324             Copy_16(pStart,                                         /* Source */
325                     &pBuffer->InDelayBuffer[0],                     /* Destination */
326                     (LVM_INT16)(NumChannels*NumSamples));           /* Number of input samples */
327         }
328 
329 
330         /*
331          * Update the delay sample count
332          */
333         pBuffer->InDelaySamples     = NumSamples;                   /* Number of delay sample pairs */
334         pInstance->SamplesToProcess = 0;                            /* All Samples used */
335     }
336 }
337 #endif
338 
339 /****************************************************************************************/
340 /*                                                                                      */
341 /* FUNCTION:                 LVM_BufferUnmanagedIn                                      */
342 /*                                                                                      */
343 /* DESCRIPTION:                                                                         */
344 /*    This mode is selected by the user code and disables the buffer management with the */
345 /*  exception of the maximum block size processing. The user must ensure that the       */
346 /*  input and output buffers are 32-bit aligned and also that the number of samples to  */
347 /*    process is a correct multiple of samples.                                         */
348 /*                                                                                      */
349 /* PARAMETERS:                                                                          */
350 /*    hInstance        -    Instance handle                                             */
351 /*  *pToProcess        -    Pointer to the start of data processing                     */
352 /*  *pProcessed        -    Pointer to the destination of the processed data            */
353 /*    pNumSamples        -    Pointer to the number of samples to process               */
354 /*                                                                                      */
355 /* RETURNS:                                                                             */
356 /*    None                                                                              */
357 /*                                                                                      */
358 /* NOTES:                                                                               */
359 /*                                                                                      */
360 /****************************************************************************************/
361 #ifdef BUILD_FLOAT
LVM_BufferUnmanagedIn(LVM_Handle_t hInstance,LVM_FLOAT ** pToProcess,LVM_FLOAT ** pProcessed,LVM_UINT16 * pNumSamples)362 void LVM_BufferUnmanagedIn(LVM_Handle_t     hInstance,
363                            LVM_FLOAT        **pToProcess,
364                            LVM_FLOAT        **pProcessed,
365                            LVM_UINT16       *pNumSamples)
366 {
367 
368     LVM_Instance_t    *pInstance = (LVM_Instance_t  *)hInstance;
369 
370 
371     /*
372      * Check if this is the first call of a block
373      */
374     if (pInstance->SamplesToProcess == 0)
375     {
376         pInstance->SamplesToProcess = (LVM_INT16)*pNumSamples;    /* Get the number of samples
377                                                                                on first call */
378         pInstance->pInputSamples    = *pToProcess;                /* Get the I/O pointers */
379         pInstance->pOutputSamples    = *pProcessed;
380 
381 
382         /*
383          * Set te block size to process
384          */
385         if (pInstance->SamplesToProcess > pInstance->InternalBlockSize)
386         {
387             *pNumSamples = (LVM_UINT16)pInstance->InternalBlockSize;
388         }
389         else
390         {
391             *pNumSamples = (LVM_UINT16)pInstance->SamplesToProcess;
392         }
393     }
394 
395     /*
396      * Set the process pointers
397      */
398     *pToProcess = pInstance->pInputSamples;
399     *pProcessed = pInstance->pOutputSamples;
400 }
401 #else
LVM_BufferUnmanagedIn(LVM_Handle_t hInstance,LVM_INT16 ** pToProcess,LVM_INT16 ** pProcessed,LVM_UINT16 * pNumSamples)402 void LVM_BufferUnmanagedIn(LVM_Handle_t     hInstance,
403                            LVM_INT16        **pToProcess,
404                            LVM_INT16        **pProcessed,
405                            LVM_UINT16       *pNumSamples)
406 {
407 
408     LVM_Instance_t    *pInstance = (LVM_Instance_t  *)hInstance;
409 
410 
411     /*
412      * Check if this is the first call of a block
413      */
414     if (pInstance->SamplesToProcess == 0)
415     {
416         pInstance->SamplesToProcess = (LVM_INT16)*pNumSamples;       /* Get the number of samples on first call */
417         pInstance->pInputSamples    = *pToProcess;                   /* Get the I/O pointers */
418         pInstance->pOutputSamples    = *pProcessed;
419 
420 
421         /*
422          * Set te block size to process
423          */
424         if (pInstance->SamplesToProcess > pInstance->InternalBlockSize)
425         {
426             *pNumSamples = (LVM_UINT16)pInstance->InternalBlockSize;
427         }
428         else
429         {
430             *pNumSamples = (LVM_UINT16)pInstance->SamplesToProcess;
431         }
432     }
433 
434     /*
435      * Set the process pointers
436      */
437     *pToProcess = pInstance->pInputSamples;
438     *pProcessed = pInstance->pOutputSamples;
439 }
440 #endif
441 
442 /****************************************************************************************/
443 /*                                                                                      */
444 /* FUNCTION:                 LVM_BufferOptimisedIn                                      */
445 /*                                                                                      */
446 /* DESCRIPTION:                                                                         */
447 /*    Optimised buffer management for the case where the data is outplace processing,   */
448 /*    the output data is 32-bit aligned and there are sufficient samples to allow some  */
449 /*    processing directly in the output buffer. This saves one data copy per sample     */
450 /*    compared with the unoptimsed version.                                             */
451 /*                                                                                      */
452 /* PARAMETERS:                                                                          */
453 /*    hInstance        -    Instance handle                                             */
454 /*    pInData            -    Pointer to the input data stream                          */
455 /*  *pToProcess        -    Pointer to the start of data processing                     */
456 /*  *pProcessed        -    Pointer to the destination of the processed data            */
457 /*    pNumSamples        -    Pointer to the number of samples to process               */
458 /*                                                                                      */
459 /* RETURNS:                                                                             */
460 /*    None                                                                              */
461 /*                                                                                      */
462 /* NOTES:                                                                               */
463 /*                                                                                      */
464 /****************************************************************************************/
465 
466 #ifndef BUILD_FLOAT
LVM_BufferOptimisedIn(LVM_Handle_t hInstance,const LVM_INT16 * pInData,LVM_INT16 ** pToProcess,LVM_INT16 ** pProcessed,LVM_UINT16 * pNumSamples)467 void LVM_BufferOptimisedIn(LVM_Handle_t         hInstance,
468                            const LVM_INT16      *pInData,
469                            LVM_INT16            **pToProcess,
470                            LVM_INT16            **pProcessed,
471                            LVM_UINT16           *pNumSamples)
472 {
473 
474     LVM_Instance_t   *pInstance = (LVM_Instance_t  *)hInstance;
475     LVM_Buffer_t     *pBuffer    = pInstance->pBufferManagement;
476     LVM_INT16        *pDest;
477     LVM_INT16        SampleCount;
478     LVM_INT16        NumSamples;
479     LVM_INT16        NumFrames;
480 
481     /*
482      * Check if it is the first call for this block
483      */
484     if (pInstance->SamplesToProcess == 0)
485     {
486         /*
487          * First call for a new block of samples
488          */
489         pBuffer->BufferState = LVM_FIRSTCALL;
490         pInstance->pInputSamples    = (LVM_INT16 *)pInData;
491         pInstance->SamplesToProcess = (LVM_INT16)*pNumSamples;
492         pBuffer->SamplesToOutput    = (LVM_INT16)*pNumSamples;
493         pDest = *pProcessed;                                    /* The start of the output buffer */
494 
495 
496         /*
497          * Copy the already processed samples to the output buffer
498          */
499         if (pBuffer->OutDelaySamples != 0)
500         {
501             Copy_16(&pBuffer->OutDelayBuffer[0],                    /* Source */
502                     pDest,                                          /* Detsination */
503                     (LVM_INT16)(2*pBuffer->OutDelaySamples));       /* Number of delay samples */
504             pDest += 2 * pBuffer->OutDelaySamples;                  /* Update the output pointer */
505             pBuffer->SamplesToOutput = (LVM_INT16)(pBuffer->SamplesToOutput - pBuffer->OutDelaySamples); /* Update the numbr of samples to output */
506         }
507         *pToProcess = pDest;                                    /* Set the address to start processing */
508         *pProcessed = pDest;                                    /* Process in the output buffer, now inplace */
509 
510         /*
511          * Copy the input delay buffer (unprocessed) samples to the output buffer
512          */
513         if (pBuffer->InDelaySamples != 0)
514         {
515             Copy_16(&pBuffer->InDelayBuffer[0],                     /* Source */
516                     pDest,                                          /* Destination */
517                     (LVM_INT16)(2*pBuffer->InDelaySamples));        /* Number of delay samples */
518             pDest += 2 * pBuffer->InDelaySamples;                   /* Update the output pointer */
519         }
520 
521 
522         /*
523          * Calculate how many input samples to process and copy
524          */
525         NumSamples    = (LVM_INT16)(*pNumSamples - pBuffer->OutDelaySamples);  /* Number that will fit in the output buffer */
526         if (NumSamples >= pInstance->InternalBlockSize)
527         {
528             NumSamples = pInstance->InternalBlockSize;
529         }
530         NumFrames      = (LVM_INT16)(NumSamples >> MIN_INTERNAL_BLOCKSHIFT);
531         SampleCount   = (LVM_INT16)(NumFrames << MIN_INTERNAL_BLOCKSHIFT);
532         *pNumSamples  = (LVM_UINT16)SampleCount;                                        /* The number of samples to process */
533         pBuffer->SamplesToOutput = (LVM_INT16)(pBuffer->SamplesToOutput - SampleCount); /* Update the number of samples to output */
534         SampleCount   = (LVM_INT16)(SampleCount - pBuffer->InDelaySamples);             /* The number of samples to copy from the input */
535 
536 
537         /*
538          * Copy samples from the input buffer and update counts and pointers
539          */
540         Copy_16(pInstance->pInputSamples,                           /* Source */
541                 pDest,                                              /* Destination */
542                 (LVM_INT16)(2*SampleCount));                        /* Number of input samples */
543         pInstance->pInputSamples += 2 * SampleCount;                /* Update the input pointer */
544         pInstance->pOutputSamples = pDest + (2 * SampleCount);      /* Update the output pointer */
545         pInstance->SamplesToProcess = (LVM_INT16)(pInstance->SamplesToProcess - SampleCount); /* Samples left in the input buffer */
546     }
547     else
548     {
549         /*
550          * Second or subsequent call in optimised mode
551          */
552         if (pBuffer->SamplesToOutput >= MIN_INTERNAL_BLOCKSIZE)
553         {
554             /*
555              * More samples can be processed directly in the output buffer
556              */
557             *pToProcess = pInstance->pOutputSamples;                /* Set the address to start processing */
558             *pProcessed = pInstance->pOutputSamples;                /* Process in the output buffer, now inplace */
559             NumSamples  = pBuffer->SamplesToOutput;                 /* Number that will fit in the output buffer */
560             if (NumSamples >= pInstance->InternalBlockSize)
561             {
562                 NumSamples = pInstance->InternalBlockSize;
563             }
564             NumFrames      = (LVM_INT16)(NumSamples >> MIN_INTERNAL_BLOCKSHIFT);
565             SampleCount   = (LVM_INT16)(NumFrames << MIN_INTERNAL_BLOCKSHIFT);
566             *pNumSamples  = (LVM_UINT16)SampleCount;            /* The number of samples to process */
567 
568 
569             /*
570              * Copy samples from the input buffer and update counts and pointers
571              */
572             Copy_16(pInstance->pInputSamples,                       /* Source */
573                     pInstance->pOutputSamples,                      /* Destination */
574                     (LVM_INT16)(2*SampleCount));                    /* Number of input samples */
575             pInstance->pInputSamples += 2 * SampleCount;            /* Update the input pointer */
576             pInstance->pOutputSamples += 2 * SampleCount;           /* Update the output pointer */
577             pInstance->SamplesToProcess = (LVM_INT16)(pInstance->SamplesToProcess - SampleCount);   /* Samples left in the input buffer */
578             pBuffer->SamplesToOutput = (LVM_INT16)(pBuffer->SamplesToOutput - SampleCount);         /* Number that will fit in the output buffer */
579         }
580         else
581         {
582             /*
583              * The remaining samples can not be processed in the output buffer
584              */
585             pBuffer->BufferState = LVM_LASTCALL;                    /* Indicate this is the last bock to process */
586             *pToProcess  = pBuffer->pScratch;                       /* Set the address to start processing */
587             *pProcessed  = pBuffer->pScratch;                       /* Process in the output buffer, now inplace */
588             NumSamples   = pInstance->SamplesToProcess;             /* Number left to be processed */
589             NumFrames     = (LVM_INT16)(NumSamples >> MIN_INTERNAL_BLOCKSHIFT);
590             SampleCount  = (LVM_INT16)(NumFrames << MIN_INTERNAL_BLOCKSHIFT);
591             *pNumSamples = (LVM_UINT16)SampleCount;                /* The number of samples to process */
592 
593 
594             /*
595              * Copy samples from the input buffer and update counts and pointers
596              */
597             Copy_16(pInstance->pInputSamples,                       /* Source */
598                     pBuffer->pScratch,                              /* Destination */
599                     (LVM_INT16)(2*SampleCount));                    /* Number of input samples */
600             pInstance->pInputSamples += 2 * SampleCount;            /* Update the input pointer */
601             pInstance->SamplesToProcess = (LVM_INT16)(pInstance->SamplesToProcess - SampleCount); /* Samples left in the input buffer */
602         }
603     }
604 }
605 #endif
606 /****************************************************************************************/
607 /*                                                                                      */
608 /* FUNCTION:                 LVM_BufferIn                                               */
609 /*                                                                                      */
610 /* DESCRIPTION:                                                                         */
611 /*    This function manages the data input, it has the following features:              */
612 /*        - Accepts data in 16-bit aligned memory                                       */
613 /*        - Copies the data to 32-bit aligned memory                                    */
614 /*        - Converts Mono inputs to Mono-in-Stereo                                      */
615 /*        - Accepts any number of samples as input, except 0                            */
616 /*        - Breaks the input sample stream in to blocks of the configured frame size or */
617 /*          multiples of the frame size                                                 */
618 /*        - Limits the processing block size to the maximum block size.                 */
619 /*        - Works with inplace or outplace processing automatically                     */
620 /*                                                                                      */
621 /*  To manage the data the function has a number of operating states:                   */
622 /*        LVM_FIRSTCALL        - The first call for this block of input samples         */
623 /*        LVM_MAXBLOCKCALL    - The current block is the maximum size. Only used for the */
624 /*                              second and subsequent blocks.                           */
625 /*        LVM_LASTCALL        - The last call for this block of input samples           */
626 /*        LVM_FIRSTLASTCALL    - This is the first and last call for this block of input*/
627 /*                              samples, this occurs when the number of samples to      */
628 /*                              process is less than the maximum block size.            */
629 /*                                                                                      */
630 /*    The function uses an internal delay buffer the size of the minimum frame, this is */
631 /*  used to temporarily hold samples when the number of samples to process is not a     */
632 /*  multiple of the frame size.                                                         */
633 /*                                                                                      */
634 /*    To ensure correct operation with inplace buffering the number of samples to output*/
635 /*  per call is calculated in this function and is set to the number of samples read    */
636 /*  from the input buffer.                                                              */
637 /*                                                                                      */
638 /*    The total number of samples to process is stored when the function is called for  */
639 /*  the first time. The value is overwritten by the size of the block to be processed   */
640 /*  in each call so the size of the processing blocks can be controlled. The number of  */
641 /*    samples actually processed for each block of input samples is always a multiple of*/
642 /*  the frame size so for any particular block of input samples the actual number of    */
643 /*  processed samples may not match the number of input samples, sometime it will be    */
644 /*  sometimes less. The average is the same and the difference is never more than the   */
645 /*  frame size.                                                                         */
646 /*                                                                                      */
647 /* PARAMETERS:                                                                          */
648 /*    hInstance        -    Instance handle                                             */
649 /*    pInData            -    Pointer to the input data stream                          */
650 /*  *pToProcess        -    Pointer to the start of data processing                     */
651 /*  *pProcessed        -    Pointer to the destination of the processed data            */
652 /*    pNumSamples        -    Pointer to the number of samples to process               */
653 /*                                                                                      */
654 /* RETURNS:                                                                             */
655 /*    None                                                                              */
656 /*                                                                                      */
657 /* NOTES:                                                                               */
658 /*                                                                                      */
659 /****************************************************************************************/
660 #ifdef BUILD_FLOAT
LVM_BufferIn(LVM_Handle_t hInstance,const LVM_FLOAT * pInData,LVM_FLOAT ** pToProcess,LVM_FLOAT ** pProcessed,LVM_UINT16 * pNumSamples)661 void LVM_BufferIn(LVM_Handle_t      hInstance,
662                   const LVM_FLOAT   *pInData,
663                   LVM_FLOAT         **pToProcess,
664                   LVM_FLOAT         **pProcessed,
665                   LVM_UINT16        *pNumSamples)
666 {
667 
668     LVM_Instance_t    *pInstance = (LVM_Instance_t  *)hInstance;
669 
670 
671     /*
672      * Check which mode, managed or unmanaged
673      */
674     if (pInstance->InstParams.BufferMode == LVM_MANAGED_BUFFERS)
675     {
676         LVM_BufferManagedIn(hInstance,
677                             pInData,
678                             pToProcess,
679                             pProcessed,
680                             pNumSamples);
681     }
682     else
683     {
684         LVM_BufferUnmanagedIn(hInstance,
685                               pToProcess,
686                               pProcessed,
687                               pNumSamples);
688     }
689 }
690 #else
LVM_BufferIn(LVM_Handle_t hInstance,const LVM_INT16 * pInData,LVM_INT16 ** pToProcess,LVM_INT16 ** pProcessed,LVM_UINT16 * pNumSamples)691 void LVM_BufferIn(LVM_Handle_t      hInstance,
692                   const LVM_INT16   *pInData,
693                   LVM_INT16         **pToProcess,
694                   LVM_INT16         **pProcessed,
695                   LVM_UINT16        *pNumSamples)
696 {
697 
698     LVM_Instance_t    *pInstance = (LVM_Instance_t  *)hInstance;
699 
700 
701     /*
702      * Check which mode, managed or unmanaged
703      */
704     if (pInstance->InstParams.BufferMode == LVM_MANAGED_BUFFERS)
705     {
706         LVM_BufferManagedIn(hInstance,
707                             pInData,
708                             pToProcess,
709                             pProcessed,
710                             pNumSamples);
711     }
712     else
713     {
714         LVM_BufferUnmanagedIn(hInstance,
715                               pToProcess,
716                               pProcessed,
717                               pNumSamples);
718     }
719 }
720 #endif
721 /****************************************************************************************/
722 /*                                                                                      */
723 /* FUNCTION:                 LVM_BufferManagedOut                                       */
724 /*                                                                                      */
725 /* DESCRIPTION:                                                                         */
726 /*  Full buffer management output. This works in conjunction with the managed input     */
727 /*  routine and ensures the correct number of samples are always output to the output   */
728 /*  buffer.                                                                             */
729 /*                                                                                      */
730 /* PARAMETERS:                                                                          */
731 /*    hInstance        - Instance handle                                                */
732 /*    pOutData        - Pointer to the output data stream                               */
733 /*    pNumSamples        - Pointer to the number of samples to process                  */
734 /*                                                                                      */
735 /* RETURNS:                                                                             */
736 /*    None                                                                              */
737 /*                                                                                      */
738 /* NOTES:                                                                               */
739 /*                                                                                      */
740 /****************************************************************************************/
741 #ifdef BUILD_FLOAT
LVM_BufferManagedOut(LVM_Handle_t hInstance,LVM_FLOAT * pOutData,LVM_UINT16 * pNumSamples)742 void LVM_BufferManagedOut(LVM_Handle_t        hInstance,
743                           LVM_FLOAT            *pOutData,
744                           LVM_UINT16        *pNumSamples)
745 {
746 
747     LVM_Instance_t  *pInstance  = (LVM_Instance_t  *)hInstance;
748     LVM_Buffer_t    *pBuffer    = pInstance->pBufferManagement;
749     LVM_INT16       SampleCount = (LVM_INT16)*pNumSamples;
750     LVM_INT16       NumSamples;
751     LVM_FLOAT       *pStart;
752     LVM_FLOAT       *pDest;
753 
754 
755     /*
756      * Set the pointers
757      */
758     NumSamples = pBuffer->SamplesToOutput;
759     pStart     = pBuffer->pScratch;
760 
761 
762     /*
763      * check if it is the first call of a block
764       */
765     if ((pBuffer->BufferState == LVM_FIRSTCALL) ||
766         (pBuffer->BufferState == LVM_FIRSTLASTCALL))
767     {
768         /* First call for a new block */
769         pInstance->pOutputSamples = pOutData;                 /* Initialise the destination */
770     }
771     pDest = pInstance->pOutputSamples;                        /* Set the output address */
772 
773 
774     /*
775      * If the number of samples is non-zero then there are still samples to send to
776      * the output buffer
777      */
778     if ((NumSamples != 0) &&
779         (pBuffer->OutDelaySamples != 0))
780     {
781         /*
782          * Copy the delayed output buffer samples to the output
783          */
784         if (pBuffer->OutDelaySamples <= NumSamples)
785         {
786             /*
787              * Copy all output delay samples to the output
788              */
789             Copy_Float(&pBuffer->OutDelayBuffer[0],                /* Source */
790                        pDest,                                      /* Detsination */
791                        (LVM_INT16)(2 * pBuffer->OutDelaySamples)); /* Number of delay samples */
792 
793             /*
794              * Update the pointer and sample counts
795              */
796             pDest += 2 * pBuffer->OutDelaySamples; /* Output sample pointer */
797             NumSamples = (LVM_INT16)(NumSamples - pBuffer->OutDelaySamples); /* Samples left \
798                                                                                 to send */
799             pBuffer->OutDelaySamples = 0; /* No samples left in the buffer */
800         }
801         else
802         {
803             /*
804              * Copy only some of the ouput delay samples to the output
805              */
806             Copy_Float(&pBuffer->OutDelayBuffer[0],                    /* Source */
807                        pDest,                                          /* Detsination */
808                        (LVM_INT16)(2 * NumSamples));       /* Number of delay samples */
809 
810             /*
811              * Update the pointer and sample counts
812              */
813             pDest += 2 * NumSamples; /* Output sample pointer */
814             /* No samples left in the buffer */
815             pBuffer->OutDelaySamples = (LVM_INT16)(pBuffer->OutDelaySamples - NumSamples);
816 
817             /*
818              * Realign the delay buffer data to avoid using circular buffer management
819              */
820             Copy_Float(&pBuffer->OutDelayBuffer[2 * NumSamples],         /* Source */
821                        &pBuffer->OutDelayBuffer[0],                    /* Destination */
822                        (LVM_INT16)(2 * pBuffer->OutDelaySamples)); /* Number of samples to move */
823             NumSamples = 0;                                /* Samples left to send */
824         }
825     }
826 
827 
828     /*
829      * Copy the processed results to the output
830      */
831     if ((NumSamples != 0) &&
832         (SampleCount != 0))
833     {
834         if (SampleCount <= NumSamples)
835         {
836             /*
837              * Copy all processed samples to the output
838              */
839             Copy_Float(pStart,                                      /* Source */
840                        pDest,                                       /* Detsination */
841                        (LVM_INT16)(2 * SampleCount)); /* Number of processed samples */
842             /*
843              * Update the pointer and sample counts
844              */
845             pDest      += 2 * SampleCount;                          /* Output sample pointer */
846             NumSamples  = (LVM_INT16)(NumSamples - SampleCount);    /* Samples left to send */
847             SampleCount = 0; /* No samples left in the buffer */
848         }
849         else
850         {
851             /*
852              * Copy only some processed samples to the output
853              */
854             Copy_Float(pStart,                                         /* Source */
855                        pDest,                                          /* Destination */
856                        (LVM_INT16)(2 * NumSamples));     /* Number of processed samples */
857             /*
858              * Update the pointers and sample counts
859                */
860             pStart      += 2 * NumSamples;                        /* Processed sample pointer */
861             pDest       += 2 * NumSamples;                        /* Output sample pointer */
862             SampleCount  = (LVM_INT16)(SampleCount - NumSamples); /* Processed samples left */
863             NumSamples   = 0;                                     /* Clear the sample count */
864         }
865     }
866 
867 
868     /*
869      * Copy the remaining processed data to the output delay buffer
870      */
871     if (SampleCount != 0)
872     {
873         Copy_Float(pStart,                                                 /* Source */
874                    &pBuffer->OutDelayBuffer[2 * pBuffer->OutDelaySamples], /* Destination */
875                    (LVM_INT16)(2 * SampleCount));               /* Number of processed samples */
876         /* Update the buffer count */
877         pBuffer->OutDelaySamples = (LVM_INT16)(pBuffer->OutDelaySamples + SampleCount);
878     }
879 
880     /*
881      * pointers, counts and set default buffer processing
882      */
883     pBuffer->SamplesToOutput  = NumSamples;                         /* Samples left to send */
884     pInstance->pOutputSamples = pDest;                              /* Output sample pointer */
885     pBuffer->BufferState      = LVM_MAXBLOCKCALL;                   /* Set for the default call \
886                                                                             block size */
887     /* This will terminate the loop when all samples processed */
888     *pNumSamples = (LVM_UINT16)pInstance->SamplesToProcess;
889 }
890 #else
LVM_BufferManagedOut(LVM_Handle_t hInstance,LVM_INT16 * pOutData,LVM_UINT16 * pNumSamples)891 void LVM_BufferManagedOut(LVM_Handle_t        hInstance,
892                           LVM_INT16            *pOutData,
893                           LVM_UINT16        *pNumSamples)
894 {
895 
896     LVM_Instance_t  *pInstance  = (LVM_Instance_t  *)hInstance;
897     LVM_Buffer_t    *pBuffer    = pInstance->pBufferManagement;
898     LVM_INT16       SampleCount = (LVM_INT16)*pNumSamples;
899     LVM_INT16       NumSamples;
900     LVM_INT16       *pStart;
901     LVM_INT16       *pDest;
902 
903 
904     /*
905      * Set the pointers
906      */
907     NumSamples = pBuffer->SamplesToOutput;
908     pStart     = pBuffer->pScratch;
909 
910 
911     /*
912      * check if it is the first call of a block
913       */
914     if ((pBuffer->BufferState == LVM_FIRSTCALL) ||
915         (pBuffer->BufferState == LVM_FIRSTLASTCALL))
916     {
917         /* First call for a new block */
918         pInstance->pOutputSamples = pOutData;                        /* Initialise the destination */
919     }
920     pDest = pInstance->pOutputSamples;                               /* Set the output address */
921 
922 
923     /*
924      * If the number of samples is non-zero then there are still samples to send to
925      * the output buffer
926      */
927     if ((NumSamples != 0) &&
928         (pBuffer->OutDelaySamples != 0))
929     {
930         /*
931          * Copy the delayed output buffer samples to the output
932          */
933         if (pBuffer->OutDelaySamples <= NumSamples)
934         {
935             /*
936              * Copy all output delay samples to the output
937              */
938             Copy_16(&pBuffer->OutDelayBuffer[0],                    /* Source */
939                     pDest,                                          /* Detsination */
940                     (LVM_INT16)(2*pBuffer->OutDelaySamples));       /* Number of delay samples */
941 
942             /*
943              * Update the pointer and sample counts
944              */
945             pDest += 2*pBuffer->OutDelaySamples;                                /* Output sample pointer */
946             NumSamples = (LVM_INT16)(NumSamples - pBuffer->OutDelaySamples);    /* Samples left to send */
947             pBuffer->OutDelaySamples = 0;                                       /* No samples left in the buffer */
948 
949         }
950         else
951         {
952             /*
953              * Copy only some of the ouput delay samples to the output
954              */
955             Copy_16(&pBuffer->OutDelayBuffer[0],                    /* Source */
956                     pDest,                                          /* Detsination */
957                     (LVM_INT16)(2*NumSamples));                     /* Number of delay samples */
958 
959             /*
960              * Update the pointer and sample counts
961              */
962             pDest += 2*NumSamples;                                                              /* Output sample pointer */
963             pBuffer->OutDelaySamples = (LVM_INT16)(pBuffer->OutDelaySamples - NumSamples);      /* No samples left in the buffer */
964 
965 
966             /*
967              * Realign the delay buffer data to avoid using circular buffer management
968              */
969             Copy_16(&pBuffer->OutDelayBuffer[2*NumSamples],         /* Source */
970                     &pBuffer->OutDelayBuffer[0],                    /* Destination */
971                     (LVM_INT16)(2*pBuffer->OutDelaySamples));       /* Number of samples to move */
972             NumSamples = 0;                                         /* Samples left to send */
973         }
974     }
975 
976 
977     /*
978      * Copy the processed results to the output
979      */
980     if ((NumSamples != 0) &&
981         (SampleCount != 0))
982     {
983         if (SampleCount <= NumSamples)
984         {
985             /*
986              * Copy all processed samples to the output
987              */
988             Copy_16(pStart,                                      /* Source */
989                     pDest,                                       /* Detsination */
990                     (LVM_INT16)(2*SampleCount));                 /* Number of processed samples */
991 
992             /*
993              * Update the pointer and sample counts
994              */
995             pDest      += 2 * SampleCount;                          /* Output sample pointer */
996             NumSamples  = (LVM_INT16)(NumSamples - SampleCount);    /* Samples left to send */
997             SampleCount = 0;                                        /* No samples left in the buffer */
998         }
999         else
1000         {
1001             /*
1002              * Copy only some processed samples to the output
1003              */
1004             Copy_16(pStart,                                         /* Source */
1005                     pDest,                                          /* Destination */
1006                     (LVM_INT16)(2*NumSamples));                     /* Number of processed samples */
1007 
1008 
1009             /*
1010              * Update the pointers and sample counts
1011                */
1012             pStart      += 2 * NumSamples;                          /* Processed sample pointer */
1013             pDest        += 2 * NumSamples;                         /* Output sample pointer */
1014             SampleCount  = (LVM_INT16)(SampleCount - NumSamples);   /* Processed samples left */
1015             NumSamples   = 0;                                       /* Clear the sample count */
1016         }
1017     }
1018 
1019 
1020     /*
1021      * Copy the remaining processed data to the output delay buffer
1022      */
1023     if (SampleCount != 0)
1024     {
1025         Copy_16(pStart,                                                 /* Source */
1026                 &pBuffer->OutDelayBuffer[2*pBuffer->OutDelaySamples],   /* Destination */
1027                 (LVM_INT16)(2*SampleCount));                            /* Number of processed samples */
1028         pBuffer->OutDelaySamples = (LVM_INT16)(pBuffer->OutDelaySamples + SampleCount); /* Update the buffer count */
1029     }
1030 
1031 
1032     /*
1033      * pointers, counts and set default buffer processing
1034      */
1035     pBuffer->SamplesToOutput  = NumSamples;                         /* Samples left to send */
1036     pInstance->pOutputSamples = pDest;                              /* Output sample pointer */
1037     pBuffer->BufferState      = LVM_MAXBLOCKCALL;                   /* Set for the default call block size */
1038     *pNumSamples = (LVM_UINT16)pInstance->SamplesToProcess;         /* This will terminate the loop when all samples processed */
1039 }
1040 #endif
1041 
1042 /****************************************************************************************/
1043 /*                                                                                      */
1044 /* FUNCTION:                 LVM_BufferUnmanagedOut                                     */
1045 /*                                                                                      */
1046 /* DESCRIPTION:                                                                         */
1047 /*  This works in conjunction with the unmanaged input routine and updates the number   */
1048 /*    of samples left to be processed    and adjusts the buffer pointers.               */
1049 /*                                                                                      */
1050 /* PARAMETERS:                                                                          */
1051 /*    hInstance        - Instance handle                                                */
1052 /*    pNumSamples        - Pointer to the number of samples to process                  */
1053 /*                                                                                      */
1054 /* RETURNS:                                                                             */
1055 /*    None                                                                              */
1056 /*                                                                                      */
1057 /* NOTES:                                                                               */
1058 /*                                                                                      */
1059 /****************************************************************************************/
1060 
LVM_BufferUnmanagedOut(LVM_Handle_t hInstance,LVM_UINT16 * pNumSamples)1061 void LVM_BufferUnmanagedOut(LVM_Handle_t        hInstance,
1062                             LVM_UINT16          *pNumSamples)
1063 {
1064 
1065     LVM_Instance_t      *pInstance  = (LVM_Instance_t  *)hInstance;
1066     LVM_INT16           NumChannels =2;
1067 
1068 
1069     /*
1070      * Update sample counts
1071      */
1072     pInstance->pInputSamples    += (LVM_INT16)(*pNumSamples * NumChannels); /* Update the I/O pointers */
1073     pInstance->pOutputSamples   += (LVM_INT16)(*pNumSamples * 2);
1074     pInstance->SamplesToProcess  = (LVM_INT16)(pInstance->SamplesToProcess - *pNumSamples); /* Update the sample count */
1075 
1076     /*
1077      * Set te block size to process
1078      */
1079     if (pInstance->SamplesToProcess > pInstance->InternalBlockSize)
1080     {
1081         *pNumSamples = (LVM_UINT16)pInstance->InternalBlockSize;
1082     }
1083     else
1084     {
1085         *pNumSamples = (LVM_UINT16)pInstance->SamplesToProcess;
1086     }
1087 }
1088 
1089 
1090 /****************************************************************************************/
1091 /*                                                                                      */
1092 /* FUNCTION:                 LVM_BufferOptimisedOut                                     */
1093 /*                                                                                      */
1094 /* DESCRIPTION:                                                                         */
1095 /*  This works in conjunction with the optimised input routine and copies the last few  */
1096 /*  processed and unprocessed samples to their respective buffers.                      */
1097 /*                                                                                      */
1098 /* PARAMETERS:                                                                          */
1099 /*    hInstance        - Instance handle                                                */
1100 /*    pNumSamples        - Pointer to the number of samples to process                  */
1101 /*                                                                                      */
1102 /* RETURNS:                                                                             */
1103 /*    None                                                                              */
1104 /*                                                                                      */
1105 /* NOTES:                                                                               */
1106 /*                                                                                      */
1107 /****************************************************************************************/
1108 
1109 #ifndef BUILD_FLOAT
LVM_BufferOptimisedOut(LVM_Handle_t hInstance,LVM_UINT16 * pNumSamples)1110 void LVM_BufferOptimisedOut(LVM_Handle_t    hInstance,
1111                             LVM_UINT16        *pNumSamples)
1112 {
1113 
1114     LVM_Instance_t      *pInstance = (LVM_Instance_t  *)hInstance;
1115     LVM_Buffer_t        *pBuffer   = pInstance->pBufferManagement;
1116 
1117     /*
1118      * Check if it is the last block to process
1119      */
1120     if (pBuffer->BufferState == LVM_LASTCALL)
1121     {
1122         LVM_INT16    *pSrc = pBuffer->pScratch;
1123 
1124         /*
1125          * Copy the unprocessed samples to the input delay buffer
1126          */
1127         if (pInstance->SamplesToProcess != 0)
1128         {
1129             Copy_16(pInstance->pInputSamples,                       /* Source */
1130                     &pBuffer->InDelayBuffer[0],                     /* Destination */
1131                     (LVM_INT16)(2*pInstance->SamplesToProcess));    /* Number of input samples */
1132             pBuffer->InDelaySamples = pInstance->SamplesToProcess;
1133             pInstance->SamplesToProcess = 0;
1134         }
1135         else
1136         {
1137             pBuffer->InDelaySamples = 0;
1138         }
1139 
1140 
1141         /*
1142          * Fill the last empty spaces in the output buffer
1143          */
1144         if (pBuffer->SamplesToOutput != 0)
1145         {
1146             Copy_16(pSrc,                                           /* Source */
1147                     pInstance->pOutputSamples,                      /* Destination */
1148                     (LVM_INT16)(2*pBuffer->SamplesToOutput));       /* Number of input samples */
1149             *pNumSamples = (LVM_UINT16)(*pNumSamples - pBuffer->SamplesToOutput);
1150             pSrc += 2 * pBuffer->SamplesToOutput;                  /* Update scratch pointer */
1151             pBuffer->SamplesToOutput = 0;                          /* No more samples in this block */
1152         }
1153 
1154 
1155         /*
1156          * Save any remaining processed samples in the output delay buffer
1157          */
1158         if (*pNumSamples != 0)
1159         {
1160             Copy_16(pSrc,                                           /* Source */
1161                     &pBuffer->OutDelayBuffer[0],                    /* Destination */
1162                     (LVM_INT16)(2**pNumSamples));                   /* Number of input samples */
1163 
1164             pBuffer->OutDelaySamples = (LVM_INT16)*pNumSamples;
1165 
1166             *pNumSamples = 0;                                      /* No more samples in this block */
1167         }
1168         else
1169         {
1170             pBuffer->OutDelaySamples = 0;
1171         }
1172     }
1173 }
1174 #endif
1175 
1176 /****************************************************************************************/
1177 /*                                                                                      */
1178 /* FUNCTION:                 LVM_BufferOut                                              */
1179 /*                                                                                      */
1180 /* DESCRIPTION:                                                                         */
1181 /*  This function manages the data output, it has the following features:               */
1182 /*        - Output data to 16-bit aligned memory                                        */
1183 /*        - Reads data from 32-bit aligned memory                                       */
1184 /*        - Reads data only in blocks of frame size or multiples of frame size          */
1185 /*        - Writes the same number of samples as the LVM_BufferIn function reads        */
1186 /*        - Works with inplace or outplace processing automatically                     */
1187 /*                                                                                      */
1188 /*  To manage the data the function has a number of operating states:                   */
1189 /*        LVM_FIRSTCALL        - The first call for this block of input samples         */
1190 /*        LVM_FIRSTLASTCALL    - This is the first and last call for this block of input*/
1191 /*                              samples, this occurs when the number of samples to      */
1192 /*                              process is less than the maximum block size.            */
1193 /*                                                                                      */
1194 /*    The function uses an internal delay buffer the size of the minimum frame, this is */
1195 /*  used to temporarily hold samples when the number of samples to write is not a       */
1196 /*  multiple of the frame size.                                                         */
1197 /*                                                                                      */
1198 /*    To ensure correct operation with inplace buffering the number of samples to output*/
1199 /*  per call is always the same as the number of samples read from the input buffer.    */
1200 /*                                                                                      */
1201 /* PARAMETERS:                                                                          */
1202 /*    hInstance        - Instance handle                                                */
1203 /*    pOutData        - Pointer to the output data stream                               */
1204 /*    pNumSamples        - Pointer to the number of samples to process                  */
1205 /*                                                                                      */
1206 /* RETURNS:                                                                             */
1207 /*    None                                                                              */
1208 /*                                                                                      */
1209 /* NOTES:                                                                               */
1210 /*                                                                                      */
1211 /****************************************************************************************/
1212 #ifdef BUILD_FLOAT
LVM_BufferOut(LVM_Handle_t hInstance,LVM_FLOAT * pOutData,LVM_UINT16 * pNumSamples)1213 void LVM_BufferOut(LVM_Handle_t     hInstance,
1214                    LVM_FLOAT        *pOutData,
1215                    LVM_UINT16       *pNumSamples)
1216 {
1217 
1218     LVM_Instance_t    *pInstance  = (LVM_Instance_t  *)hInstance;
1219 
1220 
1221     /*
1222      * Check which mode, managed or unmanaged
1223      */
1224     if (pInstance->InstParams.BufferMode == LVM_MANAGED_BUFFERS)
1225     {
1226         LVM_BufferManagedOut(hInstance,
1227                              pOutData,
1228                              pNumSamples);
1229     }
1230     else
1231     {
1232         LVM_BufferUnmanagedOut(hInstance,
1233                                pNumSamples);
1234     }
1235 }
1236 #else
LVM_BufferOut(LVM_Handle_t hInstance,LVM_INT16 * pOutData,LVM_UINT16 * pNumSamples)1237 void LVM_BufferOut(LVM_Handle_t     hInstance,
1238                    LVM_INT16        *pOutData,
1239                    LVM_UINT16       *pNumSamples)
1240 {
1241 
1242     LVM_Instance_t    *pInstance  = (LVM_Instance_t  *)hInstance;
1243 
1244 
1245     /*
1246      * Check which mode, managed or unmanaged
1247      */
1248     if (pInstance->InstParams.BufferMode == LVM_MANAGED_BUFFERS)
1249     {
1250         LVM_BufferManagedOut(hInstance,
1251                              pOutData,
1252                              pNumSamples);
1253     }
1254     else
1255     {
1256         LVM_BufferUnmanagedOut(hInstance,
1257                                pNumSamples);
1258     }
1259 }
1260 #endif
1261