This is stocAnalysis.c in view mode; [Download] [Up]
#include "../sms.h" #define ENV_THRESHOLD .01 /* get the stochastic representation from the residual waveform * by approximating its spectrum with an IIR filter * return -1 if no representation, 1 if got a representation * * float *pFResidual; residual signal * int sizeWindow; size of buffer * SMS_DATA *pSmsData; pointer to output SMS data * ANAL_PARAMS analParams; analysis parameters */ static int StocAnalysisIIR (float *pFResidual, int sizeWindow, SMS_DATA *pSmsData, ANAL_PARAMS analParams) { int nStage = pSmsData->nCoeff, nMax = pSmsData->nCoeff+1, i, j; float *pFCovMatrix, *pFOldCoeff, *pFOtherCoeff, *pFScratch, fError = 0; static float fOldError = 0; /* allocate temporary arrays */ if ((pFCovMatrix = (float *) calloc ((pSmsData->nCoeff+1) * (pSmsData->nCoeff+1), sizeof(float))) == NULL) return -1; if ((pFOldCoeff = (float *) calloc(pSmsData->nCoeff, sizeof(float))) == NULL) return -1; if ((pFOtherCoeff = (float *) calloc(pSmsData->nCoeff, sizeof(float))) == NULL) return -1; if ((pFScratch = (float *) calloc(pSmsData->nCoeff+1, sizeof(float))) == NULL) return -1; /* compute the covariance matrix */ Covariance (pFResidual-1, sizeWindow, nStage, pFCovMatrix, nMax); /* get the lattice coefficients */ for (i = 1; i <= pSmsData->nCoeff; i++) { CovLatticeHarm (pFCovMatrix, nMax, i, pFOtherCoeff, &pSmsData->pFStocCoeff[i-1], &fError, pFScratch); /* check for unstable filter */ if (fabs (pSmsData->pFStocCoeff[i-1]) >= 1) { fprintf (stderr, "stocAnalysis: unstable filter, using previous one\n"); for (j = 0; j < pSmsData->nCoeff; j++) pSmsData->pFStocCoeff[j] = pFOldCoeff[j]; fError = fOldError; break; } } /* check for wrong error */ if (fError > 0 && fError < 3.40282346638528860e+38) /* get the gain from the error */ *(pSmsData->pFStocGain) = TO_DB(sqrt(fError / sizeWindow)); else { fprintf (stderr, "stocAnalysis: unstable filter, setting to 0\n"); for (j = 0; j < pSmsData->nCoeff; j++) pSmsData->pFStocCoeff[j] = 0; *(pSmsData->pFStocGain) = 0; fError = 0; } /* save result in case next filter is unstable */ for (i = 0; i < pSmsData->nCoeff; i++) pFOldCoeff[i] = pSmsData->pFStocCoeff[i]; fOldError = fError; free ((char *) pFCovMatrix); free ((char *) pFOldCoeff); free ((char *) pFOtherCoeff); free ((char *) pFScratch); return (1); } /* get the stochastic representation from the residual waveform * by fitting a line segments to its magnitude spectrum * return -1 if no representation, 1 if got a representation * * float *pFResidual; residual signal * int sizeWindow; size of buffer * SMS_DATA *pSmsData; pointer to output SMS data * ANAL_PARAMS analParams; analysis parameters */ static int StocAnalysisFFT (float *pFResidual, int sizeWindow, SMS_DATA *pSmsData, ANAL_PARAMS analParams) { int i, sizeFft = (int) pow(2.0, (float)(1+(floor(log((float) sizeWindow) / LOG2)))), sizeMag = sizeFft >> 1; float *pFMagSpectrum, fMag = 0; static float *pFWindow = NULL; /* allocate buffers */ if ((pFMagSpectrum = (float *) calloc(sizeMag, sizeof(float))) == NULL) return -1; if (pFWindow == NULL) { if ((pFWindow = (float *) calloc(sizeWindow, sizeof(float))) == NULL) return -1; Hamming (sizeWindow, pFWindow); } QuickSpectrumF (pFResidual, pFWindow, sizeWindow, pFMagSpectrum, (float *) NULL, sizeFft); SpectralApprox (pFMagSpectrum, sizeMag, sizeMag, pSmsData->pFStocCoeff, pSmsData->nCoeff, pSmsData->nCoeff); /* get energy of spectrum */ for (i = 0; i < sizeMag; i++) fMag += pFMagSpectrum[i]; *pSmsData->pFStocGain = MAX (fMag / sizeMag, ENV_THRESHOLD); /* normalize envelope */ for (i = 0; i < pSmsData->nCoeff; i++) pSmsData->pFStocCoeff[i] /= *pSmsData->pFStocGain; *pSmsData->pFStocGain = TO_DB (*pSmsData->pFStocGain); free ((char *) pFMagSpectrum); return (1); } /* main function for the stochastic analysis * return -1 if no representation, 1 if got a representation * float *pFResidual; residual signal * int sizeWindow; size of buffer * SMS_DATA *pSmsData; pointer to output SMS data * ANAL_PARAMS analParams; analysis parameters */ int StocAnalysis (float *pFResidual, int sizeWindow, SMS_DATA *pSmsData, ANAL_PARAMS analParams) { int iError = 1; if (analParams.iStochasticType == 1) iError = StocAnalysisIIR (pFResidual, sizeWindow, pSmsData, analParams); else if (analParams.iStochasticType == 2) iError = StocAnalysisFFT (pFResidual, sizeWindow, pSmsData, analParams); else return -1; return iError; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.