/*! \brief Spectrum Envelope from Cepstrum * * from a set of cepstrum coefficients, compute the spectrum envelope * * \param sizeCepstrum order + 1 of the cepstrum * \param pCepstrum pointer to array of cepstrum coefficients * \param sizeEnv size of spectrum envelope (max frequency in bins) \todo does this have to be a pow2 * \param pEnv pointer to output spectrum envelope (real part only) */ void sms_dCepstrumEnvelope(int sizeCepstrum, sfloat *pCepstrum, int sizeEnv, sfloat *pEnv) { static sfloat *pFftBuffer; static int sizeFftArray = 0; int sizeFft = sizeEnv << 1; int i; if(sizeFftArray != sizeFft) { if(sizeFftArray != 0) free(pFftBuffer); sizeFftArray = sms_power2(sizeFft); if(sizeFftArray != sizeFft) { sms_error("bad fft size, incremented to power of 2"); } if ((pFftBuffer = (sfloat *) malloc(sizeFftArray * sizeof(float))) == NULL) { sms_error("could not allocate memory for fft array"); return; } } memset(pFftBuffer, 0, sizeFftArray * sizeof(sfloat)); pFftBuffer[0] = pCepstrum[0] * 0.5; for (i = 1; i < sizeCepstrum-1; i++) pFftBuffer[i] = pCepstrum[i]; sms_fft(sizeFftArray, pFftBuffer); for (i = 0; i < sizeEnv; i++) pEnv[i] = powf(EXP, 2. * pFftBuffer[i*2]); }
/*! \brief rewrite SMS header and close file * * \param pSmsFile pointer to SMS file * \param pSmsHeader pointer to header for SMS file * \return error code \see SMS_WRERR in SMS_ERRORS */ int sms_writeFile (FILE *pSmsFile, SMS_Header *pSmsHeader) { int iVariableSize; rewind(pSmsFile); /* check variable size of header */ iVariableSize = sizeof(char) * pSmsHeader->nTextCharacters; pSmsHeader->iHeadBSize = sizeof(SMS_Header) + iVariableSize; /* write header */ if (fwrite((void *)pSmsHeader, (size_t)1, (size_t)sizeof(SMS_Header), pSmsFile) < (size_t)sizeof(SMS_Header)) { sms_error("cannot write output file (header)"); return(-1); } if (pSmsHeader->nTextCharacters > 0) { char *pChStart = (char *) pSmsHeader->pChTextCharacters; int iSize = sizeof(char) * pSmsHeader->nTextCharacters; if (fwrite ((void *)pChStart, (size_t)1, (size_t)iSize, pSmsFile) < (size_t)iSize) { sms_error("cannot write output file (nTextCharacters)"); return(-1); } } fclose(pSmsFile); return (0); }
/* Pop up an error dialog. */ void popup_an_error(const char *fmt, ...) { va_list args; va_start(args, fmt); (void) vsnprintf(vmsgbuf, sizeof(vmsgbuf), fmt, args); va_end(args); /* Log to the trace file. */ trace_dsn("%s\n", vmsgbuf); if (sms_redirect()) { sms_error(vmsgbuf); return; } else { #if defined(C3270) /*[*/ screen_suspend(); any_error_output = True; #endif /*]*/ (void) fprintf(stderr, "%s\n", vmsgbuf); fflush(stderr); macro_output = True; } }
/*! \brief prepare the Sinc table * * used for the main lobe of a frequency domain * BlackmanHarris92 window * * \param nTableSize size of table * \return error code \see SMS_MALLOC in SMS_ERRORS */ int sms_prepSinc(int nTableSize) { int i, m; sfloat N = 512.0; sfloat fA[4] = {.35875, .48829, .14128, .01168}; sfloat fMax = 0; sfloat fTheta = -4.0 * TWO_PI / N; sfloat fThetaIncr = (8.0 * TWO_PI / N) / (nTableSize); sms_tab_sinc = (sfloat *)calloc(nTableSize, sizeof(float)); if(sms_tab_sinc == NULL) { sms_error("Could not allocate memory for sinc table"); return (SMS_MALLOC); } for(i = 0; i < nTableSize; i++) { for (m = 0; m < 4; m++) sms_tab_sinc[i] += -1 * (fA[m]/2) * (Sinc (fTheta - m * TWO_PI/N, N) + Sinc (fTheta + m * TWO_PI/N, N)); fTheta += fThetaIncr; } fMax = sms_tab_sinc[(int) nTableSize / 2]; for (i = 0; i < nTableSize; i++) sms_tab_sinc[i] = sms_tab_sinc[i] / fMax; fSincScale = (sfloat) nTableSize / 8.0; return SMS_OK; }
/*! \brief write SMS header to file * * \param pChFileName file name for SMS file * \param pSmsHeader header for SMS file * \param ppSmsFile (double pointer to) file to be created * \return error code \see SMS_WRERR in SMS_ERRORS */ int sms_writeHeader (char *pChFileName, SMS_Header *pSmsHeader, FILE **ppSmsFile) { int iVariableSize = 0; if (pSmsHeader->iSmsMagic != SMS_MAGIC) { sms_error("not an SMS file"); return(-1); } if ((*ppSmsFile = fopen (pChFileName, "w+")) == NULL) { sms_error("cannot open file for writing"); return(-1); } /* check variable size of header */ /* iVariableSize = sizeof (int) * pSmsHeader->nLoopRecords + */ /* sizeof (sfloat) * pSmsHeader->nSpecEnvelopePoints + */ /* sizeof(char) * pSmsHeader->nTextCharacters; */ iVariableSize = sizeof(char) * pSmsHeader->nTextCharacters; pSmsHeader->iHeadBSize = sizeof(SMS_Header) + iVariableSize; /* write header */ if (fwrite((void *)pSmsHeader, (size_t)1, (size_t)sizeof(SMS_Header), *ppSmsFile) < (size_t)sizeof(SMS_Header)) { sms_error("cannot write output file"); return(-1); } /* write variable part of header */ if (pSmsHeader->nTextCharacters > 0) { char *pChStart = (char *) pSmsHeader->pChTextCharacters; int iSize = sizeof(char) * pSmsHeader->nTextCharacters; if (fwrite ((void *)pChStart, (size_t)1, (size_t)iSize, *ppSmsFile) < (size_t)iSize) { sms_error("cannot write output file (nTextCharacters)"); return(-1); } } return (0); }
/*! \brief read an SMS data frame * * \param pSmsFile pointer to SMS file * \param pSmsHeader pointer to SMS header * \param iFrame frame number * \param pSmsFrame pointer to SMS frame * \return 0 on sucess, -1 on error */ int sms_getFrame (FILE *pSmsFile, SMS_Header *pSmsHeader, int iFrame, SMS_Data *pSmsFrame) { if (fseek (pSmsFile, pSmsHeader->iHeadBSize + iFrame * pSmsHeader->iFrameBSize, SEEK_SET) < 0) { sms_error ("cannot seek to the SMS frame"); return (-1); } if ((pSmsHeader->iFrameBSize = fread ((void *)pSmsFrame->pSmsData, (size_t)1, (size_t)pSmsHeader->iFrameBSize, pSmsFile)) != pSmsHeader->iFrameBSize) { sms_error ("cannot read SMS frame"); return (-1); } return (0); }
/*! \brief write SMS frame * * \param pSmsFile pointer to SMS file * \param pSmsHeader pointer to SMS header * \param pSmsFrame pointer to SMS data frame * \return 0 on success, -1 on failure */ int sms_writeFrame (FILE *pSmsFile, SMS_Header *pSmsHeader, SMS_Data *pSmsFrame) { if (fwrite ((void *)pSmsFrame->pSmsData, 1, pSmsHeader->iFrameBSize, pSmsFile) < (unsigned int) pSmsHeader->iFrameBSize) { sms_error("cannot write frame to output file"); return(-1); } else return (0); }
/*! \brief main function for computing spectral envelope from sinusoidal peaks * * Magnitudes should already be in linear for this function. * If pSmsData->iEnvelope == SMS_ENV_CEP, will return cepstrum coefficeints * If pSmsData->iEnvelope == SMS_ENV_FBINS, will return linear magnitude spectrum * * \param pSmsData pointer to SMS_Data structure with all the arrays necessary * \param pSpecEnvParams pointer to a structure of parameters for spectral enveloping */ void sms_spectralEnvelope( SMS_Data *pSmsData, SMS_SEnvParams *pSpecEnvParams) { int i, k; int sizeCepstrum = pSpecEnvParams->iOrder+1; //int nPeaks = 0; static sfloat pFreqBuff[1000], pMagBuff[1000]; /* \todo see if this memset is even necessary, once working */ //memset(pSmsData->pSpecEnv, 0, pSpecEnvParams->nCoeff * sizeof(sfloat)); /* try to store cepstrum coefficients in pSmsData->nEnvCoeff always. if cepstrum is what is wanted, memset the rest. otherwise, hand this array 2x to dCepstrumEnvelope */ if(pSpecEnvParams->iOrder + 1> pSmsData->nEnvCoeff) { sms_error("cepstrum order is larger than the size of the spectral envelope"); return; } /* find out how many tracks were actually found... many are zero \todo is this necessary? */ for(i = 0, k=0; i < pSmsData->nTracks; i++) { if(pSmsData->pFSinFreq[i] > 0.00001) { if(pSpecEnvParams->iAnchor != 0) { if(k == 0) /* add anchor at beginning */ { pFreqBuff[k] = 0.0; pMagBuff[k] = pSmsData->pFSinAmp[i]; k++; } } pFreqBuff[k] = pSmsData->pFSinFreq[i]; pMagBuff[k] = pSmsData->pFSinAmp[i]; k++; } } /* \todo see if adding an anchor at the max freq helps */ if(k < 1) // how few can this be? try out a few in python return; sms_dCepstrum(sizeCepstrum, pSmsData->pSpecEnv, k, pFreqBuff, pMagBuff, pSpecEnvParams->fLambda, pSpecEnvParams->iMaxFreq); if(pSpecEnvParams->iType == SMS_ENV_FBINS) { sms_dCepstrumEnvelope(sizeCepstrum, pSmsData->pSpecEnv, pSpecEnvParams->nCoeff, pSmsData->pSpecEnv); } }
/*! \brief prepares the sine table * \param nTableSize size of table * \return error code \see SMS_MALLOC in SMS_ERRORS */ int sms_prepSine(int nTableSize) { register int i; sfloat fTheta; sms_tab_sine = (sfloat *)malloc(nTableSize * sizeof(float)); if(sms_tab_sine == NULL) { sms_error("Could not allocate memory for sine table"); return SMS_MALLOC; } fSineScale = (sfloat)(TWO_PI) / (sfloat)(nTableSize - 1); fSineIncr = 1.0 / fSineScale; fTheta = 0.0; for(i = 0; i < nTableSize; i++) { fTheta = fSineScale * (sfloat)i; sms_tab_sine[i] = sin(fTheta); } return SMS_OK; }
/* Pop up an error dialog. */ void popup_an_error(const char *fmt, ...) { va_list args; char *s; va_start(args, fmt); s = xs_vbuffer(fmt, args); va_end(args); /* Log to the trace file. */ vtrace("%s\n", s); if (sms_redirect()) { sms_error(s); } else { screen_suspend(); (void) fprintf(stderr, "%s\n", s); fflush(stderr); any_error_output = true; macro_output = true; } Free(s); }
/*! \brief allocate memory for a frame of SMS data * * \param pSmsFrame pointer to a frame of SMS data * \param nTracks number of sinusoidal tracks in frame * \param nStochCoeff number of stochastic coefficients in frame * \param iPhase whether phase information is in the frame * \param stochType stochastic resynthesis type * \param nStochCoeff number of envelope coefficients in frame * \param nEnvCoeff number of envelope coefficients in frame * \return 0 on success, -1 on error */ int sms_allocFrame (SMS_Data *pSmsFrame, int nTracks, int nStochCoeff, int iPhase, int stochType, int nEnvCoeff) { sfloat *dataPos; /* a marker to locate specific data witin smsData */ /* calculate size of frame */ int sizeData = 2 * nTracks * sizeof(sfloat); sizeData += 1 * sizeof(sfloat); //adding one for nSamples if (iPhase > 0) sizeData += nTracks * sizeof(sfloat); if (stochType == SMS_STOC_APPROX) sizeData += (nStochCoeff + 1) * sizeof(sfloat); else if (stochType == SMS_STOC_IFFT) sizeData += (2*nStochCoeff + 1) * sizeof(sfloat); sizeData += nEnvCoeff * sizeof(sfloat); /* add in number of envelope coefficients (cep or fbins) if any */ /* allocate memory for data */ if ((pSmsFrame->pSmsData = (sfloat *) malloc (sizeData)) == NULL) { sms_error("cannot allocate memory for SMS frame data"); return (-1); } /* set the variables in the structure */ /* \todo why not set these in init functions, then allocate with them?? */ pSmsFrame->sizeData = sizeData; pSmsFrame->nTracks = nTracks; pSmsFrame->nCoeff = nStochCoeff; pSmsFrame->nEnvCoeff = nEnvCoeff; /* set pointers to data types within smsData array */ pSmsFrame->pFSinFreq = pSmsFrame->pSmsData; dataPos = (sfloat *)(pSmsFrame->pFSinFreq + nTracks); memset(pSmsFrame->pFSinFreq, 0, sizeof(sfloat) * nTracks); pSmsFrame->pFSinAmp = dataPos; dataPos = (sfloat *)(pSmsFrame->pFSinAmp + nTracks); memset(pSmsFrame->pFSinAmp, 0, sizeof(sfloat) * nTracks); if (iPhase > 0) { pSmsFrame->pFSinPha = dataPos; dataPos = (sfloat *) (pSmsFrame->pFSinPha + nTracks); memset(pSmsFrame->pFSinPha, 0, sizeof(sfloat) * nTracks); } else pSmsFrame->pFSinPha = NULL; if (stochType == SMS_STOC_APPROX) { pSmsFrame->pFStocCoeff = dataPos; dataPos = (sfloat *) (pSmsFrame->pFStocCoeff + nStochCoeff); memset(pSmsFrame->pFStocCoeff, 0, sizeof(sfloat) * nStochCoeff); pSmsFrame->pFStocGain = dataPos; dataPos = (sfloat *) (pSmsFrame->pFStocGain + 1); } else if (stochType == SMS_STOC_IFFT) { pSmsFrame->pFStocCoeff = dataPos; dataPos = (sfloat *) (pSmsFrame->pFStocCoeff + nStochCoeff); pSmsFrame->pResPhase = dataPos; dataPos = (sfloat *) (pSmsFrame->pResPhase + nStochCoeff); pSmsFrame->pFStocGain = dataPos; dataPos = (sfloat *) (pSmsFrame->pFStocGain + 1); } else { pSmsFrame->pFStocCoeff = NULL; pSmsFrame->pResPhase = NULL; pSmsFrame->pFStocGain = NULL; } if (nEnvCoeff > 0) pSmsFrame->pSpecEnv = dataPos; else pSmsFrame->pSpecEnv = NULL; return (0); }
/*! \brief function to read SMS header * * \param pChFileName file name for SMS file * \param ppSmsHeader (double pointer to) SMS header * \param ppSmsFile (double pointer to) inputfile * \return error code \see SMS_ERRORS */ int sms_getHeader (char *pChFileName, SMS_Header **ppSmsHeader, FILE **ppSmsFile) { int iHeadBSize, iFrameBSize, nFrames; int iMagicNumber; /* open file for reading */ if ((*ppSmsFile = fopen (pChFileName, "r")) == NULL) { sms_error("could not open SMS header"); return (-1); } /* read magic number */ if (fread ((void *) &iMagicNumber, (size_t) sizeof(int), (size_t)1, *ppSmsFile) < (size_t)1) { sms_error("could not read SMS header"); return (-1); } if (iMagicNumber != SMS_MAGIC) { sms_error("not an SMS file"); return (-1); } /* read size of of header */ if (fread ((void *) &iHeadBSize, (size_t) sizeof(int), (size_t)1, *ppSmsFile) < (size_t)1) { sms_error("could not read SMS header (iHeadBSize)"); return (-1); } if (iHeadBSize <= 0) { sms_error("bad SMS header size"); return (-1); } /* read number of data Frames */ if (fread ((void *) &nFrames, (size_t) sizeof(int), (size_t)1, *ppSmsFile) < (size_t)1) { sms_error("could not read SMS number of frames"); return (-1); } if (nFrames <= 0) { sms_error("number of frames <= 0"); return (-1); } /* read size of data Frames */ if (fread ((void *) &iFrameBSize, (size_t) sizeof(int), (size_t)1, *ppSmsFile) < (size_t)1) { sms_error("could not read size of SMS data"); return (-1); } if (iFrameBSize <= 0) { sms_error("size bytes of frames <= 0"); return (-1); } /* allocate memory for header */ if (((*ppSmsHeader) = (SMS_Header *)malloc (iHeadBSize)) == NULL) { sms_error("cannot allocate memory for header"); return (-1); } /* read header */ rewind (*ppSmsFile); if (fread ((void *) (*ppSmsHeader), 1, iHeadBSize, *ppSmsFile) < (unsigned int) iHeadBSize) { sms_error("cannot read header of SMS file"); return (-1); } /* set pointers to variable part of header */ /* if ((*ppSmsHeader)->nLoopRecords > 0) */ /* (*ppSmsHeader)->pILoopRecords = (int *) ((char *)(*ppSmsHeader) + */ /* sizeof(SMS_Header)); */ /* if ((*ppSmsHeader)->nSpecEnvelopePoints > 0) */ /* (*ppSmsHeader)->pFSpectralEnvelope = */ /* (sfloat *) ((char *)(*ppSmsHeader) + sizeof(SMS_Header) + */ /* sizeof(int) * (*ppSmsHeader)->nLoopRecords); */ /* if ((*ppSmsHeader)->nTextCharacters > 0) */ /* (*ppSmsHeader)->pChTextCharacters = */ /* (char *) ((char *)(*ppSmsHeader) + sizeof(SMS_Header) + */ /* sizeof(int) * (*ppSmsHeader)->nLoopRecords + */ /* sizeof(sfloat) * (*ppSmsHeader)->nSpecEnvelopePoints); */ if ((*ppSmsHeader)->nTextCharacters > 0) (*ppSmsHeader)->pChTextCharacters = (char *)(*ppSmsHeader) + sizeof(SMS_Header); return (0); }
/*! \brief main function to perform the SMS analysis on a single frame * * The input is a section of the sound, the output is the SMS data * * \param sizeWaveform size of input waveform data * \param pWaveform pointer to input waveform data * \param pSmsData pointer to output SMS data * \param pAnalParams pointer to analysis parameters * \return \todo sort out return meanings */ int sms_analyze (int sizeWaveform, sfloat *pWaveform, SMS_Data *pSmsData, SMS_AnalParams *pAnalParams) { static int sizeWindow = 0; /* size of current analysis window */ //RTE ?: shouldn't this just be initilalized outside? int iCurrentFrame = pAnalParams->iMaxDelayFrames - 1; /* frame # of current frame */ int delayFrames = pAnalParams->minGoodFrames + pAnalParams->analDelay; int i, iError, iExtraSamples; /* samples used for next analysis frame */ sfloat fRefFundamental = 0; /* reference fundamental for current frame */ SMS_AnalFrame *pTmpAnalFrame; /* clear SMS output */ sms_clearFrame (pSmsData); /* set initial analysis-window size */ if (sizeWindow == 0) sizeWindow = pAnalParams->iDefaultSizeWindow; /* fill the input sound buffer and perform pre-emphasis */ if (sizeWaveform > 0) sms_fillSoundBuffer (sizeWaveform, pWaveform, pAnalParams); /* move analysis data one frame back */ pTmpAnalFrame = pAnalParams->ppFrames[0]; for(i = 1; i < pAnalParams->iMaxDelayFrames; i++) pAnalParams->ppFrames[i-1] = pAnalParams->ppFrames[i]; pAnalParams->ppFrames[pAnalParams->iMaxDelayFrames-1] = pTmpAnalFrame; /* initialize the current frame */ sms_initFrame (iCurrentFrame, pAnalParams, sizeWindow); if(sms_errorCheck()) { printf("error in init frame: %s \n", sms_errorString()); return(-1); } /* if right data in the sound buffer do analysis */ if (pAnalParams->ppFrames[iCurrentFrame]->iStatus == SMS_FRAME_READY) { sfloat fAvgDev = sms_fundDeviation( pAnalParams, iCurrentFrame - 1); /* if single note use the default fundamental as reference */ if (pAnalParams->iSoundType == SMS_SOUND_TYPE_NOTE) fRefFundamental = pAnalParams->fDefaultFundamental; /* if sound is stable use the last fundamental as a reference */ else if (fAvgDev != -1 && fAvgDev <= pAnalParams->maxDeviation) fRefFundamental = pAnalParams->ppFrames[iCurrentFrame - 1]->fFundamental; else fRefFundamental = 0; /* compute spectrum, find peaks, and find fundamental of frame */ sms_analyzeFrame (iCurrentFrame, pAnalParams, fRefFundamental); /* set the size of the next analysis window */ if (pAnalParams->ppFrames[iCurrentFrame]->fFundamental > 0 && pAnalParams->iSoundType != SMS_SOUND_TYPE_NOTE) sizeWindow = sms_sizeNextWindow (iCurrentFrame, pAnalParams); /* figure out how much needs to be read next time */ iExtraSamples = (pAnalParams->soundBuffer.iMarker + pAnalParams->soundBuffer.sizeBuffer) - (pAnalParams->ppFrames[iCurrentFrame]->iFrameSample + pAnalParams->sizeHop); /* printf("iMarker: %d, sizeBuffer: %d, iFrameSample %d, sizeHop: %d \n", */ /* pAnalParams->soundBuffer.iMarker, pAnalParams->soundBuffer.sizeBuffer, */ /* pAnalParams->ppFrames[iCurrentFrame]->iFrameSample, pAnalParams->sizeHop); */ pAnalParams->sizeNextRead = MAX (0, (sizeWindow+1)/2 - iExtraSamples); /* printf("pAnalParams -> sizeNextRead: %d, sizeWindow: %d, iExtraSamples: %d \n", */ /* pAnalParams->sizeNextRead, sizeWindow, iExtraSamples); */ /* check again the previous frames and recompute if necessary */ /*! \todo when deviation is really off, this function returns -1, yet it isn't used.. is it being recomputed ?? */ ReAnalyzeFrame (iCurrentFrame, pAnalParams); } /* incorporate the peaks into the corresponding tracks */ /* This is done after a pAnalParams->iMaxDelayFrames delay */ if (pAnalParams->ppFrames[iCurrentFrame - delayFrames]->fFundamental > 0 || ((pAnalParams->iFormat == SMS_FORMAT_IH || pAnalParams->iFormat == SMS_FORMAT_IHP) && pAnalParams->ppFrames[iCurrentFrame - delayFrames]->nPeaks > 0)) sms_peakContinuation (iCurrentFrame - delayFrames, pAnalParams); /* fill gaps and delete short tracks */ if (pAnalParams->iCleanTracks > 0 && pAnalParams->ppFrames[iCurrentFrame - delayFrames]->iStatus != SMS_FRAME_EMPTY) sms_cleanTracks (iCurrentFrame - delayFrames, pAnalParams); /* do stochastic analysis */ if (pAnalParams->iStochasticType != SMS_STOC_NONE) { /* synthesize deterministic signal */ if (pAnalParams->ppFrames[1]->iStatus != SMS_FRAME_EMPTY && pAnalParams->ppFrames[1]->iStatus != SMS_FRAME_END) { /* shift synthesis buffer */ memcpy ( pAnalParams->synthBuffer.pFBuffer, pAnalParams->synthBuffer.pFBuffer+pAnalParams->sizeHop, sizeof(sfloat) * pAnalParams->sizeHop); memset (pAnalParams->synthBuffer.pFBuffer+pAnalParams->sizeHop, 0, sizeof(sfloat) * pAnalParams->sizeHop); /* get deterministic signal with phase */ sms_sineSynthFrame (&pAnalParams->ppFrames[1]->deterministic, pAnalParams->synthBuffer.pFBuffer+pAnalParams->sizeHop, pAnalParams->sizeHop, &pAnalParams->prevFrame, pAnalParams->iSamplingRate); } /* perform stochastic analysis after 1 frame of the */ /* deterministic synthesis because it needs two frames */ if (pAnalParams->ppFrames[0]->iStatus != SMS_FRAME_EMPTY && pAnalParams->ppFrames[0]->iStatus != SMS_FRAME_END) { int sizeResidual = pAnalParams->sizeHop * 2; int iSoundLoc = pAnalParams->ppFrames[0]->iFrameSample - pAnalParams->sizeHop; sfloat *pOriginal = &(pAnalParams->soundBuffer.pFBuffer[iSoundLoc - pAnalParams->soundBuffer.iMarker]); sfloat *pFResidual; static sfloat *pWindow; static int sizeWindowArray = 0; int sizeData = MIN (pAnalParams->soundBuffer.sizeBuffer - (iSoundLoc - pAnalParams->soundBuffer.iMarker), sizeResidual); if ((pFResidual = (sfloat *) calloc (sizeResidual, sizeof(float))) == NULL) { sms_error("sms_analyze: error allocating memory for pFResidual"); return -1; } if (sizeWindowArray != sizeData) { if(sizeWindowArray != 0) free(pWindow); if((pWindow = (sfloat *) calloc(sizeData, sizeof(float))) == NULL) { sms_error("sms_analyze: error allocating memory for pWindow"); return -1; } sms_getWindow( sizeData, pWindow, SMS_WIN_HAMMING); sms_scaleWindow( sizeData, pWindow); sizeWindowArray = sizeData; } /* obtain residual sound from original and synthesized sounds. accumulate the residual percentage.*/ pAnalParams->fResidualAccumPerc += sms_residual (sizeData, pAnalParams->synthBuffer.pFBuffer, pOriginal, pFResidual, pWindow); if (pAnalParams->iStochasticType == SMS_STOC_APPROX) { /* filter residual with a high pass filter (it solves some problems) */ sms_filterHighPass (sizeData, pFResidual, pAnalParams->iSamplingRate); /* approximate residual */ sms_stocAnalysis (sizeData, pFResidual, pWindow, pSmsData); } else if (pAnalParams->iStochasticType == SMS_STOC_IFFT) { int sizeMag = sms_power2(sizeData >> 1); sms_spectrum (sizeData, pFResidual, pWindow, sizeMag, pSmsData->pFStocCoeff, pSmsData->pResPhase); } /* get sharper transitions in deterministic representation */ /* \todo why is this done in the stochastic analysis space? */ sms_scaleDet (pAnalParams->synthBuffer.pFBuffer, pOriginal, pAnalParams->ppFrames[0]->deterministic.pFSinAmp, pAnalParams, pSmsData->nTracks); pAnalParams->ppFrames[0]->iStatus = SMS_FRAME_DONE; free ((char *) pFResidual); /* \todo get rid of this free, manage memory the same as spectrum functions */ }