コード例 #1
0
ファイル: WaveTrack.cpp プロジェクト: ruthmagnus/audacity
void WaveTrack::InsertSilence(double t, double lenSecs)
{
   // Create a new track containing as much silence as we
   // need to insert, and then call Paste to do the insertion

   sampleCount len = (sampleCount) (lenSecs * rate + 0.5);

   WaveTrack *sTrack = new WaveTrack(dirManager);
   sTrack->rate = rate;

   sampleCount idealSamples = GetIdealBlockSize();
   sampleType *buffer = new sampleType[idealSamples];
   sampleCount i;
   for (i = 0; i < idealSamples; i++)
      buffer[i] = 0;

   sampleCount pos = 0;
   BlockFile *firstBlockFile = NULL;

   while (len) {
      sampleCount l = (len > idealSamples ? idealSamples : len);

      WaveBlock *w = new WaveBlock();
      w->start = pos;
      w->len = l;
      w->min = 0;
      w->max = 0;
      if (pos == 0 || len == l) {
         w->f = dirManager->NewBlockFile();
         firstBlockFile = w->f;
         bool inited = InitBlock(w);
         wxASSERT(inited);
         FirstWrite(buffer, w, l);
      } else {
         w->f = dirManager->CopyBlockFile(firstBlockFile);
         if (!w->f) {
            wxMessageBox("Could not paste!  (Out of disk space?)");
         }            
      }

      sTrack->block->Add(w);

      pos += l;
      len -= l;
   }

   sTrack->numSamples = pos;

   Paste(t, sTrack);

   delete sTrack;

   ConsistencyCheck("InsertSilence");
}
コード例 #2
0
ファイル: Sequence.cpp プロジェクト: ruthmagnus/audacity
bool Sequence::InsertSilence(sampleCount s0, sampleCount len)
{
   // Create a new track containing as much silence as we
   // need to insert, and then call Paste to do the insertion
   Sequence *sTrack = new Sequence(mDirManager, mSampleFormat);

   sampleCount idealSamples = GetIdealBlockSize();

   // Allocate a zeroed buffer
   samplePtr buffer = NewSamples(idealSamples, mSampleFormat);
   ClearSamples(buffer, mSampleFormat, 0, idealSamples);

   sampleCount pos = 0;
   BlockFile *firstBlockFile = NULL;

   while (len) {
      sampleCount l = (len > idealSamples ? idealSamples : len);

      SeqBlock *w = new SeqBlock();
      w->start = pos;
      w->len = l;
      w->min = float(0.0);
      w->max = float(0.0);
      w->rms = float(0.0);
      if (pos == 0 || len == l) {
         w->f = mDirManager->NewBlockFile(mSummary->totalSummaryBytes);
         firstBlockFile = w->f;
         FirstWrite(buffer, w, l);
      } else {
         w->f = mDirManager->CopyBlockFile(firstBlockFile);
         if (!w->f) {
            // TODO set error message
            return false;
         }
      }

      sTrack->mBlock->Add(w);

      pos += l;
      len -= l;
   }

   sTrack->mNumSamples = pos;

   Paste(s0, sTrack);

   delete sTrack;
   DeleteSamples(buffer);

   return ConsistencyCheck("InsertSilence");
}
コード例 #3
0
ファイル: Sequence.cpp プロジェクト: Kirushanr/audacity
bool Sequence::InsertSilence(sampleCount s0, sampleCount len)
{
   // Quick check to make sure that it doesn't overflow
   if (((double)mNumSamples) + ((double)len) > wxLL(9223372036854775807))
      return false;

   // Create a new track containing as much silence as we
   // need to insert, and then call Paste to do the insertion.
   // We make use of a SilentBlockFile, which takes up no
   // space on disk.

   Sequence *sTrack = new Sequence(mDirManager, mSampleFormat);

   sampleCount idealSamples = GetIdealBlockSize();

   sampleCount pos = 0;

   while (len) {
      sampleCount l = (len > idealSamples ? idealSamples : len);

      SeqBlock *w = new SeqBlock();
      w->start = pos;
      w->f = new SilentBlockFile(l);

      sTrack->mBlock->Add(w);

      pos += l;
      len -= l;
   }

   sTrack->mNumSamples = pos;

   bool bResult = Paste(s0, sTrack);

   delete sTrack;

   return bResult && ConsistencyCheck(wxT("InsertSilence"));
}
コード例 #4
0
ファイル: Sequence.cpp プロジェクト: Kirushanr/audacity
bool Sequence::Append(samplePtr buffer, sampleFormat format,
                      sampleCount len, XMLWriter* blockFileLog /*=NULL*/)
{
   // Quick check to make sure that it doesn't overflow
   if (((double)mNumSamples) + ((double)len) > wxLL(9223372036854775807))
      return false;

   samplePtr temp = NULL;
   if (format != mSampleFormat) {
      temp = NewSamples(mMaxSamples, mSampleFormat);
      wxASSERT(temp);
   }

   // If the last block is not full, we need to add samples to it
   int numBlocks = mBlock->Count();
   if (numBlocks > 0 && mBlock->Item(numBlocks - 1)->f->GetLength() < mMinSamples) {
      SeqBlock *lastBlock = mBlock->Item(numBlocks - 1);
      sampleCount addLen;
      if (lastBlock->f->GetLength() + len < mMaxSamples)
         addLen = len;
      else
         addLen = GetIdealBlockSize() - lastBlock->f->GetLength();

      SeqBlock *newLastBlock = new SeqBlock();

      samplePtr buffer2 = NewSamples((lastBlock->f->GetLength() + addLen), mSampleFormat);
      Read(buffer2, mSampleFormat, lastBlock, 0, lastBlock->f->GetLength());

      CopySamples(buffer,
                  format,
                  buffer2 + lastBlock->f->GetLength() * SAMPLE_SIZE(mSampleFormat),
                  mSampleFormat,
                  addLen);

      newLastBlock->start = lastBlock->start;
      int newLastBlockLen = lastBlock->f->GetLength() + addLen;

      newLastBlock->f =
         mDirManager->NewSimpleBlockFile(buffer2, newLastBlockLen, mSampleFormat,
                                         blockFileLog != NULL);
      if (blockFileLog)
         ((SimpleBlockFile*)newLastBlock->f)->SaveXML(*blockFileLog);
         
      DeleteSamples(buffer2);

      mDirManager->Deref(lastBlock->f);
      delete lastBlock;
      mBlock->Item(numBlocks - 1) = newLastBlock;

      len -= addLen;
      mNumSamples += addLen;
      buffer += addLen * SAMPLE_SIZE(format);
   }
   // Append the rest as new blocks
   while (len) {
      sampleCount idealSamples = GetIdealBlockSize();
      sampleCount l = (len > idealSamples ? idealSamples : len);
      SeqBlock *w = new SeqBlock();
      w->start = mNumSamples;

      if (format == mSampleFormat) {
         w->f = mDirManager->NewSimpleBlockFile(buffer, l, mSampleFormat,
                                                blockFileLog != NULL);
      }
      else {
         CopySamples(buffer, format, temp, mSampleFormat, l);
         w->f = mDirManager->NewSimpleBlockFile(temp, l, mSampleFormat,
                                                blockFileLog != NULL);
      }

      if (blockFileLog)
         ((SimpleBlockFile*)w->f)->SaveXML(*blockFileLog);

      mBlock->Add(w);

      buffer += l * SAMPLE_SIZE(format);
      mNumSamples += l;
      len -= l;
   }

   if (format != mSampleFormat)
      DeleteSamples(temp);

// JKC: During generate we use Append again and again.
// If generating a long sequence this test would give O(n^2) 
// performance - not good!
#ifdef VERY_SLOW_CHECKING
   ConsistencyCheck(wxT("Append"));
#endif

   return true;
}
コード例 #5
0
ファイル: Sequence.cpp プロジェクト: ruthmagnus/audacity
bool Sequence::Append(samplePtr buffer, sampleFormat format,
                      sampleCount len)
{
   samplePtr temp = NULL;
   if (format != mSampleFormat) {
      temp = NewSamples(mMaxSamples, mSampleFormat);
      wxASSERT(temp);
   }

   // If the last block is not full, we need to add samples to it
   int numBlocks = mBlock->Count();
   if (numBlocks > 0 && mBlock->Item(numBlocks - 1)->len < mMinSamples) {
      SeqBlock *lastBlock = mBlock->Item(numBlocks - 1);
      sampleCount addLen;
      if (lastBlock->len + len < mMaxSamples)
         addLen = len;
      else
         addLen = GetIdealBlockSize() - lastBlock->len;

      SeqBlock *newLastBlock = NewInitedSeqBlock();

      samplePtr buffer2 = NewSamples((lastBlock->len + addLen), mSampleFormat);
      Read(buffer2, mSampleFormat, lastBlock, 0, lastBlock->len);

      if (format == mSampleFormat)
         memcpy(buffer2 + lastBlock->len * SAMPLE_SIZE(format),
                buffer,
                addLen * SAMPLE_SIZE(format));
      else {
         CopySamples(buffer, format, temp, mSampleFormat, addLen);
         memcpy(buffer2 + lastBlock->len * SAMPLE_SIZE(format),
                temp,
                addLen * SAMPLE_SIZE(format));
      }

      newLastBlock->start = lastBlock->start;
      newLastBlock->len = lastBlock->len + addLen;

      FirstWrite(buffer2, newLastBlock, lastBlock->len + addLen);

      DeleteSamples(buffer2);

      mDirManager->Deref(lastBlock->f);
      delete lastBlock;
      mBlock->Item(numBlocks - 1) = newLastBlock;

      len -= addLen;
      mNumSamples += addLen;
      buffer += addLen * SAMPLE_SIZE(format);
   }
   // Append the rest as new blocks
   while (len) {
      sampleCount idealSamples = GetIdealBlockSize();
      sampleCount l = (len > idealSamples ? idealSamples : len);
      SeqBlock *w = new SeqBlock();
      w->f = mDirManager->NewBlockFile(mSummary->totalSummaryBytes);
      w->start = mNumSamples;
      w->len = l;

      if (format == mSampleFormat)
         FirstWrite(buffer, w, l);
      else {
         CopySamples(buffer, format, temp, mSampleFormat, l);
         FirstWrite(temp, w, l);
      }

      mBlock->Add(w);

      buffer += l * SAMPLE_SIZE(format);
      mNumSamples += l;
      len -= l;
   }

   if (format != mSampleFormat)
      DeleteSamples(temp);

   ConsistencyCheck("Append");

   return true;
}
コード例 #6
0
ファイル: Mix.cpp プロジェクト: AthiVarathan/audacity
//TODO-MB: wouldn't it make more sense to DELETE the time track after 'mix and render'?
void MixAndRender(TrackList *tracks, TrackFactory *trackFactory,
                  double rate, sampleFormat format,
                  double startTime, double endTime,
                  WaveTrack::Holder &uLeft, WaveTrack::Holder &uRight)
{
   uLeft.reset(), uRight.reset();

   // This function was formerly known as "Quick Mix".
   Track *t;
   bool mono = false;   /* flag if output can be mono without loosing anything*/
   bool oneinput = false;  /* flag set to true if there is only one input track
                              (mono or stereo) */

   TrackListIterator iter(tracks);
   SelectedTrackListOfKindIterator usefulIter(Track::Wave, tracks);
   // this only iterates tracks which are relevant to this function, i.e.
   // selected WaveTracks. The tracklist is (confusingly) the list of all
   // tracks in the project

   int numWaves = 0; /* number of wave tracks in the selection */
   int numMono = 0;  /* number of mono, centre-panned wave tracks in selection*/
   t = iter.First();
   while (t) {
      if (t->GetSelected() && t->GetKind() == Track::Wave) {
         numWaves++;
         float pan = ((WaveTrack*)t)->GetPan();
         if (t->GetChannel() == Track::MonoChannel && pan == 0)
            numMono++;
      }
      t = iter.Next();
   }

   if (numMono == numWaves)
      mono = true;

   /* the next loop will do two things at once:
    * 1. build an array of all the wave tracks were are trying to process
    * 2. determine when the set of WaveTracks starts and ends, in case we
    *    need to work out for ourselves when to start and stop rendering.
    */

   double mixStartTime = 0.0;    /* start time of first track to start */
   bool gotstart = false;  // flag indicates we have found a start time
   double mixEndTime = 0.0;   /* end time of last track to end */
   double tstart, tend;    // start and end times for one track.

   WaveTrackConstArray waveArray;
   t = iter.First();

   while (t) {
      if (t->GetSelected() && t->GetKind() == Track::Wave) {
         waveArray.push_back(static_cast<WaveTrack *>(t));
         tstart = t->GetStartTime();
         tend = t->GetEndTime();
         if (tend > mixEndTime)
            mixEndTime = tend;
         // try and get the start time. If the track is empty we will get 0,
         // which is ambiguous because it could just mean the track starts at
         // the beginning of the project, as well as empty track. The give-away
         // is that an empty track also ends at zero.

         if (tstart != tend) {
            // we don't get empty tracks here
            if (!gotstart) {
               // no previous start, use this one unconditionally
               mixStartTime = tstart;
               gotstart = true;
            } else if (tstart < mixStartTime)
               mixStartTime = tstart;  // have a start, only make it smaller
         }  // end if start and end are different
      }  // end if track is a selected WaveTrack.
      /** @TODO: could we not use a SelectedTrackListOfKindIterator here? */
      t = iter.Next();
   }

   /* create the destination track (NEW track) */
   if ((numWaves == 1) || ((numWaves == 2) && (usefulIter.First()->GetLink() != NULL)))
      oneinput = true;
   // only one input track (either 1 mono or one linked stereo pair)

   auto mixLeft = trackFactory->NewWaveTrack(format, rate);
   if (oneinput)
      mixLeft->SetName(usefulIter.First()->GetName()); /* set name of output track to be the same as the sole input track */
   else
      mixLeft->SetName(_("Mix"));
   mixLeft->SetOffset(mixStartTime);
   decltype(mixLeft) mixRight{};
   if (mono) {
      mixLeft->SetChannel(Track::MonoChannel);
   }
   else {
      mixRight = trackFactory->NewWaveTrack(format, rate);
      if (oneinput) {
         if (usefulIter.First()->GetLink() != NULL)   // we have linked track
            mixLeft->SetName(usefulIter.First()->GetLink()->GetName()); /* set name to match input track's right channel!*/
         else
            mixLeft->SetName(usefulIter.First()->GetName());   /* set name to that of sole input channel */
      }
      else
         mixRight->SetName(_("Mix"));
      mixLeft->SetChannel(Track::LeftChannel);
      mixRight->SetChannel(Track::RightChannel);
      mixRight->SetOffset(mixStartTime);
      mixLeft->SetLinked(true);
   }



   int maxBlockLen = mixLeft->GetIdealBlockSize();

   // If the caller didn't specify a time range, use the whole range in which
   // any input track had clips in it.
   if (startTime == endTime) {
      startTime = mixStartTime;
      endTime = mixEndTime;
   }

   Mixer mixer(waveArray,
      Mixer::WarpOptions(tracks->GetTimeTrack()),
      startTime, endTime, mono ? 1 : 2, maxBlockLen, false,
      rate, format);

   ::wxSafeYield();

   int updateResult = eProgressSuccess;
   {
      ProgressDialog progress(_("Mix and Render"),
         _("Mixing and rendering tracks"));

      while (updateResult == eProgressSuccess) {
         sampleCount blockLen = mixer.Process(maxBlockLen);

         if (blockLen == 0)
            break;

         if (mono) {
            samplePtr buffer = mixer.GetBuffer();
            mixLeft->Append(buffer, format, blockLen);
         }
         else {
            samplePtr buffer;
            buffer = mixer.GetBuffer(0);
            mixLeft->Append(buffer, format, blockLen);
            buffer = mixer.GetBuffer(1);
            mixRight->Append(buffer, format, blockLen);
         }

         updateResult = progress.Update(mixer.MixGetCurrentTime() - startTime, endTime - startTime);
      }
   }

   mixLeft->Flush();
   if (!mono)
      mixRight->Flush();
   if (updateResult == eProgressCancelled || updateResult == eProgressFailed)
   {
      return;
   }
   else {
      uLeft = std::move(mixLeft),
         uRight = std::move(mixRight);
#if 0
   int elapsedMS = wxGetElapsedTime();
   double elapsedTime = elapsedMS * 0.001;
   double maxTracks = totalTime / (elapsedTime / numWaves);

   // Note: these shouldn't be translated - they're for debugging
   // and profiling only.
   printf("      Tracks: %d\n", numWaves);
   printf("  Mix length: %f sec\n", totalTime);
   printf("Elapsed time: %f sec\n", elapsedTime);
   printf("Max number of tracks to mix in real time: %f\n", maxTracks);
#endif
   }
}
コード例 #7
0
ファイル: WaveTrack.cpp プロジェクト: ruthmagnus/audacity
void WaveTrack::Append(sampleType * buffer, sampleCount len)
{
#if wxUSE_THREADS
   wxMutexLocker lock(*blockMutex);
#endif

   // If the last block is not full, we need to add samples to it
   int numBlocks = block->Count();
   if (numBlocks > 0 && block->Item(numBlocks - 1)->len < minSamples) {
      WaveBlock *lastBlock = block->Item(numBlocks - 1);
      sampleCount addLen;
      if (lastBlock->len + len < maxSamples)
         addLen = len;
      else
         addLen = GetIdealBlockSize() - lastBlock->len;
      sampleCount pos = lastBlock->len;

      WaveBlock *newLastBlock = NewInitedWaveBlock();

      sampleType *buffer2 = new sampleType[lastBlock->len + addLen];
      Read(buffer2, lastBlock, 0, lastBlock->len);

      for (int j = 0; j < addLen; j++)
         buffer2[lastBlock->len + j] = buffer[j];

      newLastBlock->start = lastBlock->start;
      newLastBlock->len = lastBlock->len + addLen;

      FirstWrite(buffer2, newLastBlock, lastBlock->len + addLen);

      delete[]buffer2;

      dirManager->Deref(lastBlock->f);
      delete lastBlock;
      block->Item(numBlocks - 1) = newLastBlock;

      len -= addLen;
      numSamples += addLen;
      buffer += addLen;
   }
   // Append the rest as new blocks
   while (len) {
      sampleCount idealSamples = GetIdealBlockSize();
      sampleCount l = (len > idealSamples ? idealSamples : len);
      WaveBlock *w = new WaveBlock();
      w->f = dirManager->NewBlockFile();
      w->start = numSamples;
      w->len = l;
      bool inited = InitBlock(w);
      wxASSERT(inited);
      FirstWrite(buffer, w, l);
      block->Add(w);

      buffer += l;
      numSamples += l;
      len -= l;
   }

   envelope.SetTrackLen(numSamples / rate);

   ConsistencyCheck("Append");
}
コード例 #8
0
ファイル: Sequence.cpp プロジェクト: ruthmagnus/audacity
bool Sequence::Append(samplePtr buffer, sampleFormat format,
                      sampleCount len)
{
   // Quick check to make sure that it doesn't overflow
   if (((double)mNumSamples) + ((double)len) > 2147483647)
      return false;

   samplePtr temp = NULL;
   if (format != mSampleFormat) {
      temp = NewSamples(mMaxSamples, mSampleFormat);
      wxASSERT(temp);
   }

   // If the last block is not full, we need to add samples to it
   int numBlocks = mBlock->Count();
   if (numBlocks > 0 && mBlock->Item(numBlocks - 1)->f->GetLength() < mMinSamples) {
      SeqBlock *lastBlock = mBlock->Item(numBlocks - 1);
      sampleCount addLen;
      if (lastBlock->f->GetLength() + len < mMaxSamples)
         addLen = len;
      else
         addLen = GetIdealBlockSize() - lastBlock->f->GetLength();

      SeqBlock *newLastBlock = new SeqBlock();

      samplePtr buffer2 = NewSamples((lastBlock->f->GetLength() + addLen), mSampleFormat);
      Read(buffer2, mSampleFormat, lastBlock, 0, lastBlock->f->GetLength());

      if (format == mSampleFormat)
         memcpy(buffer2 + lastBlock->f->GetLength() * SAMPLE_SIZE(format),
                buffer,
                addLen * SAMPLE_SIZE(format));
      else {
         CopySamples(buffer, format, temp, mSampleFormat, addLen);
         memcpy(buffer2 + lastBlock->f->GetLength() * SAMPLE_SIZE(format),
                temp,
                addLen * SAMPLE_SIZE(format));
      }

      newLastBlock->start = lastBlock->start;
      int newLastBlockLen = lastBlock->f->GetLength() + addLen;

      newLastBlock->f =
         mDirManager->NewSimpleBlockFile(buffer2, newLastBlockLen, mSampleFormat);

      DeleteSamples(buffer2);

      mDirManager->Deref(lastBlock->f);
      delete lastBlock;
      mBlock->Item(numBlocks - 1) = newLastBlock;

      len -= addLen;
      mNumSamples += addLen;
      buffer += addLen * SAMPLE_SIZE(format);
   }
   // Append the rest as new blocks
   while (len) {
      sampleCount idealSamples = GetIdealBlockSize();
      sampleCount l = (len > idealSamples ? idealSamples : len);
      SeqBlock *w = new SeqBlock();
      w->start = mNumSamples;

      if (format == mSampleFormat)
      {
         w->f = mDirManager->NewSimpleBlockFile(buffer, l, mSampleFormat);
      }
      else {
         CopySamples(buffer, format, temp, mSampleFormat, l);
         w->f = mDirManager->NewSimpleBlockFile(temp, l, mSampleFormat);
      }

      mBlock->Add(w);

      buffer += l * SAMPLE_SIZE(format);
      mNumSamples += l;
      len -= l;
   }

   if (format != mSampleFormat)
      DeleteSamples(temp);

   ConsistencyCheck("Append");

   return true;
}