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.