This is sineSynth.c in view mode; [Download] [Up]
#include "../sms.h" /* function to generate a sinusoid given two peaks, current and last * it interpolation between phase values and magnitudes * float fFreq; current frequency * float fMag; current magnitude * float fPhase; current phase * SMS_DATA values from last frame * float *pFWaveform; pointer to output waveform * int sizeBuffer; size of the synthesis buffer */ static void SinePhaSynth (float fFreq, float fMag, float fPhase, SMS_DATA *pLastFrame, float *pFWaveform, int sizeBuffer, int iTraj) { float fMagIncr, fInstMag, fInstPhase, fTmp; int iM, i; float fAlpha, fBeta, fTmp1, fTmp2; /* if no mag in last frame copy freq from current and make phase */ if (pLastFrame->pFMagTraj[iTraj] <= 0) { pLastFrame->pFFreqTraj[iTraj] = fFreq; fTmp = fPhase - (fFreq * sizeBuffer); pLastFrame->pFPhaTraj[iTraj] = fTmp - floor(fTmp / TWO_PI) * TWO_PI; } /* and the other way */ else if (fMag <= 0) { fFreq = pLastFrame->pFFreqTraj[iTraj]; fTmp = pLastFrame->pFPhaTraj[iTraj] + (pLastFrame->pFFreqTraj[iTraj] * sizeBuffer); fPhase = fTmp - floor(fTmp / TWO_PI) * TWO_PI; } /* caculate the instantaneous amplitude */ fMagIncr = (fMag - pLastFrame->pFMagTraj[iTraj]) / sizeBuffer; fInstMag = pLastFrame->pFMagTraj[iTraj]; /* create instantaneous phase from freq. and phase values */ fTmp1 = fFreq - pLastFrame->pFFreqTraj[iTraj]; fTmp2 = ((pLastFrame->pFPhaTraj[iTraj] + pLastFrame->pFFreqTraj[iTraj] * sizeBuffer - fPhase) + fTmp1 * sizeBuffer / 2.0) / TWO_PI; iM = (int) (fTmp2 + .5); fTmp2 = fPhase - pLastFrame->pFPhaTraj[iTraj] - pLastFrame->pFFreqTraj[iTraj] * sizeBuffer + TWO_PI * iM; fAlpha = (3.0 / (float)(sizeBuffer * sizeBuffer)) * fTmp2 - fTmp1 / sizeBuffer; fBeta = (-2.0 / ((float) (sizeBuffer * sizeBuffer * sizeBuffer))) * fTmp2 + fTmp1 / ((float) (sizeBuffer * sizeBuffer)); for(i=0; i<sizeBuffer; i++) { fInstMag += fMagIncr; fInstPhase = pLastFrame->pFPhaTraj[iTraj] + pLastFrame->pFFreqTraj[iTraj] * i + fAlpha * i * i + fBeta * i * i * i; pFWaveform[i] += TO_MAG(fInstMag) * SinTab(fInstPhase + PI_2); } /* save current values into buffer */ pLastFrame->pFFreqTraj[iTraj] = fFreq; pLastFrame->pFMagTraj[iTraj] = fMag; pLastFrame->pFPhaTraj[iTraj] = fPhase; } /* * function to generate a sinusoid given two frames, current and last * * float fFreq; current frequency * float fMag; current magnitude * SMS_DATA *pLastFrame; values from last frame * float *pFBuffer; pointer to output waveform * int sizeBuffer; size of the synthesis buffer * int iTraj; current trajectory */ static void SineSynth (float fFreq, float fMag, SMS_DATA *pLastFrame, float *pFBuffer, int sizeBuffer, int iTraj) { float fMagIncr, fInstMag, fFreqIncr, fInstPhase, fInstFreq; int i; /* if no mag in last frame copy freq from current */ if (pLastFrame->pFMagTraj[iTraj] <= 0) { pLastFrame->pFFreqTraj[iTraj] = fFreq; pLastFrame->pFPhaTraj[iTraj] = TWO_PI * ((random() - HALF_MAX) / HALF_MAX); } /* and the other way */ else if (fMag <= 0) fFreq = pLastFrame->pFFreqTraj[iTraj]; /* calculate the instantaneous amplitude */ fMagIncr = (fMag - pLastFrame->pFMagTraj[iTraj]) / sizeBuffer; fInstMag = pLastFrame->pFMagTraj[iTraj]; /* calculate instantaneous frequency */ fFreqIncr = (fFreq - pLastFrame->pFFreqTraj[iTraj]) / sizeBuffer; fInstFreq = pLastFrame->pFFreqTraj[iTraj]; fInstPhase = pLastFrame->pFPhaTraj[iTraj]; /* generate all the samples */ for (i = 0; i < sizeBuffer; i++) { fInstMag += fMagIncr; fInstFreq += fFreqIncr; fInstPhase += fInstFreq; pFBuffer[i] += TO_MAG (fInstMag) * SinTab (fInstPhase); } /* save current values into last values */ pLastFrame->pFFreqTraj[iTraj] = fFreq; pLastFrame->pFMagTraj[iTraj] = fMag; pLastFrame->pFPhaTraj[iTraj] = fInstPhase - floor(fInstPhase / TWO_PI) * TWO_PI; } /* * function to generate all the sinusoids for a given frame * * SMS_DATA *pSmsData; SMS data for current frame * int nTraj; number of partial trajectories * float *pFBuffer; pointer to output waveform * int sizeBuffer; size of the synthesis buffer * SMS_DATA *pLastFrame; SMS data from last frame */ int FrameSineSynth (SMS_DATA *pSmsData, float *pFBuffer, int sizeBuffer, SMS_DATA *pLastFrame) { float fMag, fFreq; int i, nTraj = pSmsData->nTraj; /* go through all the trajectories */ for (i = 0; i < nTraj; i++) { /* get magnitude */ fMag = pSmsData->pFMagTraj[i]; fFreq = pSmsData->pFFreqTraj[i]; if (fFreq > FHalfSamplingRate) fMag = 0; /* generate sines if there are magnitude values */ if ((fMag > 0) || (pLastFrame->pFMagTraj[i] > 0)) { /* frequency from Hz to radians */ fFreq = (fFreq == 0) ? 0 : TWO_PI * fFreq / FSamplingRate; if (pSmsData->pFPhaTraj == NULL) SineSynth(fFreq, fMag, pLastFrame, pFBuffer, sizeBuffer, i); else SinePhaSynth(fFreq, fMag, pSmsData->pFPhaTraj[i], pLastFrame, pFBuffer, sizeBuffer, i); } } return 1; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.