biquad filter实现
发布时间:2020-12-14 03:45:04 所属栏目:大数据 来源:网络整理
导读:原始频谱: LPF: HPF: ? ? 代码: #includestdio.h #include stdlib.h #include errno.h #include string .h #include pthread.h #include math.h typedef struct { char chunkId[ 4 ]; // "RIFF" unsigned long chunkSize; char format[ 4 ]; // "WAVE" }WA
原始频谱: LPF: HPF: ? ? 代码: #include<stdio.h> #include<stdlib.h> #include<errno.h> #include<string.h> #include<pthread.h> #include<math.h> typedef struct{ char chunkId[4];//"RIFF" unsigned long chunkSize; char format[4];//"WAVE" }WAVE_RIFF; typedef struct{ char chunkId[4];//"fmt" unsigned long chunkSize; unsigned short audioFormat; unsigned short chNum; unsigned long sampleRate; unsigned long byteRate;//SampleRate * NumChannels * BitsPerSample/8 unsigned short blockAlign;//NumChannels * BitsPerSample/8 unsigned short bitsPerSample;//8,16,32 }WAVE_FMT; typedef struct{ char chunkId[4];//"data" unsigned long chunkSize;//NumSamples * NumChannels * BitsPerSample/8 }WAVE_DATA; typedef struct { char fileName[256]; FILE *fp; long pos; unsigned long totalSampleNum; WAVE_RIFF riffChunk; WAVE_FMT fmtChunk; WAVE_DATA dataChunk; }WAVE_INFO; #define READ_SAMPLES 1024 #define PP_SAMPLES 64 typedef struct { unsigned short chNum; unsigned short bankNum; unsigned long samplesPerBank; unsigned short bytesPerSample; unsigned short bankRp; unsigned short bankWp; unsigned char ***pData; unsigned char fgEos; unsigned char fgInited; }PP_BUF_T; typedef enum { FADER_TYPE_LINE,FADER_TYPE_CUBIC,}FADER_TYPE_E; typedef struct { float attuationDb; FADER_TYPE_E type; unsigned long timeMs; }FADER_PARAM_T; typedef struct { FADER_PARAM_T faderParams; unsigned long timeInSample; float curVolumDb; float curGain; float startGain; float targetGain; unsigned long curSample; unsigned long sampleRate; float *segGain; unsigned short segNum; }FADER_HANDLE_T; typedef struct { short **pData; unsigned short chNum; unsigned short samples; unsigned short bytesPerSample; }DATA_INFO_T; PP_BUF_T gPpBuf; FADER_HANDLE_T gFaderHandle; unsigned char fgEnd = 0; typedef struct { unsigned long attackTimeMs; unsigned long releaseTimeMs; unsigned short ratio; float thresholdDb; }DRC_COMPRESSOR_PARAM_T; typedef struct { unsigned long attackTimeMs; unsigned long releaseTimeMs; float thresholdDb; }DRC_LIMITER_PARAM_T; typedef struct { unsigned long attackTimeMs; unsigned long releaseTimeMs; unsigned long holdTimeMs; unsigned short ratio; float thresholdDb; }DRC_EXPANDER_PARAM_T; typedef enum { DRC_TYPE_COMPRESSOR,DRC_TYPE_LIMITER,DRC_TYPE_EXPANDER,DRC_TYPE_AUTO,}DRC_TYPE_E; typedef struct { DRC_TYPE_E eDrcType; union { DRC_COMPRESSOR_PARAM_T compressorParams; DRC_LIMITER_PARAM_T limiterParams; DRC_EXPANDER_PARAM_T expanderParams; }uDrcParams; float curGain; float curSmoothGainDb; float alphaAttack; float alphaRelease; unsigned long attackHoldCounter; unsigned long releaseHoldCounter; }DRC_HANDLE_T; typedef struct { float a[3]; float b[3]; }FILTER_COEFF_T; typedef enum { FILTER_TYPE_LPF,FILTER_TYPE_HPF,FILTER_TYPE_LSF,FILTER_TYPE_HSF,FILTER_TYPE_PEF,FILTER_TYPE_MAX,}FILTER_TYPE_E; typedef struct { unsigned long fs; unsigned long f0; float Q; float gainDb; }FILTER_PARAM_T; #define FILTER_MAX_CH 2 typedef struct { unsigned short xHistory[FILTER_MAX_CH][3]; unsigned short yHistory[FILTER_MAX_CH][3]; }FILTER_HISTORY_T; typedef struct { FILTER_TYPE_E eFilterType; FILTER_PARAM_T filterParams; FILTER_COEFF_T filterCoeff; FILTER_HISTORY_T filterHistory; }FILTER_HANDLE_T; FILTER_HANDLE_T gFilterHandle; typedef struct { short sampleValue; short bytesPerSample; }SAMPLE_INFO_T; void filterInit(FILTER_HANDLE_T *pFilterHandle,FILTER_TYPE_E eFilterType,FILTER_PARAM_T *pFilterParams) { float A = pow(10,pFilterParams->gainDb / 40); float w0 = 2 * 3.1415926 * pFilterParams->f0 / pFilterParams->fs; float cos_w0 = cos(w0); float sin_w0 = sin(w0); float alpha = sin_w0 / (2 * pFilterParams->Q); float *a = pFilterHandle->filterCoeff.a; float *b = pFilterHandle->filterCoeff.b; pFilterHandle->eFilterType = eFilterType; memcpy(&(pFilterHandle->filterParams),pFilterParams,sizeof(FILTER_PARAM_T)); memset(&(pFilterHandle->filterHistory),0,sizeof(FILTER_HISTORY_T)); switch(eFilterType) { case FILTER_TYPE_LPF: b[0] = (1 - cos_w0) / 2; b[1] = 1 - cos_w0; b[2] = (1 - cos_w0) / 2; a[0] = 1 + alpha; a[1] = -2 * cos_w0; a[2] = 1- alpha; break; case FILTER_TYPE_HPF: b[0] = (1 + cos_w0) / 2; b[1] = -(1 + cos_w0); b[2] = (1 + cos_w0) / 2; a[0] = 1 + alpha; a[1] = -2 * cos_w0; a[2] = 1- alpha; break; default: break; } } short filterCore(FILTER_HANDLE_T *pFilterHandle,short curSampleValue,short curChIdx) { short *x,*y; float *a,*b; x = pFilterHandle->filterHistory.xHistory[curChIdx]; y = pFilterHandle->filterHistory.yHistory[curChIdx]; a = pFilterHandle->filterCoeff.a; b = pFilterHandle->filterCoeff.b; x[0] = curSampleValue; y[0] = (b[0] * x[0] + b[1] * x[1] + b[2] * x[2] - a[1] * y[1] - a[2] * y[2]) / a[0]; x[2] = x[1]; x[1] = x[0]; y[2] = y[1]; y[1] = y[0]; return y[0]; } void filter(FILTER_HANDLE_T *pFilterHandle,DATA_INFO_T *pDataInfo) { unsigned short sampleIdx,chIdx; for (chIdx = 0; chIdx < pDataInfo->chNum; chIdx++) { for (sampleIdx = 0; sampleIdx < pDataInfo->samples; sampleIdx++) { pDataInfo->pData[chIdx][sampleIdx] = filterCore(pFilterHandle,pDataInfo->pData[chIdx][sampleIdx],chIdx); } } } float dbToGain(float db); DRC_HANDLE_T gDrcHandle; void drcInit(DRC_HANDLE_T *pDrcHandle,void * pDrcParams,DRC_TYPE_E eDrcType) { DRC_COMPRESSOR_PARAM_T *pCompressorParams; DRC_LIMITER_PARAM_T *pLimiterParams; DRC_EXPANDER_PARAM_T *pExpanderParams; if (pDrcHandle == NULL || pDrcParams == NULL || eDrcType > DRC_TYPE_AUTO) return; pDrcHandle->eDrcType = eDrcType; switch (eDrcType) { case DRC_TYPE_COMPRESSOR: pCompressorParams = (DRC_COMPRESSOR_PARAM_T *)pDrcParams; memcpy(&pDrcHandle->uDrcParams.compressorParams,pCompressorParams,sizeof(DRC_COMPRESSOR_PARAM_T)); pDrcHandle->alphaAttack = expf(-logf(9) / (48000 * pCompressorParams->attackTimeMs / 1000)); pDrcHandle->alphaRelease = expf(-logf(9) / (48000 * pCompressorParams->releaseTimeMs / 1000)); break; case DRC_TYPE_LIMITER: pLimiterParams = (DRC_LIMITER_PARAM_T *)pDrcParams; memcpy(&pDrcHandle->uDrcParams.limiterParams,pLimiterParams,sizeof(DRC_LIMITER_PARAM_T)); pDrcHandle->alphaAttack = expf(-logf(9) / (48000 * pLimiterParams->attackTimeMs / 1000)); pDrcHandle->alphaRelease = expf(-logf(9) / (48000 * pLimiterParams->releaseTimeMs / 1000)); break; case DRC_TYPE_EXPANDER: pExpanderParams = (DRC_EXPANDER_PARAM_T *)pDrcParams; memcpy(&pDrcHandle->uDrcParams.expanderParams,pExpanderParams,sizeof(DRC_EXPANDER_PARAM_T)); pDrcHandle->alphaAttack = expf(-logf(9) / (48000 * pExpanderParams->attackTimeMs / 1000)); pDrcHandle->alphaRelease = expf(-logf(9) / (48000 * pExpanderParams->releaseTimeMs /1000)); break; case DRC_TYPE_AUTO: break; } pDrcHandle->curGain = 1; pDrcHandle->curSmoothGainDb = 0; pDrcHandle->attackHoldCounter = 0; pDrcHandle->releaseHoldCounter = 0; } float sampleValueToDb(SAMPLE_INFO_T *pSampleInfo) { if (pSampleInfo == NULL) return 0; if (pSampleInfo->sampleValue == 0) pSampleInfo->sampleValue = 1; short maxSampleValue = ((1 << (pSampleInfo->bytesPerSample * 8)) - 1) / 2; float db = 20 * log10f((float)abs(pSampleInfo->sampleValue) / maxSampleValue); //printf("maxSampleValue:%d,sampleValue:%d,db:%fn",maxSampleValue,pSampleInfo->sampleValue,db); return db; } float drcComputeGainDb(DRC_HANDLE_T *pDrcHandle,float sampleDb) { if (pDrcHandle == NULL) return 0; float staticChract; switch (pDrcHandle->eDrcType) { case DRC_TYPE_COMPRESSOR: if (sampleDb < pDrcHandle->uDrcParams.compressorParams.thresholdDb) { staticChract = sampleDb; } else { staticChract = pDrcHandle->uDrcParams.compressorParams.thresholdDb + (sampleDb - pDrcHandle->uDrcParams.compressorParams.thresholdDb) / pDrcHandle->uDrcParams.compressorParams.ratio; } break; case DRC_TYPE_LIMITER: if (sampleDb < pDrcHandle->uDrcParams.limiterParams.thresholdDb) { staticChract = sampleDb; } else { staticChract = pDrcHandle->uDrcParams.limiterParams.thresholdDb; } break; case DRC_TYPE_EXPANDER: if (sampleDb >= pDrcHandle->uDrcParams.expanderParams.thresholdDb) { staticChract = sampleDb; } else { staticChract = pDrcHandle->uDrcParams.expanderParams.thresholdDb + (sampleDb - pDrcHandle->uDrcParams.expanderParams.thresholdDb) / pDrcHandle->uDrcParams.expanderParams.ratio; } break; case DRC_TYPE_AUTO: break; } //printf("staticChract:%f,sampleDb:%fn",staticChract,sampleDb); return staticChract - sampleDb; } float drcCompressorSmoothGain(DRC_HANDLE_T *pDrcHandle,float computeGainDb) { float smoothGainDb; if (computeGainDb < pDrcHandle->curSmoothGainDb) { smoothGainDb = pDrcHandle->alphaAttack * pDrcHandle->curSmoothGainDb + (1 - pDrcHandle->alphaAttack) * computeGainDb; } else { smoothGainDb = pDrcHandle->alphaRelease * pDrcHandle->curSmoothGainDb + (1 - pDrcHandle->alphaRelease) * computeGainDb; } return smoothGainDb; } float drcExpanderSmoothGain(DRC_HANDLE_T *pDrcHandle,float computeGainDb) { float smoothGainDb; unsigned long holdTimeInSample = pDrcHandle->uDrcParams.expanderParams.holdTimeMs * 48000 / 1000; if (pDrcHandle->attackHoldCounter >= holdTimeInSample && computeGainDb > pDrcHandle->curSmoothGainDb) { smoothGainDb = pDrcHandle->alphaAttack * pDrcHandle->curSmoothGainDb + (1 - pDrcHandle->alphaAttack) * computeGainDb; } else if (pDrcHandle->attackHoldCounter < holdTimeInSample && computeGainDb > pDrcHandle->curSmoothGainDb) { smoothGainDb = pDrcHandle->curSmoothGainDb; pDrcHandle->attackHoldCounter++; pDrcHandle->releaseHoldCounter = 0; } else if (pDrcHandle->releaseHoldCounter >= holdTimeInSample && computeGainDb <= pDrcHandle->curSmoothGainDb) { smoothGainDb = pDrcHandle->alphaRelease * pDrcHandle->curSmoothGainDb + (1 - pDrcHandle->alphaRelease) * computeGainDb; } else if (pDrcHandle->releaseHoldCounter < holdTimeInSample && computeGainDb <= pDrcHandle->curSmoothGainDb) { smoothGainDb = pDrcHandle->curSmoothGainDb; pDrcHandle->releaseHoldCounter++; pDrcHandle->attackHoldCounter = 0; } return smoothGainDb; } float drcSmoothGain(DRC_HANDLE_T *pDrcHandle,float computeGainDb) { if (pDrcHandle == NULL) return 0; float smoothGainDb; switch (pDrcHandle->eDrcType) { case DRC_TYPE_COMPRESSOR: case DRC_TYPE_LIMITER: smoothGainDb = drcCompressorSmoothGain(pDrcHandle,computeGainDb); break; case DRC_TYPE_EXPANDER: smoothGainDb = drcExpanderSmoothGain(pDrcHandle,computeGainDb); break; case DRC_TYPE_AUTO: break; } return smoothGainDb; } void drcCalGain(DRC_HANDLE_T *pDrcHandle,SAMPLE_INFO_T *pSampleInfo) { if (pDrcHandle == NULL || pSampleInfo == NULL) return; float sampleDb = sampleValueToDb(pSampleInfo); float computeGainDb = drcComputeGainDb(pDrcHandle,sampleDb); pDrcHandle->curSmoothGainDb = drcSmoothGain(pDrcHandle,computeGainDb); pDrcHandle->curGain = dbToGain(pDrcHandle->curSmoothGainDb); printf("sampleDb:%f,computeGainDb:%f,smoothGainDb:%f,curGain:%fn",sampleDb,computeGainDb,pDrcHandle->curSmoothGainDb,pDrcHandle->curGain); } void drc(DRC_HANDLE_T *pDrcHandle,chIdx; SAMPLE_INFO_T sampleInfo; for (chIdx = 0; chIdx < pDataInfo->chNum; chIdx++) { for (sampleIdx = 0; sampleIdx < pDataInfo->samples; sampleIdx++) { sampleInfo.bytesPerSample = 2; sampleInfo.sampleValue = pDataInfo->pData[chIdx][sampleIdx]; drcCalGain(pDrcHandle,&sampleInfo); pDataInfo->pData[chIdx][sampleIdx] *= pDrcHandle->curGain; } } } float mapSegGainToRealGain(FADER_HANDLE_T *pFaderHandle,float segGain) { float deltaGain = pFaderHandle->targetGain - pFaderHandle->startGain; float realGain = deltaGain * segGain + pFaderHandle->startGain; return realGain; } void faderPrepareShape(FADER_HANDLE_T *pFaderHandle,unsigned short segNum) { unsigned short segIdx; pFaderHandle->segGain = (float *)malloc((segNum + 1) * sizeof(float)); pFaderHandle->segNum = segNum; float tmp; if (pFaderHandle->faderParams.type != FADER_TYPE_CUBIC) return; //0~1 divide into N seg. for (segIdx = 0; segIdx < segNum + 1; segIdx++) { tmp = (float)segIdx / segNum; pFaderHandle->segGain[segIdx] = tmp * tmp * tmp; pFaderHandle->segGain[segIdx] = mapSegGainToRealGain(pFaderHandle,pFaderHandle->segGain[segIdx]); } } float dbToGain(float db) { return pow(10,db/20); } void faderInit(FADER_HANDLE_T *pFaderHandle,float attuationDb,FADER_TYPE_E type,unsigned long timeMs,unsigned long sampleRate,float curVolumDb) { pFaderHandle->faderParams.attuationDb = attuationDb; pFaderHandle->faderParams.type = type; pFaderHandle->faderParams.timeMs = timeMs; pFaderHandle->timeInSample = timeMs * sampleRate / 1000; pFaderHandle->curGain = pFaderHandle->startGain = dbToGain(curVolumDb); pFaderHandle->targetGain = dbToGain(curVolumDb + attuationDb); pFaderHandle->curSample = 0; faderPrepareShape(pFaderHandle,20); printf("faderInitn"); } void faderCalGain(FADER_HANDLE_T *pFaderHandle) { float startGainInCurSeg,endGainInCurSeg,step; float deltaGain = pFaderHandle->targetGain - pFaderHandle->startGain; unsigned long samplesInSeg = pFaderHandle->timeInSample / pFaderHandle->segNum; unsigned short curSeg = (float)pFaderHandle->curSample / samplesInSeg; unsigned long startSampleInCurSeg = samplesInSeg * curSeg; switch (pFaderHandle->faderParams.type) { case FADER_TYPE_LINE: step = deltaGain / pFaderHandle->timeInSample; pFaderHandle->curGain += deltaGain / pFaderHandle->timeInSample; //pFaderHandle->curGain = pFaderHandle->startGain + deltaGain * pFaderHandle->curSample / pFaderHandle->timeInSample; break; case FADER_TYPE_CUBIC: startGainInCurSeg = pFaderHandle->segGain[curSeg]; endGainInCurSeg = pFaderHandle->segGain[curSeg + 1]; step = (endGainInCurSeg - startGainInCurSeg) / samplesInSeg; if (pFaderHandle->curSample == startSampleInCurSeg) pFaderHandle->curGain = startGainInCurSeg; else pFaderHandle->curGain += step; break; } printf("curGain:%f,curSample:%ld,timeInSample:%ld,curSeg:%d,startGain:%f,endGain:%fn",pFaderHandle->curGain,pFaderHandle->curSample,pFaderHandle->timeInSample,curSeg,startGainInCurSeg,endGainInCurSeg); } void fader(FADER_HANDLE_T *pFaderHandle,chIdx; for (sampleIdx = 0; sampleIdx < pDataInfo->samples; sampleIdx++) { if (pFaderHandle->curSample != pFaderHandle->timeInSample) { faderCalGain(pFaderHandle); pFaderHandle->curSample++; } for (chIdx = 0; chIdx < pDataInfo->chNum; chIdx++) { pDataInfo->pData[chIdx][sampleIdx] *= pFaderHandle->curGain; } } } void printWaveHeader(WAVE_INFO *pWaveInfo) { printf("fileName:%sn",pWaveInfo->fileName); printf("riff chunk:n"); printf("chunkId:%c%c%c%cn",pWaveInfo->riffChunk.chunkId[0],pWaveInfo->riffChunk.chunkId[1],pWaveInfo->riffChunk.chunkId[2],pWaveInfo->riffChunk.chunkId[3]); printf("chunkSize:%ldn",pWaveInfo->riffChunk.chunkSize); printf("format:%c%c%c%cn",pWaveInfo->riffChunk.format[0],pWaveInfo->riffChunk.format[1],pWaveInfo->riffChunk.format[2],pWaveInfo->riffChunk.format[3]); printf("fmt chunk:n"); printf("chunkId:%c%c%cn",pWaveInfo->fmtChunk.chunkId[0],pWaveInfo->fmtChunk.chunkId[1],pWaveInfo->fmtChunk.chunkId[2]); printf("chunkSize:%ldn",pWaveInfo->fmtChunk.chunkSize); printf("audioFormat:%dn",pWaveInfo->fmtChunk.audioFormat); printf("chNum:%dn",pWaveInfo->fmtChunk.chNum); printf("sampleRate:%ldn",pWaveInfo->fmtChunk.sampleRate); printf("byteRate:%ldn",pWaveInfo->fmtChunk.byteRate); printf("blockAlign:%dn",pWaveInfo->fmtChunk.blockAlign); printf("bitsPerSample:%dn",pWaveInfo->fmtChunk.bitsPerSample); printf("data chunk:n"); printf("chunkId:%c%c%c%cn",pWaveInfo->dataChunk.chunkId[0],pWaveInfo->dataChunk.chunkId[1],pWaveInfo->dataChunk.chunkId[2],pWaveInfo->dataChunk.chunkId[3]); printf("chunkSize:%ldn",pWaveInfo->dataChunk.chunkSize); } void initWaveInfo(WAVE_INFO *pWaveInfo,unsigned short chNum,unsigned short bitsPerSample) { //strncpy(pWaveInfo->riffChunk.chunkId,"RIFF",4); pWaveInfo->riffChunk.chunkId[0] = ‘R‘; pWaveInfo->riffChunk.chunkId[1] = ‘I‘; pWaveInfo->riffChunk.chunkId[2] = ‘F‘; pWaveInfo->riffChunk.chunkId[3] = ‘F‘; pWaveInfo->riffChunk.chunkSize = 0; //strncpy(pWaveInfo->riffChunk.format,"WAVE",4); pWaveInfo->riffChunk.format[0] = ‘W‘; pWaveInfo->riffChunk.format[1] = ‘A‘; pWaveInfo->riffChunk.format[2] = ‘V‘; pWaveInfo->riffChunk.format[3] = ‘E‘; //strncpy(pWaveInfo->fmtChunk.chunkId,"fmt",3); pWaveInfo->fmtChunk.chunkId[0] = ‘f‘; pWaveInfo->fmtChunk.chunkId[1] = ‘m‘; pWaveInfo->fmtChunk.chunkId[2] = ‘t‘; pWaveInfo->fmtChunk.chunkId[3] = ‘ ‘; pWaveInfo->fmtChunk.chunkSize = sizeof(WAVE_FMT) - 8; pWaveInfo->fmtChunk.audioFormat = 1; pWaveInfo->fmtChunk.chNum = chNum; pWaveInfo->fmtChunk.sampleRate = sampleRate; pWaveInfo->fmtChunk.byteRate = sampleRate * chNum * bitsPerSample / 8; pWaveInfo->fmtChunk.blockAlign = chNum * bitsPerSample / 8; pWaveInfo->fmtChunk.bitsPerSample = bitsPerSample; //strncpy(pWaveInfo->dataChunk.chunkId,"data",4); pWaveInfo->dataChunk.chunkId[0] = ‘d‘; pWaveInfo->dataChunk.chunkId[1] = ‘a‘; pWaveInfo->dataChunk.chunkId[2] = ‘t‘; pWaveInfo->dataChunk.chunkId[3] = ‘a‘; pWaveInfo->dataChunk.chunkSize = 0; pWaveInfo->totalSampleNum = 0; ///printWaveHeader(pWaveInfo); } void rwRiffChunk(WAVE_INFO *pWaveInfo,unsigned char fgRead) { if (fgRead) { fread((char *)&pWaveInfo->riffChunk.chunkId,4,1,pWaveInfo->fp); fread((char *)&pWaveInfo->riffChunk.chunkSize,pWaveInfo->fp); fread((char *)&pWaveInfo->riffChunk.format,pWaveInfo->fp); } else { fwrite((char *)&pWaveInfo->riffChunk.chunkId,pWaveInfo->fp); fwrite((char *)&pWaveInfo->riffChunk.chunkSize,pWaveInfo->fp); fwrite((char *)&pWaveInfo->riffChunk.format,pWaveInfo->fp); } } void rwFmtChunk(WAVE_INFO *pWaveInfo,unsigned char fgRead) { if (fgRead) { fread((char *)&pWaveInfo->fmtChunk.chunkId,pWaveInfo->fp); fread((char *)&pWaveInfo->fmtChunk.chunkSize,pWaveInfo->fp); fread((char *)&pWaveInfo->fmtChunk.audioFormat,2,pWaveInfo->fp); fread((char *)&pWaveInfo->fmtChunk.chNum,pWaveInfo->fp); fread((char *)&pWaveInfo->fmtChunk.sampleRate,pWaveInfo->fp); fread((char *)&pWaveInfo->fmtChunk.byteRate,pWaveInfo->fp); fread((char *)&pWaveInfo->fmtChunk.blockAlign,pWaveInfo->fp); fread((char *)&pWaveInfo->fmtChunk.bitsPerSample,pWaveInfo->fp); } else { fwrite((char *)&pWaveInfo->fmtChunk.chunkId,pWaveInfo->fp); fwrite((char *)&pWaveInfo->fmtChunk.chunkSize,pWaveInfo->fp); fwrite((char *)&pWaveInfo->fmtChunk.audioFormat,pWaveInfo->fp); fwrite((char *)&pWaveInfo->fmtChunk.chNum,pWaveInfo->fp); fwrite((char *)&pWaveInfo->fmtChunk.sampleRate,pWaveInfo->fp); fwrite((char *)&pWaveInfo->fmtChunk.byteRate,pWaveInfo->fp); fwrite((char *)&pWaveInfo->fmtChunk.blockAlign,pWaveInfo->fp); fwrite((char *)&pWaveInfo->fmtChunk.bitsPerSample,pWaveInfo->fp); } } void rwDataChunk(WAVE_INFO *pWaveInfo,unsigned char fgRead) { if (fgRead) { fread((char *)&pWaveInfo->dataChunk.chunkId,pWaveInfo->fp); fread((char *)&pWaveInfo->dataChunk.chunkSize,pWaveInfo->fp); } else { fwrite((char *)&pWaveInfo->dataChunk.chunkId,pWaveInfo->fp); fwrite((char *)&pWaveInfo->dataChunk.chunkSize,pWaveInfo->fp); } } void readWaveHeader(char *fileName,WAVE_INFO *pWaveInfo) { size_t retSize; strncpy(pWaveInfo->fileName,fileName,strlen(fileName)); pWaveInfo->fp = fopen(fileName,"rb"); if (pWaveInfo->fp == NULL) { printf("fopen fail,errno:%dn",errno); return; } #if 0 retSize = fread((char *)&pWaveInfo->riffChunk,sizeof(WAVE_RIFF),pWaveInfo->fp); retSize = fread((char *)&pWaveInfo->fmtChunk,sizeof(WAVE_FMT),pWaveInfo->fp); retSize = fread((char *)&pWaveInfo->dataChunk,sizeof(WAVE_DATA),pWaveInfo->fp); #endif rwRiffChunk(pWaveInfo,1); rwFmtChunk(pWaveInfo,1); rwDataChunk(pWaveInfo,1); pWaveInfo->pos = ftell(pWaveInfo->fp); pWaveInfo->totalSampleNum = pWaveInfo->dataChunk.chunkSize / (pWaveInfo->fmtChunk.bitsPerSample / 8); fclose(pWaveInfo->fp); printWaveHeader(pWaveInfo); } void initPpBuf(unsigned short chNum,unsigned short bankNum,unsigned long samplesPerBank,unsigned short bytesPerSample) { unsigned short chIdx,bankIdx; gPpBuf.chNum = chNum; gPpBuf.bankNum = bankNum; gPpBuf.samplesPerBank = samplesPerBank; gPpBuf.bytesPerSample = bytesPerSample; gPpBuf.bankRp = gPpBuf.bankWp = 0; gPpBuf.fgEos = 0; gPpBuf.pData = (unsigned char ***)malloc(chNum * sizeof(unsigned char **)); for (chIdx = 0; chIdx < chNum; chIdx++) { gPpBuf.pData[chIdx] = (unsigned char **)malloc(bankNum * sizeof(unsigned char *)); for (bankIdx =0; bankIdx < bankNum; bankIdx++) { gPpBuf.pData[chIdx][bankIdx] = (unsigned char *) malloc(samplesPerBank * bytesPerSample * sizeof(unsigned char)); } } gPpBuf.fgInited = 1; } int sendData(unsigned char *writeBuffer,unsigned short chNum) { unsigned short sampleIdx,chIdx,byteIdx; //printf("sendData,wp:%d,rp:%dn",gPpBuf.bankWp,gPpBuf.bankRp); if ((gPpBuf.bankWp + 1 ) % gPpBuf.bankNum == gPpBuf.bankRp) { //full return 1; } else { for (sampleIdx = 0; sampleIdx < PP_SAMPLES; sampleIdx++) { for (chIdx =0; chIdx < chNum; chIdx++) { for (byteIdx = 0; byteIdx < gPpBuf.bytesPerSample; byteIdx++) { gPpBuf.pData[chIdx][gPpBuf.bankWp][sampleIdx * gPpBuf.bytesPerSample + byteIdx] = writeBuffer[(chIdx + sampleIdx * chNum) * gPpBuf.bytesPerSample + byteIdx]; } } } gPpBuf.bankWp = (gPpBuf.bankWp + 1) % gPpBuf.bankNum; } return 0; } int recvData(unsigned char **readBuffer) { unsigned short chIdx; //printf("recvData,gPpBuf.bankRp); if (gPpBuf.bankWp == gPpBuf.bankRp) { //empty return 1; } else { for (chIdx = 0; chIdx < gPpBuf.chNum; chIdx++) { memcpy(&readBuffer[chIdx][0],&gPpBuf.pData[chIdx][gPpBuf.bankRp][0],PP_SAMPLES * gPpBuf.bytesPerSample * sizeof(unsigned char)); } gPpBuf.bankRp = (gPpBuf.bankRp + 1) % gPpBuf.bankNum; } return 0; } void *readThread(void *arg) { char *fileName = (char *)arg; size_t retSize; WAVE_INFO waveInfo; memset(&waveInfo,sizeof(WAVE_INFO)); unsigned long bytesPerLoop; unsigned short loopIdx,loop; unsigned long readCount = 0; readWaveHeader(fileName,&waveInfo); initPpBuf(waveInfo.fmtChunk.chNum,3,PP_SAMPLES,2); unsigned long readSize = READ_SAMPLES * waveInfo.fmtChunk.chNum * waveInfo.fmtChunk.bitsPerSample / 8; printf("readSize:%ldn",readSize); unsigned char *readBuffer = (unsigned char *)malloc(readSize * sizeof(unsigned char)); waveInfo.fp = fopen(fileName,"rb"); fseek(waveInfo.fp,waveInfo.pos,SEEK_SET); while (1) { retSize = fread(readBuffer,readSize,1,waveInfo.fp); if (retSize <= 0) { printf("fread fail,retSize:%d,%s,eof:%d,readCount:%ldn",(int) retSize,strerror(errno),feof(waveInfo.fp),readCount); gPpBuf.fgEos = 1; break; } else { bytesPerLoop = PP_SAMPLES *waveInfo.fmtChunk.chNum * waveInfo.fmtChunk.bitsPerSample / 8; loop = readSize / bytesPerLoop; loopIdx = 0; while (loopIdx < loop) { if (0 != sendData(readBuffer + loopIdx * bytesPerLoop,waveInfo.fmtChunk.chNum)) { usleep(1000); } else { loopIdx++; } } readCount++; } } return NULL; } void pp(DATA_INFO_T *pDataInfo) { //fader(&gFaderHandle,pDataInfo); //drc(&gDrcHandle,pDataInfo); filter(&gFilterHandle,pDataInfo); } void saveOneChInWave(unsigned char *pData,unsigned long size,WAVE_INFO *pWaveInfo) { size_t retSize = 0; if (pWaveInfo->fp == NULL) { pWaveInfo->fp = fopen(pWaveInfo->fileName,"wb"); #if 0 retSize = fwrite((char *)&pWaveInfo->riffChunk,pWaveInfo->fp); retSize = fwrite((char *)&pWaveInfo->fmtChunk,pWaveInfo->fp); retSize = fwrite((char *)&pWaveInfo->dataChunk,pWaveInfo->fp); #endif rwRiffChunk(pWaveInfo,0); rwFmtChunk(pWaveInfo,0); rwDataChunk(pWaveInfo,0); } retSize = fwrite(pData,size,pWaveInfo->fp); pWaveInfo->totalSampleNum += (size / pWaveInfo->fmtChunk.chNum / (pWaveInfo->fmtChunk.bitsPerSample / 8)); pWaveInfo->pos = ftell(pWaveInfo->fp); } void updateWaveHeader(WAVE_INFO *pWaveInfo) { size_t retSize; pWaveInfo->riffChunk.chunkSize = pWaveInfo->pos - 8; pWaveInfo->dataChunk.chunkSize = pWaveInfo->totalSampleNum * pWaveInfo->fmtChunk.chNum * pWaveInfo->fmtChunk.bitsPerSample / 8; fseek(pWaveInfo->fp,0,SEEK_SET); #if 0 retSize = fwrite((char *)&pWaveInfo->riffChunk,pWaveInfo->fp); retSize = fwrite((char *)&pWaveInfo->fmtChunk,pWaveInfo->fp); retSize = fwrite((char *)&pWaveInfo->dataChunk,pWaveInfo->fp); #endif rwRiffChunk(pWaveInfo,0); rwFmtChunk(pWaveInfo,0); rwDataChunk(pWaveInfo,0); fclose(pWaveInfo->fp); printWaveHeader(pWaveInfo); } void *ppThread(void *arg) { char *fileName = (char *)arg; WAVE_INFO waveInfo; memset(&waveInfo,sizeof(waveInfo)); strncpy(waveInfo.fileName,strlen(fileName)); printf("out file:%sn",waveInfo.fileName); waveInfo.fp = NULL; while(!gPpBuf.fgInited) { usleep(1000); } initWaveInfo(&waveInfo,48000,16); unsigned char **readBuffer = (unsigned char **)malloc(gPpBuf.chNum * sizeof(unsigned char *)); unsigned short chIdx; for(chIdx = 0; chIdx < gPpBuf.chNum; chIdx++) { readBuffer[chIdx] = (unsigned char *)malloc(PP_SAMPLES * gPpBuf.bytesPerSample * sizeof(unsigned char)); } while (1) { if (0 != recvData(readBuffer)) { if (gPpBuf.fgEos) break; usleep(1000); } else { DATA_INFO_T dataInfo; dataInfo.chNum = gPpBuf.chNum; dataInfo.samples = PP_SAMPLES; dataInfo.bytesPerSample = gPpBuf.bytesPerSample; dataInfo.pData = (short **)readBuffer; pp(&dataInfo); saveOneChInWave(readBuffer[0],PP_SAMPLES * gPpBuf.bytesPerSample,&waveInfo); } } updateWaveHeader(&waveInfo); fgEnd = 1; } int main(int argc,char **argv) { #if 0 WAVE_INFO inputWaveInfo,outputWaveInfo; readWaveHeader(argv[1],&inputWaveInfo); //initWaveInfo(&outputWaveInfo,2,48000,16); #endif #if 1 pthread_t readThreadId,ppThreadId; memset(&gPpBuf,sizeof(PP_BUF_T)); // initPpBuf(6,3,2); #if 0 memset(&gFaderHandle,sizeof(FADER_HANDLE_T)); float curVolumDb = 0; float attuationDb = -5; FADER_TYPE_E type = FADER_TYPE_CUBIC; unsigned long timeMs = 5000; unsigned long sampleRate = 48000; faderInit(&gFaderHandle,attuationDb,type,timeMs,sampleRate,curVolumDb); #endif memset(&gDrcHandle,sizeof(DRC_HANDLE_T)); #if 0 DRC_COMPRESSOR_PARAM_T compressorParams; compressorParams.thresholdDb = -15; compressorParams.attackTimeMs = 1; compressorParams.releaseTimeMs = 10; compressorParams.ratio = 4; drcInit(&gDrcHandle,&compressorParams,DRC_TYPE_COMPRESSOR); #endif #if 0 DRC_LIMITER_PARAM_T limiterParams; limiterParams.thresholdDb = -15; limiterParams.attackTimeMs = 20; limiterParams.releaseTimeMs = 200; drcInit(&gDrcHandle,&limiterParams,DRC_TYPE_LIMITER); #endif #if 0 DRC_EXPANDER_PARAM_T expanderParams; expanderParams.thresholdDb = -30; expanderParams.attackTimeMs = 10; expanderParams.releaseTimeMs = 100; expanderParams.ratio = 4; expanderParams.holdTimeMs = 0; drcInit(&gDrcHandle,&expanderParams,DRC_TYPE_EXPANDER); #endif #if 0 FILTER_PARAM_T filterParams; memset(&filterParams,sizeof(FILTER_PARAM_T)); filterParams.fs = 48000; filterParams.f0 = 500; filterParams.Q = 0.707; filterInit(&gFilterHandle,FILTER_TYPE_LPF,&filterParams); #endif FILTER_PARAM_T filterParams; memset(&filterParams,sizeof(FILTER_PARAM_T)); filterParams.fs = 48000; filterParams.f0 = 8000; filterParams.Q = 0.707; filterInit(&gFilterHandle,&filterParams); pthread_create(&readThreadId,NULL,readThread,argv[1]); pthread_create(&ppThreadId,ppThread,argv[2]); while(!fgEnd) { sleep(1); } #endif return 0; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |