/* * Copyright (c) 2008 MUSIC TECHNOLOGY GROUP (MTG) * UNIVERSITAT POMPEU FABRA * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ /*! \file sms.h * \brief header file to be included in all SMS application */ #ifndef _SMS_H #define _SMS_H #include #include #include #include #include #define SMS_VERSION 1.15 /*!< \brief version control number */ #define SMS_MAX_NPEAKS 400 /*!< \brief maximum number of peaks */ #define SMS_MAX_FRAME_SIZE 10000 /* maximum size of input frame in samples */ #define SMS_MAX_SPEC 8192 /*! \brief maximum size for magnitude spectrum */ #define sfloat double /*! \struct SMS_Header * \brief structure for the header of an SMS file * * This header contains all the information necessary to read an SMS * file, prepare memory and synthesizer parameters. * * The header also contains variable components for additional information * that may be stored along with the analysis, such as descriptors or text. * * The first four members of the Header are necessary in this order to correctly * open the .sms files created by this library. * * iSampleRate contains the samplerate of the analysis signal because it is * necessary to know this information to recreate the residual spectrum. * * In the first release, the descriptors are not used, but are here because they * were implemented in previous versions of this code (in the 90's). With time, * the documentation will be updated to reflect which members of the header * are useful in manipulations, and what functions to use for these manipulatinos */ typedef struct SMSHeader { int iSmsMagic; /*!< identification constant */ int iHeadBSize; /*!< size in bytes of header */ int nFrames; /*!< number of data frames */ int iFrameBSize; /*!< size in bytes of each data frame */ int iSamplingRate; /*!< samplerate of analysis signal (necessary to recreate residual spectrum */ int iFormat; /*!< type of data format \see SMS_Format */ int nTracks; /*!< number of sinusoidal tracks per frame */ int iFrameRate; /*!< rate in Hz of data frames */ int iStochasticType; /*!< type stochastic representation */ int nStochasticCoeff; /*!< number of stochastic coefficients per frame */ int iEnvType; /*!< type of envelope representation */ int nEnvCoeff; /*!< number of cepstral coefficents per frame */ int iMaxFreq; /*!< maximum frequency of peaks (also corresponds to the last bin of the specEnv */ sfloat fResidualPerc; /*!< percentage of the residual to original */ } SMS_Header; /*! \struct SMS_Data * \brief structure with SMS data * * Here is where all the analysis data ends up. Once data is in here, it is ready * for synthesis. * * It is in one contigous block (pSmsData), the other pointer members point * specifically to each component in the block. * * pFSinPha is optional in the final output, but it is always used to construct the * residual signal. */ typedef struct SMSData { sfloat *pSmsData; /*!< pointer to all SMS data */ int sizeData; /*!< size of all the data */ sfloat *pFSinFreq; /*!< frequency of sinusoids */ sfloat *pFSinAmp; /*!< magnitude of sinusoids (stored in dB) */ sfloat *pFSinPha; /*!< phase of sinusoids */ int nTracks; /*!< number of sinusoidal tracks in frame */ sfloat *pFStocGain; /*!< gain of stochastic component */ int nCoeff; /*!< number of filter coefficients */ sfloat *pFStocCoeff; /*!< filter coefficients for stochastic component */ sfloat *pResPhase; /*!< residual phase spectrum */ int nEnvCoeff; /*!< number of spectral envelope coefficients */ sfloat *pSpecEnv; } SMS_Data; /*! \struct SMS_SndBuffer * \brief buffer for sound data * * This structure is used for holding a buffer of audio data. iMarker is a * sample number of the sound source that corresponds to the first sample * in the buffer. * */ typedef struct { sfloat *pFBuffer; /*!< buffer for sound data*/ int sizeBuffer; /*!< size of buffer */ int iMarker; /*!< sample marker relating to sound source */ int iFirstGood; /*!< first sample in buffer that is a good one */ } SMS_SndBuffer; /*! \struct SMS_Peak * \brief structure for sinusodial peak */ typedef struct { sfloat fFreq; /*!< frequency of peak */ sfloat fMag; /*!< magnitude of peak */ sfloat fPhase; /*!< phase of peak */ } SMS_Peak; /* a collection of spectral peaks */ typedef struct SMSSpectralPeaks { SMS_Peak *pSpectralPeaks; int nPeaks; int nPeaksFound; } SMS_SpectralPeaks; /*! \struct SMS_AnalFrame * \brief structure to hold an analysis frame * * This structure has extra information for continuing the analysis, * which can be disregarded once the analysis is complete. */ typedef struct { int iFrameSample; /*!< sample number of the middle of the frame */ int iFrameSize; /*!< number of samples used in the frame */ int iFrameNum; /*!< frame number */ SMS_Peak *pSpectralPeaks; /*!< spectral peaks found in frame */ int nPeaks; /*!< number of peaks found */ sfloat fFundamental; /*!< fundamental frequency in frame */ SMS_Data deterministic; /*!< deterministic data */ int iStatus; /*!< status of frame enumerated by SMS_FRAME_STATUS \see SMS_FRAME_STATUS */ } SMS_AnalFrame; /*! \struct SMS_SEnvParams; * \brief structure information and data for spectral enveloping * */ typedef struct { int iType; /*!< envelope type \see SMS_SpecEnvType */ int iOrder; /*!< ceptrum order */ int iMaxFreq; /*!< maximum frequency covered by the envelope */ sfloat fLambda; /*!< regularization factor */ int nCoeff; /*!< number of coefficients (bins) in the envelope */ int iAnchor; /*!< whether to make anchor points at DC / Nyquist or not */ } SMS_SEnvParams; /*! \struct SMS_Guide * \brief information attached to a guide * * This structure is used to organize the detected peaks into time-varying * trajectories, or sinusoidal tracks. As the analysis progresses, previous * guides may be updated according to new information in the peak continuation * of new frames (two-way mismatch). */ typedef struct { sfloat fFreq; /*!< frequency of guide */ sfloat fMag; /*!< magnitude of guide */ int iStatus; /*!< status of guide: DEAD, SLEEPING, ACTIVE */ int iPeakChosen; /*!< peak number chosen by the guide */ } SMS_Guide; /*! \struct SMS_ResidualParams * \brief structure with information for residual functions * * This structure contains all the necessary settings and memory for residual synthesis. * */ typedef struct { int samplingRate; int hopSize; int residualSize; sfloat *residual; sfloat *fftWindow; sfloat *ifftWindow; sfloat windowScale; sfloat residualMag; sfloat originalMag; int nCoeffs; sfloat *stocCoeffs; int sizeStocMagSpectrum; sfloat *stocMagSpectrum; sfloat *stocPhaseSpectrum; sfloat *approx; sfloat *approxEnvelope; sfloat fftBuffer[SMS_MAX_SPEC * 2]; } SMS_ResidualParams; /*! \struct SMS_AnalParams * \brief structure with useful information for analysis functions * * Each analysis needs one of these, which contains all settings, * sound data, deterministic synthesis data, and every other * piece of data that needs to be shared between functions. * * There is an array of already analyzed frames (hardcoded to 50 right now - * \todo make it variable) that are accumulated for good harmonic detection * and partial tracking. For instance, once the fundamental frequency of a * harmonic signal is located (after a few frames), the harmonic analysis * and peak detection/continuation process can be re-computed with more accuracy. * */ typedef struct SMSAnalysisParams { int iDebugMode; /*!< debug codes enumerated by SMS_DBG \see SMS_DBG */ int iFormat; /*!< analysis format code defined by SMS_Format \see SMS_Format */ int iSoundType; /*!< type of sound to be analyzed \see SMS_SOUND_TYPE */ int iStochasticType; /*!< type of stochastic model defined by SMS_StocSynthType \see SMS_StocSynthType */ int iFrameRate; /*!< rate in Hz of data frames */ int nStochasticCoeff; /*!< number of stochastic coefficients per frame */ sfloat fLowestFundamental; /*!< lowest fundamental frequency in Hz */ sfloat fHighestFundamental; /*!< highest fundamental frequency in Hz */ sfloat fDefaultFundamental; /*!< default fundamental in Hz */ sfloat fPeakContToGuide; /*!< contribution of previous peak to current guide (between 0 and 1) */ sfloat fFundContToGuide; /*!< contribution of current fundamental to current guide (between 0 and 1) */ sfloat fFreqDeviation; /*!< maximum deviation from peak to peak */ int iSamplingRate; /*! sampling rate of sound to be analyzed */ int iDefaultSizeWindow; /*!< default size of analysis window in samples */ int windowSize; /*!< the current window size */ int sizeHop; /*!< hop size of analysis window in samples */ sfloat fSizeWindow; /*!< size of analysis window in number of periods */ int nTracks; /*!< number of sinusoidal tracks in frame */ int maxPeaks; /*!< maximum number of peaks in a frame */ int nGuides; /*!< number of guides used for peak detection and continuation \see SMS_Guide */ int iCleanTracks; /*!< whether or not to clean sinusoidal tracks */ sfloat fMinRefHarmMag; /*!< minimum magnitude in dB for reference peak */ sfloat fRefHarmMagDiffFromMax; /*!< maximum magnitude difference from reference peak to highest peak */ int iRefHarmonic; /*!< reference harmonic to use in the fundamental detection */ int iMinTrackLength; /*!< minimum length in samples of a given track */ int iMaxSleepingTime; /*!< maximum sleeping time for a track */ sfloat fLowestFreq; /*!< lowest frequency to be searched */ sfloat fHighestFreq; /*!< highest frequency to be searched */ sfloat fMinPeakMag; /*!< minimum magnitude in dB for a good peak */ int iAnalysisDirection; /*!< analysis direction, direct or reverse */ int iSizeSound; /*!< total size of sound to be analyzed in samples */ int nFrames; /*!< total number of frames that will be analyzed */ int iWindowType; /*!< type of FFT analysis window \see SMS_WINDOWS */ int iMaxDelayFrames; /*!< maximum number of frames to delay before peak continuation */ int minGoodFrames; /*!< minimum number of stable frames for backward search */ sfloat maxDeviation; /*!< maximum deviation allowed */ int analDelay; /*! number of frames in the past to be looked in possible re-analyze */ sfloat fResidualAccumPerc; /*!< accumalitive residual percentage */ int sizeNextRead; /*!< size of samples to read from sound file next analysis */ int preEmphasis; /*!< whether or not to perform pre-emphasis */ sfloat preEmphasisLastValue; SMS_Data prevFrame; /*!< the previous analysis frame */ SMS_SEnvParams specEnvParams; /*!< all data for spectral enveloping */ SMS_SndBuffer soundBuffer; /*!< signal to be analyzed */ SMS_SndBuffer synthBuffer; /*!< resynthesized signal used to create the residual */ SMS_AnalFrame *pFrames; /*!< an array of frames that have already been analyzed */ sfloat magSpectrum[SMS_MAX_SPEC]; sfloat phaseSpectrum[SMS_MAX_SPEC]; sfloat spectrumWindow[SMS_MAX_SPEC]; sfloat fftBuffer[SMS_MAX_SPEC * 2]; SMS_ResidualParams residualParams; int *guideStates; SMS_Guide* guides; sfloat inputBuffer[SMS_MAX_FRAME_SIZE]; int sizeStocMagSpectrum; sfloat *stocMagSpectrum; sfloat *approxEnvelope; /*!< spectral approximation envelope */ SMS_AnalFrame **ppFrames; /*!< pointers to the frames analyzed (it is circular-shifted once the array is full */ } SMS_AnalParams; /*! \struct SMS_ModifyParams * * \brief structure with parameters and data that will be used to modify an SMS_Data frame */ typedef struct { int ready; /*!< a flag to know if the struct has been initialized) */ int maxFreq; /*!< maximum frequency component */ int doResGain; /*!< whether or not to scale residual gain */ sfloat resGain; /*!< residual scale factor */ int doTranspose; /*!< whether or not to transpose */ sfloat transpose; /*!< transposition factor */ int doSinEnv; /*!< whether or not to apply a new spectral envelope to the sin component */ sfloat sinEnvInterp; /*!< value between 0 (use frame's env) and 1 (use *env). Interpolates inbetween values*/ int sizeSinEnv; /*!< size of the envelope pointed to by env */ sfloat *sinEnv; /*!< sinusoidal spectral envelope */ int doResEnv; /*!< whether or not to apply a new spectral envelope to the residual component */ sfloat resEnvInterp; /*!< value between 0 (use frame's env) and 1 (use *env). Interpolates inbetween values*/ int sizeResEnv; /*!< size of the envelope pointed to by resEnv */ sfloat *resEnv; /*!< residual spectral envelope */ } SMS_ModifyParams; /*! \struct SMS_SynthParams * \brief structure with information for synthesis functions * * This structure contains all the necessary settings for different types of synthesis. * It also holds arrays for windows and the inverse-FFT, as well as the previously * synthesized frame. * */ typedef struct SMSSynthParams { int iStochasticType; /*!< type of stochastic model defined by SMS_StocSynthType \see SMS_StocSynthType */ int iSynthesisType; /*!< type of synthesis to perform \see SMS_SynthType */ int iDetSynthType; /*!< method for synthesizing deterministic component \see SMS_DetSynthType */ int iOriginalSRate; /*!< samplerate of the sound model source (for stochastic synthesis approximation) */ int iSamplingRate; /*!< synthesis samplerate */ int sizeHop; /*!< number of samples to synthesis for each frame */ int origSizeHop; /*!< original number of samples used to create each analysis frame */ int nTracks; int nStochasticCoeff; int deEmphasis; /*!< whether or not to perform de-emphasis */ sfloat deEmphasisLastValue; sfloat *pFDetWindow; /*!< array to hold the window used for deterministic synthesis \see SMS_WIN_IFFT */ sfloat *pFStocWindow; /*!< array to hold the window used for stochastic synthesis (Hanning) */ sfloat *pSynthBuff; /*!< an array for keeping samples during overlap-add (2x sizeHop) */ sfloat *pMagBuff; /*!< an array for keeping magnitude spectrum for stochastic synthesis */ sfloat *pPhaseBuff; /*!< an array for keeping phase spectrum for stochastic synthesis */ sfloat *pSpectra; /*!< array for in-place FFT transform */ SMS_Data prevFrame; /*!< previous data frame, for interpolation between frames */ SMS_ModifyParams modParams; /*!< modification parameters */ sfloat *approxEnvelope; /*!< spectral approximation envelope */ } SMS_SynthParams; /*! \struct SMS_HarmCandidate * \brief structure to hold information about a harmonic candidate * * This structure provides storage for accumimlated statistics when * trying to decide which track is the fundamental frequency, during * harmonic detection. */ typedef struct { sfloat fFreq; /*!< frequency of harmonic */ sfloat fMag; /*!< magnitude of harmonic */ sfloat fMagPerc; /*!< percentage of magnitude */ sfloat fFreqDev; /*!< deviation from perfect harmonic */ sfloat fHarmRatio; /*!< percentage of harmonics found */ } SMS_HarmCandidate; /*! \struct SMS_ContCandidate * \brief structure to hold information about a continuation candidate * * This structure holds statistics about the guides, which is used to * decide the status of the guide */ typedef struct { sfloat fFreqDev; /*!< frequency deviation from guide */ sfloat fMagDev; /*!< magnitude deviation from guide */ int iPeak; /*!< peak number (organized according to frequency)*/ } SMS_ContCandidate; /*! \brief analysis format * * Is the signal is known to be harmonic, using format harmonic (with out without * phase) will give more accuracy to the peak continuation algorithm. If the signal * is known to be inharmonic, then it is best to use one of the inharmonic settings * to tell the peak continuation algorithm to just look at the peaks and connect them, * instead of trying to look for peaks at specific frequencies (harmonic partials). */ enum SMS_Format { SMS_FORMAT_H, /*!< 0, format harmonic */ SMS_FORMAT_IH, /*!< 1, format inharmonic */ SMS_FORMAT_HP, /*!< 2, format harmonic with phase */ SMS_FORMAT_IHP /*!< 3, format inharmonic with phase */ }; /*! \brief synthesis types * * These values are used to determine whether to synthesize * both deterministic and stochastic components together, * the deterministic component alone, or the stochastic * component alone. */ enum SMS_SynthType { SMS_STYPE_ALL, /*!< both components combined */ SMS_STYPE_DET, /*!< deterministic component alone */ SMS_STYPE_STOC /*!< stochastic component alone */ }; /*! \brief synthesis method for deterministic component * * There are two options for deterministic synthesis available to the * SMS synthesizer. The Inverse Fast Fourier Transform method * (IFFT) is more effecient for models with lots of partial tracks, but can * possibly smear transients. The Sinusoidal Table Lookup (SIN) can * theoritically support faster moving tracks at a higher fidelity, but * can consume lots of cpu at varying rates. */ enum SMS_DetSynthType { SMS_DET_IFFT, /*!< Inverse Fast Fourier Transform (IFFT) */ SMS_DET_SIN /*!< Sinusoidal Table Lookup (SIN) */ }; /*! \brief synthesis method for stochastic component * * Currently, Stochastic Approximation is the only reasonable choice * for stochastic synthesis: this method approximates the spectrum of * the stochastic component by a specified number of coefficients during * analyses, and then approximates another set of coefficients during * synthesis in order to fit the specified hopsize. The phases of the * coefficients are randomly generated, according to the theory that a * stochastic spectrum consists of random phases. * * The Inverse FFT method is not implemented, but is based on the idea of storing * the exact spectrum and phases of the residual component to file. Synthesis * could then be an exact reconstruction of the original signal, provided * interpolation is not necessary. * * No stochastic component can also be specified in order to skip the this * time consuming process altogether. This is especially useful when * performing multiple analyses to fine tune parameters pertaining to the * determistic component; once that is achieved, the stochastic component * will be much better as well. */ enum SMS_StocSynthType { SMS_STOC_NONE, /*!< 0, no stochastistic component */ SMS_STOC_APPROX, /*!< 1, Inverse FFT, magnitude approximation and generated phases */ SMS_STOC_IFFT /*!< 2, inverse FFT, interpolated spectrum (not used) */ }; /*! \brief synthesis method for deterministic component * * There are two options for deterministic synthesis available to the * SMS synthesizer. The Inverse Fast Fourier Transform method * (IFFT) is more effecient for models with lots of partial tracks, but can * possibly smear transients. The Sinusoidal Table Lookup (SIN) can * theoritically support faster moving tracks at a higher fidelity, but * can consume lots of cpu at varying rates. */ enum SMS_SpecEnvType { SMS_ENV_NONE, /*!< none */ SMS_ENV_CEP, /*!< cepstral coefficients */ SMS_ENV_FBINS /*!< frequency bins */ }; /*! \brief Error codes returned by SMS file functions */ /* \todo remove me */ enum SMS_ERRORS { SMS_OK, /*!< 0, no error*/ SMS_NOPEN, /*!< 1, couldn't open file */ SMS_NSMS , /*!< 2, not a SMS file */ SMS_MALLOC, /*!< 3, couldn't allocate memory */ SMS_RDERR, /*!< 4, read error */ SMS_WRERR, /*!< 5, write error */ SMS_SNDERR /*!< 6, sound IO error */ }; /*! \brief debug modes * * \todo write details about debug files */ enum SMS_DBG { SMS_DBG_NONE, /*!< 0, no debugging */ SMS_DBG_DET, /*!< 1, not yet implemented \todo make this show main information to look at for discovering the correct deterministic parameters*/ SMS_DBG_PEAK_DET, /*!< 2, peak detection function */ SMS_DBG_HARM_DET, /*!< 3, harmonic detection function */ SMS_DBG_PEAK_CONT, /*!< 4, peak continuation function */ SMS_DBG_CLEAN_TRAJ, /*!< 5, clean tracks function */ SMS_DBG_SINE_SYNTH, /*!< 6, sine synthesis function */ SMS_DBG_STOC_ANAL, /*!< 7, stochastic analysis function */ SMS_DBG_STOC_SYNTH, /*!< 8, stochastic synthesis function */ SMS_DBG_SMS_ANAL, /*!< 9, top level analysis function */ SMS_DBG_ALL, /*!< 10, everything */ SMS_DBG_RESIDUAL, /*!< 11, write residual to file */ SMS_DBG_SYNC, /*!< 12, write original, synthesis and residual to a text file */ }; #define SMS_MAX_WINDOW 8190 /*!< \brief maximum size for analysis window */ /* \brief type of sound to be analyzed * * \todo explain the differences between these two */ enum SMS_SOUND_TYPE { SMS_SOUND_TYPE_MELODY, /*!< 0, sound composed of several notes */ SMS_SOUND_TYPE_NOTE /*!< 1, sound composed of a single note */ }; /* \brief direction of analysis * * Sometimes a signal can be clearer at the end than at * the beginning. If the signal is very harmonic at the end then * doing the analysis in reverse could provide better results. */ enum SMS_DIRECTION { SMS_DIR_FWD, /*!< analysis from left to right */ SMS_DIR_REV /*!< analysis from right to left */ }; /* \brief window selection */ enum SMS_WINDOWS { SMS_WIN_HAMMING, /*!< 0: hamming */ SMS_WIN_BH_62, /*!< 1: blackman-harris, 62dB cutoff */ SMS_WIN_BH_70, /*!< 2: blackman-harris, 70dB cutoff */ SMS_WIN_BH_74, /*!< 3: blackman-harris, 74dB cutoff */ SMS_WIN_BH_92, /*!< 4: blackman-harris, 92dB cutoff */ SMS_WIN_HANNING, /*!< 5: hanning */ SMS_WIN_IFFT /*!< 6: window for deterministic synthesis based on the Inverse-FFT algorithm. This is a combination of an inverse Blackman-Harris 92dB and a triangular window. */ }; /*! * \brief frame status */ enum SMS_FRAME_STATUS { SMS_FRAME_EMPTY, SMS_FRAME_READY, SMS_FRAME_PEAKS_FOUND, SMS_FRAME_FUND_FOUND, SMS_FRAME_TRAJ_FOUND, SMS_FRAME_CLEANED, SMS_FRAME_RECOMPUTED, SMS_FRAME_DETER_SYNTH, SMS_FRAME_STOC_COMPUTED, SMS_FRAME_DONE, SMS_FRAME_END }; #define SMS_MIN_SIZE_FRAME 128 /* size of synthesis frame */ /*! \defgroup math_macros Math Macros * \brief mathematical operations and values needed for functions within * this library * \{ */ #define PI 3.141592653589793238462643 /*!< pi */ #define TWO_PI 6.28318530717958647692 /*!< pi * 2 */ #define INV_TWO_PI (1 / TWO_PI) /*!< 1 / ( pi * 2) */ #define PI_2 1.57079632679489661923 /*!< pi / 2 */ #define LOG2 0.69314718055994529 /*!< natural logarithm of 2 */ #define LOG10 2.3025850929940459 /*!< natural logarithm of 10 */ #define EXP 2.7182818284590451 /*!< Eurler's number */ sfloat sms_magToDB(sfloat x); sfloat sms_dBToMag(sfloat x); void sms_arrayMagToDB(int sizeArray, sfloat *pArray); void sms_arrayDBToMag(int sizeArray, sfloat *pArray); void sms_setMagThresh(sfloat x); sfloat sms_rms(int sizeArray, sfloat *pArray); sfloat sms_sine(sfloat fTheta); sfloat sms_sinc(sfloat fTheta); sfloat sms_random(void); int sms_power2(int n); sfloat sms_scalarTempered(sfloat x); void sms_arrayScalarTempered(int sizeArray, sfloat *pArray); #ifndef MAX /*! \brief returns the maximum of a and b */ #define MAX(a,b) ((a) > (b) ? (a) : (b)) #endif #ifndef MIN /*! \brief returns the minimum of a and b */ #define MIN(a,b) ((a) < (b) ? (a) : (b)) #endif /*! \} */ /* function declarations */ void sms_setPeaks(SMS_AnalParams *pAnalParams, int numamps, sfloat* amps, int numfreqs, sfloat* freqs, int numphases, sfloat* phases); int sms_findPeaks(int sizeWaveform, sfloat *pWaveform, SMS_AnalParams *pAnalParams, SMS_SpectralPeaks *pSpectralPeaks); int sms_findPartials(SMS_Data *pSmsFrame, SMS_AnalParams *pAnalParams); int sms_findResidual(int sizeSynthesis, sfloat* pSynthesis, int sizeOriginal, sfloat* pOriginal, SMS_ResidualParams *residualParams); void sms_approxResidual(int sizeResidual, sfloat* residual, int sizeApprox, sfloat* approx, SMS_ResidualParams *residualParams); int sms_analyze(int sizeWaveform, sfloat *pWaveform, SMS_Data *pSmsData, SMS_AnalParams *pAnalParams); void sms_analyzeFrame(int iCurrentFrame, SMS_AnalParams *pAnalParams, sfloat fRefFundamental); int sms_init(); void sms_free(); int sms_initAnalysis(SMS_AnalParams *pAnalParams); void sms_initAnalParams(SMS_AnalParams *pAnalParams); void sms_initSynthParams(SMS_SynthParams *synthParams); int sms_initSynth(SMS_SynthParams *pSynthParams); void sms_freeAnalysis(SMS_AnalParams *pAnalParams); void sms_freeSynth(SMS_SynthParams *pSynthParams); int sms_initSpectralPeaks(SMS_SpectralPeaks* peaks, int n); void sms_freeSpectralPeaks(SMS_SpectralPeaks* peaks); void sms_fillSoundBuffer(int sizeWaveform, sfloat *pWaveform, SMS_AnalParams *pAnalParams); void sms_windowCentered(int sizeWindow, sfloat *pWaveform, sfloat *pWindow, int sizeFft, sfloat *pFftBuffer); void sms_getWindow(int sizeWindow, sfloat *pWindow, int iWindowType); void sms_scaleWindow(int sizeWindow, sfloat *pWindow); int sms_spectrum(int sizeWindow, sfloat *pWaveform, sfloat *pWindow, int sizeMag, sfloat *pMag, sfloat *pPhase, sfloat *pFftBuffer); int sms_spectrumW(int sizeWindow, sfloat *pWaveform, sfloat *pWindow, int sizeMag, sfloat *pMag, sfloat *pPhase, sfloat *pFftBuffer); int sms_invSpectrum(int sizeWaveform, sfloat *pWaveform, sfloat *pWindow , int sizeMag, sfloat *pMag, sfloat *pPhase, sfloat *pFftBuffer); /* \todo remove this once invSpectrum is completely implemented */ int sms_invQuickSpectrumW(sfloat *pFMagSpectrum, sfloat *pFPhaseSpectrum, int sizeFft, sfloat *pFWaveform, int sizeWave, sfloat *pFWindow, sfloat *pFftBuffer); int sms_spectralApprox(sfloat *pSpec1, int sizeSpec1, int sizeSpec1Used, sfloat *pSpec2, int sizeSpec2, int nCoefficients, sfloat *envelope); int sms_spectrumMag(int sizeWindow, sfloat *pWaveform, sfloat *pWindow, int sizeMag, sfloat *pMag, sfloat *pFftBuffer); void sms_dCepstrum(int sizeCepstrum, sfloat *pCepstrum, int sizeFreq, sfloat *pFreq, sfloat *pMag, sfloat fLambda, int iSamplingRate); void sms_dCepstrumEnvelope(int sizeCepstrum, sfloat *pCepstrum, int sizeEnv, sfloat *pEnv); void sms_spectralEnvelope(SMS_Data *pSmsData, SMS_SEnvParams *pSpecEnvParams); int sms_sizeNextWindow(int iCurrentFrame, SMS_AnalParams *pAnalParams); sfloat sms_fundDeviation(SMS_AnalParams *pAnalParams, int iCurrentFrame); int sms_detectPeaks(int sizeSpec, sfloat *pFMag, sfloat *pPhase, SMS_Peak *pSpectralPeaks, SMS_AnalParams *pAnalParams); sfloat sms_harmDetection(int numPeaks, SMS_Peak* spectralPeaks, sfloat refFundamental, sfloat refHarmonic, sfloat lowestFreq, sfloat highestFreq, int soundType, sfloat minRefHarmMag, sfloat refHarmMagDiffFromMax); int sms_peakContinuation(int iFrame, SMS_AnalParams *pAnalParams); sfloat sms_preEmphasis(sfloat fInput, SMS_AnalParams *pAnalParams); sfloat sms_deEmphasis(sfloat fInput, SMS_SynthParams *pSynthParams); void sms_cleanTracks(int iCurrentFrame, SMS_AnalParams *pAnalParams); void sms_scaleDet(sfloat *pSynthBuffer, sfloat *pOriginalBuffer, sfloat *pSinAmp, SMS_AnalParams *pAnalParams, int nTracks); int sms_prepSine(int nTableSize); int sms_prepSinc(int nTableSize); void sms_clearSine(); void sms_clearSinc(); void sms_synthesize(SMS_Data *pSmsFrame, sfloat*pSynthesis, SMS_SynthParams *pSynthParams); void sms_sineSynthFrame(SMS_Data *pSmsFrame, sfloat *pBuffer, int sizeBuffer, SMS_Data *pLastFrame, int iSamplingRate); void sms_initHeader(SMS_Header *pSmsHeader); int sms_getHeader(char *pChFileName, SMS_Header **ppSmsHeader, FILE **ppInputFile); void sms_fillHeader(SMS_Header *pSmsHeader, SMS_AnalParams *pAnalParams); int sms_writeHeader(char *pFileName, SMS_Header *pSmsHeader, FILE **ppOutSmsFile); int sms_writeFile(FILE *pSmsFile, SMS_Header *pSmsHeader); int sms_initFrame(int iCurrentFrame, SMS_AnalParams *pAnalParams, int sizeWindow); int sms_clearAnalysisFrame(int iCurrentFrame, SMS_AnalParams *pAnalParams); int sms_allocFrame(SMS_Data *pSmsFrame, int nTracks, int nCoeff, int iPhase, int stochType, int nEnvCoeff); int sms_allocFrameH(SMS_Header *pSmsHeader, SMS_Data *pSmsFrame); int sms_getFrame(FILE *pInputFile, SMS_Header *pSmsHeader, int iFrame, SMS_Data *pSmsFrame); int sms_writeFrame(FILE *pSmsFile, SMS_Header *pSmsHeader, SMS_Data *pSmsFrame); void sms_freeFrame(SMS_Data *pSmsFrame); void sms_clearFrame(SMS_Data *pSmsFrame); void sms_copyFrame(SMS_Data *pCopySmsFrame, SMS_Data *pOriginalSmsFrame); int sms_frameSizeB(SMS_Header *pSmsHeader); void sms_initResidualParams(SMS_ResidualParams *residualParams); int sms_initResidual(SMS_ResidualParams *residualParams); void sms_freeResidual(SMS_ResidualParams *residualParams); int sms_residual(int sizeWindow, sfloat *pSynthesis, sfloat *pOriginal, SMS_ResidualParams* residualParams); void sms_filterHighPass(int sizeResidual, sfloat *pResidual, int iSamplingRate); int sms_stocAnalysis(int sizeWindow, sfloat *pResidual, sfloat *pWindow, SMS_Data *pSmsFrame, SMS_AnalParams *pAnalParams); void sms_interpolateFrames(SMS_Data *pSmsFrame1, SMS_Data *pSmsFrame2, SMS_Data *pSmsFrameOut, sfloat fInterpFactor); void sms_fft(int sizeFft, sfloat *pArray); void sms_ifft(int sizeFft, sfloat *pArray); void sms_RectToPolar(int sizeSpec, sfloat *pReal, sfloat *pMag, sfloat *pPhase); void sms_PolarToRect(int sizeSpec, sfloat *pReal, sfloat *pMag, sfloat *pPhase); void sms_spectrumRMS(int sizeMag, sfloat *pReal, sfloat *pMag); void sms_initModify(SMS_Header *header, SMS_ModifyParams *params); void sms_initModifyParams(SMS_ModifyParams *params); void sms_freeModify(SMS_ModifyParams *params); void sms_modify(SMS_Data *frame, SMS_ModifyParams *params); /***********************************************************************************/ /************* debug functions: ******************************************************/ int sms_createDebugFile(SMS_AnalParams *pAnalParams); void sms_writeDebugData(sfloat *pBuffer1, sfloat *pBuffer2, sfloat *pBuffer3, int sizeBuffer); void sms_writeDebugFile(); void sms_error(char *pErrorMessage ); int sms_errorCheck(); char* sms_errorString(); #endif /* _SMS_H */