Exemple #1
0
sampleCount Mixer::Process(int maxToProcess)
{
   if (mT >= mT1)
      return 0;
   
   int i, j;
   sampleCount out;
   sampleCount maxOut = 0;
   int *channelFlags = new int[mNumChannels];

   mMaxOut = maxToProcess;

   Clear();
   for(i=0; i<mNumInputTracks; i++) {
      WaveTrack *track = mInputTrack[i];
      for(j=0; j<mNumChannels; j++)
         channelFlags[j] = 0;

      switch(track->GetChannel()) {
      case Track::MonoChannel:
      default:
         for(j=0; j<mNumChannels; j++)
            channelFlags[j] = 1;
         break;
      case Track::LeftChannel:
         channelFlags[0] = 1;
         break;
      case Track::RightChannel:
         if (mNumChannels >= 2)
            channelFlags[1] = 1;
         else
            channelFlags[0] = 1;
         break;
      }

      if (mTimeTrack ||
          track->GetRate() != mRate)
         out = MixVariableRates(channelFlags, track,
                                &mSamplePos[i], mSampleQueue[i],
                                &mQueueStart[i], &mQueueLen[i], mSRC[i]);
      else
         out = MixSameRate(channelFlags, track, &mSamplePos[i]);

      if (out > maxOut)
         maxOut = out;
   }

   mT += (maxOut / mRate);

   delete [] channelFlags; 

   return maxOut;
}
bool EffectTwoPassSimpleMono::ProcessPass()
{
   //Iterate over each track
   SelectedTrackListOfKindIterator iter(Track::Wave, mOutputTracks);
   WaveTrack *track = (WaveTrack *) iter.First();
   mCurTrackNum = 0;
   while (track) {
      //Get start and end times from track
      double trackStart = track->GetStartTime();
      double trackEnd = track->GetEndTime();

      //Set the current bounds to whichever left marker is
      //greater and whichever right marker is less:
      mCurT0 = mT0 < trackStart? trackStart: mT0;
      mCurT1 = mT1 > trackEnd? trackEnd: mT1;

      // Process only if the right marker is to the right of the left marker
      if (mCurT1 > mCurT0) {

         //Transform the marker timepoints to samples
         sampleCount start = track->TimeToLongSamples(mCurT0);
         sampleCount end = track->TimeToLongSamples(mCurT1);
         
         //Get the track rate and samples
         mCurRate = track->GetRate();
         mCurChannel = track->GetChannel();

         //NewTrackPass1/2() returns true by default
         bool ret;
         if (mPass == 0)
            ret = NewTrackPass1();
         else
            ret = NewTrackPass2();
         if (!ret)
            return false;

         //ProcessOne() (implemented below) processes a single track
         if (!ProcessOne(track, start, end))
            return false;
      }
      
      //Iterate to the next track
      track = (WaveTrack *) iter.Next();
      mCurTrackNum++;
   }

   return true;
}
Exemple #3
0
bool EffectSimpleMono::Process()
{
   //Iterate over each track
   this->CopyInputWaveTracks(); // Set up mOutputWaveTracks.
   bool bGoodResult = true;

   TrackListIterator iter(mOutputWaveTracks);
   WaveTrack* pOutWaveTrack = (WaveTrack*)(iter.First());
   mCurTrackNum = 0;
   while (pOutWaveTrack != NULL)
   {
      //Get start and end times from track
      double trackStart = pOutWaveTrack->GetStartTime();
      double trackEnd = pOutWaveTrack->GetEndTime();

      //Set the current bounds to whichever left marker is
      //greater and whichever right marker is less:
      mCurT0 = mT0 < trackStart? trackStart: mT0;
      mCurT1 = mT1 > trackEnd? trackEnd: mT1;

      // Process only if the right marker is to the right of the left marker
      if (mCurT1 > mCurT0) {

         //Transform the marker timepoints to samples
         longSampleCount start = pOutWaveTrack->TimeToLongSamples(mCurT0);
         longSampleCount end = pOutWaveTrack->TimeToLongSamples(mCurT1);
         
         //Get the track rate and samples
         mCurRate = pOutWaveTrack->GetRate();
         mCurChannel = pOutWaveTrack->GetChannel();

         //NewTrackSimpleMono() will returns true by default
         //ProcessOne() processes a single track
         if (!NewTrackSimpleMono() || !ProcessOne(pOutWaveTrack, start, end))
         {
            bGoodResult = false;
            break;
         }
      }
      
      //Iterate to the next track
      pOutWaveTrack = (WaveTrack*)(iter.Next());
      mCurTrackNum++;
   }

   this->ReplaceProcessedWaveTracks(bGoodResult); 
   return bGoodResult;
}
bool EffectSoundTouch::Process()
{
   //Assumes that mSoundTouch has already been initialized
   //by the subclass

   //Iterate over each track
   TrackListIterator iter(mWaveTracks);
   WaveTrack *track = (WaveTrack *) iter.First();
   mCurTrackNum = 0;
	m_maxNewLength = 0.0;
   while (track) {
      //Get start and end times from track
      double trackStart = track->GetStartTime();
      double trackEnd = track->GetEndTime();

      //Set the current bounds to whichever left marker is
      //greater and whichever right marker is less:
      mCurT0 = mT0 < trackStart? trackStart: mT0;
      mCurT1 = mT1 > trackEnd? trackEnd: mT1;

      // Process only if the right marker is to the right of the left marker
      if (mCurT1 > mCurT0) {

         //Transform the marker timepoints to samples
         longSampleCount start = track->TimeToLongSamples(mCurT0);
         longSampleCount end = track->TimeToLongSamples(mCurT1);
         
         //Get the track rate and samples
         mCurRate = track->GetRate();
         mCurChannel = track->GetChannel();

         //ProcessOne() (implemented below) processes a single track
         if (!ProcessOne(track, start, end))
            return false;
      }
      
      //Iterate to the next track
      track = (WaveTrack *) iter.Next();
      mCurTrackNum++;
   }

   delete mSoundTouch;
   mSoundTouch = NULL;

	mT1 = mT0 + m_maxNewLength; // Update selection.
   return true;
}
Exemple #5
0
sampleCount Mixer::Process(int maxToProcess)
{
   if (mT >= mT1)
      return 0;
   
   int i, j;
   sampleCount out;
   sampleCount maxOut = 0;
   int *channelFlags = new int[mNumChannels];

   mMaxOut = maxToProcess;

   Clear();
   for(i=0; i<mNumInputTracks; i++) {
      WaveTrack *track = mInputTrack[i];
      for(j=0; j<mNumChannels; j++)
         channelFlags[j] = 0;

      if( mMixerSpec ) {
         //ignore left and right when downmixing is not required
         for( j = 0; j < mNumChannels; j++ )
            channelFlags[ j ] = mMixerSpec->mMap[ i ][ j ] ? 1 : 0;
      }
      else {
         switch(track->GetChannel()) {
         case Track::MonoChannel:
         default:
            for(j=0; j<mNumChannels; j++)
               channelFlags[j] = 1;
            break;
         case Track::LeftChannel:
            channelFlags[0] = 1;
            break;
         case Track::RightChannel:
            if (mNumChannels >= 2)
               channelFlags[1] = 1;
            else
               channelFlags[0] = 1;
            break;
         }
      }

      if (mTimeTrack ||
          track->GetRate() != mRate)
         out = MixVariableRates(channelFlags, track,
                                &mSamplePos[i], mSampleQueue[i],
                                &mQueueStart[i], &mQueueLen[i], mSRC[i]);
      else
         out = MixSameRate(channelFlags, track, &mSamplePos[i]);

      if (out > maxOut)
         maxOut = out;
   }
   out = mInterleaved ? maxOut * mNumChannels : maxOut;
   for(int c=0; c<mNumBuffers; c++)
      CopySamples(mTemp[c], floatSample, mBuffer[c], mFormat, out);

   mT += (maxOut / mRate);

   delete [] channelFlags; 

   return maxOut;
}
Exemple #6
0
sampleCount Mixer::Process(sampleCount maxToProcess)
{
   // MB: this is wrong! mT represented warped time, and mTime is too inaccurate to use
   // it here. It's also unnecessary I think.
   //if (mT >= mT1)
   //   return 0;

   int i, j;
   sampleCount maxOut = 0;
   int *channelFlags = new int[mNumChannels];

   mMaxOut = maxToProcess;

   Clear();
   for(i=0; i<mNumInputTracks; i++) {
      WaveTrack *track = mInputTrack[i];
      for(j=0; j<mNumChannels; j++)
         channelFlags[j] = 0;

      if( mMixerSpec ) {
         //ignore left and right when downmixing is not required
         for( j = 0; j < mNumChannels; j++ )
            channelFlags[ j ] = mMixerSpec->mMap[ i ][ j ] ? 1 : 0;
      }
      else {
         switch(track->GetChannel()) {
         case Track::MonoChannel:
         default:
            for(j=0; j<mNumChannels; j++)
               channelFlags[j] = 1;
            break;
         case Track::LeftChannel:
            channelFlags[0] = 1;
            break;
         case Track::RightChannel:
            if (mNumChannels >= 2)
               channelFlags[1] = 1;
            else
               channelFlags[0] = 1;
            break;
         }
      }
      if (mbVariableRates || track->GetRate() != mRate)
         maxOut = std::max(maxOut,
         MixVariableRates(channelFlags, track,
         &mSamplePos[i], mSampleQueue[i],
         &mQueueStart[i], &mQueueLen[i], mResample[i]));
      else
         maxOut = std::max(maxOut,
         MixSameRate(channelFlags, track, &mSamplePos[i]));

      double t = (double)mSamplePos[i] / (double)track->GetRate();
      if (mT0 > mT1)
         // backwards (as possibly in scrubbing)
         mTime = std::max(std::min(t, mTime), mT1);
      else
         // forwards (the usual)
         mTime = std::min(std::max(t, mTime), mT1);
   }
   if(mInterleaved) {
      for(int c=0; c<mNumChannels; c++) {
         CopySamples(mTemp[0] + (c * SAMPLE_SIZE(floatSample)),
            floatSample,
            mBuffer[0] + (c * SAMPLE_SIZE(mFormat)),
            mFormat,
            maxOut,
            mHighQuality,
            mNumChannels,
            mNumChannels);
      }
   }
   else {
      for(int c=0; c<mNumBuffers; c++) {
         CopySamples(mTemp[c],
            floatSample,
            mBuffer[c],
            mFormat,
            maxOut,
            mHighQuality);
      }
   }
   // MB: this doesn't take warping into account, replaced with code based on mSamplePos
   //mT += (maxOut / mRate);

   delete [] channelFlags;

   return maxOut;
}
bool EffectNormalize::Process()
{
   bool wasLinked = false; // set when a track has a linked (stereo) track

   if (mGain == false &&
       mDC == false)
      return true;

   //Iterate over each track
   this->CopyInputTracks(); // Set up mOutputTracks.
   bool bGoodResult = true;

   SelectedTrackListOfKindIterator iter(Track::Wave, mOutputTracks);
   WaveTrack *track = (WaveTrack *) iter.First();
   mCurTrackNum = 0;
   while (track) {
      //Get start and end times from track
      double trackStart = track->GetStartTime();
      double trackEnd = track->GetEndTime();

      //Set the current bounds to whichever left marker is
      //greater and whichever right marker is less:
      mCurT0 = mT0 < trackStart? trackStart: mT0;
      mCurT1 = mT1 > trackEnd? trackEnd: mT1;

      // Process only if the right marker is to the right of the left marker
      if (mCurT1 > mCurT0) {

         //Transform the marker timepoints to samples
         sampleCount start = track->TimeToLongSamples(mCurT0);
         sampleCount end = track->TimeToLongSamples(mCurT1);
         
         //Get the track rate and samples
         mCurRate = track->GetRate();
         mCurChannel = track->GetChannel();

         if(mStereoInd) // do stereo tracks independently (the easy way)
            track->GetMinMax(&mMin, &mMax, mCurT0, mCurT1);
         else
         {
            if(!wasLinked) // new mono track or first of a stereo pair
            {
               track->GetMinMax(&mMin, &mMax, mCurT0, mCurT1);
               if(track->GetLinked())
               {
                  wasLinked = true; // so we use these values for the next (linked) track
                  track = (WaveTrack *) iter.Next();  // get the next one for the max/min
                  float min, max;
                  track->GetMinMax(&min, &max, mCurT0, mCurT1);
                  mMin = min < mMin ? min : mMin;
                  mMax = max > mMax ? max : mMax;
                  track = (WaveTrack *) iter.Prev();  // back to the one we are on
               }
            }
            else
               wasLinked = false;   // second of the stereo pair, next one is mono or first
         }

         //ProcessOne() (implemented below) processes a single track
         if (!ProcessOne(track, start, end))
         {
            bGoodResult = false;
            break;
         }
      }
      
      //Iterate to the next track
      track = (WaveTrack *) iter.Next();
      mCurTrackNum++;
   }

   this->ReplaceProcessedTracks(bGoodResult); 
   return bGoodResult;
}
Exemple #8
0
void AudioIO::FillBuffers()
{
   unsigned int numEmpty = 0;
   unsigned int i;
   
   // Playback buffers

   for(i=0; i<mNumOutBuffers; i++) {
      if (mOutBuffer[i].ID == 0)
         numEmpty++;
   }
   
   if (numEmpty > (mNumOutBuffers/2)) {
      sampleCount block = numEmpty * mBufferSize;   
      double deltat = block / mRate;
      if (mT + deltat > mT1) {
         deltat = mT1 - mT;
         if(deltat < 0.0) return;
         block = (sampleCount)(deltat * mRate + 0.5);
      }
      
      Mixer *mixer = new Mixer(mNumOutChannels, block, true,
                               mRate, mFormat);
      mixer->UseVolumeSlider(mProject->GetControlToolBar());

      mixer->Clear();

      TrackListIterator iter2(mTracks);
      int numSolo = 0;
      Track *vt = iter2.First();
      while (vt) {
         if (vt->GetKind() == Track::Wave && vt->GetSolo())
            numSolo++;
         vt = iter2.Next();
      }

      TrackListIterator iter(mTracks);
      vt = iter.First();
      while (vt) {
         if (vt->GetKind() == Track::Wave) {      

            Track *mt = vt;
         
            // We want to extract mute and solo information from
            // the top of the two tracks if they're linked
            // (i.e. a stereo pair only has one set of mute/solo buttons)
            Track *partner = mTracks->GetLink(vt);
            if (partner && !vt->GetLinked())
               mt = partner;
            else
               mt = vt;

            // Cut if somebody else is soloing
            if (numSolo>0 && !mt->GetSolo()) {
               vt = iter.Next();
               continue;
            }
            
            // Cut if we're muted (unless we're soloing)
            if (mt->GetMute() && !mt->GetSolo()) {
               vt = iter.Next();
               continue;
            }

            WaveTrack *t = (WaveTrack *) vt;
            
            switch (t->GetChannel()) {
            case Track::LeftChannel:
               mixer->MixLeft(t, mT, mT + deltat);
               break;
            case Track::RightChannel:
               mixer->MixRight(t, mT, mT + deltat);
               break;
            case Track::MonoChannel:
               mixer->MixMono(t, mT, mT + deltat);
               break;
            }
         }

         vt = iter.Next();
      }     
   
      // Copy the mixed samples into the buffers

      samplePtr outbytes = mixer->GetBuffer();   

      for(i=0; i<mNumOutBuffers && block>0; i++)
         if (mOutBuffer[i].ID == 0) {
            sampleCount count;
            if (block > mBufferSize)
               count = mBufferSize;
            else
               count = block;
            
            memcpy(mOutBuffer[i].data, outbytes,
                   count*mNumOutChannels*SAMPLE_SIZE(mFormat));
            block -= count;
            outbytes += (count*mNumOutChannels*SAMPLE_SIZE(mFormat));
            mOutBuffer[i].len = count;
            mOutBuffer[i].ID = mOutID;
            mOutID++;
         }

      delete mixer;

      mT += deltat;
   }
   
   // Recording buffers
   
   unsigned int numFull = 0;
   unsigned int f, c; // loop counters
   sampleCount flatLen;
      
   for(i=0; i<mNumInBuffers; i++) {
      if (mInBuffer[i].ID != 0)
         numFull++;
   }
   
   if (numFull > 8) {
   
      samplePtr *flat = new samplePtr[mNumInChannels];
      for(i=0; i<mNumInChannels; i++)
         flat[i] = NewSamples(numFull * mBufferSize, mFormat);
      
      flatLen = 0;
      for(f=0; f<numFull; f++) {
         int minID = mInID+1;
         int minIndex = 0;
         for(i=0; i<mNumInBuffers; i++)
            if (mInBuffer[i].ID > 0 &&
                mInBuffer[i].ID < minID) {
               minIndex = i;
               minID = mInBuffer[i].ID;
            }

         switch(mFormat) {
         case floatSample:
            int j;
            for(j=0; j<mInBuffer[minIndex].len; j++)
               for(c=0; c<mNumInChannels; c++) {
                  ((float *)flat[c])[flatLen+j] =
                     ((float *)mInBuffer[minIndex].data)[j*mNumInChannels + c];
               }
            break;
         default:
            wxASSERT(0);
         }

         flatLen += mInBuffer[minIndex].len;
         mInBuffer[minIndex].ID = 0;
      }
      
      for(i=0; i<mNumInChannels; i++)
         mInTracks[i]->Append(flat[i], mFormat, flatLen);

      for(i=0; i<mNumInChannels; i++)
         DeleteSamples(flat[i]);
      delete[] flat;

      mProject->RedrawProject();
   }
}