/*! \brief scale deterministic magnitude if synthesis is larger than original * * \param pFSynthBuffer synthesis buffer * \param pFOriginalBuffer original sound * \param pFSinAmp magnitudes to be scaled * \param pAnalParams pointer to analysis parameters * \param nTrack number of tracks */ void sms_scaleDet (sfloat *pFSynthBuffer, sfloat *pFOriginalBuffer, sfloat *pFSinAmp, SMS_AnalParams *pAnalParams, int nTrack) { sfloat fOriginalMag = 0, fSynthesisMag = 0; sfloat fCosScaleFactor; int iTrack, i; /* get sound energy */ for (i = 0; i < pAnalParams->sizeHop; i++) { fOriginalMag += fabs((double) pFOriginalBuffer[i]); fSynthesisMag += fabs((double) pFSynthBuffer[i]); } /* if total energy of deterministic sound is larger than original, scale deterministic representation */ if (fSynthesisMag > (1.5 * fOriginalMag)) { fCosScaleFactor = fOriginalMag / fSynthesisMag; if(pAnalParams->iDebugMode == SMS_DBG_CLEAN_TRAJ || pAnalParams->iDebugMode == SMS_DBG_ALL) fprintf (stdout, "Frame %d: magnitude scaled by %f\n", pAnalParams->ppFrames[0]->iFrameNum, fCosScaleFactor); for (iTrack = 0; iTrack < nTrack; iTrack++) if (pFSinAmp[iTrack] > 0) pFSinAmp[iTrack] = sms_magToDB (sms_dBToMag (pFSinAmp[iTrack]) * fCosScaleFactor); } }
/*! \brief generate a sinusoid given two peaks, current and last * * it interpolation between phase values and magnitudes * * \param fFreq current frequency * \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 iTrack current track */ 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; /* 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; }
/*! \brief generate a sinusoid given two frames, current and last * * \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 iTrack current track */ 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) { 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; }