This is getResidual.c in view mode; [Download] [Up]
#include "../sms.h" SNDSoundStruct residualHeader; char *pChResidualFile = "residual.snd"; char *pChDebugFile = "debug.txt"; FILE *pSfResidual, *pDebug; /* function to create the residual sound file */ int createResidualFile (ANAL_PARAMS analParams) { if ((pSfResidual = fopen(pChResidualFile, "w+")) == NULL) { fprintf(stderr, "Cannot open soundfile: %s\n", pChResidualFile); exit(1); } residualHeader.magic = SND_MAGIC; residualHeader.dataLocation = sizeof(SNDSoundStruct); residualHeader.dataSize = 0; residualHeader.dataFormat = SND_FORMAT_LINEAR_16; residualHeader.samplingRate = (int) analParams.fSamplingRate; residualHeader.channelCount = 1; *(int *)residualHeader.info = 0; fwrite((void *)&residualHeader, sizeof(SNDSoundStruct), 1, pSfResidual); return 1; } /* function to create the residual sound file */ int createDebugFile (ANAL_PARAMS analParams) { if ((pDebug = fopen(pChDebugFile, "w+")) == NULL) { fprintf(stderr, "Cannot open debugfile: %s\n", pChDebugFile); exit(1); } return 1; } /* function to write to the residual sound file */ static int writeToResidualFile (float *pFBuffer, int sizeBuffer) { int i; short *pSResidual; if ((pSResidual = (short *) calloc(sizeBuffer, sizeof(short))) == NULL) return -1; for (i = 0; i < sizeBuffer; i++) pSResidual[i] = (short) DeEmphasis (pFBuffer[i]); fwrite((void *)pSResidual, sizeof(short), sizeBuffer, pSfResidual); residualHeader.dataSize += sizeBuffer * sizeof(short); free (pSResidual); return 1; } /* function to write to the debug file */ static int writeToDebugFile (float *pFBuffer1, float *pFBuffer2, float *pFBuffer3, int sizeBuffer) { int i; static int counter = 0; for (i = 0; i < sizeBuffer; i++) fprintf (pDebug, "%d %d %d %d\n", counter++, (int)pFBuffer1[i], (int)pFBuffer2[i], (int)pFBuffer3[i]); return 1; } /* function to write the residual sound file to disk */ int writeResidualFile () { rewind(pSfResidual); fwrite((void *)&residualHeader, sizeof(SNDSoundStruct), 1, pSfResidual); fclose (pSfResidual); return 1; } /* function to write the residual sound file to disk */ int writeDebugFile () { fclose (pDebug); return 1; } /* function to implement a pole-zero filter * the returned value is the filtered sample * * float *pFa; numerator coefficients * float *pFb; denominator coefficients * int nCoeff; number of coefficients * float fInput; input sample */ static float ZeroPoleFilter (float *pFa, float *pFb, int nCoeff, float fInput, float *pD) { double fOut = 0; int iSection; pD[0] = fInput; for (iSection = nCoeff-1; iSection > 0; iSection--) { fOut = fOut + pFa[iSection] * pD[iSection]; pD[0] = pD[0] - pFb[iSection] * pD[iSection]; pD[iSection] = pD [iSection-1]; } fOut = fOut + pFa[0] * pD[0]; return((float) fOut); } /* cutoff 1500 Hz */ /* static float pFCoeff32k[10] = {0.679459, -2.71784, 4.07676, -2.71784, 0.679459, 1, -3.23168, 3.97664, -2.20137, 0.461665}; static float pFCoeff36k[10] = {0.709489, -2.83796, 4.25694, -2.83796, 0.709489, 1, -3.31681, 4.17425, -2.3574, 0.503375}; static float pFCoeff40k[10] = {0.734408, -2.93763, 4.40645, -2.93763, 0.734408, 1, -3.38497, 4.33706, -2.48914, 0.539355}; static float pFCoeff441k[10] = {0.755893, -3.02357, 4.53536, -3.02357, 0.755893, 1, -3.44205, 4.47657, -2.6043, 0.571374}; static float pFCoeff48k[10] = {0.773347, -3.09339, 4.64008, -3.09339, 0.773347, 1, -3.48731, 4.58929, -2.69888, 0.598065}; */ /* function to filter a waveform with a high-pass filter with cutoff * at 1500 Hz * * float *pFResidual; residual signal * int sizeResidual; size of signal * float fSamplingRate; sampling rate of signal */ static void FilterResidual (float *pFResidual, int sizeResidual, float fSamplingRate, float *pD) { /* cutoff 800Hz */ static float pFCoeff32k[10] = {0.814255, -3.25702, 4.88553, -3.25702, 0.814255, 1, -3.58973, 4.85128, -2.92405, 0.66301}; static float pFCoeff36k[10] = {0.833098, -3.33239, 4.99859, -3.33239, 0.833098, 1, -3.63528, 4.97089, -3.02934,0.694052}; static float pFCoeff40k[10] = {0.848475, -3.3939, 5.09085, -3.3939, 0.848475, 1, -3.67173, 5.068, -3.11597, 0.71991}; static float pFCoeff441k[10] = {0.861554, -3.44622, 5.16932, -3.44622, 0.861554, 1, -3.70223, 5.15023, -3.19013, 0.742275}; static float pFCoeff48k[10] = {0.872061, -3.48824, 5.23236, -3.48824, 0.872061, 1, -3.72641, 5.21605, -3.25002, 0.76049}; float *pFCoeff, fSample = 0; int i; if (fSamplingRate <= 32000) pFCoeff = pFCoeff32k; else if (fSamplingRate <= 36000) pFCoeff = pFCoeff36k; else if (fSamplingRate <= 40000) pFCoeff = pFCoeff40k; else if (fSamplingRate <= 44100) pFCoeff = pFCoeff441k; else pFCoeff = pFCoeff48k; for(i = 0; i < sizeResidual; i++) { /* try to avoid underflow when there is nothing to filter */ if (i > 0 && fSample == 0 && pFResidual[i] == 0) return; fSample = pFResidual[i]; pFResidual[i] = ZeroPoleFilter (&pFCoeff[0], &pFCoeff[5], 5, fSample, pD); } } /* get the residual waveform * return 0 if no representation, 1 if got a representation * * float *pFSynthesis; deterministic component * float *pFOriginal; original waveform * float *pFResidual; output residual waveform * int sizeWindow; size of buffer * SMS_DATA *pSmsData; pointer to output SMS data * ANAL_PARAMS analParams; analysis parameters */ int GetResidual (float *pFSynthesis, float *pFOriginal, float *pFResidual, int sizeWindow, ANAL_PARAMS analParams) { static float fResidualMag = 0, fOriginalMag = 0, *pD = NULL, *pFWindow = NULL; float fScale = 1, fCurrentResidualMag = 0, fCurrentOriginalMag = 0; int i; /* allocate memory for filter coefficients */ if (pD == NULL) pD = (float *) calloc(5, sizeof(float)); if (pFWindow == NULL) { if ((pFWindow = (float *) calloc(sizeWindow, sizeof(float))) == NULL) return -1; Hamming (sizeWindow, pFWindow); } /* get residual */ for (i=0; i<sizeWindow; i++) pFResidual[i] = pFOriginal[i] - pFSynthesis[i]; /* get energy of residual */ for (i=0; i<sizeWindow; i++) fCurrentResidualMag += fabs((double) pFResidual[i] * pFWindow[i]); /* if residual is big enough compute coefficients */ if (fCurrentResidualMag/sizeWindow > .01) { /* get energy of original */ for (i=0; i<sizeWindow; i++) fCurrentOriginalMag += fabs((double) pFOriginal[i] * pFWindow[i]); fOriginalMag = .5 * (fCurrentOriginalMag/sizeWindow + fOriginalMag); fResidualMag = .5 * (fCurrentResidualMag/sizeWindow + fResidualMag); /* scale residual if need to be */ if (fResidualMag > fOriginalMag) { fScale = fOriginalMag / fResidualMag; for (i=0; i<sizeWindow; i++) pFResidual[i] *= fScale; if (analParams.iDebugMode == DEBUG_ALL || analParams.iDebugMode == DEBUG_STOC_ANAL) fprintf(stdout, "getResidual: frame %d: scaled residual by %f\n", ppFrames[0]->iFrameNum, fScale); } /* store residual percentage in global variable */ FResidualPerc += fCurrentResidualMag / fCurrentOriginalMag; if (analParams.iDebugMode == DEBUG_ALL || analParams.iDebugMode == DEBUG_STOC_ANAL) fprintf (stdout, "getResidual: frame %d, residual perc %f \n", ppFrames[0]->iFrameNum, fCurrentResidualMag / fCurrentOriginalMag); if (analParams.iDebugMode == 13) fprintf (stdout, "%f\n", fCurrentResidualMag / fCurrentOriginalMag); if (analParams.iDebugMode == DEBUG_SYNC) writeToDebugFile (pFOriginal+sizeWindow/2, pFSynthesis+sizeWindow/2, pFResidual+sizeWindow/2, sizeWindow/2); if (analParams.iDebugMode == DEBUG_RESIDUAL) writeToResidualFile (pFResidual+sizeWindow/2, sizeWindow/2); /* filter residual with a high pass filter (it solves some problems) */ FilterResidual (pFResidual, sizeWindow, analParams.fSamplingRate, pD); return (1); } if (analParams.iDebugMode == DEBUG_SYNC) writeToDebugFile (pFOriginal+sizeWindow/2, pFSynthesis+sizeWindow/2, pFResidual+sizeWindow/2, sizeWindow/2); if (analParams.iDebugMode == DEBUG_RESIDUAL) writeToResidualFile (pFResidual+sizeWindow/2, sizeWindow/2); return (0); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.