This is smsAnalysis.c in view mode; [Download] [Up]
#include "../sms.h" /* * function to perform the SMS analysis on a single frame * the input is a section of the sound, the output is the SMS data * * short *pSWaveform; input data * int sizeNewData; the size of input data * SMS_DATA *pSmsData; output SMS data * ANAL_PARAMS analParams; analysis parameters * int *pINextSizeRead; size of next data to read */ int SmsAnalysis (short *pSWaveform, int sizeNewData, SMS_DATA *pSmsData, ANAL_PARAMS analParams, int *pINextSizeRead) { static int sizeWindow = 0; /* size of current analysis window */ static SMS_DATA lastFrame; int iCurrentFrame = MaxDelayFrames - 1; /* frame # of current frame */ int iExtraSamples; /* samples used for next analysis frame */ float fRefFundamental = 0; /* reference fundamental for current frame */ /* initialize structures */ if (ppFrames == NULL) { Initialize (analParams); allocateSmsRecord (&lastFrame, analParams.nGuides, pSmsData->nCoeff, 1); } /* clear SMS output */ ClearSms (pSmsData, analParams.iFormat); /* set initial analysis-window size */ if (sizeWindow == 0) sizeWindow = analParams.iDefaultSizeWindow; /* fill the input sound buffer and perform pre-emphasis */ if (sizeNewData > 0) FillBuffer (pSWaveform, sizeNewData, &soundBuffer, analParams); /* move analysis data one frame back */ MoveFrames (); /* initialize the current frame */ InitializeFrame (iCurrentFrame, soundBuffer, analParams, sizeWindow); /* if right data in the sound buffer do analysis */ if (ppFrames[iCurrentFrame]->iStatus == READY) { float fAvgDev = GetDeviation(iCurrentFrame - 1); if (analParams.iDebugMode == DEBUG_SMS_ANAL || analParams.iDebugMode == DEBUG_ALL) fprintf (stdout, "Frame %d: sizeWindow %d, sizeNewData %d, firstSampleBuffer %d, centerSample %d\n", ppFrames[iCurrentFrame]->iFrameNum, sizeWindow, sizeNewData, soundBuffer.iSoundSample, ppFrames[iCurrentFrame]->iFrameSample); /* if single note use the default fundamental as reference */ if (analParams.iSoundType == TYPE_SINGLE_NOTE) fRefFundamental = analParams.fDefaultFundamental; /* if sound is stable use the last fundamental as a reference */ else if (fAvgDev != -1 && fAvgDev <= MAX_DEVIATION) fRefFundamental = ppFrames[iCurrentFrame - 1]->fFundamental; else fRefFundamental = 0; /* compute spectrum, find peaks, and find fundamental of frame */ ComputeFrame (iCurrentFrame, analParams, fRefFundamental); /* set the size of the next analysis window */ if (ppFrames[iCurrentFrame]->fFundamental > 0 && analParams.iSoundType != TYPE_SINGLE_NOTE) sizeWindow = SetSizeWindow(iCurrentFrame, analParams); /* figure out how much needs to be read next time */ iExtraSamples = (soundBuffer.iSoundSample + soundBuffer.sizeBuffer) - (ppFrames[iCurrentFrame]->iFrameSample + analParams.sizeHop); *pINextSizeRead = MAX (0, (sizeWindow+1)/2 - iExtraSamples); /* check again the previous frames and recompute if necessary */ ReAnalyze (iCurrentFrame, analParams); } /* incorporate the peaks into the corresponding trajectories */ /* This is done after a DELAY_FRAMES delay */ if (ppFrames[iCurrentFrame - DELAY_FRAMES]->fFundamental > 0 || ((analParams.iFormat == FORMAT_INHARMONIC || analParams.iFormat == FORMAT_INHARMONIC_WITH_PHASE) && ppFrames[iCurrentFrame - DELAY_FRAMES]->nPeaks > 0)) PeakContinuation (iCurrentFrame - DELAY_FRAMES, analParams); /* fill gaps and delete short trajectories */ if (analParams.iCleanTraj > 0 && ppFrames[iCurrentFrame - DELAY_FRAMES]->iStatus != EMPTY) CleanTrajectories (iCurrentFrame - DELAY_FRAMES, analParams); /* do stochastic analysis */ if (analParams.iStochasticType != STOC_NONE) { /* synthesize deterministic signal */ if (ppFrames[1]->iStatus != EMPTY && ppFrames[1]->iStatus != END) { /* allocate sine table */ if (pFSTab == NULL) PrepSine(4096); /* shift synthesis buffer */ memcpy ((char *) synthBuffer.pFBuffer, (char *) (synthBuffer.pFBuffer+analParams.sizeHop), sizeof(float) * analParams.sizeHop); memset ((char *) (synthBuffer.pFBuffer+analParams.sizeHop), 0, sizeof(float) * analParams.sizeHop); /* get deterministic signal with phase */ FrameSineSynth (&ppFrames[1]->deterministic, synthBuffer.pFBuffer+analParams.sizeHop, analParams.sizeHop, &lastFrame); } /* perform stochastic analysis after 1 frame of the */ /* deterministic synthesis because it needs two frames */ if (ppFrames[0]->iStatus != EMPTY && ppFrames[0]->iStatus != END) { int sizeResidual = analParams.sizeHop * 2; int iSoundLoc = ppFrames[0]->iFrameSample - analParams.sizeHop; float *pFData = &(soundBuffer.pFBuffer[iSoundLoc - soundBuffer.iSoundSample]); float *pFResidual; int sizeData = MIN (soundBuffer.sizeBuffer - (iSoundLoc - soundBuffer.iSoundSample), sizeResidual); if ((pFResidual = (float *) calloc (sizeResidual, sizeof(float))) == NULL) return -1; /* obtain residual sound from original and synthesized sounds */ GetResidual (synthBuffer.pFBuffer, pFData, pFResidual, sizeData, analParams); /* approximate residual */ StocAnalysis (pFResidual, sizeData, pSmsData, analParams); /* get sharper transitions in deterministic representation */ ScaleDeterministic (synthBuffer.pFBuffer, pFData, ppFrames[0]->deterministic.pFMagTraj, analParams, pSmsData->nTraj); ppFrames[0]->iStatus = DONE; free ((char *) pFResidual); } } else if (ppFrames[0]->iStatus != EMPTY && ppFrames[0]->iStatus != END) ppFrames[0]->iStatus = DONE; /* get the result */ if (ppFrames[0]->iStatus == EMPTY) return (0); /* return analysis data */ else if (ppFrames[0]->iStatus == DONE) { /* put data into output */ int length = sizeof(float) * pSmsData->nTraj; memcpy ((char *) pSmsData->pFFreqTraj, (char *) ppFrames[0]->deterministic.pFFreqTraj, length); memcpy ((char *) pSmsData->pFMagTraj, (char *) ppFrames[0]->deterministic.pFMagTraj, length); if (analParams.iFormat == FORMAT_HARMONIC_WITH_PHASE || analParams.iFormat == FORMAT_INHARMONIC_WITH_PHASE) memcpy ((char *) pSmsData->pFPhaTraj, (char *) ppFrames[0]->deterministic.pFPhaTraj, length); return (1); } /* done, end of sound */ else if (ppFrames[0]->iStatus == END) return (-1); else { fprintf (stderr, "error: wrong status of frame\n"); exit (1); } return (1); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.