ftp.nice.ch/pub/next/unix/audio/sms.N.bs.tar.gz#/sms/library/variousFunctions.c

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.