|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <math.h>
|
|
|
#include <stdlib.h>
|
|
|
#include <string.h>
|
|
|
#include <stdio.h>
|
|
|
|
|
|
#include "fscvrt.h"
|
|
|
#include "fscvrt_st.h"
|
|
|
#include "biquad.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int AUP_Fscvrt_FilterSet(int resampleRate, int* nsect,
|
|
|
const float* B[_FSCVRT_MAXNSEC],
|
|
|
const float* A[_FSCVRT_MAXNSEC],
|
|
|
const float** G) {
|
|
|
int idx;
|
|
|
if (resampleRate == 2) {
|
|
|
*nsect = _FSCVRT_1over2_LOWPASS_NSEC;
|
|
|
for (idx = 0; idx < (*nsect); idx++) {
|
|
|
B[idx] = &(_FSCVRT_1over2_LOWPASS_B[idx][0]);
|
|
|
A[idx] = &(_FSCVRT_1over2_LOWPASS_A[idx][0]);
|
|
|
}
|
|
|
*G = _FSCVRT_1over2_LOWPASS_G;
|
|
|
} else if (resampleRate == 3) {
|
|
|
*nsect = _FSCVRT_1over3_LOWPASS_NSEC;
|
|
|
for (idx = 0; idx < (*nsect); idx++) {
|
|
|
B[idx] = &(_FSCVRT_1over3_LOWPASS_B[idx][0]);
|
|
|
A[idx] = &(_FSCVRT_1over3_LOWPASS_A[idx][0]);
|
|
|
}
|
|
|
*G = _FSCVRT_1over3_LOWPASS_G;
|
|
|
} else if (resampleRate == 4) {
|
|
|
*nsect = _FSCVRT_1over4_LOWPASS_NSEC;
|
|
|
for (idx = 0; idx < (*nsect); idx++) {
|
|
|
B[idx] = &(_FSCVRT_1over4_LOWPASS_B[idx][0]);
|
|
|
A[idx] = &(_FSCVRT_1over4_LOWPASS_A[idx][0]);
|
|
|
}
|
|
|
*G = _FSCVRT_1over4_LOWPASS_G;
|
|
|
} else if (resampleRate == 6) {
|
|
|
*nsect = _FSCVRT_1over6_LOWPASS_NSEC;
|
|
|
for (idx = 0; idx < (*nsect); idx++) {
|
|
|
B[idx] = &(_FSCVRT_1over6_LOWPASS_B[idx][0]);
|
|
|
A[idx] = &(_FSCVRT_1over6_LOWPASS_A[idx][0]);
|
|
|
}
|
|
|
*G = _FSCVRT_1over6_LOWPASS_G;
|
|
|
} else {
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
static int AUP_Fscvrt_dynamMemPrepare(FscvrtSt* stHdl, void* memPtrExt,
|
|
|
size_t memSize) {
|
|
|
char* memPtr = NULL;
|
|
|
int biquadInBufMemSize = 0;
|
|
|
int biquadOutBufMemSize = 0;
|
|
|
int totalMemSize = 0;
|
|
|
|
|
|
if (stHdl == NULL) {
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
biquadInBufMemSize = _FSCVRT_ALIGN8(sizeof(float) * stHdl->biquadInBufLen);
|
|
|
totalMemSize += biquadInBufMemSize;
|
|
|
|
|
|
biquadOutBufMemSize = _FSCVRT_ALIGN8(sizeof(float) * stHdl->biquadOutBufLen);
|
|
|
totalMemSize += biquadOutBufMemSize;
|
|
|
|
|
|
totalMemSize = _FSCVRT_MAX(totalMemSize, 80);
|
|
|
|
|
|
|
|
|
|
|
|
if (memPtrExt == NULL) {
|
|
|
return (totalMemSize);
|
|
|
}
|
|
|
|
|
|
|
|
|
if ((size_t)totalMemSize > memSize) {
|
|
|
return -1;
|
|
|
}
|
|
|
memPtr = (char*)memPtrExt;
|
|
|
|
|
|
stHdl->biquadInBuf = NULL;
|
|
|
if (biquadInBufMemSize != 0) {
|
|
|
stHdl->biquadInBuf = (float*)memPtr;
|
|
|
memPtr += biquadInBufMemSize;
|
|
|
}
|
|
|
|
|
|
stHdl->biquadOutBuf = NULL;
|
|
|
if (biquadOutBufMemSize != 0) {
|
|
|
stHdl->biquadOutBuf = (float*)memPtr;
|
|
|
memPtr += biquadOutBufMemSize;
|
|
|
}
|
|
|
|
|
|
if (((int)(memPtr - (char*)memPtrExt)) > totalMemSize) {
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
return (totalMemSize);
|
|
|
}
|
|
|
|
|
|
static int AUP_Fscvrt_checkStatCfg(FscvrtStaticCfg* pCfg) {
|
|
|
if (pCfg == NULL) {
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
if (pCfg->inputFs != 16000 && pCfg->inputFs != 24000 &&
|
|
|
pCfg->inputFs != 32000 && pCfg->inputFs != 48000) {
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
if (pCfg->outputFs != 16000 && pCfg->outputFs != 24000 &&
|
|
|
pCfg->outputFs != 32000 && pCfg->outputFs != 48000) {
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
if (pCfg->stepSz > AUP_FSCVRT_MAX_INPUT_LEN || pCfg->stepSz < 1) {
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
if (pCfg->inputType != 0) {
|
|
|
pCfg->inputType = 1;
|
|
|
}
|
|
|
|
|
|
if (pCfg->outputType != 0) {
|
|
|
pCfg->outputType = 1;
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
static int AUP_Fscvrt_publishStaticCfg(FscvrtSt* stHdl) {
|
|
|
int tmpRatio;
|
|
|
int ret;
|
|
|
int maxResmplRate = 0;
|
|
|
|
|
|
stHdl->mode = 0;
|
|
|
stHdl->upSmplRate = 1;
|
|
|
stHdl->downSmplRate = 1;
|
|
|
if (stHdl->stCfg.inputFs != stHdl->stCfg.outputFs) {
|
|
|
if (stHdl->stCfg.outputFs > stHdl->stCfg.inputFs) {
|
|
|
tmpRatio = (stHdl->stCfg.outputFs / stHdl->stCfg.inputFs);
|
|
|
if (stHdl->stCfg.outputFs == tmpRatio * stHdl->stCfg.inputFs) {
|
|
|
stHdl->mode = 1;
|
|
|
stHdl->upSmplRate = tmpRatio;
|
|
|
stHdl->downSmplRate = 1;
|
|
|
} else {
|
|
|
stHdl->mode = 3;
|
|
|
stHdl->upSmplRate = _FSCVRT_COMMON_FS / stHdl->stCfg.inputFs;
|
|
|
stHdl->downSmplRate = _FSCVRT_COMMON_FS / stHdl->stCfg.outputFs;
|
|
|
}
|
|
|
} else {
|
|
|
tmpRatio = (stHdl->stCfg.inputFs / stHdl->stCfg.outputFs);
|
|
|
if (stHdl->stCfg.inputFs == tmpRatio * stHdl->stCfg.outputFs) {
|
|
|
stHdl->mode = 2;
|
|
|
stHdl->upSmplRate = 1;
|
|
|
stHdl->downSmplRate = tmpRatio;
|
|
|
} else {
|
|
|
stHdl->mode = 3;
|
|
|
stHdl->upSmplRate = _FSCVRT_COMMON_FS / stHdl->stCfg.inputFs;
|
|
|
stHdl->downSmplRate = _FSCVRT_COMMON_FS / stHdl->stCfg.outputFs;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (stHdl->mode == 0) {
|
|
|
stHdl->biquadInBufLen = 0;
|
|
|
stHdl->biquadOutBufLen = 0;
|
|
|
} else {
|
|
|
stHdl->biquadInBufLen = stHdl->stCfg.stepSz * stHdl->upSmplRate;
|
|
|
stHdl->biquadOutBufLen = 2 * (stHdl->stCfg.stepSz * stHdl->upSmplRate);
|
|
|
}
|
|
|
|
|
|
maxResmplRate = _FSCVRT_MAX(stHdl->upSmplRate, stHdl->downSmplRate);
|
|
|
|
|
|
stHdl->nSec = 0;
|
|
|
memset(stHdl->biquadB, 0, sizeof(stHdl->biquadB));
|
|
|
memset(stHdl->biquadA, 0, sizeof(stHdl->biquadA));
|
|
|
stHdl->biquadG = NULL;
|
|
|
|
|
|
if (stHdl->mode != 0) {
|
|
|
ret = AUP_Fscvrt_FilterSet(maxResmplRate, &(stHdl->nSec), stHdl->biquadB,
|
|
|
stHdl->biquadA, &(stHdl->biquadG));
|
|
|
if (ret < 0) {
|
|
|
return -1;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
static int AUP_Fscvrt_resetVariables(FscvrtSt* stHdl) {
|
|
|
stHdl->biquadInBufCnt = 0;
|
|
|
stHdl->biquadOutBufCnt = 0;
|
|
|
|
|
|
if (stHdl->dynamMemPtr != NULL && stHdl->dynamMemSize > 0) {
|
|
|
memset(stHdl->dynamMemPtr, 0, stHdl->dynamMemSize);
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int AUP_Fscvrt_create(void** stPtr) {
|
|
|
FscvrtSt* tmpPtr;
|
|
|
|
|
|
if (stPtr == NULL) {
|
|
|
return -1;
|
|
|
}
|
|
|
*stPtr = (void*)malloc(sizeof(FscvrtSt));
|
|
|
if (*stPtr == NULL) {
|
|
|
return -1;
|
|
|
}
|
|
|
memset(*stPtr, 0, sizeof(FscvrtSt));
|
|
|
|
|
|
tmpPtr = (FscvrtSt*)(*stPtr);
|
|
|
|
|
|
tmpPtr->dynamMemPtr = NULL;
|
|
|
tmpPtr->dynamMemSize = 0;
|
|
|
|
|
|
tmpPtr->stCfg.inputFs = 24000;
|
|
|
tmpPtr->stCfg.outputFs = 32000;
|
|
|
tmpPtr->stCfg.stepSz = 240;
|
|
|
tmpPtr->stCfg.inputType = 0;
|
|
|
tmpPtr->stCfg.outputType = 0;
|
|
|
|
|
|
if (AUP_Biquad_create(&(tmpPtr->biquadSt)) < 0) {
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int AUP_Fscvrt_destroy(void** stPtr) {
|
|
|
FscvrtSt* stHdl;
|
|
|
|
|
|
if (stPtr == NULL) {
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
stHdl = (FscvrtSt*)(*stPtr);
|
|
|
if (stHdl == NULL) {
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
AUP_Biquad_destroy(&(stHdl->biquadSt));
|
|
|
if (stHdl->dynamMemPtr != NULL) {
|
|
|
free(stHdl->dynamMemPtr);
|
|
|
}
|
|
|
stHdl->dynamMemPtr = NULL;
|
|
|
|
|
|
free(stHdl);
|
|
|
(*stPtr) = NULL;
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int AUP_Fscvrt_memAllocate(void* stPtr, const FscvrtStaticCfg* pCfg) {
|
|
|
FscvrtSt* stHdl = NULL;
|
|
|
FscvrtStaticCfg tmpStatCfg = {0};
|
|
|
Biquad_StaticCfg bqStatCfg;
|
|
|
int idx, ret;
|
|
|
int totalMemSize = 0;
|
|
|
|
|
|
if (stPtr == NULL || pCfg == NULL) {
|
|
|
return -1;
|
|
|
}
|
|
|
stHdl = (FscvrtSt*)(stPtr);
|
|
|
|
|
|
memcpy(&tmpStatCfg, pCfg, sizeof(FscvrtStaticCfg));
|
|
|
if (AUP_Fscvrt_checkStatCfg(&tmpStatCfg) < 0) {
|
|
|
return -1;
|
|
|
}
|
|
|
memcpy(&(stHdl->stCfg), &tmpStatCfg, sizeof(FscvrtStaticCfg));
|
|
|
|
|
|
if (AUP_Fscvrt_publishStaticCfg(stHdl) < 0) {
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
|
|
|
totalMemSize = AUP_Fscvrt_dynamMemPrepare(stHdl, NULL, 0);
|
|
|
if (totalMemSize < 0) {
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
|
|
|
if ((size_t)totalMemSize > stHdl->dynamMemSize) {
|
|
|
if (stHdl->dynamMemPtr != NULL) {
|
|
|
free(stHdl->dynamMemPtr);
|
|
|
stHdl->dynamMemSize = 0;
|
|
|
}
|
|
|
stHdl->dynamMemPtr = (void*)malloc(totalMemSize);
|
|
|
if (stHdl->dynamMemPtr == NULL) {
|
|
|
return -1;
|
|
|
}
|
|
|
stHdl->dynamMemSize = totalMemSize;
|
|
|
}
|
|
|
memset(stHdl->dynamMemPtr, 0, stHdl->dynamMemSize);
|
|
|
|
|
|
|
|
|
if (AUP_Fscvrt_dynamMemPrepare(stHdl, stHdl->dynamMemPtr,
|
|
|
stHdl->dynamMemSize) < 0) {
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
|
|
|
if (stHdl->nSec != 0) {
|
|
|
if (stHdl->nSec > AGORA_UAP_BIQUAD_MAX_SECTION) {
|
|
|
return -1;
|
|
|
}
|
|
|
memset(&bqStatCfg, 0, sizeof(Biquad_StaticCfg));
|
|
|
bqStatCfg.maxNSample = (size_t)(stHdl->biquadInBufLen);
|
|
|
bqStatCfg.nsect = stHdl->nSec;
|
|
|
for (idx = 0; idx < stHdl->nSec; idx++) {
|
|
|
bqStatCfg.B[idx] = stHdl->biquadB[idx];
|
|
|
bqStatCfg.A[idx] = stHdl->biquadA[idx];
|
|
|
}
|
|
|
bqStatCfg.G = stHdl->biquadG;
|
|
|
|
|
|
ret = AUP_Biquad_memAllocate(stHdl->biquadSt, &bqStatCfg);
|
|
|
if (ret < 0) {
|
|
|
return -1;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int AUP_Fscvrt_init(void* stPtr) {
|
|
|
FscvrtSt* stHdl;
|
|
|
|
|
|
if (stPtr == NULL) {
|
|
|
return -1;
|
|
|
}
|
|
|
stHdl = (FscvrtSt*)(stPtr);
|
|
|
|
|
|
|
|
|
if (AUP_Fscvrt_resetVariables(stHdl) < 0) {
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
|
|
|
if (stHdl->biquadSt != NULL && stHdl->nSec != 0) {
|
|
|
if (AUP_Biquad_init(stHdl->biquadSt) < 0) {
|
|
|
return -1;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int AUP_Fscvrt_getStaticCfg(const void* stPtr, FscvrtStaticCfg* pCfg) {
|
|
|
const FscvrtSt* stHdl;
|
|
|
|
|
|
if (stPtr == NULL || pCfg == NULL) {
|
|
|
return -1;
|
|
|
}
|
|
|
stHdl = (const FscvrtSt*)(stPtr);
|
|
|
|
|
|
memcpy(pCfg, &(stHdl->stCfg), sizeof(FscvrtStaticCfg));
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int AUP_Fscvrt_getInfor(const void* stPtr, FscvrtGetData* buff) {
|
|
|
const FscvrtSt* stHdl;
|
|
|
int delayBiquad = 0;
|
|
|
int tmp;
|
|
|
|
|
|
if (stPtr == NULL || buff == NULL) {
|
|
|
return -1;
|
|
|
}
|
|
|
stHdl = (const FscvrtSt*)(stPtr);
|
|
|
|
|
|
if (stHdl->nSec != 0) {
|
|
|
if (AUP_Biquad_getAlgDelay(stHdl->biquadSt, &delayBiquad) < 0) {
|
|
|
return -1;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (stHdl->mode == 0) {
|
|
|
buff->delayInInputFs = 0;
|
|
|
} else if (stHdl->mode == 1) {
|
|
|
buff->delayInInputFs =
|
|
|
(int)roundf(delayBiquad / (float)(stHdl->upSmplRate));
|
|
|
} else if (stHdl->mode == 2) {
|
|
|
buff->delayInInputFs = delayBiquad;
|
|
|
} else {
|
|
|
buff->delayInInputFs =
|
|
|
(int)roundf(delayBiquad / (float)(stHdl->upSmplRate));
|
|
|
}
|
|
|
tmp = stHdl->stCfg.stepSz * stHdl->upSmplRate / stHdl->downSmplRate;
|
|
|
if (tmp * stHdl->downSmplRate == stHdl->stCfg.stepSz * stHdl->upSmplRate) {
|
|
|
buff->maxOutputStepSz = tmp;
|
|
|
} else {
|
|
|
buff->maxOutputStepSz = tmp + 1;
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int AUP_Fscvrt_proc(void* stPtr, const FscvrtInData* pIn, FscvrtOutData* pOut) {
|
|
|
FscvrtSt* stHdl = NULL;
|
|
|
const FscvrtStaticCfg* pCfg;
|
|
|
Biquad_InputData bqdInData;
|
|
|
Biquad_OutputData bqdOutData;
|
|
|
const short* shortSrcPtr = NULL;
|
|
|
const float* floatSrcPtr = NULL;
|
|
|
short* shortTgtPtr = NULL;
|
|
|
float* floatTgtPtr = NULL;
|
|
|
int idx, tgtIdx;
|
|
|
int nOutSamples = 0, samplesTaken = 0, samplesLeft = 0;
|
|
|
int jumpRate;
|
|
|
|
|
|
if (stPtr == NULL || pIn == NULL || pOut == NULL || pIn->inDataSeq == NULL ||
|
|
|
pOut->outDataSeq == NULL) {
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
stHdl = (FscvrtSt*)(stPtr);
|
|
|
pCfg = (const FscvrtStaticCfg*)&(stHdl->stCfg);
|
|
|
shortSrcPtr = (const short*)(pIn->inDataSeq);
|
|
|
floatSrcPtr = (const float*)(pIn->inDataSeq);
|
|
|
|
|
|
|
|
|
if (stHdl->mode == 0) {
|
|
|
if (pIn->outDataSeqLen < pCfg->stepSz) {
|
|
|
return -1;
|
|
|
}
|
|
|
pOut->nOutData = pCfg->stepSz;
|
|
|
pOut->outDataType = pCfg->outputType;
|
|
|
if (pIn->inDataSeq == pOut->outDataSeq) {
|
|
|
if (pCfg->outputType == pCfg->inputType)
|
|
|
return 0;
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
if (pCfg->inputType == 0 && pCfg->outputType == 0) {
|
|
|
memcpy(pOut->outDataSeq, pIn->inDataSeq, sizeof(short) * pCfg->stepSz);
|
|
|
} else if (pCfg->inputType == 1 && pCfg->outputType == 1) {
|
|
|
memcpy(pOut->outDataSeq, pIn->inDataSeq, sizeof(float) * pCfg->stepSz);
|
|
|
} else if (pCfg->inputType == 0 && pCfg->outputType == 1) {
|
|
|
for (idx = 0; idx < pCfg->stepSz; idx++) {
|
|
|
((float*)pOut->outDataSeq)[idx] = ((short*)pIn->inDataSeq)[idx];
|
|
|
}
|
|
|
} else {
|
|
|
for (idx = 0; idx < pCfg->stepSz; idx++) {
|
|
|
((short*)pOut->outDataSeq)[idx] =
|
|
|
(short)_FSCVRT_FLOAT2SHORT(((float*)pIn->inDataSeq)[idx]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
|
|
|
memset(stHdl->biquadInBuf, 0, sizeof(float) * stHdl->biquadInBufLen);
|
|
|
if (pCfg->inputType == 0) {
|
|
|
for (idx = 0; idx < pCfg->stepSz; idx++) {
|
|
|
stHdl->biquadInBuf[idx * (stHdl->upSmplRate)] =
|
|
|
((float)shortSrcPtr[idx]) * stHdl->upSmplRate;
|
|
|
}
|
|
|
} else {
|
|
|
for (idx = 0; idx < pCfg->stepSz; idx++) {
|
|
|
stHdl->biquadInBuf[idx * (stHdl->upSmplRate)] =
|
|
|
floatSrcPtr[idx] * stHdl->upSmplRate;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
memset(&bqdInData, 0, sizeof(Biquad_InputData));
|
|
|
memset(&bqdOutData, 0, sizeof(Biquad_OutputData));
|
|
|
bqdInData.samplesPtr = (const void*)(stHdl->biquadInBuf);
|
|
|
bqdInData.sampleType = 1;
|
|
|
bqdInData.nsamples = (size_t)(pCfg->stepSz * stHdl->upSmplRate);
|
|
|
bqdOutData.outputBuff = (void*)&(stHdl->biquadOutBuf[stHdl->biquadOutBufCnt]);
|
|
|
if (stHdl->biquadOutBufCnt + (pCfg->stepSz * stHdl->upSmplRate) >
|
|
|
stHdl->biquadOutBufLen) {
|
|
|
return -1;
|
|
|
}
|
|
|
if (AUP_Biquad_proc(stHdl->biquadSt, &bqdInData, &bqdOutData) < 0) {
|
|
|
return -1;
|
|
|
}
|
|
|
stHdl->biquadOutBufCnt += (pCfg->stepSz * stHdl->upSmplRate);
|
|
|
|
|
|
|
|
|
nOutSamples = stHdl->biquadOutBufCnt / stHdl->downSmplRate;
|
|
|
if (pIn->outDataSeqLen < nOutSamples) {
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
|
|
|
pOut->nOutData = nOutSamples;
|
|
|
pOut->outDataType = pCfg->outputType;
|
|
|
|
|
|
shortTgtPtr = (short*)pOut->outDataSeq;
|
|
|
floatTgtPtr = (float*)pOut->outDataSeq;
|
|
|
jumpRate = stHdl->downSmplRate;
|
|
|
if (pCfg->outputType == 0) {
|
|
|
for (idx = (jumpRate - 1), tgtIdx = 0; idx < stHdl->biquadOutBufCnt;
|
|
|
idx += jumpRate, tgtIdx++) {
|
|
|
shortTgtPtr[tgtIdx] = _FSCVRT_FLOAT2SHORT(stHdl->biquadOutBuf[idx]);
|
|
|
}
|
|
|
} else {
|
|
|
for (idx = (jumpRate - 1), tgtIdx = 0; idx < stHdl->biquadOutBufCnt;
|
|
|
idx += jumpRate, tgtIdx++) {
|
|
|
floatTgtPtr[tgtIdx] = stHdl->biquadOutBuf[idx];
|
|
|
}
|
|
|
}
|
|
|
if (nOutSamples != tgtIdx) {
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
|
|
|
samplesTaken = nOutSamples * jumpRate;
|
|
|
samplesLeft = stHdl->biquadOutBufCnt - samplesTaken;
|
|
|
if (samplesLeft == 0) {
|
|
|
stHdl->biquadOutBufCnt = 0;
|
|
|
} else if (samplesLeft > 0) {
|
|
|
stHdl->biquadOutBufCnt = samplesLeft;
|
|
|
memmove(stHdl->biquadOutBuf, &(stHdl->biquadOutBuf[samplesTaken]),
|
|
|
sizeof(float) * samplesLeft);
|
|
|
} else {
|
|
|
stHdl->biquadOutBufCnt = 0;
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|