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.