12c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* 22c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Copyright (C) 2004-2010 NXP Software 32c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Copyright (C) 2010 The Android Open Source Project 42c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * 52c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Licensed under the Apache License, Version 2.0 (the "License"); 62c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * you may not use this file except in compliance with the License. 72c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * You may obtain a copy of the License at 82c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * 92c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * http://www.apache.org/licenses/LICENSE-2.0 102c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * 112c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Unless required by applicable law or agreed to in writing, software 122c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * distributed under the License is distributed on an "AS IS" BASIS, 132c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 142c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * See the License for the specific language governing permissions and 152c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * limitations under the License. 162c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 172c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 182c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 192c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/****************************************************************************************/ 202c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 212c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* Includes */ 222c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 232c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/****************************************************************************************/ 242c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 252c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent#include "LVM_Private.h" 262c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent#include "VectorArithmetic.h" 272c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 282c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/****************************************************************************************/ 292c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 302c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* FUNCTION: LVM_BufferManagedIn */ 312c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 322c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* DESCRIPTION: */ 332c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* Full buffer management allowing the user to provide input and output buffers on */ 342c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* any alignment and with any number of samples. The alignment is corrected within */ 352c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* the buffer management and the samples are grouped in to blocks of the correct size */ 362c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* before processing. */ 372c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 382c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* PARAMETERS: */ 392c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* hInstance - Instance handle */ 402c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* pInData - Pointer to the input data stream */ 412c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* *pToProcess - Pointer to pointer to the start of data processing */ 422c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* *pProcessed - Pointer to pointer to the destination of the processed data */ 432c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* pNumSamples - Pointer to the number of samples to process */ 442c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 452c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* RETURNS: */ 462c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* None */ 472c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 482c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* NOTES: */ 492c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 502c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/****************************************************************************************/ 512c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 522c87e9c923b0362fabf8c97ff63997542394c428Eric Laurentvoid LVM_BufferManagedIn(LVM_Handle_t hInstance, 532c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent const LVM_INT16 *pInData, 542c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_INT16 **pToProcess, 552c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_INT16 **pProcessed, 562c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_UINT16 *pNumSamples) 572c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent{ 582c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 592c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_INT16 SampleCount; /* Number of samples to be processed this call */ 602c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_INT16 NumSamples; /* Number of samples in scratch buffer */ 612c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_INT16 *pStart; 622c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_Instance_t *pInstance = (LVM_Instance_t *)hInstance; 632c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_Buffer_t *pBuffer; 642c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_INT16 *pDest; 652c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_INT16 NumChannels =2; 662c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 672c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 682c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 692c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Set the processing address pointers 702c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 712c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pBuffer = pInstance->pBufferManagement; 722c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pDest = pBuffer->pScratch; 732c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent *pToProcess = pBuffer->pScratch; 742c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent *pProcessed = pBuffer->pScratch; 752c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 762c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 772c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Check if it is the first call of a block 782c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 792c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent if (pInstance->SamplesToProcess == 0) 802c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 812c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 822c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * First call for a new block of samples 832c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 842c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pInstance->SamplesToProcess = (LVM_INT16)(*pNumSamples + pBuffer->InDelaySamples); 852c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pInstance->pInputSamples = (LVM_INT16 *)pInData; 862c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pBuffer->BufferState = LVM_FIRSTCALL; 872c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 882c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pStart = pInstance->pInputSamples; /* Pointer to the input samples */ 892c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pBuffer->SamplesToOutput = 0; /* Samples to output is same as number read for inplace processing */ 902c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 912c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 922c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 932c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Calculate the number of samples to process this call and update the buffer state 942c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 952c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent if (pInstance->SamplesToProcess > pInstance->InternalBlockSize) 962c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 972c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 982c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Process the maximum bock size of samples. 992c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 1002c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent SampleCount = pInstance->InternalBlockSize; 1012c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent NumSamples = pInstance->InternalBlockSize; 1022c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 1032c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent else 1042c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 1052c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 1062c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Last call for the block, so calculate how many frames and samples to process 1072c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 1082c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_INT16 NumFrames; 1092c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 1102c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent NumSamples = pInstance->SamplesToProcess; 1112c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent NumFrames = (LVM_INT16)(NumSamples >> MIN_INTERNAL_BLOCKSHIFT); 1122c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent SampleCount = (LVM_INT16)(NumFrames << MIN_INTERNAL_BLOCKSHIFT); 1132c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 1142c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 1152c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Update the buffer state 1162c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 1172c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent if (pBuffer->BufferState == LVM_FIRSTCALL) 1182c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 1192c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pBuffer->BufferState = LVM_FIRSTLASTCALL; 1202c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 1212c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent else 1222c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 1232c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pBuffer->BufferState = LVM_LASTCALL; 1242c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 1252c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 1262c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent *pNumSamples = (LVM_UINT16)SampleCount; /* Set the number of samples to process this call */ 1272c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 1282c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 1292c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 1302c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Copy samples from the delay buffer as required 1312c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 1322c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent if (((pBuffer->BufferState == LVM_FIRSTCALL) || 1332c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent (pBuffer->BufferState == LVM_FIRSTLASTCALL)) && 1342c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent (pBuffer->InDelaySamples != 0)) 1352c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 1362c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent Copy_16(&pBuffer->InDelayBuffer[0], /* Source */ 1372c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pDest, /* Destination */ 1382c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent (LVM_INT16)(NumChannels*pBuffer->InDelaySamples)); /* Number of delay samples, left and right */ 1392c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent NumSamples = (LVM_INT16)(NumSamples - pBuffer->InDelaySamples); /* Update sample count */ 1402c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pDest += NumChannels * pBuffer->InDelaySamples; /* Update the destination pointer */ 1412c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 1422c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 1432c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 1442c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 1452c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Copy the rest of the samples for this call from the input buffer 1462c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 1472c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent if (NumSamples > 0) 1482c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 1492c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent Copy_16(pStart, /* Source */ 1502c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pDest, /* Destination */ 1512c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent (LVM_INT16)(NumChannels*NumSamples)); /* Number of input samples */ 1522c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pStart += NumChannels * NumSamples; /* Update the input pointer */ 1532c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 1542c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 1552c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Update the input data pointer and samples to output 1562c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 1572c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pBuffer->SamplesToOutput = (LVM_INT16)(pBuffer->SamplesToOutput + NumSamples); /* Update samples to output */ 1582c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 1592c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 1602c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 1612c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 1622c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Update the sample count and input pointer 1632c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 1642c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pInstance->SamplesToProcess = (LVM_INT16)(pInstance->SamplesToProcess - SampleCount); /* Update the count of samples */ 1652c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pInstance->pInputSamples = pStart; /* Update input sample pointer */ 1662c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 1672c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 1682c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 1692c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Save samples to the delay buffer if any left unprocessed 1702c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 1712c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent if ((pBuffer->BufferState == LVM_FIRSTLASTCALL) || 1722c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent (pBuffer->BufferState == LVM_LASTCALL)) 1732c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 1742c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent NumSamples = pInstance->SamplesToProcess; 1752c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pStart = pBuffer->pScratch; /* Start of the buffer */ 1762c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pStart += NumChannels*SampleCount; /* Offset by the number of processed samples */ 1772c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent if (NumSamples != 0) 1782c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 1792c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent Copy_16(pStart, /* Source */ 1802c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent &pBuffer->InDelayBuffer[0], /* Destination */ 1812c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent (LVM_INT16)(NumChannels*NumSamples)); /* Number of input samples */ 1822c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 1832c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 1842c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 1852c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 1862c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Update the delay sample count 1872c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 1882c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pBuffer->InDelaySamples = NumSamples; /* Number of delay sample pairs */ 1892c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pInstance->SamplesToProcess = 0; /* All Samples used */ 1902c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 1912c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent} 1922c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 1932c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 1942c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/****************************************************************************************/ 1952c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 1962c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* FUNCTION: LVM_BufferUnmanagedIn */ 1972c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 1982c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* DESCRIPTION: */ 1992c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* This mode is selected by the user code and disables the buffer management with the */ 2002c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* exception of the maximum block size processing. The user must ensure that the */ 2012c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* input and output buffers are 32-bit aligned and also that the number of samples to */ 2022c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* process is a correct multiple of samples. */ 2032c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 2042c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* PARAMETERS: */ 2052c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* hInstance - Instance handle */ 2062c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* *pToProcess - Pointer to the start of data processing */ 2072c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* *pProcessed - Pointer to the destination of the processed data */ 2082c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* pNumSamples - Pointer to the number of samples to process */ 2092c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 2102c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* RETURNS: */ 2112c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* None */ 2122c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 2132c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* NOTES: */ 2142c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 2152c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/****************************************************************************************/ 2162c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 2172c87e9c923b0362fabf8c97ff63997542394c428Eric Laurentvoid LVM_BufferUnmanagedIn(LVM_Handle_t hInstance, 2182c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_INT16 **pToProcess, 2192c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_INT16 **pProcessed, 2202c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_UINT16 *pNumSamples) 2212c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent{ 2222c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 2232c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_Instance_t *pInstance = (LVM_Instance_t *)hInstance; 2242c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 2252c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 2262c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 2272c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Check if this is the first call of a block 2282c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 2292c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent if (pInstance->SamplesToProcess == 0) 2302c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 2312c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pInstance->SamplesToProcess = (LVM_INT16)*pNumSamples; /* Get the number of samples on first call */ 2322c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pInstance->pInputSamples = *pToProcess; /* Get the I/O pointers */ 2332c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pInstance->pOutputSamples = *pProcessed; 2342c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 2352c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 2362c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 2372c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Set te block size to process 2382c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 2392c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent if (pInstance->SamplesToProcess > pInstance->InternalBlockSize) 2402c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 2412c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent *pNumSamples = (LVM_UINT16)pInstance->InternalBlockSize; 2422c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 2432c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent else 2442c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 2452c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent *pNumSamples = (LVM_UINT16)pInstance->SamplesToProcess; 2462c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 2472c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 2482c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 2492c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 2502c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Set the process pointers 2512c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 2522c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent *pToProcess = pInstance->pInputSamples; 2532c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent *pProcessed = pInstance->pOutputSamples; 2542c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent} 2552c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 2562c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 2572c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/****************************************************************************************/ 2582c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 2592c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* FUNCTION: LVM_BufferOptimisedIn */ 2602c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 2612c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* DESCRIPTION: */ 2622c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* Optimised buffer management for the case where the data is outplace processing, */ 2632c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* the output data is 32-bit aligned and there are sufficient samples to allow some */ 2642c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* processing directly in the output buffer. This saves one data copy per sample */ 2652c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* compared with the unoptimsed version. */ 2662c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 2672c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* PARAMETERS: */ 2682c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* hInstance - Instance handle */ 2692c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* pInData - Pointer to the input data stream */ 2702c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* *pToProcess - Pointer to the start of data processing */ 2712c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* *pProcessed - Pointer to the destination of the processed data */ 2722c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* pNumSamples - Pointer to the number of samples to process */ 2732c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 2742c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* RETURNS: */ 2752c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* None */ 2762c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 2772c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* NOTES: */ 2782c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 2792c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/****************************************************************************************/ 2802c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 2812c87e9c923b0362fabf8c97ff63997542394c428Eric Laurentvoid LVM_BufferOptimisedIn(LVM_Handle_t hInstance, 2822c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent const LVM_INT16 *pInData, 2832c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_INT16 **pToProcess, 2842c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_INT16 **pProcessed, 2852c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_UINT16 *pNumSamples) 2862c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent{ 2872c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 2882c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_Instance_t *pInstance = (LVM_Instance_t *)hInstance; 2892c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_Buffer_t *pBuffer = pInstance->pBufferManagement; 2902c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_INT16 *pDest; 2912c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_INT16 SampleCount; 2922c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_INT16 NumSamples; 2932c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_INT16 NumFrames; 2942c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 2952c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 2962c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Check if it is the first call for this block 2972c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 2982c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent if (pInstance->SamplesToProcess == 0) 2992c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 3002c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 3012c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * First call for a new block of samples 3022c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 3032c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pBuffer->BufferState = LVM_FIRSTCALL; 3042c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pInstance->pInputSamples = (LVM_INT16 *)pInData; 3052c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pInstance->SamplesToProcess = (LVM_INT16)*pNumSamples; 3062c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pBuffer->SamplesToOutput = (LVM_INT16)*pNumSamples; 3072c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pDest = *pProcessed; /* The start of the output buffer */ 3082c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 3092c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 3102c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 3112c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Copy the already processed samples to the output buffer 3122c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 3132c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent if (pBuffer->OutDelaySamples != 0) 3142c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 3152c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent Copy_16(&pBuffer->OutDelayBuffer[0], /* Source */ 3162c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pDest, /* Detsination */ 3172c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent (LVM_INT16)(2*pBuffer->OutDelaySamples)); /* Number of delay samples */ 3182c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pDest += 2 * pBuffer->OutDelaySamples; /* Update the output pointer */ 3192c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pBuffer->SamplesToOutput = (LVM_INT16)(pBuffer->SamplesToOutput - pBuffer->OutDelaySamples); /* Update the numbr of samples to output */ 3202c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 3212c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent *pToProcess = pDest; /* Set the address to start processing */ 3222c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent *pProcessed = pDest; /* Process in the output buffer, now inplace */ 3232c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 3242c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 3252c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Copy the input delay buffer (unprocessed) samples to the output buffer 3262c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 3272c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent if (pBuffer->InDelaySamples != 0) 3282c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 3292c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent Copy_16(&pBuffer->InDelayBuffer[0], /* Source */ 3302c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pDest, /* Destination */ 3312c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent (LVM_INT16)(2*pBuffer->InDelaySamples)); /* Number of delay samples */ 3322c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pDest += 2 * pBuffer->InDelaySamples; /* Update the output pointer */ 3332c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 3342c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 3352c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 3362c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 3372c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Calculate how many input samples to process and copy 3382c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 3392c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent NumSamples = (LVM_INT16)(*pNumSamples - pBuffer->OutDelaySamples); /* Number that will fit in the output buffer */ 3402c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent if (NumSamples >= pInstance->InternalBlockSize) 3412c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 3422c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent NumSamples = pInstance->InternalBlockSize; 3432c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 3442c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent NumFrames = (LVM_INT16)(NumSamples >> MIN_INTERNAL_BLOCKSHIFT); 3452c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent SampleCount = (LVM_INT16)(NumFrames << MIN_INTERNAL_BLOCKSHIFT); 3462c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent *pNumSamples = (LVM_UINT16)SampleCount; /* The number of samples to process */ 3472c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pBuffer->SamplesToOutput = (LVM_INT16)(pBuffer->SamplesToOutput - SampleCount); /* Update the number of samples to output */ 3482c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent SampleCount = (LVM_INT16)(SampleCount - pBuffer->InDelaySamples); /* The number of samples to copy from the input */ 3492c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 3502c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 3512c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 3522c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Copy samples from the input buffer and update counts and pointers 3532c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 3542c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent Copy_16(pInstance->pInputSamples, /* Source */ 3552c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pDest, /* Destination */ 3562c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent (LVM_INT16)(2*SampleCount)); /* Number of input samples */ 3572c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pInstance->pInputSamples += 2 * SampleCount; /* Update the input pointer */ 3582c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pInstance->pOutputSamples = pDest + (2 * SampleCount); /* Update the output pointer */ 3592c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pInstance->SamplesToProcess = (LVM_INT16)(pInstance->SamplesToProcess - SampleCount); /* Samples left in the input buffer */ 3602c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 3612c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent else 3622c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 3632c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 3642c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Second or subsequent call in optimised mode 3652c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 3662c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent if (pBuffer->SamplesToOutput >= MIN_INTERNAL_BLOCKSIZE) 3672c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 3682c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 3692c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * More samples can be processed directly in the output buffer 3702c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 3712c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent *pToProcess = pInstance->pOutputSamples; /* Set the address to start processing */ 3722c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent *pProcessed = pInstance->pOutputSamples; /* Process in the output buffer, now inplace */ 3732c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent NumSamples = pBuffer->SamplesToOutput; /* Number that will fit in the output buffer */ 3742c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent if (NumSamples >= pInstance->InternalBlockSize) 3752c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 3762c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent NumSamples = pInstance->InternalBlockSize; 3772c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 3782c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent NumFrames = (LVM_INT16)(NumSamples >> MIN_INTERNAL_BLOCKSHIFT); 3792c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent SampleCount = (LVM_INT16)(NumFrames << MIN_INTERNAL_BLOCKSHIFT); 3802c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent *pNumSamples = (LVM_UINT16)SampleCount; /* The number of samples to process */ 3812c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 3822c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 3832c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 3842c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Copy samples from the input buffer and update counts and pointers 3852c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 3862c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent Copy_16(pInstance->pInputSamples, /* Source */ 3872c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pInstance->pOutputSamples, /* Destination */ 3882c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent (LVM_INT16)(2*SampleCount)); /* Number of input samples */ 3892c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pInstance->pInputSamples += 2 * SampleCount; /* Update the input pointer */ 3902c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pInstance->pOutputSamples += 2 * SampleCount; /* Update the output pointer */ 3912c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pInstance->SamplesToProcess = (LVM_INT16)(pInstance->SamplesToProcess - SampleCount); /* Samples left in the input buffer */ 3922c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pBuffer->SamplesToOutput = (LVM_INT16)(pBuffer->SamplesToOutput - SampleCount); /* Number that will fit in the output buffer */ 3932c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 3942c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent else 3952c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 3962c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 3972c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * The remaining samples can not be processed in the output buffer 3982c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 3992c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pBuffer->BufferState = LVM_LASTCALL; /* Indicate this is the last bock to process */ 4002c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent *pToProcess = pBuffer->pScratch; /* Set the address to start processing */ 4012c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent *pProcessed = pBuffer->pScratch; /* Process in the output buffer, now inplace */ 4022c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent NumSamples = pInstance->SamplesToProcess; /* Number left to be processed */ 4032c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent NumFrames = (LVM_INT16)(NumSamples >> MIN_INTERNAL_BLOCKSHIFT); 4042c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent SampleCount = (LVM_INT16)(NumFrames << MIN_INTERNAL_BLOCKSHIFT); 4052c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent *pNumSamples = (LVM_UINT16)SampleCount; /* The number of samples to process */ 4062c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 4072c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 4082c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 4092c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Copy samples from the input buffer and update counts and pointers 4102c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 4112c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent Copy_16(pInstance->pInputSamples, /* Source */ 4122c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pBuffer->pScratch, /* Destination */ 4132c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent (LVM_INT16)(2*SampleCount)); /* Number of input samples */ 4142c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pInstance->pInputSamples += 2 * SampleCount; /* Update the input pointer */ 4152c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pInstance->SamplesToProcess = (LVM_INT16)(pInstance->SamplesToProcess - SampleCount); /* Samples left in the input buffer */ 4162c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 4172c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 4182c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent} 4192c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 4202c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/****************************************************************************************/ 4212c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 4222c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* FUNCTION: LVM_BufferIn */ 4232c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 4242c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* DESCRIPTION: */ 4252c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* This function manages the data input, it has the following features: */ 4262c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* - Accepts data in 16-bit aligned memory */ 4272c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* - Copies the data to 32-bit aligned memory */ 4282c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* - Converts Mono inputs to Mono-in-Stereo */ 4292c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* - Accepts any number of samples as input, except 0 */ 4302c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* - Breaks the input sample stream in to blocks of the configured frame size or */ 4312c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* multiples of the frame size */ 4322c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* - Limits the processing block size to the maximum block size. */ 4332c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* - Works with inplace or outplace processing automatically */ 4342c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 4352c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* To manage the data the function has a number of operating states: */ 4362c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* LVM_FIRSTCALL - The first call for this block of input samples */ 4372c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* LVM_MAXBLOCKCALL - The current block is the maximum size. Only used for the */ 4382c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* second and subsequent blocks. */ 4392c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* LVM_LASTCALL - The last call for this block of input samples */ 4402c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* LVM_FIRSTLASTCALL - This is the first and last call for this block of input*/ 4412c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* samples, this occurs when the number of samples to */ 4422c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* process is less than the maximum block size. */ 4432c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 4442c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* The function uses an internal delay buffer the size of the minimum frame, this is */ 4452c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* used to temporarily hold samples when the number of samples to process is not a */ 4462c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* multiple of the frame size. */ 4472c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 4482c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* To ensure correct operation with inplace buffering the number of samples to output*/ 4492c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* per call is calculated in this function and is set to the number of samples read */ 4502c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* from the input buffer. */ 4512c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 4522c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* The total number of samples to process is stored when the function is called for */ 4532c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* the first time. The value is overwritten by the size of the block to be processed */ 4542c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* in each call so the size of the processing blocks can be controlled. The number of */ 4552c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* samples actually processed for each block of input samples is always a multiple of*/ 4562c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* the frame size so for any particular block of input samples the actual number of */ 4572c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* processed samples may not match the number of input samples, sometime it will be */ 4582c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* sometimes less. The average is the same and the difference is never more than the */ 4592c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* frame size. */ 4602c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 4612c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* PARAMETERS: */ 4622c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* hInstance - Instance handle */ 4632c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* pInData - Pointer to the input data stream */ 4642c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* *pToProcess - Pointer to the start of data processing */ 4652c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* *pProcessed - Pointer to the destination of the processed data */ 4662c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* pNumSamples - Pointer to the number of samples to process */ 4672c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 4682c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* RETURNS: */ 4692c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* None */ 4702c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 4712c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* NOTES: */ 4722c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 4732c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/****************************************************************************************/ 4742c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 4752c87e9c923b0362fabf8c97ff63997542394c428Eric Laurentvoid LVM_BufferIn(LVM_Handle_t hInstance, 4762c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent const LVM_INT16 *pInData, 4772c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_INT16 **pToProcess, 4782c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_INT16 **pProcessed, 4792c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_UINT16 *pNumSamples) 4802c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent{ 4812c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 4822c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_Instance_t *pInstance = (LVM_Instance_t *)hInstance; 4832c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 4842c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 4852c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 4862c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Check which mode, managed or unmanaged 4872c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 4882c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent if (pInstance->InstParams.BufferMode == LVM_MANAGED_BUFFERS) 4892c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 4902c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_BufferManagedIn(hInstance, 4912c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pInData, 4922c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pToProcess, 4932c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pProcessed, 4942c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pNumSamples); 4952c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 4962c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent else 4972c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 4982c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_BufferUnmanagedIn(hInstance, 4992c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pToProcess, 5002c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pProcessed, 5012c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pNumSamples); 5022c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 5032c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent} 5042c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 5052c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/****************************************************************************************/ 5062c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 5072c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* FUNCTION: LVM_BufferManagedOut */ 5082c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 5092c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* DESCRIPTION: */ 5102c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* Full buffer management output. This works in conjunction with the managed input */ 5112c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* routine and ensures the correct number of samples are always output to the output */ 5122c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* buffer. */ 5132c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 5142c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* PARAMETERS: */ 5152c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* hInstance - Instance handle */ 5162c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* pOutData - Pointer to the output data stream */ 5172c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* pNumSamples - Pointer to the number of samples to process */ 5182c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 5192c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* RETURNS: */ 5202c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* None */ 5212c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 5222c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* NOTES: */ 5232c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 5242c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/****************************************************************************************/ 5252c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 5262c87e9c923b0362fabf8c97ff63997542394c428Eric Laurentvoid LVM_BufferManagedOut(LVM_Handle_t hInstance, 5272c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_INT16 *pOutData, 5282c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_UINT16 *pNumSamples) 5292c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent{ 5302c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 5312c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_Instance_t *pInstance = (LVM_Instance_t *)hInstance; 5322c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_Buffer_t *pBuffer = pInstance->pBufferManagement; 5332c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_INT16 SampleCount = (LVM_INT16)*pNumSamples; 5342c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_INT16 NumSamples; 5352c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_INT16 *pStart; 5362c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_INT16 *pDest; 5372c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 5382c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 5392c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 5402c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Set the pointers 5412c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 5422c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent NumSamples = pBuffer->SamplesToOutput; 5432c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pStart = pBuffer->pScratch; 5442c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 5452c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 5462c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 5472c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * check if it is the first call of a block 5482c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 5492c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent if ((pBuffer->BufferState == LVM_FIRSTCALL) || 5502c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent (pBuffer->BufferState == LVM_FIRSTLASTCALL)) 5512c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 5522c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* First call for a new block */ 5532c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pInstance->pOutputSamples = pOutData; /* Initialise the destination */ 5542c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 5552c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pDest = pInstance->pOutputSamples; /* Set the output address */ 5562c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 5572c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 5582c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 5592c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * If the number of samples is non-zero then there are still samples to send to 5602c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * the output buffer 5612c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 5622c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent if ((NumSamples != 0) && 5632c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent (pBuffer->OutDelaySamples != 0)) 5642c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 5652c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 5662c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Copy the delayed output buffer samples to the output 5672c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 5682c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent if (pBuffer->OutDelaySamples <= NumSamples) 5692c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 5702c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 5712c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Copy all output delay samples to the output 5722c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 5732c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent Copy_16(&pBuffer->OutDelayBuffer[0], /* Source */ 5742c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pDest, /* Detsination */ 5752c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent (LVM_INT16)(2*pBuffer->OutDelaySamples)); /* Number of delay samples */ 5762c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 5772c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 5782c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Update the pointer and sample counts 5792c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 5802c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pDest += 2*pBuffer->OutDelaySamples; /* Output sample pointer */ 5812c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent NumSamples = (LVM_INT16)(NumSamples - pBuffer->OutDelaySamples); /* Samples left to send */ 5822c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pBuffer->OutDelaySamples = 0; /* No samples left in the buffer */ 5832c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 5842c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 5852c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent else 5862c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 5872c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 5882c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Copy only some of the ouput delay samples to the output 5892c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 5902c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent Copy_16(&pBuffer->OutDelayBuffer[0], /* Source */ 5912c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pDest, /* Detsination */ 5922c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent (LVM_INT16)(2*NumSamples)); /* Number of delay samples */ 5932c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 5942c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 5952c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Update the pointer and sample counts 5962c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 5972c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pDest += 2*NumSamples; /* Output sample pointer */ 5982c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pBuffer->OutDelaySamples = (LVM_INT16)(pBuffer->OutDelaySamples - NumSamples); /* No samples left in the buffer */ 5992c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 6002c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 6012c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 6022c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Realign the delay buffer data to avoid using circular buffer management 6032c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 6042c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent Copy_16(&pBuffer->OutDelayBuffer[2*NumSamples], /* Source */ 6052c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent &pBuffer->OutDelayBuffer[0], /* Destination */ 6062c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent (LVM_INT16)(2*pBuffer->OutDelaySamples)); /* Number of samples to move */ 6072c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent NumSamples = 0; /* Samples left to send */ 6082c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 6092c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 6102c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 6112c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 6122c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 6132c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Copy the processed results to the output 6142c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 6152c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent if ((NumSamples != 0) && 6162c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent (SampleCount != 0)) 6172c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 6182c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent if (SampleCount <= NumSamples) 6192c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 6202c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 6212c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Copy all processed samples to the output 6222c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 6232c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent Copy_16(pStart, /* Source */ 6242c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pDest, /* Detsination */ 6252c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent (LVM_INT16)(2*SampleCount)); /* Number of processed samples */ 6262c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 6272c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 6282c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Update the pointer and sample counts 6292c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 6302c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pDest += 2 * SampleCount; /* Output sample pointer */ 6312c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent NumSamples = (LVM_INT16)(NumSamples - SampleCount); /* Samples left to send */ 6322c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent SampleCount = 0; /* No samples left in the buffer */ 6332c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 6342c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent else 6352c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 6362c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 6372c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Copy only some processed samples to the output 6382c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 6392c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent Copy_16(pStart, /* Source */ 6402c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pDest, /* Destination */ 6412c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent (LVM_INT16)(2*NumSamples)); /* Number of processed samples */ 6422c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 6432c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 6442c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 6452c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Update the pointers and sample counts 6462c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 6472c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pStart += 2 * NumSamples; /* Processed sample pointer */ 6482c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pDest += 2 * NumSamples; /* Output sample pointer */ 6492c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent SampleCount = (LVM_INT16)(SampleCount - NumSamples); /* Processed samples left */ 6502c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent NumSamples = 0; /* Clear the sample count */ 6512c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 6522c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 6532c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 6542c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 6552c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 6562c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Copy the remaining processed data to the output delay buffer 6572c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 6582c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent if (SampleCount != 0) 6592c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 6602c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent Copy_16(pStart, /* Source */ 6612c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent &pBuffer->OutDelayBuffer[2*pBuffer->OutDelaySamples], /* Destination */ 6622c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent (LVM_INT16)(2*SampleCount)); /* Number of processed samples */ 6632c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pBuffer->OutDelaySamples = (LVM_INT16)(pBuffer->OutDelaySamples + SampleCount); /* Update the buffer count */ 6642c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 6652c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 6662c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 6672c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 6682c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * pointers, counts and set default buffer processing 6692c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 6702c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pBuffer->SamplesToOutput = NumSamples; /* Samples left to send */ 6712c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pInstance->pOutputSamples = pDest; /* Output sample pointer */ 6722c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pBuffer->BufferState = LVM_MAXBLOCKCALL; /* Set for the default call block size */ 6732c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent *pNumSamples = (LVM_UINT16)pInstance->SamplesToProcess; /* This will terminate the loop when all samples processed */ 6742c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent} 6752c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 6762c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 6772c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/****************************************************************************************/ 6782c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 6792c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* FUNCTION: LVM_BufferUnmanagedOut */ 6802c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 6812c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* DESCRIPTION: */ 6822c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* This works in conjunction with the unmanaged input routine and updates the number */ 6832c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* of samples left to be processed and adjusts the buffer pointers. */ 6842c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 6852c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* PARAMETERS: */ 6862c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* hInstance - Instance handle */ 6872c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* pNumSamples - Pointer to the number of samples to process */ 6882c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 6892c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* RETURNS: */ 6902c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* None */ 6912c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 6922c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* NOTES: */ 6932c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 6942c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/****************************************************************************************/ 6952c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 6962c87e9c923b0362fabf8c97ff63997542394c428Eric Laurentvoid LVM_BufferUnmanagedOut(LVM_Handle_t hInstance, 6972c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_UINT16 *pNumSamples) 6982c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent{ 6992c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 7002c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_Instance_t *pInstance = (LVM_Instance_t *)hInstance; 7012c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_INT16 NumChannels =2; 7022c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 7032c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 7042c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 7052c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Update sample counts 7062c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 7072c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pInstance->pInputSamples += (LVM_INT16)(*pNumSamples * NumChannels); /* Update the I/O pointers */ 7082c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pInstance->pOutputSamples += (LVM_INT16)(*pNumSamples * 2); 7092c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pInstance->SamplesToProcess = (LVM_INT16)(pInstance->SamplesToProcess - *pNumSamples); /* Update the sample count */ 7102c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 7112c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 7122c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Set te block size to process 7132c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 7142c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent if (pInstance->SamplesToProcess > pInstance->InternalBlockSize) 7152c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 7162c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent *pNumSamples = (LVM_UINT16)pInstance->InternalBlockSize; 7172c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 7182c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent else 7192c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 7202c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent *pNumSamples = (LVM_UINT16)pInstance->SamplesToProcess; 7212c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 7222c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent} 7232c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 7242c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 7252c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/****************************************************************************************/ 7262c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 7272c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* FUNCTION: LVM_BufferOptimisedOut */ 7282c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 7292c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* DESCRIPTION: */ 7302c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* This works in conjunction with the optimised input routine and copies the last few */ 7312c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* processed and unprocessed samples to their respective buffers. */ 7322c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 7332c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* PARAMETERS: */ 7342c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* hInstance - Instance handle */ 7352c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* pNumSamples - Pointer to the number of samples to process */ 7362c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 7372c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* RETURNS: */ 7382c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* None */ 7392c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 7402c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* NOTES: */ 7412c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 7422c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/****************************************************************************************/ 7432c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 7442c87e9c923b0362fabf8c97ff63997542394c428Eric Laurentvoid LVM_BufferOptimisedOut(LVM_Handle_t hInstance, 7452c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_UINT16 *pNumSamples) 7462c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent{ 7472c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 7482c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_Instance_t *pInstance = (LVM_Instance_t *)hInstance; 7492c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_Buffer_t *pBuffer = pInstance->pBufferManagement; 7502c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 7512c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 7522c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Check if it is the last block to process 7532c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 7542c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent if (pBuffer->BufferState == LVM_LASTCALL) 7552c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 7562c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_INT16 *pSrc = pBuffer->pScratch; 7572c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 7582c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 7592c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Copy the unprocessed samples to the input delay buffer 7602c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 7612c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent if (pInstance->SamplesToProcess != 0) 7622c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 7632c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent Copy_16(pInstance->pInputSamples, /* Source */ 7642c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent &pBuffer->InDelayBuffer[0], /* Destination */ 7652c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent (LVM_INT16)(2*pInstance->SamplesToProcess)); /* Number of input samples */ 7662c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pBuffer->InDelaySamples = pInstance->SamplesToProcess; 7672c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pInstance->SamplesToProcess = 0; 7682c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 7692c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent else 7702c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 7712c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pBuffer->InDelaySamples = 0; 7722c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 7732c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 7742c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 7752c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 7762c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Fill the last empty spaces in the output buffer 7772c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 7782c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent if (pBuffer->SamplesToOutput != 0) 7792c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 7802c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent Copy_16(pSrc, /* Source */ 7812c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pInstance->pOutputSamples, /* Destination */ 7822c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent (LVM_INT16)(2*pBuffer->SamplesToOutput)); /* Number of input samples */ 7832c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent *pNumSamples = (LVM_UINT16)(*pNumSamples - pBuffer->SamplesToOutput); 7842c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pSrc += 2 * pBuffer->SamplesToOutput; /* Update scratch pointer */ 7852c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pBuffer->SamplesToOutput = 0; /* No more samples in this block */ 7862c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 7872c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 7882c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 7892c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 7902c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Save any remaining processed samples in the output delay buffer 7912c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 7922c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent if (*pNumSamples != 0) 7932c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 7942c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent Copy_16(pSrc, /* Source */ 7952c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent &pBuffer->OutDelayBuffer[0], /* Destination */ 7962c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent (LVM_INT16)(2**pNumSamples)); /* Number of input samples */ 7972c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 7982c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pBuffer->OutDelaySamples = (LVM_INT16)*pNumSamples; 7992c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 8002c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent *pNumSamples = 0; /* No more samples in this block */ 8012c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 8022c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent else 8032c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 8042c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pBuffer->OutDelaySamples = 0; 8052c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 8062c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 8072c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent} 8082c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 8092c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 8102c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/****************************************************************************************/ 8112c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 8122c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* FUNCTION: LVM_BufferOut */ 8132c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 8142c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* DESCRIPTION: */ 8152c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* This function manages the data output, it has the following features: */ 8162c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* - Output data to 16-bit aligned memory */ 8172c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* - Reads data from 32-bit aligned memory */ 8182c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* - Reads data only in blocks of frame size or multiples of frame size */ 8192c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* - Writes the same number of samples as the LVM_BufferIn function reads */ 8202c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* - Works with inplace or outplace processing automatically */ 8212c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 8222c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* To manage the data the function has a number of operating states: */ 8232c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* LVM_FIRSTCALL - The first call for this block of input samples */ 8242c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* LVM_FIRSTLASTCALL - This is the first and last call for this block of input*/ 8252c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* samples, this occurs when the number of samples to */ 8262c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* process is less than the maximum block size. */ 8272c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 8282c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* The function uses an internal delay buffer the size of the minimum frame, this is */ 8292c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* used to temporarily hold samples when the number of samples to write is not a */ 8302c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* multiple of the frame size. */ 8312c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 8322c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* To ensure correct operation with inplace buffering the number of samples to output*/ 8332c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* per call is always the same as the number of samples read from the input buffer. */ 8342c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 8352c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* PARAMETERS: */ 8362c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* hInstance - Instance handle */ 8372c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* pOutData - Pointer to the output data stream */ 8382c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* pNumSamples - Pointer to the number of samples to process */ 8392c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 8402c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* RETURNS: */ 8412c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* None */ 8422c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 8432c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* NOTES: */ 8442c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/* */ 8452c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent/****************************************************************************************/ 8462c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 8472c87e9c923b0362fabf8c97ff63997542394c428Eric Laurentvoid LVM_BufferOut(LVM_Handle_t hInstance, 8482c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_INT16 *pOutData, 8492c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_UINT16 *pNumSamples) 8502c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent{ 8512c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 8522c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_Instance_t *pInstance = (LVM_Instance_t *)hInstance; 8532c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 8542c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 8552c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent /* 8562c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent * Check which mode, managed or unmanaged 8572c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent */ 8582c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent if (pInstance->InstParams.BufferMode == LVM_MANAGED_BUFFERS) 8592c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 8602c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_BufferManagedOut(hInstance, 8612c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pOutData, 8622c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pNumSamples); 8632c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 8642c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent else 8652c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent { 8662c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent LVM_BufferUnmanagedOut(hInstance, 8672c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent pNumSamples); 8682c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent } 8692c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent} 8702c87e9c923b0362fabf8c97ff63997542394c428Eric Laurent 871