コード例 #1
0
ファイル: Compressor.cpp プロジェクト: henricj/audacity
bool EffectCompressor::InitPass1()
{
   mMax=0.0;
   if (!mNormalize)
      DisableSecondPass();

   // Find the maximum block length required for any track
   size_t maxlen = 0;
   SelectedTrackListOfKindIterator iter(Track::Wave, mTracks);
   WaveTrack *track = (WaveTrack *) iter.First();
   while (track) {
      maxlen = std::max(maxlen, track->GetMaxBlockSize());
      //Iterate to the next track
      track = (WaveTrack *) iter.Next();
   }
   if(mFollow1!=NULL) {
      delete[] mFollow1;
      mFollow1 = NULL;
   }
   if(mFollow2!=NULL) {
      delete[] mFollow2;
      mFollow2 = NULL;
   }
   // Allocate buffers for the envelope
   if(maxlen > 0) {
      mFollow1 = new float[maxlen];
      mFollow2 = new float[maxlen];
   }
   mFollowLen = maxlen;

   return true;
}
コード例 #2
0
ファイル: WaveTrack.cpp プロジェクト: Kirushanr/audacity
bool WaveTrack::Cut(double t0, double t1, Track **dest)
{
   bool success;
   sampleCount s0, s1;
   WaveTrack *newTrack;

   if (t1 < t0)
      return false;

   TimeToSamplesClip(t0, &s0);
   TimeToSamplesClip(t1, &s1);

   newTrack = new WaveTrack(mDirManager);
   delete newTrack->mSequence;
   newTrack->mSequence = NULL;
   success = mSequence->Copy(s0, s1, &newTrack->mSequence);
   if (success)
      success = mSequence->Delete(s0, s1-s0);
   
   if (!success) {
      *dest = NULL;
      delete newTrack;
      return false;
   }

   newTrack->GetEnvelope()->CopyFrom(GetEnvelope(), t0, t1);
   mEnvelope->CollapseRegion(t0, t1);

   *dest = newTrack;
   MarkChanged();
   return true;
}
コード例 #3
0
ファイル: VoiceKey.cpp プロジェクト: henricj/audacity
//This might continue over a number of blocks.
double VoiceKey::TestEnergy (WaveTrack & t, sampleCount start, sampleCount len)
{

   double sum = 1;
   auto s = start;                                //Keep track of start
   auto originalLen = len;                        //Keep track of the length of block to process (its not the length of t)
   const auto blockSize = limitSampleBufferSize(
      t.GetMaxBlockSize(), len);               //Determine size of sampling buffer
   float *buffer = new float[blockSize];       //Get a sampling buffer

   while(len > 0)
      {
         //Figure out how much to grab
         auto block = limitSampleBufferSize ( t.GetBestBlockSize(s), len );

         t.Get((samplePtr)buffer,floatSample, s,block);                      //grab the block;

         //Now, go through the block and calculate energy
         for(decltype(block) i = 0; i< block; i++)
            {
               sum += buffer[i]*buffer[i];
            }

         len -= block;
         s += block;
      }

   delete [] buffer;
   return sum / originalLen.as_double();
}
コード例 #4
0
ファイル: ClickRemoval.cpp プロジェクト: Kirushanr/audacity
bool EffectClickRemoval::Process()
{
   this->CopyInputTracks(); // Set up mOutputTracks.
   bool bGoodResult = true;

   SelectedTrackListOfKindIterator iter(Track::Wave, mOutputTracks);
   WaveTrack *track = (WaveTrack *) iter.First();
   int count = 0;
   while (track) {
      double trackStart = track->GetStartTime();
      double trackEnd = track->GetEndTime();
      double t0 = mT0 < trackStart? trackStart: mT0;
      double t1 = mT1 > trackEnd? trackEnd: mT1;

      if (t1 > t0) {
         sampleCount start = track->TimeToLongSamples(t0);
         sampleCount end = track->TimeToLongSamples(t1);
         sampleCount len = (sampleCount)(end - start);

         if (!ProcessOne(count, track, start, len))
         {
            bGoodResult = false;
            break;
         }
      }

      track = (WaveTrack *) iter.Next();
      count++;
   }
   this->ReplaceProcessedTracks(bGoodResult); 
   return bGoodResult;
}
コード例 #5
0
ファイル: Paulstretch.cpp プロジェクト: finefin/audacity
bool EffectPaulstretch::Process()
{
   CopyInputTracks();
   SelectedTrackListOfKindIterator iter(Track::Wave, mOutputTracks.get());
   WaveTrack *track = (WaveTrack *) iter.First();
   m_t1=mT1;
   int count=0;
   while (track) {
      double trackStart = track->GetStartTime();
      double trackEnd = track->GetEndTime();
      double t0 = mT0 < trackStart? trackStart: mT0;
      double t1 = mT1 > trackEnd? trackEnd: mT1;

      if (t1 > t0) {
         if (!ProcessOne(track, t0,t1,count))
            return false;
      }

      track = (WaveTrack *) iter.Next();
      count++;
   }
   mT1=m_t1;

   ReplaceProcessedTracks(true);

   return true;
}
コード例 #6
0
ファイル: WaveTrack.cpp プロジェクト: Kirushanr/audacity
bool WaveTrack::Copy(double t0, double t1, Track **dest)
{
   if (t1 < t0)
      return false;

   sampleCount s0, s1;

   TimeToSamplesClip(t0, &s0);
   TimeToSamplesClip(t1, &s1);

   WaveTrack *newTrack = new WaveTrack(mDirManager);
   newTrack->Init(*this);

   delete newTrack->mSequence;
   newTrack->mSequence = NULL;
   
   if (!mSequence->Copy(s0, s1, &newTrack->mSequence)) {
      // Error
      *dest = NULL;
      delete newTrack;
      return false;
   }

   newTrack->GetEnvelope()->CopyFrom(GetEnvelope(), t0, t1);

   *dest = newTrack;
   MarkChanged();
   return true;
}
コード例 #7
0
ファイル: audioprefetch.cpp プロジェクト: AndreeeCZ/muse
void AudioPrefetch::prefetch(bool doSeek)
      {
      if (writePos == ~0U) {
            printf("AudioPrefetch::prefetch: invalid write position\n");
            return;
            }
      if (MusEGlobal::song->loop() && !MusEGlobal::audio->bounce() && !MusEGlobal::extSyncFlag.value()) {
            const Pos& loop = MusEGlobal::song->rPos();
            unsigned n = loop.frame() - writePos;
            if (n < MusEGlobal::segmentSize) {
                  unsigned lpos = MusEGlobal::song->lPos().frame();
                  // adjust loop start so we get exact loop len
                  if (n > lpos)
                        n = 0;
                  writePos = lpos - n;
                  }
            }
      WaveTrackList* tl = MusEGlobal::song->waves();
      for (iWaveTrack it = tl->begin(); it != tl->end(); ++it) {
            WaveTrack* track = *it;
            // Save time. Don't bother if track is off. Track On/Off not designed for rapid repeated response (but mute is). (p3.3.29)
            if(track->off())
              continue;
            
            int ch           = track->channels();
            float* bp[ch];
            if (track->prefetchFifo()->getWriteBuffer(ch, MusEGlobal::segmentSize, bp, writePos))
                  continue;

            track->fetchData(writePos, MusEGlobal::segmentSize, bp, doSeek);
            
            }
      writePos += MusEGlobal::segmentSize;
      }
コード例 #8
0
ファイル: ScienFilter.cpp プロジェクト: finefin/audacity
bool EffectScienFilter::Init()
{
   int selcount = 0;
   double rate = 0.0;

   TrackListOfKindIterator iter(Track::Wave, inputTracks());
   WaveTrack *t = (WaveTrack *) iter.First();

   mNyquist = (t ? t->GetRate() : GetActiveProject()->GetRate()) / 2.0;

   while (t)
   {
      if (t->GetSelected())
      {
         if (selcount == 0)
         {
            rate = t->GetRate();
         }
         else
         {
            if (t->GetRate() != rate)
            {
               Effect::MessageBox(_("To apply a filter, all selected tracks must have the same sample rate."));
               return false;
            }
         }
         selcount++;
      }
      t = (WaveTrack *) iter.Next();
   }

   return true;
}
コード例 #9
0
ファイル: Compressor.cpp プロジェクト: rbuj/audacity
bool EffectCompressor::InitPass1()
{
   mMax=0.0;
   if (!mNormalize)
      DisableSecondPass();

   // Find the maximum block length required for any track
   size_t maxlen = 0;
   SelectedTrackListOfKindIterator iter(Track::Wave, inputTracks());
   WaveTrack *track = (WaveTrack *) iter.First();
   while (track) {
      maxlen = std::max(maxlen, track->GetMaxBlockSize());
      //Iterate to the next track
      track = (WaveTrack *) iter.Next();
   }
   mFollow1.reset();
   mFollow2.reset();
   // Allocate buffers for the envelope
   if(maxlen > 0) {
      mFollow1.reinit(maxlen);
      mFollow2.reinit(maxlen);
   }
   mFollowLen = maxlen;

   return true;
}
コード例 #10
0
ファイル: Equalization.cpp プロジェクト: ruthmagnus/audacity
bool EffectEqualization::Process()
{
   TrackListIterator iter(mWaveTracks);
   WaveTrack *track = (WaveTrack *) iter.First();
   int count = 0;
   while (track) {
      double trackStart = track->GetStartTime();
      double trackEnd = track->GetEndTime();
      double t0 = mT0 < trackStart? trackStart: mT0;
      double t1 = mT1 > trackEnd? trackEnd: mT1;

      if (t1 > t0) {
         longSampleCount start = track->TimeToLongSamples(t0);
         longSampleCount end = track->TimeToLongSamples(t1);
         sampleCount len = (sampleCount)(end - start);

         if (!ProcessOne(count, track, start, len))
            return false;
      }

      track = (WaveTrack *) iter.Next();
      count++;
   }

   return true;
}
コード例 #11
0
//This might continue over a number of blocks.
double VoiceKey::TestEnergy (WaveTrack & t, sampleCount start, sampleCount len)
{

    double sum = 1;
    sampleCount s = start;                                //Keep track of start
    sampleCount originalLen = len;                        //Keep track of the length of block to process (its not the length of t)
    sampleCount blockSize = t.GetMaxBlockSize();         //Determine size of sampling buffer


    if( blockSize > len)
        blockSize = len;
    float *buffer = new float[blockSize];       //Get a sampling buffer

    while(len > 0)
    {
        sampleCount block = t.GetBestBlockSize(s);          //Figure out how much to grab
        if(block > len)	block = len;                 //Don't grab too much!

        t.Get((samplePtr)buffer,floatSample, s,block);                      //grab the block;

        //Now, go through the block and calculate energy
        for(int i = 0; i< block; i++)
        {
            sum += buffer[i]*buffer[i];
        }

        len -= block;
        s += block;
    }

    delete [] buffer;
    return sum / originalLen;
}
コード例 #12
0
ファイル: ChangePitch.cpp プロジェクト: MindFy/audacity
// Deduce m_FromFrequency from the samples at the beginning of
// the selection. Then set some other params accordingly.
void EffectChangePitch::DeduceFrequencies()
{
   // As a neat trick, attempt to get the frequency of the note at the
   // beginning of the selection.
   SelectedTrackListOfKindIterator iter(Track::Wave, inputTracks());
   WaveTrack *track = (WaveTrack *) iter.First();
   if (track) {
      double rate = track->GetRate();

      // Auto-size window -- high sample rates require larger windowSize.
      // Aim for around 2048 samples at 44.1 kHz (good down to about 100 Hz).
      // To detect single notes, analysis period should be about 0.2 seconds.
      // windowSize must be a power of 2.
      const size_t windowSize =
         // windowSize < 256 too inaccurate
         std::max(256, wxRound(pow(2.0, floor((log(rate / 20.0)/log(2.0)) + 0.5))));

      // we want about 0.2 seconds to catch the first note.
      // number of windows rounded to nearest integer >= 1.
      const unsigned numWindows =
         std::max(1, wxRound((double)(rate / (5.0f * windowSize))));

      double trackStart = track->GetStartTime();
      double t0 = mT0 < trackStart? trackStart: mT0;
      auto start = track->TimeToLongSamples(t0);

      auto analyzeSize = windowSize * numWindows;
      Floats buffer{ analyzeSize };

      Floats freq{ windowSize / 2 };
      Floats freqa{ windowSize / 2, true };

      track->Get((samplePtr) buffer.get(), floatSample, start, analyzeSize);
      for(unsigned i = 0; i < numWindows; i++) {
         ComputeSpectrum(buffer.get() + i * windowSize, windowSize,
                         windowSize, rate, freq.get(), true);
         for(size_t j = 0; j < windowSize / 2; j++)
            freqa[j] += freq[j];
      }
      size_t argmax = 0;
      for(size_t j = 1; j < windowSize / 2; j++)
         if (freqa[j] > freqa[argmax])
            argmax = j;

      auto lag = (windowSize / 2 - 1) - argmax;
      m_dStartFrequency = rate / lag;
   }

   double dFromMIDInote = FreqToMIDInote(m_dStartFrequency);
   double dToMIDInote = dFromMIDInote + m_dSemitonesChange;
   m_nFromPitch = PitchIndex(dFromMIDInote);
   m_nFromOctave = PitchOctave(dFromMIDInote);
   m_nToPitch = PitchIndex(dToMIDInote);
   m_nToOctave = PitchOctave(dToMIDInote);

   m_FromFrequency = m_dStartFrequency;
   Calc_PercentChange();
   Calc_ToFrequency();
}
コード例 #13
0
ファイル: UndoManager.cpp プロジェクト: tuanmasterit/audacity
// get the sum of the sizes of all blocks this track list
// references.  However, if a block is referred to multiple
// times it is only counted once.  Return value is in bytes.
wxLongLong UndoManager::CalculateSpaceUsage(int index)
{
   TrackListOfKindIterator iter(Track::Wave);
   WaveTrack *wt;
   WaveClipList::compatibility_iterator it;
   BlockArray *blocks;
   unsigned int i;

   // get a map of all blocks referenced in this TrackList
   std::map<BlockFile*, wxLongLong> cur;

   wt = (WaveTrack *) iter.First(stack[index]->tracks);
   while (wt) {
      for (it = wt->GetClipIterator(); it; it = it->GetNext()) {
         blocks = it->GetData()->GetSequenceBlockArray();
         for (i = 0; i < blocks->GetCount(); i++) 
         {
            BlockFile* pBlockFile = blocks->Item(i)->f;
            if (pBlockFile->GetFileName().FileExists())
               cur[pBlockFile] = pBlockFile->GetSpaceUsage();
         }
      }
      wt = (WaveTrack *) iter.Next();
   }

   if (index > 0) {
      // get a set of all blocks referenced in all prev TrackList
      std::set<BlockFile*> prev;
      while (--index) {
         wt = (WaveTrack *) iter.First(stack[index]->tracks);
         while (wt) {
            for (it = wt->GetClipIterator(); it; it = it->GetNext()) {
               blocks = it->GetData()->GetSequenceBlockArray();
               for (i = 0; i < blocks->GetCount(); i++) {
                  prev.insert(blocks->Item(i)->f);
               }
            }
            wt = (WaveTrack *) iter.Next();
         }
      }

      // remove all blocks in prevBlockFiles from curBlockFiles
      std::set<BlockFile*>::const_iterator prevIter;
      for (prevIter = prev.begin(); prevIter != prev.end(); prevIter++) {
         cur.erase(*prevIter);
      }
   }

   // sum the sizes of the blocks remaining in curBlockFiles;
   wxLongLong bytes = 0;
   std::map<BlockFile*, wxLongLong>::const_iterator curIter;
   for (curIter = cur.begin(); curIter != cur.end(); curIter++) {
      bytes += curIter->second;
   }

   return bytes;
}
コード例 #14
0
ファイル: UndoManager.cpp プロジェクト: ruthmagnus/audacity
void UndoManager::Debug()
{
   for (unsigned int i = 0; i < stack.Count(); i++) {

      TrackListIterator iter(stack[i]->tracks);
      WaveTrack *t = (WaveTrack *) (iter.First());
      printf("*%d* %s %f\n", i, (i == (unsigned int)current) ? "-->" : "   ",
             t ? t->GetEndTime()-t->GetStartTime() : 0);
   }
}
コード例 #15
0
bool EffectNoiseRemoval::Process()
{
   if (!mDoProfile && !mHasProfile)
      CleanSpeechMayReadNoisegate();
   
   // If we still don't have a profile we have a problem.
   // This should only happen in CleanSpeech.
   if(!mDoProfile && !mHasProfile) {
      wxMessageBox(
        _("Attempt to run Noise Removal without a noise profile.\n"));
      return false;
   }

   Initialize();

   // This same code will both remove noise and profile it,
   // depending on 'mDoProfile'
   this->CopyInputWaveTracks(); // Set up mOutputWaveTracks.
   bool bGoodResult = true;

   TrackListIterator iter(mOutputWaveTracks);
   WaveTrack *track = (WaveTrack *) iter.First();
   int count = 0;
   while (track) {
      double trackStart = track->GetStartTime();
      double trackEnd = track->GetEndTime();
      double t0 = mT0 < trackStart? trackStart: mT0;
      double t1 = mT1 > trackEnd? trackEnd: mT1;

      if (t1 > t0) {
         sampleCount start = track->TimeToLongSamples(t0);
         sampleCount end = track->TimeToLongSamples(t1);
         sampleCount len = (sampleCount)(end - start);

         if (!ProcessOne(count, track, start, len)) {
            Cleanup();
            bGoodResult = false;
            break;
         }
      }
      track = (WaveTrack *) iter.Next();
      count++;
   }

   if (bGoodResult && mDoProfile) {
      CleanSpeechMayWriteNoiseGate();
      mHasProfile = true;
      mDoProfile = false;
   }

   if (bGoodResult)
      Cleanup();
   this->ReplaceProcessedWaveTracks(bGoodResult); 
   return bGoodResult;
}
コード例 #16
0
ファイル: FindClipping.cpp プロジェクト: PhilSee/audacity
bool EffectFindClipping::Process()
{
   LabelTrack *l = NULL;
   Track *original = NULL;

   TrackListOfKindIterator iter(Track::Label, mTracks);
   for (Track *t = iter.First(); t; t = iter.Next()) {
      if (t->GetName() == wxT("Clipping")) {
         l = (LabelTrack *) t;
         // copy LabelTrack here, so it can be undone on cancel
         l->Copy(l->GetStartTime(), l->GetEndTime(), &original);
         original->SetOffset(l->GetStartTime());
         original->SetName(wxT("Clipping"));
         break;
      }
   }

   if (!l) {
      l = mFactory->NewLabelTrack();
      l->SetName(_("Clipping"));
      mTracks->Add((Track *) l);
   }

   int count = 0;

   // JC: Only process selected tracks.
   SelectedTrackListOfKindIterator waves(Track::Wave, mTracks);
   WaveTrack *t = (WaveTrack *) waves.First();
   while (t) {
      double trackStart = t->GetStartTime();
      double trackEnd = t->GetEndTime();
      double t0 = mT0 < trackStart ? trackStart : mT0;
      double t1 = mT1 > trackEnd ? trackEnd : mT1;

      if (t1 > t0) {
         sampleCount start = t->TimeToLongSamples(t0);
         sampleCount end = t->TimeToLongSamples(t1);
         sampleCount len = (sampleCount)(end - start);

         if (!ProcessOne(l, count, t, start, len)) {
            //put it back how it was
            mTracks->Remove((Track *) l);
            if(original) {
               mTracks->Add((Track *) original);
            }
            return false;
         }
      }

      count++;
      t = (WaveTrack *) waves.Next();
   }

   return true;
}
コード例 #17
0
ファイル: audioprefetch.cpp プロジェクト: 87maxi/oom
void AudioPrefetch::seek(unsigned seekTo)
{
	// printf("seek %d\n", seekTo);
#ifdef AUDIOPREFETCH_DEBUG
	printf("AudioPrefetch::seek to:%u seekCount:%d\n", seekTo, seekCount);
#endif

	// Speedup: More than one seek message pending?
	// Eat up seek messages until we get to the very LATEST one,
	//  because all the rest which came before it are irrelevant now,
	//  and processing them all was taking extreme time, especially with
	//  resampling enabled.
	// In particular, when the user 'slides' the play cursor back and forth
	//  there are MANY seek messages in the pipe, and with resampling enabled
	//  it was taking minutes to finish seeking. If the user hit play during that time,
	//  things were messed up (FIFO underruns, choppy intermittent sound etc).
	// Added by Tim. p3.3.20
	if (seekCount > 1)
	{
		--seekCount;
		return;
	}

	writePos = seekTo;
	WaveTrackList* tl = song->waves();
	for (iWaveTrack it = tl->begin(); it != tl->end(); ++it)
	{
		WaveTrack* track = *it;
		track->clearPrefetchFifo();
	}

	bool isFirstPrefetch = true;
	for (unsigned int i = 0; i < (fifoLength) - 1; ++i)//prevent compiler warning: comparison of signed/unsigned
	{
		// Indicate do a seek command before read, but only on the first pass.
		// Changed by Tim. p3.3.17
		//prefetch();
		prefetch(isFirstPrefetch);

		isFirstPrefetch = false;

		// To help speed things up even more, check the count again. Return if more seek messages are pending.
		// Added by Tim. p3.3.20
		if (seekCount > 1)
		{
			--seekCount;
			return;
		}
	}

	seekPos = seekTo;
	//seekDone = true;
	--seekCount;
}
コード例 #18
0
ファイル: Menus.cpp プロジェクト: andreipaga/audacity
void AudacityProject::OnPlotSpectrum(wxCommandEvent & event)
{
   int selcount = 0;
   WaveTrack *selt = NULL;
   TrackListIterator iter(mTracks);
   VTrack *t = iter.First();
   while (t) {
      if (t->GetSelected())
         selcount++;
      if (t->GetKind() == VTrack::Wave)
         selt = (WaveTrack *) t;
      t = iter.Next();
   }
   if (selcount != 1) {
      wxMessageBox(_("Please select a single track first.\n"));
      return;
   }

   /* This shouldn't be possible, since the menu is grayed out.
    * But we'll check just in case it does happen, to prevent
    * the crash that would result. */

   if (!selt) {
      wxMessageBox(_("Please select a track first.\n"));
      return;
   }


   sampleCount s0 = (sampleCount) ((mViewInfo.sel0 - selt->GetOffset())
                                   * selt->GetRate());
   sampleCount s1 = (sampleCount) ((mViewInfo.sel1 - selt->GetOffset())
                                   * selt->GetRate());
   sampleCount slen = s1 - s0;

   if (slen > 1048576)
      slen = 1048576;

   float *data = new float[slen];
   sampleType *data_sample = new sampleType[slen];

   if (s0 >= selt->GetNumSamples() || s0 + slen > selt->GetNumSamples()) {
      wxMessageBox(_("Not enough samples selected.\n"));
      delete[]data;
      delete[]data_sample;
      return;
   }

   selt->Get(data_sample, s0, slen);

   for (sampleCount i = 0; i < slen; i++)
      data[i] = data_sample[i] / 32767.;

   gFreqWindow->Plot(slen, data, selt->GetRate());
   gFreqWindow->Show(true);
   gFreqWindow->Raise();

   delete[]data;
   delete[]data_sample;
}
コード例 #19
0
void UndoManager::CalculateSpaceUsage()
{
   TIMER_START( "CalculateSpaceUsage", space_calc );
   TrackListOfKindIterator iter(Track::Wave);

   space.Clear();
   space.Add(0, stack.GetCount());

   Set s1, s2;
   Set *prev = &s1;
   Set *cur = &s2;

   for (size_t i = 0, cnt = stack.GetCount(); i < cnt; i++)
   {
      // Swap map pointers
      std::swap(cur, prev);

      // And clean out the NEW current map
      cur->clear();

      // Scan all tracks at current level
      WaveTrack *wt = (WaveTrack *) iter.First(stack[i]->tracks);
      while (wt)
      {
         // Scan all clips within current track
         WaveClipList::compatibility_iterator it = wt->GetClipIterator();
         while (it)
         {
            // Scan all blockfiles within current clip
            BlockArray *blocks = it->GetData()->GetSequenceBlockArray();
            for (size_t b = 0, cnt = blocks->size(); b < cnt; b++)
            {
               BlockFile *file = (*blocks)[b].f;

               // Accumulate space used by the file if the file didn't exist
               // in the previous level
               if (prev->count(file) == 0 && cur->count(file) == 0)
               {
                  space[i] += file->GetSpaceUsage().GetValue();
               }
               
               // Add file to current set
               cur->insert(file);
            }
            
            it = it->GetNext();
         }

         wt = (WaveTrack *) iter.Next();
      }
   }

   TIMER_STOP( space_calc );
}
コード例 #20
0
ファイル: Mix.cpp プロジェクト: Kirushanr/audacity
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;
}
コード例 #21
0
ファイル: Track.cpp プロジェクト: ruthmagnus/audacity
// Find out how much additional space was used to execute
// this operation.
//
// Computed by getting a list of all blocks referenced by
// *this* TrackList and removing all blocks referenced by
// any previous TrackList.
wxLongLong TrackList::GetAdditionalSpaceUsage(UndoStack *stack)
{
   TrackListNode *p;
   // get a map of all blocks referenced in this TrackList
   std::map<BlockFile*,wxLongLong> curBlockFiles;
   for (p = head; p; p = p->next) {
      if (p->t->GetKind() == Track::Wave) {
         WaveTrack* track = ((WaveTrack*)p->t);
         for (WaveClipList::Node* it=track->GetClipIterator(); it; it=it->GetNext())
         {
            WaveClip* clip = it->GetData();
            BlockArray *blocks = clip->GetSequenceBlockArray();
            for (unsigned int i = 0; i < blocks->GetCount(); i++)
               curBlockFiles[blocks->Item(i)->f] = blocks->Item(i)->f->GetSpaceUsage();
         }
      }
   }

   // get a set of all blocks referenced in all prev TrackList
   std::set<BlockFile*> prevBlockFiles;
   unsigned int undoStackIdx = 0;
   for (; undoStackIdx < stack->GetCount(); undoStackIdx++) {
      UndoStackElem *stackElem = stack->Item(undoStackIdx);
      if (stackElem->tracks == this)
         break;
      for (p = stackElem->tracks->head; p; p = p->next) {
         if (p->t->GetKind() == Track::Wave) {
            WaveTrack* track = ((WaveTrack*)p->t);
            for (WaveClipList::Node* it=track->GetClipIterator(); it; it=it->GetNext())
            {
               WaveClip* clip = it->GetData();
               BlockArray *blocks = clip->GetSequenceBlockArray();
               for (unsigned int i = 0; i < blocks->GetCount(); i++)
                  prevBlockFiles.insert(blocks->Item(i)->f);
            }         
         }
      }
   }

   // remove all blocks in prevBlockFiles from curBlockFiles
   std::set<BlockFile*>::const_iterator prevIter = prevBlockFiles.begin();
   for (; prevIter != prevBlockFiles.end(); prevIter++)
      curBlockFiles.erase(*prevIter);

   // sum the sizes of the blocks remaining in curBlockFiles;
   std::map<BlockFile*,wxLongLong>::const_iterator curBfIter =
      curBlockFiles.begin();
   wxLongLong bytes = 0;
   for (;curBfIter != curBlockFiles.end(); curBfIter++)
      bytes += curBfIter->second;

   return bytes;
}
コード例 #22
0
ファイル: StereoToMono.cpp プロジェクト: andreipaga/audacity
//TODO: There are a lot of places where a track is being checked
//      to see if it is stereo. Consolidate these
bool EffectStereoToMono::CheckWhetherSkipEffect()
{
   TrackListIterator iter(mWaveTracks);
   WaveTrack *t = (WaveTrack*)iter.First();
   while (t) {
      if (t->GetLinked()) {
         return false;
      }
      t = (WaveTrack *)iter.Next();
   }

   return true;
}
コード例 #23
0
void FreqWindow::GetAudio()
{
   int selcount = 0;
   int i;
   bool warning = false;
   //wxLogDebug(wxT("Entering FreqWindow::GetAudio()"));
   TrackListIterator iter(p->GetTracks());
   Track *t = iter.First();
   while (t) {
      if (t->GetSelected() && t->GetKind() == Track::Wave) {
         WaveTrack *track = (WaveTrack *)t;
         if (selcount==0) {
            mRate = track->GetRate();
            sampleCount start, end;
            start = track->TimeToLongSamples(p->mViewInfo.sel0);
            end = track->TimeToLongSamples(p->mViewInfo.sel1);
            mDataLen = (sampleCount)(end - start);
            if (mDataLen > 10485760) {
               warning = true;
               mDataLen = 10485760;
            }
            if (mBuffer) {
               delete [] mBuffer;
            }
            mBuffer = new float[mDataLen];
            track->Get((samplePtr)mBuffer, floatSample, start, mDataLen);
         }
         else {
            if (track->GetRate() != mRate) {
               wxMessageBox(_("To plot the spectrum, all selected tracks must be the same sample rate."));
               delete[] mBuffer;
               mBuffer = NULL;
               return;
            }
            sampleCount start;
            start = track->TimeToLongSamples(p->mViewInfo.sel0);
            float *buffer2 = new float[mDataLen];
            track->Get((samplePtr)buffer2, floatSample, start, mDataLen);
            for(i=0; i<mDataLen; i++)
               mBuffer[i] += buffer2[i];
            delete[] buffer2;
         }
         selcount++;
      }
      t = iter.Next();
   }
   
   if (selcount == 0)
      return;

   if (warning) {
      wxString msg;
      msg.Printf(_("Too much audio was selected.  Only the first %.1f seconds of audio will be analyzed."),
                          (mDataLen / mRate));
      //wxLogDebug(wxT("About to show length warning message"));
      wxMessageBox(msg);
      //wxLogDebug(wxT("Length warning message done"));
   }
   //wxLogDebug(wxT("Leaving FreqWindow::GetAudio()"));
}
コード例 #24
0
ファイル: Menus.cpp プロジェクト: andreipaga/audacity
void AudacityProject::OnNewWaveTrack(wxCommandEvent & event)
{
   WaveTrack *t = new WaveTrack(&mDirManager);

   SelectNone();

   mTracks->Add(t);
   t->SetSelected(true);

   PushState(_("Created new audio track"));

   FixScrollbars();
   mTrackPanel->Refresh(false);
}
コード例 #25
0
void FreqWindow::GetAudio()
{
   mData.reset();
   mDataLen = 0;

   int selcount = 0;
   bool warning = false;
   TrackListIterator iter(p->GetTracks());
   Track *t = iter.First();
   while (t) {
      if (t->GetSelected() && t->GetKind() == Track::Wave) {
         WaveTrack *track = (WaveTrack *)t;
         if (selcount==0) {
            mRate = track->GetRate();
            auto start = track->TimeToLongSamples(p->mViewInfo.selectedRegion.t0());
            auto end = track->TimeToLongSamples(p->mViewInfo.selectedRegion.t1());
            auto dataLen = end - start;
            if (dataLen > 10485760) {
               warning = true;
               mDataLen = 10485760;
            }
            else
               // dataLen is not more than 10 * 2 ^ 20
               mDataLen = dataLen.as_size_t();
            mData = Floats{ mDataLen };
            // Don't allow throw for bad reads
            track->Get((samplePtr)mData.get(), floatSample, start, mDataLen,
                       fillZero, false);
         }
         else {
            if (track->GetRate() != mRate) {
               AudacityMessageBox(_("To plot the spectrum, all selected tracks must be the same sample rate."));
               mData.reset();
               mDataLen = 0;
               return;
            }
            auto start = track->TimeToLongSamples(p->mViewInfo.selectedRegion.t0());
            Floats buffer2{ mDataLen };
            // Again, stop exceptions
            track->Get((samplePtr)buffer2.get(), floatSample, start, mDataLen,
                       fillZero, false);
            for (size_t i = 0; i < mDataLen; i++)
               mData[i] += buffer2[i];
         }
         selcount++;
      }
      t = iter.Next();
   }

   if (selcount == 0)
      return;

   if (warning) {
      wxString msg;
      msg.Printf(_("Too much audio was selected.  Only the first %.1f seconds of audio will be analyzed."),
                          (mDataLen / mRate));
      AudacityMessageBox(msg);
   }
}
コード例 #26
0
ファイル: ChangeSpeed.cpp プロジェクト: ruthmagnus/audacity
bool EffectChangeSpeed::Process()
{
	// Similar to EffectSoundTouch::Process()

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

   TrackListIterator iter(m_pOutputWaveTracks);
   WaveTrack* pOutWaveTrack = (WaveTrack*)(iter.First());
   mCurTrackNum = 0;
	m_maxNewLength = 0.0;
   while (pOutWaveTrack != NULL)
   {
      //Get start and end times from track
      mCurT0 = pOutWaveTrack->GetStartTime();
      mCurT1 = pOutWaveTrack->GetEndTime();

      //Set the current bounds to whichever left marker is
      //greater and whichever right marker is less:
      mCurT0 = wxMax(mT0, mCurT0);
      mCurT1 = wxMin(mT1, mCurT1);

      // 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);

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

   this->ReplaceProcessedWaveTracks(bGoodResult); 

// mT1 = mT0 + m_maxNewLength; // Update selection.

   return bGoodResult;
}
コード例 #27
0
ファイル: Repeat.cpp プロジェクト: ruthmagnus/audacity
bool EffectRepeat::PromptUser()
{
   //
   // Figure out the maximum number of times the selection
   // could be repeated without overflowing any track
   //
   int maxCount = -1;
   TrackListIterator iter(mWaveTracks);
   WaveTrack *track = (WaveTrack *) iter.First();
   while (track) {
      sampleCount trackLen = 
         (sampleCount)((track->GetEndTime() - track->GetStartTime()) * 
                       track->GetRate());
      sampleCount selectionLen = (sampleCount)((mT1 - mT0) * track->GetRate());
      int availSamples = 2147483647 - trackLen;
      int count = availSamples / selectionLen;
      if (maxCount == -1 || count < maxCount)
         maxCount = count;

      track = (WaveTrack *) iter.Next();
   }
   
   if (maxCount <= 1) {
      wxMessageBox(_("Tracks are too long to repeat the selection."),
                   _("Repeat"), wxOK | wxCENTRE, mParent);
      return false;
   }

   RepeatDialog dlog(this, mParent);
   dlog.repeatCount = repeatCount;
   dlog.selectionTimeSecs = mT1 - mT0;
   dlog.maxCount = maxCount;
   dlog.TransferDataToWindow();

   dlog.CentreOnParent();

   dlog.ShowModal();

  if (dlog.GetReturnCode() == wxID_CANCEL)
      return false;

   repeatCount = dlog.repeatCount;
   if (repeatCount > maxCount)
      repeatCount = maxCount;
   if (repeatCount < 1)
      repeatCount = 1;

   return true;
}
コード例 #28
0
bool BlockGenerator::GenerateTrack(WaveTrack *tmp,
                                   const WaveTrack &track,
                                   int ntrack)
{
   bool bGoodResult = true;
   numSamples = track.TimeToLongSamples(GetDuration());
   sampleCount i = 0;
   float *data = new float[tmp->GetMaxBlockSize()];
   sampleCount block = 0;

   while ((i < numSamples) && bGoodResult) {
      block = tmp->GetBestBlockSize(i);
      if (block > (numSamples - i))
         block = numSamples - i;

      GenerateBlock(data, track, block);

      // Add the generated data to the temporary track
      tmp->Append((samplePtr)data, floatSample, block);
      i += block;

      // Update the progress meter
      if (TrackProgress(ntrack, (double)i / numSamples))
         bGoodResult = false;
   }
   delete[] data;
   return bGoodResult;
}
コード例 #29
0
ファイル: Repeat.cpp プロジェクト: ruthmagnus/audacity
bool EffectRepeat::Process()
{
   this->CopyInputWaveTracks(); // Set up mOutputWaveTracks.
   bool bGoodResult = true;

   TrackListIterator iter(mOutputWaveTracks);
   WaveTrack *track = (WaveTrack *) iter.First();
   int nTrack = 0;
	double maxDestLen = 0.0; // used to change selection to generated bit
   while ((track != NULL) && bGoodResult) {
      double trackStart = track->GetStartTime();
      double trackEnd = track->GetEndTime();
      double t0 = mT0 < trackStart? trackStart: mT0;
      double t1 = mT1 > trackEnd? trackEnd: mT1;

      if (t1 <= t0)
         continue;

      sampleCount start = track->TimeToLongSamples(t0);
      sampleCount end = track->TimeToLongSamples(t1);
      sampleCount len = (sampleCount)(end - start);
      double tLen = track->LongSamplesToTime(len);
      double tc = t0 + tLen;

      if (len <= 0)
         continue;

      Track *dest;
      track->Copy(t0, t1, &dest);
      for(int j=0; j<repeatCount; j++)
      {
         if (!track->Paste(tc, dest) || 
               TrackProgress(nTrack, j / repeatCount)) // TrackProgress returns true on Cancel.
         {
            bGoodResult = false;
            break;
         }
         tc += tLen;
      }
      if (tc > maxDestLen)
         maxDestLen = tc;
      delete dest;

      track = (WaveTrack *) iter.Next();
      nTrack++;
   }

   if (bGoodResult)
   {
      // Change selection to just the generated bits.
      mT0 = mT1;
	   mT1 = maxDestLen;
   }

   this->ReplaceProcessedWaveTracks(bGoodResult); 
   return bGoodResult;
}
コード例 #30
0
ファイル: audioprefetch.cpp プロジェクト: 87maxi/oom
void AudioPrefetch::prefetch(bool doSeek)
{
	if (writePos == ~0U)
	{
		printf("AudioPrefetch::prefetch: invalid write position\n");
		return;
	}
	if (song->loop() && !audio->bounce() && !extSyncFlag.value())
	{
		const Pos& loop = song->rPos();
		unsigned n = loop.frame() - writePos;
		if (n < segmentSize)
		{
			unsigned lpos = song->lPos().frame();
			// adjust loop start so we get exact loop len
			if (n > lpos)
				n = 0;
			// printf("prefetch seek %d\n", writePos);
			writePos = lpos - n;
		}
	}
	WaveTrackList* tl = song->waves();
	for (iWaveTrack it = tl->begin(); it != tl->end(); ++it)
	{
		WaveTrack* track = *it;
		// p3.3.29
		// Save time. Don't bother if track is off. Track On/Off not designed for rapid repeated response (but mute is).
		if (track->off())
			continue;

		int ch = track->channels();
		float* bp[ch];
		// printf("prefetch %d\n", writePos);
		if (track->prefetchFifo()->getWriteBuffer(ch, segmentSize, bp, writePos))
		{
			// printf("AudioPrefetch::prefetch No write buffer!\n"); // p3.3.46 Was getting this...
			continue;
		}
		//track->fetchData(writePos, segmentSize, bp);
		track->fetchData(writePos, segmentSize, bp, doSeek);

		// p3.3.41
		//fprintf(stderr, "AudioPrefetch::prefetch data: segmentSize:%ld %e %e %e %e\n", segmentSize, bp[0][0], bp[0][1], bp[0][2], bp[0][3]);

	}
	writePos += segmentSize;
}