Пример #1
0
float ContrastDialog::GetDB()
{
//   not good
//  why not?
// what if more than one track?
   float rms = float(0.0);

   AudacityProject *p = GetActiveProject();
   TrackListIterator iter(p->GetTracks());
   Track *t = iter.First();
   if(mT0 > mT1)
   {
      wxMessageDialog m(NULL, _("Start time after after end time!\nPlease enter reasonable times."), _("Error"), wxOK);
      m.ShowModal();
      return 1234.0; // 'magic number', but the whole +ve dB range will 'almost' never occur
   }
   if(mT0 < t->GetStartTime())
      mT0 = t->GetStartTime();
   if(mT1 > t->GetEndTime())
      mT1 = t->GetEndTime();
   if(mT0 > mT1)
   {
      wxMessageDialog m(NULL, _("Times are not reasonable!\nPlease enter reasonable times."), _("Error"), wxOK);
      m.ShowModal();
      return 1234.0;
   }
   if(mT0 == mT1)
      return 1234.0;
   while(t) {  // this isn't quite right.  What to do if more than one track selected?
      ((WaveTrack *)t)->GetRMS(&rms, mT0, mT1);
      t = iter.Next();
   }
   return 20.0*log10(rms);
}
Пример #2
0
double TrackList::GetStartTime() const
{
   if (IsEmpty())
      return 0.0;
   
   double min = head->t->GetStartTime(); // head->t should be APIfied
   ConstTrackListIterator iter(this);
   
   for (Track *t = iter.First(); t; t = iter.Next()) {
      double l = t->GetStartTime();
      if (l < min)
         min = l;
   }
   
   return min;
}
Пример #3
0
void SnapManager::Reinit()
{
   int snapTo = mProject->GetSnapTo();
   double rate = mProject->GetRate();
   wxString format = mProject->GetSelectionFormat();

   // No need to reinit if these are still the same
   if (snapTo == mSnapTo && rate == mRate && format == mFormat)
   {
      return;
   }

   // Save NEW settings
   mSnapTo = snapTo;
   mRate = rate;
   mFormat = format;

   mSnapPoints.clear();

   // Grab time-snapping prefs (unless otherwise requested)
   mSnapToTime = false;

   // Look up the format string
   if (mSnapTo != SNAP_OFF && !mNoTimeSnap)
   {
      mSnapToTime = true;
      mConverter.SetSampleRate(mRate);
      mConverter.SetFormatName(mFormat);
   }

   // Add a SnapPoint at t=0
   mSnapPoints.push_back(SnapPoint{});

   TrackListIterator iter(mTracks);
   for (Track *track = iter.First();  track; track = iter.Next())
   {
      if (mTrackExclusions &&
          mTrackExclusions->end() !=
          std::find(mTrackExclusions->begin(), mTrackExclusions->end(), track))
      {
         continue;
      }

      if (track->GetKind() == Track::Label)
      {
         LabelTrack *labelTrack = (LabelTrack *)track;
         for (int i = 0, cnt = labelTrack->GetNumLabels(); i < cnt; ++i)
         {
            const LabelStruct *label = labelTrack->GetLabel(i);
            const double t0 = label->getT0();
            const double t1 = label->getT1();
            CondListAdd(t0, labelTrack);
            if (t1 != t0)
            {
               CondListAdd(t1, labelTrack);
            }
         }
      }
      else if (track->GetKind() == Track::Wave)
      {
         auto waveTrack = static_cast<const WaveTrack *>(track);
         for (const auto &clip: waveTrack->GetClips())
         {
            if (mClipExclusions)
            {
               bool skip = false;
               for (size_t j = 0, cnt = mClipExclusions->size(); j < cnt; ++j)
               {
                  if ((*mClipExclusions)[j].track == waveTrack &&
                      (*mClipExclusions)[j].clip == clip.get())
                  {
                     skip = true;
                     break;
                  }
               }

               if (skip)
               {
                  continue;
               }
            }

            CondListAdd(clip->GetStartTime(), waveTrack);
            CondListAdd(clip->GetEndTime(), waveTrack);
         }
      }
#ifdef USE_MIDI
      else if (track->GetKind() == Track::Note)
      {
         CondListAdd(track->GetStartTime(), track);
         CondListAdd(track->GetEndTime(), track);
      }
#endif
   }

   // Sort all by time
   std::sort(mSnapPoints.begin(), mSnapPoints.end());
}
Пример #4
0
bool GetTrackInfoCommand::Apply(CommandExecutionContext context)
{
   wxString mode = GetString(wxT("Type"));

   long trackIndex = GetLong(wxT("TrackIndex"));

   // Get the track indicated by the TrackIndex parameter
   // (Note: this ought to be somewhere else)
   long i = 0;
   TrackListIterator iter(context.proj->GetTracks());
   Track *t = iter.First();
   while (t && i != trackIndex)
   {
      t = iter.Next();
      ++i;
   }
   if (i != trackIndex || !t)
   {
      Error(wxT("TrackIndex was invalid."));
      return false;
   }

   // Now get the particular desired item about the track of interest
   if (mode.IsSameAs(wxT("Name")))
   {
      Status(t->GetName());
   }
   else if (mode.IsSameAs(wxT("StartTime")))
   {
      Status(wxString::Format(wxT("%f"), t->GetStartTime()));
   }
   else if (mode.IsSameAs(wxT("EndTime")))
   {
      Status(wxString::Format(wxT("%f"), t->GetEndTime()));
   }
   else if (mode.IsSameAs(wxT("Pan")))
   {
     if(t->GetKind() == Track::Wave)
       Status(wxString::Format(wxT("%f"), static_cast<WaveTrack*>(t)->GetPan()));
   }
   else if (mode.IsSameAs(wxT("Gain")))
   {
      if(t->GetKind() == Track::Wave)
         Status(wxString::Format(wxT("%f"), static_cast<WaveTrack*>(t)->GetGain()));
   }
   else if (mode.IsSameAs(wxT("Focused")))
   {
      TrackPanel *panel = context.proj->GetTrackPanel();
      SendBooleanStatus(panel->GetFocusedTrack() == t);
   }
   else if (mode.IsSameAs(wxT("Selected")))
   {
      SendBooleanStatus(t->GetSelected());
   }
   else if (mode.IsSameAs(wxT("Linked")))
   {
      SendBooleanStatus(t->GetLinked());
   }
   else if (mode.IsSameAs(wxT("Solo")))
   {
      if (t->GetKind() == Track::Wave)
         SendBooleanStatus(t->GetSolo());
      else
         SendBooleanStatus(false);
   }
   else if (mode.IsSameAs(wxT("Mute")))
   {
      if (t->GetKind() == Track::Wave)
         SendBooleanStatus(t->GetMute());
      else
         SendBooleanStatus(false);
   }
   else
   {
      Error(wxT("Invalid info type!"));
      return false;
   }
   return true;
}
Пример #5
0
//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
   }
}
Пример #6
0
float ContrastDialog::GetDB()
{
   // FIXME: what if more than one track?
   float rms = float(0.0);

   AudacityProject *p = GetActiveProject();
   TrackListOfKindIterator iter(Track::Wave, p->GetTracks());
   Track *t = iter.First();
   if(mT0 > mT1)
   {
      wxMessageDialog m(NULL, _("Start time after end time!\nPlease enter reasonable times."), _("Error"), wxOK);
      m.ShowModal();
      return 1234.0; // 'magic number', but the whole +ve dB range will 'almost' never occur
   }
   if(mT0 < t->GetStartTime())
      mT0 = t->GetStartTime();
   if(mT1 > t->GetEndTime())
      mT1 = t->GetEndTime();
   if(mT0 > mT1)
   {
      wxMessageDialog m(NULL, _("Times are not reasonable!\nPlease enter reasonable times."), _("Error"), wxOK);
      m.ShowModal();
      return 1234.0;
   }
   if(mT0 == mT1)
   {
      wxMessageDialog m(NULL, _("Nothing to measure.\nPlease select a section of a track."), _("Error"), wxOK);
      m.ShowModal();
      return 1234.0;
   }
   bool mSelected = false;
   while(t) {  
      if( ((WaveTrack *)t)->GetSelected() )
      {
         if( mSelected == true ) // already measured one track
         {
            wxMessageDialog m(NULL, _("You can only measure one track at a time."), _("Error"), wxOK);
            m.ShowModal();
            return 1234.0;
         }
         else
         {
            ((WaveTrack *)t)->GetRMS(&rms, mT0, mT1);
            mSelected = true;
         }
      }
      t = iter.Next();
   }
   if( mSelected )
   {
      if( rms < 1.0E-30 )
         return -60.0;
      return 20.0*log10(rms);
   }
   else
   {
      wxMessageDialog m(NULL, _("Please select something to be measured."), _("Error"), wxOK);
      m.ShowModal();
      return 1234.0;
   }
}
Пример #7
0
double StretchHandle::GetT0(const Track &track, const ViewInfo &viewInfo)
{
   return std::max(track.GetStartTime(), viewInfo.selectedRegion.t0());
}
Пример #8
0
SnapManager::SnapManager(TrackList *tracks, TrackClipArray *exclusions,
                         double zoom, int pixelTolerance, bool noTimeSnap)
{
   int i;

   // Grab time-snapping prefs (unless otherwise requested)
   mSnapToTime = false;

   AudacityProject *p = GetActiveProject();
   wxASSERT(p);
   if (p)
   {
      // Look up the format string
      if (p->GetSnapTo() && !noTimeSnap) {
         mSnapToTime = true;
         mConverter.SetSampleRate(p->GetRate());
         mConverter.SetFormatName(p->GetSelectionFormat());
      }
   }

   mSnapPoints = new SnapPointArray(CompareSnapPoints);
   if (zoom > 0 && pixelTolerance > 0)
      mTolerance = pixelTolerance / zoom;
   else {
      // This shouldn't happen, but we don't want to crash if we get
      // illegal values.  The net effect of this is to never snap.
      mTolerance = 0.0;
   }
   // Two time points closer than this are considered the same
   mEpsilon = 1 / 44100.0;

   // Add a SnapPoint at t=0
   mSnapPoints->Add(new SnapPoint(0.0, NULL));

   TrackListIterator iter(tracks);
   Track *track = iter.First();
   while (track) {
      if (track->GetKind() == Track::Label) {
         LabelTrack *labelTrack = (LabelTrack *)track;
         for(i = 0; i < labelTrack->GetNumLabels(); i++) {
            const LabelStruct *label = labelTrack->GetLabel(i);
            CondListAdd(label->t, labelTrack);
            if (label->t1 != label->t) {
               CondListAdd(label->t1, labelTrack);
            }
         }
      }
      else if (track->GetKind() == Track::Wave) {
         WaveTrack *waveTrack = (WaveTrack *)track;
         WaveClipList::compatibility_iterator it;
         for (it=waveTrack->GetClipIterator(); it; it=it->GetNext()) {
            WaveClip *clip = it->GetData();
            if (exclusions) {
               bool skip = false;
               for(int j=0; j<(int)exclusions->GetCount(); j++) {
                  if ((*exclusions)[j].track == waveTrack &&
                      (*exclusions)[j].clip == clip)
                     skip = true;
               }
               if (skip)
                  continue;
            }
            CondListAdd(clip->GetStartTime(), waveTrack);
            CondListAdd(clip->GetEndTime(), waveTrack);
         }
      }
#ifdef USE_MIDI
      else if (track->GetKind() == Track::Note) {
         CondListAdd(track->GetStartTime(), track);
         CondListAdd(track->GetEndTime(), track);
      }
#endif
      track = iter.Next();
   }
}