Exemple #1
0
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// devTimeStretcher
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void DevSuite::devTimeStretcher()
{
   Logger msg( "devTimeStretcher" );
   msg << Msg::Info << "Running devTimeStretcher..." << Msg::EndReq;

   // std::unique_ptr< std::vector< Music::Note > > trueMelody( new std::vector< Music::Note >() );
   // RawPcmData::Ptr data = TestDataSupply::generateRandomMelody( trueMelody.get() );
   // RawPcmData::Ptr data = TestDataSupply::getCurrentTestSample();

   SamplingInfo samplingInfo;
   Synthesizer::SineGenerator sineGen( samplingInfo );
   sineGen.setFrequency( 440 );
   RawPcmData::Ptr data = sineGen.generate( 1024 * 128 + 46 );

   Music::TimeStretcher timeStretchAlg( 2 );
   RawPcmData stretchedMusic = timeStretchAlg.execute( *data );

   gPlotFactory().createPlot( "RegeneratedWaveFile" );
   gPlotFactory().drawPcmData( *data );
   gPlotFactory().drawPcmData( stretchedMusic, Qt::red );

   data->normaliseToPeak();
   stretchedMusic.normaliseToPeak();

   MultiChannelRawPcmData waveData( new RawPcmData( *data ) );
   MultiChannelRawPcmData waveDataStretched( new RawPcmData( stretchedMusic ) );

   // WaveFile::write( "OriginalBeforeStretch.wav", waveData );
   // WaveFile::write( "StretchedMusic.wav", waveDataStretched );
}
Exemple #2
0
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// devImprovedPeakAlgorithm
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void DevSuite::devImprovedPeakAlgorithm()
{
   Logger msg( "devImprovedPeakAlgorithm" );
   msg << Msg::Info << "Running devImprovedPeakAlgorithm..." << Msg::EndReq;

   // Take fourier bin size = 4096
   // Take sine with phase = 0
   // Make center frequency variable
   // Pick range around center frequency with delta_freq
   // Compute max rel amp as function of freq delta (envelope)
   // First sort by amp, remove all non-increasing frequency entries

   size_t fourierSize = 4096;
   size_t zeroPadSize = 3*fourierSize;

   const RealVector& centreFreqs = realVector( 400 );
   double deltaRange = 100;
   size_t numFreqs = 100;
   const double freqDelta = deltaRange / numFreqs;

   SamplingInfo samplingInfo;
   Synthesizer::SineGenerator sineGen( samplingInfo );

   RealVector relMaxY;
   RealVector diffX;

   for ( size_t iCentreFreq = 0; iCentreFreq < centreFreqs.size(); ++iCentreFreq )
   {
      for ( size_t iFreq = 0; iFreq < numFreqs; ++iFreq )
      {
         double frequency = centreFreqs[ iCentreFreq ] + freqDelta * iFreq;
         sineGen.setFrequency( frequency );
         RawPcmData::Ptr data = sineGen.generate( fourierSize );

         WaveAnalysis::SpectralReassignmentTransform transform( samplingInfo, fourierSize, zeroPadSize, 2 );
         WaveAnalysis::StftData::Ptr stftData = transform.execute( *data );
         const WaveAnalysis::SrSpectrum& spec = stftData->getSrSpectrum( 0 );

         const RealVector& x = spec.getFrequencies();
         RealVector&& y = spec.getMagnitude();

         y /= Utils::getMaxValue( y );
         RealVector deltaX = x - frequency;
         // msg << Msg::Info << deltaX << Msg::EndReq;

         relMaxY.insert( relMaxY.end(), y.begin(), y.end() );
         diffX.insert( diffX.end(), deltaX.begin(), deltaX.end() );
      }
   }

   SortCache relYSc( diffX );
   const RealVector& relMaxYSorted = relYSc.applyTo( relMaxY );
   const RealVector& relDiffXSorted = relYSc.applyTo( diffX );

   Math::Log10Function log10;

   gPlotFactory().createPlot( "envelope" );
   gPlotFactory().createGraph( relDiffXSorted, relMaxYSorted );

   // Create envelope by requiring linear interpolation is always above curve.
   size_t nEnvelopeSamples = 500;

   RealVector linearGrid = Utils::createRangeReal( -1000, 1000, nEnvelopeSamples );
   RealVector zeros = RealVector( nEnvelopeSamples, 0 );

   gPlotFactory().createScatter( linearGrid, zeros, Plotting::MarkerDrawAttr( Qt::red ) );


   gPlotFactory().createPlot( "envelopLog" );
   gPlotFactory().createGraph( relDiffXSorted, log10.evalMany( relMaxYSorted ) );



   // RealVector fCorr = spec.getFrequencyCorrections();
   // for ( size_t i = 0; i < spec.getFrequencies().size(); ++i )
   // {
   //    fCorr[ i ] /= spec.getFrequency( i );
   // }


   // Math::Log10Function log10Fct;

   // gPlotFactory().createPlot( "plot1" );
   // gPlotFactory().createGraph( x, log10Fct.evalMany( y ), Qt::blue );
   // gPlotFactory().createScatter( x, log10Fct.evalMany( y ) );
   // gPlotFactory().createGraph( x, log10Fct.evalMany( fCorr ), Qt::green );
   // gPlotFactory().createScatter( x, log10Fct.evalMany( fCorr ), Plotting::MarkerDrawAttr( Qt::red ) );

   // msg << Msg::Info << "Number of spectra in STFT: " << stftData->getNumSpectra() << Msg::EndReq;
   // for ( size_t iSpec = 0; iSpec < stftData->getNumSpectra(); ++iSpec )
   // {
   //    const WaveAnalysis::WindowLocation* windowLoc = stftData->getSpectrum( iSpec ).getWindowLocation();
   //    msg << Msg::Info << "WindowLocation: [" << windowLoc->getFirstSample() << ", " << windowLoc->getLastSample() << "]" << Msg::EndReq;
   // }



}
    void YSE::DSP::sineWave::process(SOUND_STATUS & intent, Int & latency) {
      Flt lastVolume = volumeCurve.getBack();
      Clamp(lastVolume, 0.f, 1.f);

      if (latency >= STANDARD_BUFFERSIZE) {
        // no new attack, but a previous curve might not be done yet
        if (intent == SS_STOPPED || intent == SS_PAUSED) {
          // complete fade out if needed
          if (lastVolume > 0) {
            volumeCurve.drawLine(0, (UInt)(lastVolume * 200), lastVolume, 0);
            volumeCurve.drawLine((UInt)((lastVolume)* 200), STANDARD_BUFFERSIZE, 0);
          }
          else {
            volumeCurve = 0.f;
          }
        }
        else if (intent == SS_PLAYING) {
          // complete fade in if needed
          if (lastVolume < 1) {
            volumeCurve.drawLine(0, (UInt)((1 - lastVolume) * 200), lastVolume, 1);
            volumeCurve.drawLine((UInt)((1 - lastVolume) * 200), STANDARD_BUFFERSIZE, 1);
          }
          else {
            volumeCurve = 1.f;
          }
        }
        else {
          // in all other cases continue the previous volume status
          volumeCurve = lastVolume;
        }

        // frequency can be changed within a note, but if intent != playing, we assume
        // it will change on the next attack
        if (intent != SS_PLAYING) {
          // just keep the last freqency
          frequencyCurve = currentFrequency;
        }
        else {
          currentFrequency = parmFrequency;
          frequencyCurve = currentFrequency;
        }

      }
      else if (latency == 0) {
        // no latency at all, just do everything at the beginning of the sample
        if (intent == SS_STOPPED || intent == SS_PAUSED) {
          // complete fade out if needed
          if (lastVolume > 0) {
            volumeCurve.drawLine(0, (UInt)(lastVolume * 200), lastVolume, 0);
            volumeCurve.drawLine((UInt)((lastVolume)* 200), STANDARD_BUFFERSIZE, 0);
          }
          else {
            volumeCurve = 0.f;
          }
          frequencyCurve = currentFrequency;
        }
        else if (intent == SS_PLAYING) {
          // complete fade in if needed
          if (lastVolume < 1) {
            volumeCurve.drawLine(0, (UInt)((1 - lastVolume) * 200), lastVolume, 1);
            volumeCurve.drawLine((UInt)((1 - lastVolume) * 200), STANDARD_BUFFERSIZE, 1);
          }
          else {
            volumeCurve = 1.f;
          }
          frequencyCurve = currentFrequency;
        }
        else if (intent == SS_WANTSTOPLAY || intent == SS_WANTSTORESTART) {
          volumeCurve.drawLine(0, 200, lastVolume, 1);
          volumeCurve.drawLine(200, STANDARD_BUFFERSIZE, 1);
          currentFrequency = parmFrequency;
          frequencyCurve = currentFrequency;
          intent = SS_PLAYING;
        }
        else if (intent == SS_WANTSTOPAUSE || intent == SS_WANTSTOSTOP) {
          volumeCurve.drawLine(0, 200, lastVolume, 0);
          volumeCurve.drawLine(200, STANDARD_BUFFERSIZE, 0);
          frequencyCurve = currentFrequency;
          intent = SS_STOPPED;
        }


      }
      else {
        // latency > 0, but smaller as buffersize
        // this means the change has to come somewhere in the middle of the sample

        // no new attack, but a previous curve might not be done yet
        if (intent == SS_STOPPED || intent == SS_PAUSED) {
          // complete fade out if needed
          if (lastVolume > 0) {
            volumeCurve.drawLine(0, (UInt)(lastVolume * 200), lastVolume, 0);
            volumeCurve.drawLine((UInt)((lastVolume)* 200), STANDARD_BUFFERSIZE, 0);
          }
          else {
            volumeCurve = 0.f;
          }
          frequencyCurve = currentFrequency;

        }
        else if (intent == SS_PLAYING) {
          // complete fade in if needed
          if (lastVolume < 1) {
            volumeCurve.drawLine(0, (UInt)((1 - lastVolume) * 200), lastVolume, 1);
            volumeCurve.drawLine((UInt)((1 - lastVolume) * 200), STANDARD_BUFFERSIZE, 1);
          }
          else {
            volumeCurve = 1.f;
          }
          frequencyCurve = currentFrequency;

        }
        else if (intent == SS_WANTSTOPLAY || intent == SS_WANTSTORESTART) {
          Int slopeLength = (latency + 200) >= STANDARD_BUFFERSIZE ? STANDARD_BUFFERSIZE - latency : 200;
          volumeCurve.drawLine(0, latency, lastVolume);
          volumeCurve.drawLine(latency, latency + slopeLength, lastVolume, slopeLength * 0.005f);
          if ((latency + slopeLength) < STANDARD_BUFFERSIZE) {
            volumeCurve.drawLine(latency + slopeLength, STANDARD_BUFFERSIZE, 1);
          }
          // change frequency after latency
          frequencyCurve.drawLine(0, latency, currentFrequency);
          currentFrequency = parmFrequency;
          frequencyCurve.drawLine(latency, STANDARD_BUFFERSIZE, currentFrequency);

          intent = SS_PLAYING;

        }
        else if (intent == SS_WANTSTOSTOP || intent == SS_WANTSTOPAUSE) {
          Int slopeLength = latency + 200 > STANDARD_BUFFERSIZE ? STANDARD_BUFFERSIZE - latency : 200;
          volumeCurve.drawLine(0, latency, lastVolume);
          volumeCurve.drawLine(latency, latency + slopeLength, lastVolume, 1 - slopeLength * 0.005f);
          if (latency + slopeLength < STANDARD_BUFFERSIZE) {
            volumeCurve.drawLine(latency + slopeLength, STANDARD_BUFFERSIZE, 0);
          }
          // we don't care about frequency here because it's inaudible anyway
          frequencyCurve = currentFrequency;
          intent = SS_STOPPED;
        }
      }


      YSE::DSP::buffer & sin = sineGen(frequencyCurve);
      for (UInt i = 0; i < buffer.size(); i++) {
        buffer[i] = sin;
        buffer[i] *= volumeCurve;
      }
      latency -= STANDARD_BUFFERSIZE;
      if (latency < 0) latency = 0;
    }