• 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 /*    Includes                                                                              */
21 /*                                                                                        */
22 /****************************************************************************************/
23 
24 #include "LVM_Private.h"
25 #include "VectorArithmetic.h"
26 
27 #include <log/log.h>
28 
29 /****************************************************************************************/
30 /*                                                                                      */
31 /* FUNCTION:                 LVM_BufferManagedIn                                        */
32 /*                                                                                      */
33 /* DESCRIPTION:                                                                         */
34 /*    Full buffer management allowing the user to provide input and output buffers on   */
35 /*  any alignment and with any number of samples. The alignment is corrected within     */
36 /*  the buffer management and the samples are grouped in to blocks of the correct size  */
37 /*  before processing.                                                                  */
38 /*                                                                                      */
39 /* PARAMETERS:                                                                          */
40 /*    hInstance        -    Instance handle                                             */
41 /*    pInData            -    Pointer to the input data stream                          */
42 /*  *pToProcess        -    Pointer to pointer to the start of data processing          */
43 /*  *pProcessed        -    Pointer to pointer to the destination of the processed data */
44 /*    pNumSamples        -    Pointer to the number of samples to process               */
45 /*                                                                                      */
46 /* RETURNS:                                                                             */
47 /*    None                                                                              */
48 /*                                                                                      */
49 /* NOTES:                                                                               */
50 /*                                                                                      */
51 /****************************************************************************************/
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, const LVM_FLOAT* pInData, LVM_FLOAT** pToProcess,
53                          LVM_FLOAT** pProcessed, LVM_UINT16* pNumSamples) {
54     LVM_INT16 SampleCount; /* Number of samples to be processed this call */
55     LVM_INT16 NumSamples;  /* Number of samples in scratch buffer */
56     LVM_FLOAT* pStart;
57     LVM_Instance_t* pInstance = (LVM_Instance_t*)hInstance;
58     LVM_Buffer_t* pBuffer;
59     LVM_FLOAT* pDest;
60     LVM_INT16 NumChannels = pInstance->NrChannels;
61 
62     /*
63      * Set the processing address pointers
64      */
65     pBuffer = pInstance->pBufferManagement;
66     pDest = pBuffer->pScratch;
67     *pToProcess = pBuffer->pScratch;
68     *pProcessed = pBuffer->pScratch;
69 
70     /*
71      * Check if it is the first call of a block
72      */
73     if (pInstance->SamplesToProcess == 0) {
74         /*
75          * First call for a new block of samples
76          */
77         pInstance->SamplesToProcess = (LVM_INT16)(*pNumSamples + pBuffer->InDelaySamples);
78         pInstance->pInputSamples = (LVM_FLOAT*)pInData;
79         pBuffer->BufferState = LVM_FIRSTCALL;
80     }
81     pStart = pInstance->pInputSamples; /* Pointer to the input samples */
82     pBuffer->SamplesToOutput = 0;      /* Samples to output is same as
83                                           number read for inplace processing */
84 
85     /*
86      * Calculate the number of samples to process this call and update the buffer state
87      */
88     if (pInstance->SamplesToProcess > pInstance->InternalBlockSize) {
89         /*
90          * Process the maximum bock size of samples.
91          */
92         SampleCount = pInstance->InternalBlockSize;
93         NumSamples = pInstance->InternalBlockSize;
94     } else {
95         /*
96          * Last call for the block, so calculate how many frames and samples to process
97          */
98         LVM_INT16 NumFrames;
99 
100         NumSamples = pInstance->SamplesToProcess;
101         NumFrames = (LVM_INT16)(NumSamples >> MIN_INTERNAL_BLOCKSHIFT);
102         SampleCount = (LVM_INT16)(NumFrames << MIN_INTERNAL_BLOCKSHIFT);
103 
104         /*
105          * Update the buffer state
106          */
107         if (pBuffer->BufferState == LVM_FIRSTCALL) {
108             pBuffer->BufferState = LVM_FIRSTLASTCALL;
109         } else {
110             pBuffer->BufferState = LVM_LASTCALL;
111         }
112     }
113     *pNumSamples = (LVM_UINT16)SampleCount; /* Set the number of samples to process this call */
114 
115     /*
116      * Copy samples from the delay buffer as required
117      */
118     if (((pBuffer->BufferState == LVM_FIRSTCALL) || (pBuffer->BufferState == LVM_FIRSTLASTCALL)) &&
119         (pBuffer->InDelaySamples != 0)) {
120         Copy_Float(&pBuffer->InDelayBuffer[0],                          /* Source */
121                    pDest,                                               /* Destination */
122                    (LVM_INT16)(NumChannels * pBuffer->InDelaySamples)); /* Number of delay \
123                                                                     samples, left and right */
124         NumSamples = (LVM_INT16)(NumSamples - pBuffer->InDelaySamples); /* Update sample count */
125         pDest += NumChannels * pBuffer->InDelaySamples; /* Update the destination pointer */
126     }
127 
128     /*
129      * Copy the rest of the samples for this call from the input buffer
130      */
131     if (NumSamples > 0) {
132         Copy_Float(pStart,                                 /* Source */
133                    pDest,                                  /* Destination */
134                    (LVM_INT16)(NumChannels * NumSamples)); /* Number of input samples */
135         pStart += NumChannels * NumSamples;                /* Update the input pointer */
136 
137         /*
138          * Update the input data pointer and samples to output
139          */
140         /* Update samples to output */
141         pBuffer->SamplesToOutput = (LVM_INT16)(pBuffer->SamplesToOutput + NumSamples);
142     }
143 
144     /*
145      * Update the sample count and input pointer
146      */
147     /* Update the count of samples */
148     pInstance->SamplesToProcess = (LVM_INT16)(pInstance->SamplesToProcess - SampleCount);
149     pInstance->pInputSamples = pStart; /* Update input sample pointer */
150 
151     /*
152      * Save samples to the delay buffer if any left unprocessed
153      */
154     if ((pBuffer->BufferState == LVM_FIRSTLASTCALL) || (pBuffer->BufferState == LVM_LASTCALL)) {
155         NumSamples = pInstance->SamplesToProcess;
156         pStart = pBuffer->pScratch;          /* Start of the buffer */
157         pStart += NumChannels * SampleCount; /* Offset by the number of processed samples */
158         if (NumSamples != 0) {
159             Copy_Float(pStart,                                 /* Source */
160                        &pBuffer->InDelayBuffer[0],             /* Destination */
161                        (LVM_INT16)(NumChannels * NumSamples)); /* Number of input samples */
162         }
163 
164         /*
165          * Update the delay sample count
166          */
167         pBuffer->InDelaySamples = NumSamples; /* Number of delay sample pairs */
168         pInstance->SamplesToProcess = 0;      /* All Samples used */
169     }
170 }
171 
172 /****************************************************************************************/
173 /*                                                                                      */
174 /* FUNCTION:                 LVM_BufferUnmanagedIn                                      */
175 /*                                                                                      */
176 /* DESCRIPTION:                                                                         */
177 /*    This mode is selected by the user code and disables the buffer management with the */
178 /*  exception of the maximum block size processing. The user must ensure that the       */
179 /*  input and output buffers are 32-bit aligned and also that the number of samples to  */
180 /*    process is a correct multiple of samples.                                         */
181 /*                                                                                      */
182 /* PARAMETERS:                                                                          */
183 /*    hInstance        -    Instance handle                                             */
184 /*  *pToProcess        -    Pointer to the start of data processing                     */
185 /*  *pProcessed        -    Pointer to the destination of the processed data            */
186 /*    pNumSamples        -    Pointer to the number of samples to process               */
187 /*                                                                                      */
188 /* RETURNS:                                                                             */
189 /*    None                                                                              */
190 /*                                                                                      */
191 /* NOTES:                                                                               */
192 /*                                                                                      */
193 /****************************************************************************************/
LVM_BufferUnmanagedIn(LVM_Handle_t hInstance,LVM_FLOAT ** pToProcess,LVM_FLOAT ** pProcessed,LVM_UINT16 * pNumSamples)194 void LVM_BufferUnmanagedIn(LVM_Handle_t hInstance, LVM_FLOAT** pToProcess, LVM_FLOAT** pProcessed,
195                            LVM_UINT16* pNumSamples) {
196     LVM_Instance_t* pInstance = (LVM_Instance_t*)hInstance;
197 
198     /*
199      * Check if this is the first call of a block
200      */
201     if (pInstance->SamplesToProcess == 0) {
202         pInstance->SamplesToProcess = (LVM_INT16)*pNumSamples; /* Get the number of samples
203                                                                             on first call */
204         pInstance->pInputSamples = *pToProcess;                /* Get the I/O pointers */
205         pInstance->pOutputSamples = *pProcessed;
206 
207         /*
208          * Set te block size to process
209          */
210         if (pInstance->SamplesToProcess > pInstance->InternalBlockSize) {
211             *pNumSamples = (LVM_UINT16)pInstance->InternalBlockSize;
212         } else {
213             *pNumSamples = (LVM_UINT16)pInstance->SamplesToProcess;
214         }
215     }
216 
217     /*
218      * Set the process pointers
219      */
220     *pToProcess = pInstance->pInputSamples;
221     *pProcessed = pInstance->pOutputSamples;
222 }
223 
224 /****************************************************************************************/
225 /*                                                                                      */
226 /* FUNCTION:                 LVM_BufferOptimisedIn                                      */
227 /*                                                                                      */
228 /* DESCRIPTION:                                                                         */
229 /*    Optimised buffer management for the case where the data is outplace processing,   */
230 /*    the output data is 32-bit aligned and there are sufficient samples to allow some  */
231 /*    processing directly in the output buffer. This saves one data copy per sample     */
232 /*    compared with the unoptimsed version.                                             */
233 /*                                                                                      */
234 /* PARAMETERS:                                                                          */
235 /*    hInstance        -    Instance handle                                             */
236 /*    pInData            -    Pointer to the input data stream                          */
237 /*  *pToProcess        -    Pointer to the start of data processing                     */
238 /*  *pProcessed        -    Pointer to the destination of the processed data            */
239 /*    pNumSamples        -    Pointer to the number of samples to process               */
240 /*                                                                                      */
241 /* RETURNS:                                                                             */
242 /*    None                                                                              */
243 /*                                                                                      */
244 /* NOTES:                                                                               */
245 /*                                                                                      */
246 /****************************************************************************************/
247 
248 /****************************************************************************************/
249 /*                                                                                      */
250 /* FUNCTION:                 LVM_BufferIn                                               */
251 /*                                                                                      */
252 /* DESCRIPTION:                                                                         */
253 /*    This function manages the data input, it has the following features:              */
254 /*        - Accepts data in 16-bit aligned memory                                       */
255 /*        - Copies the data to 32-bit aligned memory                                    */
256 /*        - Converts Mono inputs to Mono-in-Stereo                                      */
257 /*        - Accepts any number of samples as input, except 0                            */
258 /*        - Breaks the input sample stream in to blocks of the configured frame size or */
259 /*          multiples of the frame size                                                 */
260 /*        - Limits the processing block size to the maximum block size.                 */
261 /*        - Works with inplace or outplace processing automatically                     */
262 /*                                                                                      */
263 /*  To manage the data the function has a number of operating states:                   */
264 /*        LVM_FIRSTCALL        - The first call for this block of input samples         */
265 /*        LVM_MAXBLOCKCALL    - The current block is the maximum size. Only used for the */
266 /*                              second and subsequent blocks.                           */
267 /*        LVM_LASTCALL        - The last call for this block of input samples           */
268 /*        LVM_FIRSTLASTCALL    - This is the first and last call for this block of input*/
269 /*                              samples, this occurs when the number of samples to      */
270 /*                              process is less than the maximum block size.            */
271 /*                                                                                      */
272 /*    The function uses an internal delay buffer the size of the minimum frame, this is */
273 /*  used to temporarily hold samples when the number of samples to process is not a     */
274 /*  multiple of the frame size.                                                         */
275 /*                                                                                      */
276 /*    To ensure correct operation with inplace buffering the number of samples to output*/
277 /*  per call is calculated in this function and is set to the number of samples read    */
278 /*  from the input buffer.                                                              */
279 /*                                                                                      */
280 /*    The total number of samples to process is stored when the function is called for  */
281 /*  the first time. The value is overwritten by the size of the block to be processed   */
282 /*  in each call so the size of the processing blocks can be controlled. The number of  */
283 /*    samples actually processed for each block of input samples is always a multiple of*/
284 /*  the frame size so for any particular block of input samples the actual number of    */
285 /*  processed samples may not match the number of input samples, sometime it will be    */
286 /*  sometimes less. The average is the same and the difference is never more than the   */
287 /*  frame size.                                                                         */
288 /*                                                                                      */
289 /* PARAMETERS:                                                                          */
290 /*    hInstance        -    Instance handle                                             */
291 /*    pInData            -    Pointer to the input data stream                          */
292 /*  *pToProcess        -    Pointer to the start of data processing                     */
293 /*  *pProcessed        -    Pointer to the destination of the processed data            */
294 /*    pNumSamples        -    Pointer to the number of samples to process               */
295 /*                                                                                      */
296 /* RETURNS:                                                                             */
297 /*    None                                                                              */
298 /*                                                                                      */
299 /* NOTES:                                                                               */
300 /*                                                                                      */
301 /****************************************************************************************/
LVM_BufferIn(LVM_Handle_t hInstance,const LVM_FLOAT * pInData,LVM_FLOAT ** pToProcess,LVM_FLOAT ** pProcessed,LVM_UINT16 * pNumSamples)302 void LVM_BufferIn(LVM_Handle_t hInstance, const LVM_FLOAT* pInData, LVM_FLOAT** pToProcess,
303                   LVM_FLOAT** pProcessed, LVM_UINT16* pNumSamples) {
304     LVM_Instance_t* pInstance = (LVM_Instance_t*)hInstance;
305 
306     /*
307      * Check which mode, managed or unmanaged
308      */
309     if (pInstance->InstParams.BufferMode == LVM_MANAGED_BUFFERS) {
310         LVM_BufferManagedIn(hInstance, pInData, pToProcess, pProcessed, pNumSamples);
311     } else {
312         LVM_BufferUnmanagedIn(hInstance, pToProcess, pProcessed, pNumSamples);
313     }
314 }
315 /****************************************************************************************/
316 /*                                                                                      */
317 /* FUNCTION:                 LVM_BufferManagedOut                                       */
318 /*                                                                                      */
319 /* DESCRIPTION:                                                                         */
320 /*  Full buffer management output. This works in conjunction with the managed input     */
321 /*  routine and ensures the correct number of samples are always output to the output   */
322 /*  buffer.                                                                             */
323 /*                                                                                      */
324 /* PARAMETERS:                                                                          */
325 /*    hInstance        - Instance handle                                                */
326 /*    pOutData        - Pointer to the output data stream                               */
327 /*    pNumSamples        - Pointer to the number of samples to process                  */
328 /*                                                                                      */
329 /* RETURNS:                                                                             */
330 /*    None                                                                              */
331 /*                                                                                      */
332 /* NOTES:                                                                               */
333 /*                                                                                      */
334 /****************************************************************************************/
LVM_BufferManagedOut(LVM_Handle_t hInstance,LVM_FLOAT * pOutData,LVM_UINT16 * pNumSamples)335 void LVM_BufferManagedOut(LVM_Handle_t hInstance, LVM_FLOAT* pOutData, LVM_UINT16* pNumSamples) {
336     LVM_Instance_t* pInstance = (LVM_Instance_t*)hInstance;
337     LVM_Buffer_t* pBuffer = pInstance->pBufferManagement;
338     LVM_INT16 SampleCount = (LVM_INT16)*pNumSamples;
339     LVM_INT16 NumSamples;
340     LVM_FLOAT* pStart;
341     LVM_FLOAT* pDest;
342     LVM_INT32 NrChannels = pInstance->NrChannels;
343 #define NrFrames NumSamples  // alias for clarity
344 #define FrameCount SampleCount
345 
346     /*
347      * Set the pointers
348      */
349     NumSamples = pBuffer->SamplesToOutput;
350     pStart = pBuffer->pScratch;
351 
352     /*
353      * check if it is the first call of a block
354      */
355     if ((pBuffer->BufferState == LVM_FIRSTCALL) || (pBuffer->BufferState == LVM_FIRSTLASTCALL)) {
356         /* First call for a new block */
357         pInstance->pOutputSamples = pOutData; /* Initialise the destination */
358     }
359     pDest = pInstance->pOutputSamples; /* Set the output address */
360 
361     /*
362      * If the number of samples is non-zero then there are still samples to send to
363      * the output buffer
364      */
365     if ((NumSamples != 0) && (pBuffer->OutDelaySamples != 0)) {
366         /*
367          * Copy the delayed output buffer samples to the output
368          */
369         if (pBuffer->OutDelaySamples <= NumSamples) {
370             /*
371              * Copy all output delay samples to the output
372              */
373             Copy_Float(&pBuffer->OutDelayBuffer[0], /* Source */
374                        pDest,                       /* Destination */
375                        /* Number of delay samples */
376                        (LVM_INT16)(NrChannels * pBuffer->OutDelaySamples));
377 
378             /*
379              * Update the pointer and sample counts
380              */
381             pDest += NrChannels * pBuffer->OutDelaySamples; /* Output sample pointer */
382             NumSamples = (LVM_INT16)(NumSamples - pBuffer->OutDelaySamples); /* Samples left \
383                                                                                 to send */
384             pBuffer->OutDelaySamples = 0; /* No samples left in the buffer */
385         } else {
386             /*
387              * Copy only some of the output delay samples to the output
388              */
389             Copy_Float(&pBuffer->OutDelayBuffer[0],         /* Source */
390                        pDest,                               /* Destination */
391                        (LVM_INT16)(NrChannels * NrFrames)); /* Number of delay samples */
392 
393             /*
394              * Update the pointer and sample counts
395              */
396             pDest += NrChannels * NrFrames; /* Output sample pointer */
397             /* No samples left in the buffer */
398             pBuffer->OutDelaySamples = (LVM_INT16)(pBuffer->OutDelaySamples - NumSamples);
399 
400             /*
401              * Realign the delay buffer data to avoid using circular buffer management
402              */
403             Copy_Float(&pBuffer->OutDelayBuffer[NrChannels * NrFrames], /* Source */
404                        &pBuffer->OutDelayBuffer[0],                     /* Destination */
405                        /* Number of samples to move */
406                        (LVM_INT16)(NrChannels * pBuffer->OutDelaySamples));
407             NumSamples = 0; /* Samples left to send */
408         }
409     }
410 
411     /*
412      * Copy the processed results to the output
413      */
414     if ((NumSamples != 0) && (SampleCount != 0)) {
415         if (SampleCount <= NumSamples) {
416             /*
417              * Copy all processed samples to the output
418              */
419             Copy_Float(pStart,                                /* Source */
420                        pDest,                                 /* Destination */
421                        (LVM_INT16)(NrChannels * FrameCount)); /* Number of processed samples */
422             /*
423              * Update the pointer and sample counts
424              */
425             pDest += NrChannels * FrameCount;                   /* Output sample pointer */
426             NumSamples = (LVM_INT16)(NumSamples - SampleCount); /* Samples left to send */
427             SampleCount = 0;                                    /* No samples left in the buffer */
428         } else {
429             /*
430              * Copy only some processed samples to the output
431              */
432             Copy_Float(pStart,                              /* Source */
433                        pDest,                               /* Destination */
434                        (LVM_INT16)(NrChannels * NrFrames)); /* Number of processed samples */
435             /*
436              * Update the pointers and sample counts
437              */
438             pStart += NrChannels * NrFrames;                     /* Processed sample pointer */
439             pDest += NrChannels * NrFrames;                      /* Output sample pointer */
440             SampleCount = (LVM_INT16)(SampleCount - NumSamples); /* Processed samples left */
441             NumSamples = 0;                                      /* Clear the sample count */
442         }
443     }
444 
445     /*
446      * Copy the remaining processed data to the output delay buffer
447      */
448     if (SampleCount != 0) {
449         Copy_Float(pStart, /* Source */
450                    /* Destination */
451                    &pBuffer->OutDelayBuffer[NrChannels * pBuffer->OutDelaySamples],
452                    (LVM_INT16)(NrChannels * FrameCount)); /* Number of processed samples */
453         /* Update the buffer count */
454         pBuffer->OutDelaySamples = (LVM_INT16)(pBuffer->OutDelaySamples + SampleCount);
455     }
456 
457     /*
458      * pointers, counts and set default buffer processing
459      */
460     pBuffer->SamplesToOutput = NumSamples;   /* Samples left to send */
461     pInstance->pOutputSamples = pDest;       /* Output sample pointer */
462     pBuffer->BufferState = LVM_MAXBLOCKCALL; /* Set for the default call \
463                                                      block size */
464     /* This will terminate the loop when all samples processed */
465     *pNumSamples = (LVM_UINT16)pInstance->SamplesToProcess;
466 }
467 
468 /****************************************************************************************/
469 /*                                                                                      */
470 /* FUNCTION:                 LVM_BufferUnmanagedOut                                     */
471 /*                                                                                      */
472 /* DESCRIPTION:                                                                         */
473 /*  This works in conjunction with the unmanaged input routine and updates the number   */
474 /*    of samples left to be processed    and adjusts the buffer pointers.               */
475 /*                                                                                      */
476 /* PARAMETERS:                                                                          */
477 /*    hInstance        - Instance handle                                                */
478 /*    pNumSamples        - Pointer to the number of samples to process                  */
479 /*                                                                                      */
480 /* RETURNS:                                                                             */
481 /*    None                                                                              */
482 /*                                                                                      */
483 /* NOTES:                                                                               */
484 /*                                                                                      */
485 /****************************************************************************************/
486 
LVM_BufferUnmanagedOut(LVM_Handle_t hInstance,LVM_UINT16 * pNumSamples)487 void LVM_BufferUnmanagedOut(LVM_Handle_t hInstance, LVM_UINT16* pNumSamples) {
488     LVM_Instance_t* pInstance = (LVM_Instance_t*)hInstance;
489     LVM_INT16 NumChannels = pInstance->NrChannels;
490 #undef NrFrames
491 #define NrFrames (*pNumSamples)  // alias for clarity
492 
493     /*
494      * Update sample counts
495      */
496     pInstance->pInputSamples +=
497             (LVM_INT16)(*pNumSamples * NumChannels); /* Update the I/O pointers */
498     pInstance->pOutputSamples += (LVM_INT16)(NrFrames * NumChannels);
499     pInstance->SamplesToProcess =
500             (LVM_INT16)(pInstance->SamplesToProcess - *pNumSamples); /* Update the sample count */
501 
502     /*
503      * Set te block size to process
504      */
505     if (pInstance->SamplesToProcess > pInstance->InternalBlockSize) {
506         *pNumSamples = (LVM_UINT16)pInstance->InternalBlockSize;
507     } else {
508         *pNumSamples = (LVM_UINT16)pInstance->SamplesToProcess;
509     }
510 }
511 
512 /****************************************************************************************/
513 /*                                                                                      */
514 /* FUNCTION:                 LVM_BufferOptimisedOut                                     */
515 /*                                                                                      */
516 /* DESCRIPTION:                                                                         */
517 /*  This works in conjunction with the optimised input routine and copies the last few  */
518 /*  processed and unprocessed samples to their respective buffers.                      */
519 /*                                                                                      */
520 /* PARAMETERS:                                                                          */
521 /*    hInstance        - Instance handle                                                */
522 /*    pNumSamples        - Pointer to the number of samples to process                  */
523 /*                                                                                      */
524 /* RETURNS:                                                                             */
525 /*    None                                                                              */
526 /*                                                                                      */
527 /* NOTES:                                                                               */
528 /*                                                                                      */
529 /****************************************************************************************/
530 
531 /****************************************************************************************/
532 /*                                                                                      */
533 /* FUNCTION:                 LVM_BufferOut                                              */
534 /*                                                                                      */
535 /* DESCRIPTION:                                                                         */
536 /*  This function manages the data output, it has the following features:               */
537 /*        - Output data to 16-bit aligned memory                                        */
538 /*        - Reads data from 32-bit aligned memory                                       */
539 /*        - Reads data only in blocks of frame size or multiples of frame size          */
540 /*        - Writes the same number of samples as the LVM_BufferIn function reads        */
541 /*        - Works with inplace or outplace processing automatically                     */
542 /*                                                                                      */
543 /*  To manage the data the function has a number of operating states:                   */
544 /*        LVM_FIRSTCALL        - The first call for this block of input samples         */
545 /*        LVM_FIRSTLASTCALL    - This is the first and last call for this block of input*/
546 /*                              samples, this occurs when the number of samples to      */
547 /*                              process is less than the maximum block size.            */
548 /*                                                                                      */
549 /*    The function uses an internal delay buffer the size of the minimum frame, this is */
550 /*  used to temporarily hold samples when the number of samples to write is not a       */
551 /*  multiple of the frame size.                                                         */
552 /*                                                                                      */
553 /*    To ensure correct operation with inplace buffering the number of samples to output*/
554 /*  per call is always the same as the number of samples read from the input buffer.    */
555 /*                                                                                      */
556 /* PARAMETERS:                                                                          */
557 /*    hInstance        - Instance handle                                                */
558 /*    pOutData        - Pointer to the output data stream                               */
559 /*    pNumSamples        - Pointer to the number of samples to process                  */
560 /*                                                                                      */
561 /* RETURNS:                                                                             */
562 /*    None                                                                              */
563 /*                                                                                      */
564 /* NOTES:                                                                               */
565 /*                                                                                      */
566 /****************************************************************************************/
LVM_BufferOut(LVM_Handle_t hInstance,LVM_FLOAT * pOutData,LVM_UINT16 * pNumSamples)567 void LVM_BufferOut(LVM_Handle_t hInstance, LVM_FLOAT* pOutData, LVM_UINT16* pNumSamples) {
568     LVM_Instance_t* pInstance = (LVM_Instance_t*)hInstance;
569 
570     /*
571      * Check which mode, managed or unmanaged
572      */
573     if (pInstance->InstParams.BufferMode == LVM_MANAGED_BUFFERS) {
574         LVM_BufferManagedOut(hInstance, pOutData, pNumSamples);
575     } else {
576         LVM_BufferUnmanagedOut(hInstance, pNumSamples);
577     }
578 }
579