diff options
author | John Glover <glover.john@gmail.com> | 2010-11-24 23:26:43 +0000 |
---|---|---|
committer | John Glover <glover.john@gmail.com> | 2010-11-24 23:26:43 +0000 |
commit | 5e25edb1b78f28bee09bd7513a80fb500bbd59c4 (patch) | |
tree | 9290c3757abdecf2525c68cd5e5082fa9604ca61 /sms/sineSynth.c | |
parent | 580dd2e019e9666dc5f4771dedeb0720aa8d1d07 (diff) | |
download | simpl-5e25edb1b78f28bee09bd7513a80fb500bbd59c4.tar.gz simpl-5e25edb1b78f28bee09bd7513a80fb500bbd59c4.tar.bz2 simpl-5e25edb1b78f28bee09bd7513a80fb500bbd59c4.zip |
Updated libsms to the latest version (1.15), includes some memory management improvements/simplifications but the basic API is the same. Also started updating the unit tests, which will now use the nose framework
Diffstat (limited to 'sms/sineSynth.c')
-rw-r--r-- | sms/sineSynth.c | 268 |
1 files changed, 135 insertions, 133 deletions
diff --git a/sms/sineSynth.c b/sms/sineSynth.c index 58768bd..f2110af 100644 --- a/sms/sineSynth.c +++ b/sms/sineSynth.c @@ -32,163 +32,165 @@ * \param fMag current magnitude * \param fPhase current phase * \param pLastFrame stucture with values from last frame - * \param pFWaveform pointer to output waveform - * \param sizeBuffer size of the synthesis buffer + * \param pFWaveform pointer to output waveform + * \param sizeBuffer size of the synthesis buffer * \param iTrack current track */ -static void SinePhaSynth (sfloat fFreq, sfloat fMag, sfloat fPhase, - SMS_Data *pLastFrame, sfloat *pFWaveform, - int sizeBuffer, int iTrack) +static void SinePhaSynth(sfloat fFreq, sfloat fMag, sfloat fPhase, + SMS_Data *pLastFrame, sfloat *pFWaveform, + int sizeBuffer, int iTrack) { - sfloat fMagIncr, fInstMag, fInstPhase, fTmp; - int iM, i; - sfloat fAlpha, fBeta, fTmp1, fTmp2; + sfloat fMagIncr, fInstMag, fInstPhase, fTmp; + int iM, i; + sfloat fAlpha, fBeta, fTmp1, fTmp2; - /* if no mag in last frame copy freq from current and make phase */ - if (pLastFrame->pFSinAmp[iTrack] <= 0) - { - pLastFrame->pFSinFreq[iTrack] = fFreq; - fTmp = fPhase - (fFreq * sizeBuffer); - pLastFrame->pFSinPha[iTrack] = fTmp - floor(fTmp / TWO_PI) * TWO_PI; - } - /* and the other way */ - else if (fMag <= 0) - { - fFreq = pLastFrame->pFSinFreq[iTrack]; - fTmp = pLastFrame->pFSinPha[iTrack] + + /* if no mag in last frame copy freq from current and make phase */ + if (pLastFrame->pFSinAmp[iTrack] <= 0) + { + pLastFrame->pFSinFreq[iTrack] = fFreq; + fTmp = fPhase - (fFreq * sizeBuffer); + pLastFrame->pFSinPha[iTrack] = fTmp - floor(fTmp / TWO_PI) * TWO_PI; + } + /* and the other way */ + else if (fMag <= 0) + { + fFreq = pLastFrame->pFSinFreq[iTrack]; + fTmp = pLastFrame->pFSinPha[iTrack] + (pLastFrame->pFSinFreq[iTrack] * sizeBuffer); - fPhase = fTmp - floor(fTmp / TWO_PI) * TWO_PI; - } - - /* caculate the instantaneous amplitude */ - fMagIncr = (fMag - pLastFrame->pFSinAmp[iTrack]) / sizeBuffer; - fInstMag = pLastFrame->pFSinAmp[iTrack]; - - /* create instantaneous phase from freq. and phase values */ - fTmp1 = fFreq - pLastFrame->pFSinFreq[iTrack]; - fTmp2 = ((pLastFrame->pFSinPha[iTrack] + - pLastFrame->pFSinFreq[iTrack] * sizeBuffer - fPhase) + - fTmp1 * sizeBuffer / 2.0) / TWO_PI; - iM = (int) (fTmp2 + .5); - fTmp2 = fPhase - pLastFrame->pFSinPha[iTrack] - - pLastFrame->pFSinFreq[iTrack] * sizeBuffer + - TWO_PI * iM; - fAlpha = (3.0 / (sfloat)(sizeBuffer * sizeBuffer)) * - fTmp2 - fTmp1 / sizeBuffer; - fBeta = (-2.0 / ((sfloat) (sizeBuffer * sizeBuffer * sizeBuffer))) * - fTmp2 + fTmp1 / ((sfloat) (sizeBuffer * sizeBuffer)); - - for(i=0; i<sizeBuffer; i++) - { - fInstMag += fMagIncr; - fInstPhase = pLastFrame->pFSinPha[iTrack] + - pLastFrame->pFSinFreq[iTrack] * i + - fAlpha * i * i + fBeta * i * i * i; - -/* pFWaveform[i] += sms_dBToMag(fInstMag) * sms_sine(fInstPhase + PI_2); */ - pFWaveform[i] += sms_dBToMag(fInstMag) * sinf(fInstPhase + PI_2); - } - /* save current values into buffer */ - pLastFrame->pFSinFreq[iTrack] = fFreq; - pLastFrame->pFSinAmp[iTrack] = fMag; - pLastFrame->pFSinPha[iTrack] = fPhase; + fPhase = fTmp - floor(fTmp / TWO_PI) * TWO_PI; + } + + /* caculate the instantaneous amplitude */ + fMagIncr = (fMag - pLastFrame->pFSinAmp[iTrack]) / sizeBuffer; + fInstMag = pLastFrame->pFSinAmp[iTrack]; + + /* create instantaneous phase from freq. and phase values */ + fTmp1 = fFreq - pLastFrame->pFSinFreq[iTrack]; + fTmp2 = ((pLastFrame->pFSinPha[iTrack] + + pLastFrame->pFSinFreq[iTrack] * sizeBuffer - fPhase) + + fTmp1 * sizeBuffer / 2.0) / TWO_PI; + iM = (int) (fTmp2 + .5); + fTmp2 = fPhase - pLastFrame->pFSinPha[iTrack] - + pLastFrame->pFSinFreq[iTrack] * sizeBuffer + + TWO_PI * iM; + fAlpha = (3.0 / (sfloat)(sizeBuffer * sizeBuffer)) * + fTmp2 - fTmp1 / sizeBuffer; + fBeta = (-2.0 / ((sfloat) (sizeBuffer * sizeBuffer * sizeBuffer))) * + fTmp2 + fTmp1 / ((sfloat) (sizeBuffer * sizeBuffer)); + + for(i=0; i<sizeBuffer; i++) + { + fInstMag += fMagIncr; + fInstPhase = pLastFrame->pFSinPha[iTrack] + + pLastFrame->pFSinFreq[iTrack] * i + + fAlpha * i * i + fBeta * i * i * i; + + /* pFWaveform[i] += sms_dBToMag(fInstMag) * sms_sine(fInstPhase + PI_2); */ + pFWaveform[i] += sms_dBToMag(fInstMag) * sinf(fInstPhase + PI_2); + } + /* save current values into buffer */ + pLastFrame->pFSinFreq[iTrack] = fFreq; + pLastFrame->pFSinAmp[iTrack] = fMag; + pLastFrame->pFSinPha[iTrack] = fPhase; } /*! \brief generate a sinusoid given two frames, current and last * - * \param fFreq current frequency + * \param fFreq current frequency * \param fMag current magnitude * \param pLastFrame stucture with values from last frame - * \param pFBuffer pointer to output waveform - * \param sizeBuffer size of the synthesis buffer + * \param pFBuffer pointer to output waveform + * \param sizeBuffer size of the synthesis buffer * \param iTrack current track */ -static void SineSynth (sfloat fFreq, sfloat fMag, SMS_Data *pLastFrame, - sfloat *pFBuffer, int sizeBuffer, int iTrack) +static void SineSynth(sfloat fFreq, sfloat fMag, SMS_Data *pLastFrame, + sfloat *pFBuffer, int sizeBuffer, int iTrack) { - sfloat fMagIncr, fInstMag, fFreqIncr, fInstPhase, fInstFreq; - int i; - - /* if no mag in last frame copy freq from current */ - if (pLastFrame->pFSinAmp[iTrack] <= 0) - { + sfloat fMagIncr, fInstMag, fFreqIncr, fInstPhase, fInstFreq; + int i; + + /* if no mag in last frame copy freq from current */ + if (pLastFrame->pFSinAmp[iTrack] <= 0) + { + pLastFrame->pFSinFreq[iTrack] = fFreq; + pLastFrame->pFSinPha[iTrack] = + TWO_PI * sms_random(); + } + /* and the other way */ + else if (fMag <= 0) + fFreq = pLastFrame->pFSinFreq[iTrack]; + + /* calculate the instantaneous amplitude */ + fMagIncr = (fMag - pLastFrame->pFSinAmp[iTrack]) / sizeBuffer; + fInstMag = pLastFrame->pFSinAmp[iTrack]; + /* calculate instantaneous frequency */ + fFreqIncr = (fFreq - pLastFrame->pFSinFreq[iTrack]) / sizeBuffer; + fInstFreq = pLastFrame->pFSinFreq[iTrack]; + fInstPhase = pLastFrame->pFSinPha[iTrack]; + + /* generate all the samples */ + for (i = 0; i < sizeBuffer; i++) + { + fInstMag += fMagIncr; + fInstFreq += fFreqIncr; + fInstPhase += fInstFreq; + + pFBuffer[i] += sms_dBToMag(fInstMag) * sms_sine(fInstPhase); + } + + /* save current values into last values */ pLastFrame->pFSinFreq[iTrack] = fFreq; - pLastFrame->pFSinPha[iTrack] = - TWO_PI * sms_random(); - } - /* and the other way */ - else if (fMag <= 0) - fFreq = pLastFrame->pFSinFreq[iTrack]; - - /* calculate the instantaneous amplitude */ - fMagIncr = (fMag - pLastFrame->pFSinAmp[iTrack]) / sizeBuffer; - fInstMag = pLastFrame->pFSinAmp[iTrack]; - /* calculate instantaneous frequency */ - fFreqIncr = (fFreq - pLastFrame->pFSinFreq[iTrack]) / sizeBuffer; - fInstFreq = pLastFrame->pFSinFreq[iTrack]; - fInstPhase = pLastFrame->pFSinPha[iTrack]; - - /* generate all the samples */ - for (i = 0; i < sizeBuffer; i++) - { - fInstMag += fMagIncr; - fInstFreq += fFreqIncr; - fInstPhase += fInstFreq; - - pFBuffer[i] += sms_dBToMag (fInstMag) * sms_sine (fInstPhase); - } - - /* save current values into last values */ - pLastFrame->pFSinFreq[iTrack] = fFreq; - pLastFrame->pFSinAmp[iTrack] = fMag; - pLastFrame->pFSinPha[iTrack] = fInstPhase - - floor(fInstPhase / TWO_PI) * TWO_PI; + pLastFrame->pFSinAmp[iTrack] = fMag; + pLastFrame->pFSinPha[iTrack] = fInstPhase - + floor(fInstPhase / TWO_PI) * TWO_PI; } /*! \brief generate all the sinusoids for a given frame * * \param pSmsData SMS data for current frame - * \param pFBuffer pointer to output waveform + * \param pFBuffer pointer to output waveform * \param sizeBuffer size of the synthesis buffer * \param pLastFrame SMS data from last frame * \param iSamplingRate sampling rate to synthesize for */ -void sms_sineSynthFrame (SMS_Data *pSmsData, sfloat *pFBuffer, - int sizeBuffer, SMS_Data *pLastFrame, int iSamplingRate) +void sms_sineSynthFrame(SMS_Data *pSmsData, sfloat *pFBuffer, + int sizeBuffer, SMS_Data *pLastFrame, + int iSamplingRate) { - sfloat fMag, fFreq; - int i; - int nTracks = pSmsData->nTracks; - int iHalfSamplingRate = iSamplingRate >> 1; - - /* go through all the tracks */ - for (i = 0; i < nTracks; i++) - { - /* get magnitude */ - fMag = pSmsData->pFSinAmp[i]; - - fFreq = pSmsData->pFSinFreq[i]; - - /* gaurd so transposed frequencies don't alias */ - if (fFreq > iHalfSamplingRate || fFreq < 0) - fMag = 0; - - /* generate sines if there are magnitude values */ - if ((fMag > 0) || (pLastFrame->pFSinAmp[i] > 0)) - { - /* frequency from Hz to radians */ - fFreq = (fFreq == 0) ? 0 : TWO_PI * fFreq / iSamplingRate; - - /* \todo make seperate function for SineSynth /wo phase */ - if (pSmsData->pFSinPha == NULL) - { - SineSynth(fFreq, fMag, pLastFrame, pFBuffer, sizeBuffer, i); - } - else - { - SinePhaSynth(fFreq, fMag, pSmsData->pFSinPha[i], pLastFrame, - pFBuffer, sizeBuffer, i); - } - } + sfloat fMag, fFreq; + int i; + int nTracks = pSmsData->nTracks; + int iHalfSamplingRate = iSamplingRate >> 1; + + /* go through all the tracks */ + for (i = 0; i < nTracks; i++) + { + /* get magnitude */ + fMag = pSmsData->pFSinAmp[i]; + + fFreq = pSmsData->pFSinFreq[i]; + + /* gaurd so transposed frequencies don't alias */ + if (fFreq > iHalfSamplingRate || fFreq < 0) + fMag = 0; + + /* generate sines if there are magnitude values */ + if ((fMag > 0) || (pLastFrame->pFSinAmp[i] > 0)) + { + /* frequency from Hz to radians */ + fFreq = (fFreq == 0) ? 0 : TWO_PI * fFreq / iSamplingRate; + + /* \todo make seperate function for SineSynth /wo phase */ + if (pSmsData->pFSinPha == NULL) + { + SineSynth(fFreq, fMag, pLastFrame, pFBuffer, sizeBuffer, i); + } + else + { + SinePhaSynth(fFreq, fMag, pSmsData->pFSinPha[i], pLastFrame, + pFBuffer, sizeBuffer, i); + } } + } } + |