// --------------------------------------------------------------------------- // phaseTravel // // Compute the sinusoidal phase travel between two Breakpoints. // Return the total unwrapped phase travel. // static double phaseTravel( Partial::const_iterator bp0, Partial::const_iterator bp1 ) { double f0 = bp0->frequency(); double t0 = bp0.time(); double f1 = bp1->frequency(); double t1 = bp1.time(); double favg = .5 * ( f0 + f1 ); double dt = t1 - t0; return 2 * Pi * favg * dt; }
// --------------------------------------------------------------------------- // setup // --------------------------------------------------------------------------- //! Prepare internal structures for synthesis. PartialList is transformed to //! to more conveniant structure for real-time processing. reset() is also called. //! Fade in/out Breakpoints are inserted at either end of the Partial. //! Partials with start times earlier than the Partial fade //! time will have shorter onset fades. //! //! \param partials The Partials to synthesize. //! \param pitch original pitch of the partials //! \return Nothing. //! \post This RealTimeSynthesizer's is ready for synthesise the sound specified //! by given partials. void RealTimeSynthesizer::setup(PartialList & partials, double pitch) noexcept { this->partials.clear(); this->pitch = pitch; clearPartialsBeingProcessed(); // assuming I am getting sorted partials by time for (auto it : partials) { if (it.numBreakpoints() <= 0) continue; PartialStruct pStruct; pStruct.numBreakpoints = it.numBreakpoints() + 2;// + fade in + fade out pStruct.breakpoints.reserve(pStruct.numBreakpoints); pStruct.label = it.label(); pStruct.startTime = ( m_fadeTimeSec < it.startTime() ) ? ( it.startTime() - m_fadeTimeSec ) : 0.;// compute fade in bp time pStruct.endTime = it.endTime() + m_fadeTimeSec;// compute fade out bp time // breakpoints Partial::const_iterator jt = it.begin(); // fade in breakpoint, compute fade in time pStruct.breakpoints.push_back(std::make_pair(pStruct.startTime, BreakpointUtils::makeNullBefore( jt.breakpoint(), it.startTime() - pStruct.startTime))); double sumF = 0; for (; jt != it.end(); jt++) { sumF += jt->frequency(); pStruct.breakpoints.push_back(std::make_pair(jt.time(), jt.breakpoint())); } pStruct.avgFrequency = sumF / (float) it.numBreakpoints(); // fade out breakpoint jt--; pStruct.breakpoints.push_back(std::make_pair(jt.time() + m_fadeTimeSec, BreakpointUtils::makeNullAfter( jt.breakpoint(), m_fadeTimeSec ))); this->partials.push_back(pStruct); // pStruct.breakpoints[0].second.setAmplitude(pStruct.breakpoints[1].second.amplitude()); } reset(); }
// --------------------------------------------------------------------------- // avgFrequency // --------------------------------------------------------------------------- //! Return the average frequency over all Breakpoints in this Partial. //! Return zero if the Partial has no Breakpoints. //! //! \param p is the Partial to evaluate //! \return the average frequency (Hz) of Breakpoints in the Partial p // double avgFrequency( const Partial & p ) { double avg = 0; for ( Partial::const_iterator it = p.begin(); it != p.end(); ++it ) { avg += it->frequency(); } if ( avg != 0 ) { avg /= p.numBreakpoints(); } return avg; }
// --------------------------------------------------------------------------- // weightedAvgFrequency // --------------------------------------------------------------------------- //! Return the average frequency over all Breakpoints in this Partial, //! weighted by the Breakpoint amplitudes. //! Return zero if the Partial has no Breakpoints. //! //! \param p is the Partial to evaluate //! \return the average frequency (Hz) of Breakpoints in the Partial p // double weightedAvgFrequency( const Partial & p ) { double avg = 0; double ampsum = 0; for ( Partial::const_iterator it = p.begin(); it != p.end(); ++it ) { avg += it->amplitude() * it->frequency(); ampsum += it->amplitude(); } if ( avg != 0 && ampsum != 0 ) { avg /= ampsum; } else { avg = 0; } return avg; }