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,
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 #ifdef SUPPORT_MC
66 LVM_INT16 NumChannels = pInstance->NrChannels;
67 #else
68 LVM_INT16 NumChannels = 2;
69 #endif
70
71 /*
72 * Set the processing address pointers
73 */
74 pBuffer = pInstance->pBufferManagement;
75 pDest = pBuffer->pScratch;
76 *pToProcess = pBuffer->pScratch;
77 *pProcessed = pBuffer->pScratch;
78
79 /*
80 * Check if it is the first call of a block
81 */
82 if (pInstance->SamplesToProcess == 0)
83 {
84 /*
85 * First call for a new block of samples
86 */
87 pInstance->SamplesToProcess = (LVM_INT16)(*pNumSamples + pBuffer->InDelaySamples);
88 pInstance->pInputSamples = (LVM_FLOAT *)pInData;
89 pBuffer->BufferState = LVM_FIRSTCALL;
90 }
91 pStart = pInstance->pInputSamples; /* Pointer to the input samples */
92 pBuffer->SamplesToOutput = 0; /* Samples to output is same as
93 number read for inplace processing */
94
95 /*
96 * Calculate the number of samples to process this call and update the buffer state
97 */
98 if (pInstance->SamplesToProcess > pInstance->InternalBlockSize)
99 {
100 /*
101 * Process the maximum bock size of samples.
102 */
103 SampleCount = pInstance->InternalBlockSize;
104 NumSamples = pInstance->InternalBlockSize;
105 }
106 else
107 {
108 /*
109 * Last call for the block, so calculate how many frames and samples to process
110 */
111 LVM_INT16 NumFrames;
112
113 NumSamples = pInstance->SamplesToProcess;
114 NumFrames = (LVM_INT16)(NumSamples >> MIN_INTERNAL_BLOCKSHIFT);
115 SampleCount = (LVM_INT16)(NumFrames << MIN_INTERNAL_BLOCKSHIFT);
116
117 /*
118 * Update the buffer state
119 */
120 if (pBuffer->BufferState == LVM_FIRSTCALL)
121 {
122 pBuffer->BufferState = LVM_FIRSTLASTCALL;
123 }
124 else
125 {
126 pBuffer->BufferState = LVM_LASTCALL;
127 }
128 }
129 *pNumSamples = (LVM_UINT16)SampleCount; /* Set the number of samples to process this call */
130
131 /*
132 * Copy samples from the delay buffer as required
133 */
134 if (((pBuffer->BufferState == LVM_FIRSTCALL) ||
135 (pBuffer->BufferState == LVM_FIRSTLASTCALL)) &&
136 (pBuffer->InDelaySamples != 0))
137 {
138 Copy_Float(&pBuffer->InDelayBuffer[0], /* Source */
139 pDest, /* Destination */
140 (LVM_INT16)(NumChannels * pBuffer->InDelaySamples)); /* Number of delay \
141 samples, left and right */
142 NumSamples = (LVM_INT16)(NumSamples - pBuffer->InDelaySamples); /* Update sample count */
143 pDest += NumChannels * pBuffer->InDelaySamples; /* Update the destination pointer */
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 * Update the sample count and input pointer
165 */
166 /* Update the count of samples */
167 pInstance->SamplesToProcess = (LVM_INT16)(pInstance->SamplesToProcess - SampleCount);
168 pInstance->pInputSamples = pStart; /* Update input sample pointer */
169
170 /*
171 * Save samples to the delay buffer if any left unprocessed
172 */
173 if ((pBuffer->BufferState == LVM_FIRSTLASTCALL) ||
174 (pBuffer->BufferState == LVM_LASTCALL))
175 {
176 NumSamples = pInstance->SamplesToProcess;
177 pStart = pBuffer->pScratch; /* Start of the buffer */
178 pStart += NumChannels * SampleCount; /* Offset by the number of processed samples */
179 if (NumSamples != 0)
180 {
181 Copy_Float(pStart, /* Source */
182 &pBuffer->InDelayBuffer[0], /* Destination */
183 (LVM_INT16)(NumChannels * NumSamples)); /* Number of input samples */
184 }
185
186 /*
187 * Update the delay sample count
188 */
189 pBuffer->InDelaySamples = NumSamples; /* Number of delay sample pairs */
190 pInstance->SamplesToProcess = 0; /* All Samples used */
191 }
192 }
193
194 /****************************************************************************************/
195 /* */
196 /* FUNCTION: LVM_BufferUnmanagedIn */
197 /* */
198 /* DESCRIPTION: */
199 /* This mode is selected by the user code and disables the buffer management with the */
200 /* exception of the maximum block size processing. The user must ensure that the */
201 /* input and output buffers are 32-bit aligned and also that the number of samples to */
202 /* process is a correct multiple of samples. */
203 /* */
204 /* PARAMETERS: */
205 /* hInstance - Instance handle */
206 /* *pToProcess - Pointer to the start of data processing */
207 /* *pProcessed - Pointer to the destination of the processed data */
208 /* pNumSamples - Pointer to the number of samples to process */
209 /* */
210 /* RETURNS: */
211 /* None */
212 /* */
213 /* NOTES: */
214 /* */
215 /****************************************************************************************/
LVM_BufferUnmanagedIn(LVM_Handle_t hInstance,LVM_FLOAT ** pToProcess,LVM_FLOAT ** pProcessed,LVM_UINT16 * pNumSamples)216 void LVM_BufferUnmanagedIn(LVM_Handle_t hInstance,
217 LVM_FLOAT **pToProcess,
218 LVM_FLOAT **pProcessed,
219 LVM_UINT16 *pNumSamples)
220 {
221
222 LVM_Instance_t *pInstance = (LVM_Instance_t *)hInstance;
223
224 /*
225 * Check if this is the first call of a block
226 */
227 if (pInstance->SamplesToProcess == 0)
228 {
229 pInstance->SamplesToProcess = (LVM_INT16)*pNumSamples; /* Get the number of samples
230 on first call */
231 pInstance->pInputSamples = *pToProcess; /* Get the I/O pointers */
232 pInstance->pOutputSamples = *pProcessed;
233
234 /*
235 * Set te block size to process
236 */
237 if (pInstance->SamplesToProcess > pInstance->InternalBlockSize)
238 {
239 *pNumSamples = (LVM_UINT16)pInstance->InternalBlockSize;
240 }
241 else
242 {
243 *pNumSamples = (LVM_UINT16)pInstance->SamplesToProcess;
244 }
245 }
246
247 /*
248 * Set the process pointers
249 */
250 *pToProcess = pInstance->pInputSamples;
251 *pProcessed = pInstance->pOutputSamples;
252 }
253
254 /****************************************************************************************/
255 /* */
256 /* FUNCTION: LVM_BufferOptimisedIn */
257 /* */
258 /* DESCRIPTION: */
259 /* Optimised buffer management for the case where the data is outplace processing, */
260 /* the output data is 32-bit aligned and there are sufficient samples to allow some */
261 /* processing directly in the output buffer. This saves one data copy per sample */
262 /* compared with the unoptimsed version. */
263 /* */
264 /* PARAMETERS: */
265 /* hInstance - Instance handle */
266 /* pInData - Pointer to the input data stream */
267 /* *pToProcess - Pointer to the start of data processing */
268 /* *pProcessed - Pointer to the destination of the processed data */
269 /* pNumSamples - Pointer to the number of samples to process */
270 /* */
271 /* RETURNS: */
272 /* None */
273 /* */
274 /* NOTES: */
275 /* */
276 /****************************************************************************************/
277
278 /****************************************************************************************/
279 /* */
280 /* FUNCTION: LVM_BufferIn */
281 /* */
282 /* DESCRIPTION: */
283 /* This function manages the data input, it has the following features: */
284 /* - Accepts data in 16-bit aligned memory */
285 /* - Copies the data to 32-bit aligned memory */
286 /* - Converts Mono inputs to Mono-in-Stereo */
287 /* - Accepts any number of samples as input, except 0 */
288 /* - Breaks the input sample stream in to blocks of the configured frame size or */
289 /* multiples of the frame size */
290 /* - Limits the processing block size to the maximum block size. */
291 /* - Works with inplace or outplace processing automatically */
292 /* */
293 /* To manage the data the function has a number of operating states: */
294 /* LVM_FIRSTCALL - The first call for this block of input samples */
295 /* LVM_MAXBLOCKCALL - The current block is the maximum size. Only used for the */
296 /* second and subsequent blocks. */
297 /* LVM_LASTCALL - The last call for this block of input samples */
298 /* LVM_FIRSTLASTCALL - This is the first and last call for this block of input*/
299 /* samples, this occurs when the number of samples to */
300 /* process is less than the maximum block size. */
301 /* */
302 /* The function uses an internal delay buffer the size of the minimum frame, this is */
303 /* used to temporarily hold samples when the number of samples to process is not a */
304 /* multiple of the frame size. */
305 /* */
306 /* To ensure correct operation with inplace buffering the number of samples to output*/
307 /* per call is calculated in this function and is set to the number of samples read */
308 /* from the input buffer. */
309 /* */
310 /* The total number of samples to process is stored when the function is called for */
311 /* the first time. The value is overwritten by the size of the block to be processed */
312 /* in each call so the size of the processing blocks can be controlled. The number of */
313 /* samples actually processed for each block of input samples is always a multiple of*/
314 /* the frame size so for any particular block of input samples the actual number of */
315 /* processed samples may not match the number of input samples, sometime it will be */
316 /* sometimes less. The average is the same and the difference is never more than the */
317 /* frame size. */
318 /* */
319 /* PARAMETERS: */
320 /* hInstance - Instance handle */
321 /* pInData - Pointer to the input data stream */
322 /* *pToProcess - Pointer to the start of data processing */
323 /* *pProcessed - Pointer to the destination of the processed data */
324 /* pNumSamples - Pointer to the number of samples to process */
325 /* */
326 /* RETURNS: */
327 /* None */
328 /* */
329 /* NOTES: */
330 /* */
331 /****************************************************************************************/
LVM_BufferIn(LVM_Handle_t hInstance,const LVM_FLOAT * pInData,LVM_FLOAT ** pToProcess,LVM_FLOAT ** pProcessed,LVM_UINT16 * pNumSamples)332 void LVM_BufferIn(LVM_Handle_t hInstance,
333 const LVM_FLOAT *pInData,
334 LVM_FLOAT **pToProcess,
335 LVM_FLOAT **pProcessed,
336 LVM_UINT16 *pNumSamples)
337 {
338
339 LVM_Instance_t *pInstance = (LVM_Instance_t *)hInstance;
340
341 /*
342 * Check which mode, managed or unmanaged
343 */
344 if (pInstance->InstParams.BufferMode == LVM_MANAGED_BUFFERS)
345 {
346 LVM_BufferManagedIn(hInstance,
347 pInData,
348 pToProcess,
349 pProcessed,
350 pNumSamples);
351 }
352 else
353 {
354 LVM_BufferUnmanagedIn(hInstance,
355 pToProcess,
356 pProcessed,
357 pNumSamples);
358 }
359 }
360 /****************************************************************************************/
361 /* */
362 /* FUNCTION: LVM_BufferManagedOut */
363 /* */
364 /* DESCRIPTION: */
365 /* Full buffer management output. This works in conjunction with the managed input */
366 /* routine and ensures the correct number of samples are always output to the output */
367 /* buffer. */
368 /* */
369 /* PARAMETERS: */
370 /* hInstance - Instance handle */
371 /* pOutData - Pointer to the output data stream */
372 /* pNumSamples - Pointer to the number of samples to process */
373 /* */
374 /* RETURNS: */
375 /* None */
376 /* */
377 /* NOTES: */
378 /* */
379 /****************************************************************************************/
LVM_BufferManagedOut(LVM_Handle_t hInstance,LVM_FLOAT * pOutData,LVM_UINT16 * pNumSamples)380 void LVM_BufferManagedOut(LVM_Handle_t hInstance,
381 LVM_FLOAT *pOutData,
382 LVM_UINT16 *pNumSamples)
383 {
384
385 LVM_Instance_t *pInstance = (LVM_Instance_t *)hInstance;
386 LVM_Buffer_t *pBuffer = pInstance->pBufferManagement;
387 LVM_INT16 SampleCount = (LVM_INT16)*pNumSamples;
388 LVM_INT16 NumSamples;
389 LVM_FLOAT *pStart;
390 LVM_FLOAT *pDest;
391 #ifdef SUPPORT_MC
392 LVM_INT32 NrChannels = pInstance->NrChannels;
393 #define NrFrames NumSamples // alias for clarity
394 #define FrameCount SampleCount
395 #endif
396
397 /*
398 * Set the pointers
399 */
400 NumSamples = pBuffer->SamplesToOutput;
401 pStart = pBuffer->pScratch;
402
403 /*
404 * check if it is the first call of a block
405 */
406 if ((pBuffer->BufferState == LVM_FIRSTCALL) ||
407 (pBuffer->BufferState == LVM_FIRSTLASTCALL))
408 {
409 /* First call for a new block */
410 pInstance->pOutputSamples = pOutData; /* Initialise the destination */
411 }
412 pDest = pInstance->pOutputSamples; /* Set the output address */
413
414 /*
415 * If the number of samples is non-zero then there are still samples to send to
416 * the output buffer
417 */
418 if ((NumSamples != 0) &&
419 (pBuffer->OutDelaySamples != 0))
420 {
421 /*
422 * Copy the delayed output buffer samples to the output
423 */
424 if (pBuffer->OutDelaySamples <= NumSamples)
425 {
426 /*
427 * Copy all output delay samples to the output
428 */
429 #ifdef SUPPORT_MC
430 Copy_Float(&pBuffer->OutDelayBuffer[0], /* Source */
431 pDest, /* Destination */
432 /* Number of delay samples */
433 (LVM_INT16)(NrChannels * pBuffer->OutDelaySamples));
434 #else
435 Copy_Float(&pBuffer->OutDelayBuffer[0], /* Source */
436 pDest, /* Destination */
437 (LVM_INT16)(2 * pBuffer->OutDelaySamples)); /* Number of delay samples */
438 #endif
439
440 /*
441 * Update the pointer and sample counts
442 */
443 #ifdef SUPPORT_MC
444 pDest += NrChannels * pBuffer->OutDelaySamples; /* Output sample pointer */
445 #else
446 pDest += 2 * pBuffer->OutDelaySamples; /* Output sample pointer */
447 #endif
448 NumSamples = (LVM_INT16)(NumSamples - pBuffer->OutDelaySamples); /* Samples left \
449 to send */
450 pBuffer->OutDelaySamples = 0; /* No samples left in the buffer */
451 }
452 else
453 {
454 /*
455 * Copy only some of the ouput delay samples to the output
456 */
457 #ifdef SUPPORT_MC
458 Copy_Float(&pBuffer->OutDelayBuffer[0], /* Source */
459 pDest, /* Destination */
460 (LVM_INT16)(NrChannels * NrFrames)); /* Number of delay samples */
461 #else
462 Copy_Float(&pBuffer->OutDelayBuffer[0], /* Source */
463 pDest, /* Destination */
464 (LVM_INT16)(2 * NumSamples)); /* Number of delay samples */
465 #endif
466
467 /*
468 * Update the pointer and sample counts
469 */
470 #ifdef SUPPORT_MC
471 pDest += NrChannels * NrFrames; /* Output sample pointer */
472 #else
473 pDest += 2 * NumSamples; /* Output sample pointer */
474 #endif
475 /* No samples left in the buffer */
476 pBuffer->OutDelaySamples = (LVM_INT16)(pBuffer->OutDelaySamples - NumSamples);
477
478 /*
479 * Realign the delay buffer data to avoid using circular buffer management
480 */
481 #ifdef SUPPORT_MC
482 Copy_Float(&pBuffer->OutDelayBuffer[NrChannels * NrFrames], /* Source */
483 &pBuffer->OutDelayBuffer[0], /* Destination */
484 /* Number of samples to move */
485 (LVM_INT16)(NrChannels * pBuffer->OutDelaySamples));
486 #else
487 Copy_Float(&pBuffer->OutDelayBuffer[2 * NumSamples], /* Source */
488 &pBuffer->OutDelayBuffer[0], /* Destination */
489 (LVM_INT16)(2 * pBuffer->OutDelaySamples)); /* Number of samples to move */
490 #endif
491 NumSamples = 0; /* Samples left to send */
492 }
493 }
494
495 /*
496 * Copy the processed results to the output
497 */
498 if ((NumSamples != 0) &&
499 (SampleCount != 0))
500 {
501 if (SampleCount <= NumSamples)
502 {
503 /*
504 * Copy all processed samples to the output
505 */
506 #ifdef SUPPORT_MC
507 Copy_Float(pStart, /* Source */
508 pDest, /* Destination */
509 (LVM_INT16)(NrChannels * FrameCount)); /* Number of processed samples */
510 #else
511 Copy_Float(pStart, /* Source */
512 pDest, /* Destination */
513 (LVM_INT16)(2 * SampleCount)); /* Number of processed samples */
514 #endif
515 /*
516 * Update the pointer and sample counts
517 */
518 #ifdef SUPPORT_MC
519 pDest += NrChannels * FrameCount; /* Output sample pointer */
520 #else
521 pDest += 2 * SampleCount; /* Output sample pointer */
522 #endif
523 NumSamples = (LVM_INT16)(NumSamples - SampleCount); /* Samples left to send */
524 SampleCount = 0; /* No samples left in the buffer */
525 }
526 else
527 {
528 /*
529 * Copy only some processed samples to the output
530 */
531 #ifdef SUPPORT_MC
532 Copy_Float(pStart, /* Source */
533 pDest, /* Destination */
534 (LVM_INT16)(NrChannels * NrFrames)); /* Number of processed samples */
535 #else
536 Copy_Float(pStart, /* Source */
537 pDest, /* Destination */
538 (LVM_INT16)(2 * NumSamples)); /* Number of processed samples */
539 #endif
540 /*
541 * Update the pointers and sample counts
542 */
543 #ifdef SUPPORT_MC
544 pStart += NrChannels * NrFrames; /* Processed sample pointer */
545 pDest += NrChannels * NrFrames; /* Output sample pointer */
546 #else
547 pStart += 2 * NumSamples; /* Processed sample pointer */
548 pDest += 2 * NumSamples; /* Output sample pointer */
549 #endif
550 SampleCount = (LVM_INT16)(SampleCount - NumSamples); /* Processed samples left */
551 NumSamples = 0; /* Clear the sample count */
552 }
553 }
554
555 /*
556 * Copy the remaining processed data to the output delay buffer
557 */
558 if (SampleCount != 0)
559 {
560 #ifdef SUPPORT_MC
561 Copy_Float(pStart, /* Source */
562 /* Destination */
563 &pBuffer->OutDelayBuffer[NrChannels * pBuffer->OutDelaySamples],
564 (LVM_INT16)(NrChannels * FrameCount)); /* Number of processed samples */
565 #else
566 Copy_Float(pStart, /* Source */
567 &pBuffer->OutDelayBuffer[2 * pBuffer->OutDelaySamples], /* Destination */
568 (LVM_INT16)(2 * SampleCount)); /* Number of processed samples */
569 #endif
570 /* Update the buffer count */
571 pBuffer->OutDelaySamples = (LVM_INT16)(pBuffer->OutDelaySamples + SampleCount);
572 }
573
574 /*
575 * pointers, counts and set default buffer processing
576 */
577 pBuffer->SamplesToOutput = NumSamples; /* Samples left to send */
578 pInstance->pOutputSamples = pDest; /* Output sample pointer */
579 pBuffer->BufferState = LVM_MAXBLOCKCALL; /* Set for the default call \
580 block size */
581 /* This will terminate the loop when all samples processed */
582 *pNumSamples = (LVM_UINT16)pInstance->SamplesToProcess;
583 }
584
585 /****************************************************************************************/
586 /* */
587 /* FUNCTION: LVM_BufferUnmanagedOut */
588 /* */
589 /* DESCRIPTION: */
590 /* This works in conjunction with the unmanaged input routine and updates the number */
591 /* of samples left to be processed and adjusts the buffer pointers. */
592 /* */
593 /* PARAMETERS: */
594 /* hInstance - Instance handle */
595 /* pNumSamples - Pointer to the number of samples to process */
596 /* */
597 /* RETURNS: */
598 /* None */
599 /* */
600 /* NOTES: */
601 /* */
602 /****************************************************************************************/
603
LVM_BufferUnmanagedOut(LVM_Handle_t hInstance,LVM_UINT16 * pNumSamples)604 void LVM_BufferUnmanagedOut(LVM_Handle_t hInstance,
605 LVM_UINT16 *pNumSamples)
606 {
607
608 LVM_Instance_t *pInstance = (LVM_Instance_t *)hInstance;
609 #ifdef SUPPORT_MC
610 LVM_INT16 NumChannels = pInstance->NrChannels;
611 if (NumChannels == 1)
612 {
613 /* Mono input is processed as stereo by LVM module */
614 NumChannels = 2;
615 }
616 #undef NrFrames
617 #define NrFrames (*pNumSamples) // alias for clarity
618 #else
619 LVM_INT16 NumChannels = 2;
620 #endif
621
622 /*
623 * Update sample counts
624 */
625 pInstance->pInputSamples += (LVM_INT16)(*pNumSamples * NumChannels); /* Update the I/O pointers */
626 #ifdef SUPPORT_MC
627 pInstance->pOutputSamples += (LVM_INT16)(NrFrames * NumChannels);
628 #else
629 pInstance->pOutputSamples += (LVM_INT16)(*pNumSamples * 2);
630 #endif
631 pInstance->SamplesToProcess = (LVM_INT16)(pInstance->SamplesToProcess - *pNumSamples); /* Update the sample count */
632
633 /*
634 * Set te block size to process
635 */
636 if (pInstance->SamplesToProcess > pInstance->InternalBlockSize)
637 {
638 *pNumSamples = (LVM_UINT16)pInstance->InternalBlockSize;
639 }
640 else
641 {
642 *pNumSamples = (LVM_UINT16)pInstance->SamplesToProcess;
643 }
644 }
645
646 /****************************************************************************************/
647 /* */
648 /* FUNCTION: LVM_BufferOptimisedOut */
649 /* */
650 /* DESCRIPTION: */
651 /* This works in conjunction with the optimised input routine and copies the last few */
652 /* processed and unprocessed samples to their respective buffers. */
653 /* */
654 /* PARAMETERS: */
655 /* hInstance - Instance handle */
656 /* pNumSamples - Pointer to the number of samples to process */
657 /* */
658 /* RETURNS: */
659 /* None */
660 /* */
661 /* NOTES: */
662 /* */
663 /****************************************************************************************/
664
665 /****************************************************************************************/
666 /* */
667 /* FUNCTION: LVM_BufferOut */
668 /* */
669 /* DESCRIPTION: */
670 /* This function manages the data output, it has the following features: */
671 /* - Output data to 16-bit aligned memory */
672 /* - Reads data from 32-bit aligned memory */
673 /* - Reads data only in blocks of frame size or multiples of frame size */
674 /* - Writes the same number of samples as the LVM_BufferIn function reads */
675 /* - Works with inplace or outplace processing automatically */
676 /* */
677 /* To manage the data the function has a number of operating states: */
678 /* LVM_FIRSTCALL - The first call for this block of input samples */
679 /* LVM_FIRSTLASTCALL - This is the first and last call for this block of input*/
680 /* samples, this occurs when the number of samples to */
681 /* process is less than the maximum block size. */
682 /* */
683 /* The function uses an internal delay buffer the size of the minimum frame, this is */
684 /* used to temporarily hold samples when the number of samples to write is not a */
685 /* multiple of the frame size. */
686 /* */
687 /* To ensure correct operation with inplace buffering the number of samples to output*/
688 /* per call is always the same as the number of samples read from the input buffer. */
689 /* */
690 /* PARAMETERS: */
691 /* hInstance - Instance handle */
692 /* pOutData - Pointer to the output data stream */
693 /* pNumSamples - Pointer to the number of samples to process */
694 /* */
695 /* RETURNS: */
696 /* None */
697 /* */
698 /* NOTES: */
699 /* */
700 /****************************************************************************************/
LVM_BufferOut(LVM_Handle_t hInstance,LVM_FLOAT * pOutData,LVM_UINT16 * pNumSamples)701 void LVM_BufferOut(LVM_Handle_t hInstance,
702 LVM_FLOAT *pOutData,
703 LVM_UINT16 *pNumSamples)
704 {
705
706 LVM_Instance_t *pInstance = (LVM_Instance_t *)hInstance;
707
708 /*
709 * Check which mode, managed or unmanaged
710 */
711 if (pInstance->InstParams.BufferMode == LVM_MANAGED_BUFFERS)
712 {
713 LVM_BufferManagedOut(hInstance,
714 pOutData,
715 pNumSamples);
716 }
717 else
718 {
719 LVM_BufferUnmanagedOut(hInstance,
720 pNumSamples);
721 }
722 }
723