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