This is variousFunctions.c in view mode; [Download] [Up]
#include "../sms.h"
/* initialize data structures
*
* ANAL_PARAMS analParams; analysis paramaters
*/
int Initialize (ANAL_PARAMS analParams)
{
int sizeBuffer = (MaxDelayFrames * analParams.sizeHop) + MAX_SIZE_WINDOW;
int i;
/* sound buffer */
if ((soundBuffer.pFBuffer = (float *) calloc(sizeBuffer, sizeof(float)))
== NULL)
return -1;
soundBuffer.iSoundSample = -sizeBuffer;
soundBuffer.iFirstSample = sizeBuffer;
soundBuffer.sizeBuffer = sizeBuffer;
/* deterministic synthesis buffer */
if ((synthBuffer.pFBuffer =
(float *) calloc(2 * analParams.sizeHop, sizeof(float))) == NULL)
return -1;
synthBuffer.iSoundSample = -sizeBuffer;
synthBuffer.sizeBuffer = analParams.sizeHop * 2;
synthBuffer.iSoundSample = analParams.sizeHop * 2;
/* buffer of analysis frames */
if ((pFrames = (ANAL_FRAME *) calloc(MaxDelayFrames, sizeof(ANAL_FRAME)))
== NULL)
return -1;
if ((ppFrames =
(ANAL_FRAME **) calloc(MaxDelayFrames, sizeof(ANAL_FRAME *)))
== NULL)
return -1;
/* initialize the frame pointers and allocate memory */
for (i = 0; i < MaxDelayFrames; i++)
{
pFrames[i].iStatus = EMPTY;
(pFrames[i].deterministic).nTraj = analParams.nGuides;
if (((pFrames[i].deterministic).pFFreqTraj =
(float *)calloc (analParams.nGuides, sizeof(float))) == NULL)
return -1;
if (((pFrames[i].deterministic).pFMagTraj =
(float *)calloc (analParams.nGuides, sizeof(float))) == NULL)
return -1;
if (((pFrames[i].deterministic).pFPhaTraj =
(float *) calloc (analParams.nGuides, sizeof(float))) == NULL)
return -1;
ppFrames[i] = &pFrames[i];
}
/* initialitze window buffer for spectrum */
pFWindowSpec = (float *) calloc (MAX_SIZE_WINDOW, sizeof(float));
return (1);
}
/* clear the SMS data structure
*
* SMS_DATA *pSmsData; pointer to frame of SMS data
* int iFormat; format of the SMS data
*/
void ClearSms (SMS_DATA *pSmsData, int iFormat)
{
memset ((char *) pSmsData->pFFreqTraj, 0, sizeof(float) * pSmsData->nTraj);
memset ((char *) pSmsData->pFMagTraj, 0, sizeof(float) * pSmsData->nTraj);
if (iFormat == FORMAT_HARMONIC_WITH_PHASE ||
iFormat == FORMAT_INHARMONIC_WITH_PHASE)
memset ((char *) pSmsData->pFPhaTraj, 0,
sizeof(float) * pSmsData->nTraj);
if (pSmsData->pFStocCoeff)
memset ((char *) pSmsData->pFStocCoeff, 0,
sizeof(float) * pSmsData->nCoeff);
if (pSmsData->pFStocGain)
*(pSmsData->pFStocGain) = 0;
}
/* initialize the SMS data structure
*
* SMS_DATA *pSmsData; pointer to a frame of SMS data
*/
void initSms (SMS_DATA *pSmsData)
{
pSmsData->pFFreqTraj = NULL;
pSmsData->pFMagTraj = NULL;
pSmsData->pFPhaTraj = NULL;
pSmsData->pFStocCoeff = NULL;
pSmsData->pFStocGain = NULL;
pSmsData->nTraj = 0;
pSmsData->nCoeff = 0;
}
/* allocate memory for a frame of SMS data
*
* SMS_DATA *pSmsData; pointer to a frame of SMS data
* int nTraj; number of trajectories in frame
* int nCoeff; number of stochastic coefficients in frame
* int iPhase; whether phase information is in the frame
*/
void allocateSmsRecord (SMS_DATA *pSmsData, int nTraj, int nCoeff, int iPhase)
{
pSmsData->pFFreqTraj = (float *) calloc (nTraj, sizeof(float));
pSmsData->pFMagTraj = (float *) calloc (nTraj, sizeof(float));
if (iPhase > 0)
pSmsData->pFPhaTraj = (float *) calloc (nTraj, sizeof(float));
else
pSmsData->pFPhaTraj = NULL;
pSmsData->nTraj = nTraj;
if (nCoeff > 0)
{
pSmsData->pFStocCoeff = (float *) calloc (nCoeff, sizeof(float));
pSmsData->pFStocGain = (float *) calloc (1, sizeof(float));
pSmsData->nCoeff = nCoeff;
}
else
{
pSmsData->pFStocCoeff = NULL;
pSmsData->pFStocGain = NULL;
pSmsData->nCoeff = 0;
}
}
/* free the memory from a SMS frame
*
* SMS_DATA *pSmsData; pointer to a frame of SMS data
*/
void freeSmsRecord (SMS_DATA *pSmsData)
{
free (pSmsData->pFFreqTraj);
free (pSmsData->pFMagTraj);
if (pSmsData->pFPhaTraj != NULL)
free (pSmsData->pFPhaTraj);
pSmsData->nTraj = 0;
if (pSmsData->pFStocCoeff != NULL)
free (pSmsData->pFStocCoeff);
if (pSmsData->pFStocGain != NULL)
free (pSmsData->pFStocGain);
pSmsData->nCoeff = 0;
}
/* copy a frame of SMS data into another
*
* SMS_DATA *pCopySmsData; copy of frame
* SMS_DATA *pOriginalSmsData; original frame
*/
int copySmsRecord (SMS_DATA *pCopySmsData, SMS_DATA *pOriginalSmsData)
{
int nTraj = MIN (pCopySmsData->nTraj, pOriginalSmsData->nTraj);
int nCoeff = MIN (pCopySmsData->nCoeff, pOriginalSmsData->nCoeff);
memcpy ((char *)pCopySmsData->pFFreqTraj,
(char *)pOriginalSmsData->pFFreqTraj,
sizeof(float) * nTraj);
memcpy ((char *)pCopySmsData->pFMagTraj,
(char *)pOriginalSmsData->pFMagTraj,
sizeof(float) * nTraj);
if (pOriginalSmsData->pFPhaTraj != NULL &&
pCopySmsData->pFPhaTraj != NULL)
memcpy ((char *)pCopySmsData->pFPhaTraj,
(char *)pOriginalSmsData->pFPhaTraj,
sizeof(float) * nTraj);
if (pOriginalSmsData->pFStocCoeff != NULL &&
pCopySmsData->pFStocCoeff != NULL)
memcpy ((char *)pCopySmsData->pFStocCoeff,
(char *)pOriginalSmsData->pFStocCoeff,
sizeof(float) * nCoeff);
if (pOriginalSmsData->pFStocGain != NULL &&
pCopySmsData->pFStocGain != NULL)
memcpy ((char *)pCopySmsData->pFStocGain,
(char *)pOriginalSmsData->pFStocGain,
sizeof(float));
return (1);
}
/* fill the sound buffer
*
* short *pSWaveform input data
* int sizeNewData size of input data
* SOUND_BUFFER *pSoundBuffer sound buffer
* int sizeHop analysis hop size
*/
void FillBuffer (short *pSWaveform, int sizeNewData,
SOUND_BUFFER *pSoundBuffer, ANAL_PARAMS analParams)
{
int i;
/* leave space for new data */
memcpy ((char *) pSoundBuffer->pFBuffer,
(char *) (pSoundBuffer->pFBuffer+sizeNewData),
sizeof(float) * (pSoundBuffer->sizeBuffer - sizeNewData));
pSoundBuffer->iFirstSample =
MAX (0, pSoundBuffer->iFirstSample - sizeNewData);
pSoundBuffer->iSoundSample += sizeNewData;
/* put the new data in, and do some pre-emphasis */
if (analParams.iAnalysisDirection == REVERSE)
for (i=0; i<sizeNewData; i++)
pSoundBuffer->pFBuffer[soundBuffer.sizeBuffer - sizeNewData + i] =
PreEmphasis((float) pSWaveform[sizeNewData - (1+ i)]);
else
for (i=0; i<sizeNewData; i++)
pSoundBuffer->pFBuffer[soundBuffer.sizeBuffer - sizeNewData + i] =
PreEmphasis((float) pSWaveform[i]);
}
/* shift the buffer of analysis frames to the left */
void MoveFrames ()
{
int i;
ANAL_FRAME *tmp;
/* shift the frame pointers */
tmp = ppFrames[0];
for(i = 1; i < MaxDelayFrames; i++)
ppFrames[i-1] = ppFrames[i];
ppFrames[MaxDelayFrames-1] = tmp;
}
/* initialize the current frame
*
* int iCurrentFrame; frame number of current frame in buffer
* SOUND_BUFFER soundBuffer; buffer for input sound
* ANAL_PARAMS analParams; analysis parameters
* int sizeWindow; size of analysis window
*/
void InitializeFrame (int iCurrentFrame, SOUND_BUFFER soundBuffer,
ANAL_PARAMS analParams, int sizeWindow)
{
/* clear deterministic data */
memset ((float *) ppFrames[iCurrentFrame]->deterministic.pFFreqTraj, 0,
sizeof(float) * analParams.nGuides);
memset ((float *) ppFrames[iCurrentFrame]->deterministic.pFMagTraj, 0,
sizeof(float) * analParams.nGuides);
memset ((float *) ppFrames[iCurrentFrame]->deterministic.pFPhaTraj, 0,
sizeof(float) * analParams.nGuides);
/* clear peaks */
memset ((void *) ppFrames[iCurrentFrame]->pSpectralPeaks, 0,
sizeof (PEAK) * MAX_NUM_PEAKS);
ppFrames[iCurrentFrame]->nPeaks = 0;
ppFrames[iCurrentFrame]->fFundamental = 0;
ppFrames[iCurrentFrame]->iFrameNum =
ppFrames[iCurrentFrame - 1]->iFrameNum + 1;
ppFrames[iCurrentFrame]->iFrameSize = sizeWindow;
/* if first frame set center of data around 0 */
if(ppFrames[iCurrentFrame]->iFrameNum == 1)
ppFrames[iCurrentFrame]->iFrameSample = 0;
/* increment center of data by sizeHop */
else
ppFrames[iCurrentFrame]->iFrameSample =
ppFrames[iCurrentFrame-1]->iFrameSample + analParams.sizeHop;
/* check for error */
if (soundBuffer.iSoundSample >
ppFrames[iCurrentFrame]->iFrameSample - (sizeWindow+1)/2)
{
fprintf(stderr, "error: runoff on the sound buffer\n");
exit(1);
}
/* check for end of sound */
if ((ppFrames[iCurrentFrame]->iFrameSample + (sizeWindow+1)/2) >=
analParams.iSizeSound)
{
ppFrames[iCurrentFrame]->iFrameNum = -1;
ppFrames[iCurrentFrame]->iFrameSize = 0;
ppFrames[iCurrentFrame]->iStatus = END;
}
else
/* good status, ready to start computing */
ppFrames[iCurrentFrame]->iStatus = READY;
}
/* compute spectrum, find peaks, and fundamental of given frame
*
* int iCurrentFrame frame number to be computed
* ANAL_PARAMS analParams analysis parameters
* float fRefFundamental reference fundamental
*/
void ComputeFrame (int iCurrentFrame, ANAL_PARAMS analParams,
float fRefFundamental)
{
static float pFMagSpectrum[MAX_SIZE_MAG];
static float pFPhaSpectrum[MAX_SIZE_MAG];
int sizeMag, i;
int iSoundLoc = ppFrames[iCurrentFrame]->iFrameSample -
(ppFrames[iCurrentFrame]->iFrameSize + 1) / 2 + 1;
float *pFData =
&(soundBuffer.pFBuffer[iSoundLoc - soundBuffer.iSoundSample]);
/* compute the magnitude and phase spectra */
sizeMag = Spectrum(pFData, ppFrames[iCurrentFrame]->iFrameSize,
pFMagSpectrum, pFPhaSpectrum, analParams);
/* find the prominent peaks */
ppFrames[iCurrentFrame]->nPeaks =
PeakDetection (pFMagSpectrum, pFPhaSpectrum, sizeMag,
ppFrames[iCurrentFrame]->iFrameSize,
ppFrames[iCurrentFrame]->pSpectralPeaks,
analParams);
if (analParams.iDebugMode == DEBUG_PEAK_DET ||
analParams.iDebugMode == DEBUG_ALL)
{
fprintf(stdout, "Frame %d peaks: ",
ppFrames[iCurrentFrame]->iFrameNum);
/* print only the first 10 peaks */
for(i=0; i<10; i++)
fprintf(stdout, " %.0f[%.1f], ",
ppFrames[iCurrentFrame]->pSpectralPeaks[i].fFreq,
ppFrames[iCurrentFrame]->pSpectralPeaks[i].fMag);
fprintf(stdout, "\n");
}
/* find a reference harmonic */
if (ppFrames[iCurrentFrame]->nPeaks > 0 &&
(analParams.iFormat == FORMAT_HARMONIC ||
analParams.iFormat == FORMAT_HARMONIC_WITH_PHASE))
HarmDetection (ppFrames[iCurrentFrame], fRefFundamental, analParams);
if (analParams.iDebugMode == DEBUG_HARM_DET ||
analParams.iDebugMode == DEBUG_ALL)
fprintf(stdout, "Frame %d: fundamental %f\n",
ppFrames[iCurrentFrame]->iFrameNum,
ppFrames[iCurrentFrame]->fFundamental);
}
/* set window size for next frame
*
* int iCurrentFrame; number of current frame
* ANAL_PARAMS analParams; analysis parameters
*/
int SetSizeWindow (int iCurrentFrame, ANAL_PARAMS analParams)
{
float fFund = ppFrames[iCurrentFrame]->fFundamental;
float fPrevFund = ppFrames[iCurrentFrame-1]->fFundamental;
int sizeWindow;
/* if the previous fundamental was stable use it to set the window size */
if (fPrevFund > 0 &&
fabs(fPrevFund - fFund) / fFund <= .2)
sizeWindow = (int) ((analParams.fSamplingRate/fFund) *
analParams.fSizeWindow/2) * 2 + 1;
/* otherwise use the default size window */
else
sizeWindow = analParams.iDefaultSizeWindow;
if (sizeWindow > MAX_SIZE_WINDOW)
{
fprintf (stderr, "sizeWindow (%d) too big, set to %d\n", sizeWindow,
MAX_SIZE_WINDOW);
sizeWindow = MAX_SIZE_WINDOW;
}
return (sizeWindow);
}
/* get deviation from average fundamental
*
* return -1 if really off
* int iCurrentFrame; number of current frame
*/
float GetDeviation (int iCurrentFrame)
{
float fFund, fSum = 0, fAverage, fDeviation = 0;
int i;
/* get the sum of the past few fundamentals */
for (i = 0; i < MIN_GOOD_FRAMES; i++)
{
fFund = ppFrames[iCurrentFrame-i]->fFundamental;
if(fFund <= 0)
return(-1);
else
fSum += fFund;
}
/* find the average */
fAverage = fSum / MIN_GOOD_FRAMES;
/* get the deviation from the average */
for (i = 0; i < MIN_GOOD_FRAMES; i++)
fDeviation += fabs(ppFrames[iCurrentFrame-i]->fFundamental - fAverage);
/* return the deviation from the average */
return (fDeviation / (MIN_GOOD_FRAMES * fAverage));
}
/* re-analyze the previous frames if necessary
*
* int iCurrentFrame; current frame number
* ANAL_PARAMS analParams; analysis parameters
*/
int ReAnalyze (int iCurrentFrame, ANAL_PARAMS analParams)
{
float fAvgDeviation = GetDeviation(iCurrentFrame),
fFund, fLastFund, fDev;
int iNewFrameSize, i,
iFirstFrame = iCurrentFrame - MIN_GOOD_FRAMES;
if (analParams.iDebugMode == DEBUG_SMS_ANAL ||
analParams.iDebugMode == DEBUG_ALL)
fprintf(stdout, "Frame %d reAnalyze: Freq. deviation %f\n",
ppFrames[iCurrentFrame]->iFrameNum, fAvgDeviation);
if (fAvgDeviation == -1)
return (-1);
/* if the last MIN_GOOD_FRAMES are stable look before them */
/* and recompute the frames that are not stable */
if (fAvgDeviation <= MAX_DEVIATION)
for (i = 0; i < ANAL_DELAY; i++)
{
if (ppFrames[iFirstFrame - i]->iFrameNum <= 0 ||
ppFrames[iFirstFrame - i]->iStatus == RECOMPUTED)
return(-1);
fFund = ppFrames[iFirstFrame - i]->fFundamental;
fLastFund = ppFrames[iFirstFrame - i + 1]->fFundamental;
fDev = fabs (fFund - fLastFund) / fLastFund;
iNewFrameSize = ((analParams.fSamplingRate/fLastFund) *
analParams.fSizeWindow/2) * 2 + 1;
if (fFund <= 0 || fDev > .2 ||
fabs ((double)(ppFrames[iFirstFrame - i]->iFrameSize -
iNewFrameSize)) /
iNewFrameSize >= .2)
{
ppFrames[iFirstFrame - i]->iFrameSize = iNewFrameSize;
ppFrames[iFirstFrame - i]->iStatus = READY;
if (analParams.iDebugMode == DEBUG_SMS_ANAL ||
analParams.iDebugMode == DEBUG_ALL)
fprintf(stdout, "re-analyzing frame %d\n",
ppFrames[iFirstFrame - i]->iFrameNum);
/* recompute frame */
ComputeFrame (iFirstFrame - i, analParams, fLastFund);
ppFrames[iFirstFrame - i]->iStatus = RECOMPUTED;
if (fabs(ppFrames[iFirstFrame - i]->fFundamental - fLastFund) /
fLastFund >= .2)
return(-1);
}
}
return (1);
}These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.