Exemple #1
0
void ControlToolBar::OnRecord(wxCommandEvent &evt)
{
   if (gAudioIO->IsBusy()) {
      mRecord->PopUp();
      return;
   }
   AudacityProject *p = GetActiveProject();

   if( evt.GetInt() == 1 ) // used when called by keyboard shortcut. Default (0) ignored.
      mRecord->SetShift(true);
   if( evt.GetInt() == 2 )
      mRecord->SetShift(false);

   SetRecord(true);

   if (p) {
      TrackList *t = p->GetTracks();
      TrackListIterator it(t);
      if(it.First() == NULL)
         mRecord->SetShift(false);
      double t0 = p->GetSel0();
      double t1 = p->GetSel1();
      if (t1 == t0)
         t1 = 1000000000.0;     // record for a long, long time (tens of years)

      /* TODO: set up stereo tracks if that is how the user has set up
       * their preferences, and choose sample format based on prefs */
      WaveTrackArray newRecordingTracks, playbackTracks;
#ifdef EXPERIMENTAL_MIDI_OUT
      NoteTrackArray midiTracks;
#endif
      bool duplex;
      gPrefs->Read(wxT("/AudioIO/Duplex"), &duplex, true);

      if(duplex){
         playbackTracks = t->GetWaveTrackArray(false);
#ifdef EXPERIMENTAL_MIDI_OUT
         midiTracks = t->GetNoteTrackArray(false);
#endif
     }
      else {
         playbackTracks = WaveTrackArray();
#ifdef EXPERIMENTAL_MIDI_OUT
         midiTracks = NoteTrackArray();
#endif
     }

      // If SHIFT key was down, the user wants append to tracks
      int recordingChannels = 0;
      bool shifted = mRecord->WasShiftDown();
      if (shifted) {
         WaveTrack *wt;
         bool sel = false;
         double allt0 = t0;

         // Find the maximum end time of selected and all wave tracks
         for (Track *tt = it.First(); tt; tt = it.Next()) {
            if (tt->GetKind() == Track::Wave) {
               wt = (WaveTrack *)tt;
               if (wt->GetEndTime() > allt0) {
                  allt0 = wt->GetEndTime();
               }

               if (tt->GetSelected()) {
                  sel = true;
                  if (duplex)
                     playbackTracks.Remove(wt);
                  if (wt->GetEndTime() > t0) {
                     t0 = wt->GetEndTime();
                  }
               }
            }
         }

         // Use end time of all wave tracks if none selected
         if (!sel) {
            t0 = allt0;
         }

         // Pad selected/all wave tracks to make them all the same length
         for (Track *tt = it.First(); tt; tt = it.Next()) {
            if (tt->GetKind() == Track::Wave && (tt->GetSelected() || !sel)) {
               wt = (WaveTrack *)tt;
               t1 = wt->GetEndTime();
               if (t1 < t0) {
                  WaveTrack *newTrack = p->GetTrackFactory()->NewWaveTrack();
                  newTrack->InsertSilence(0.0, t0 - t1);
                  newTrack->Flush();
                  wt->Clear(t1, t0);
                  bool bResult = wt->Paste(t1, newTrack);
                  wxASSERT(bResult); // TO DO: Actually handle this.
                  delete newTrack;
               }
               newRecordingTracks.Add(wt);
            }
         }

         t1 = 1000000000.0;     // record for a long, long time (tens of years)
      }
      else {
         recordingChannels = gPrefs->Read(wxT("/AudioIO/RecordChannels"), 2);
         for (int c = 0; c < recordingChannels; c++) {
            WaveTrack *newTrack = p->GetTrackFactory()->NewWaveTrack();

            newTrack->SetOffset(t0);

            if (recordingChannels > 2)
              newTrack->SetMinimized(true);

            if (recordingChannels == 2) {
               if (c == 0) {
                  newTrack->SetChannel(Track::LeftChannel);
                  newTrack->SetLinked(true);
               }
               else {
                  newTrack->SetChannel(Track::RightChannel);
               }
            }
            else {
               newTrack->SetChannel( Track::MonoChannel );
            }

            newRecordingTracks.Add(newTrack);
         }

         // msmeyer: StartStream calls a callback which triggers auto-save, so
         // we add the tracks where recording is done into now. We remove them
         // later if starting the stream fails
         for (unsigned int i = 0; i < newRecordingTracks.GetCount(); i++)
            t->Add(newRecordingTracks[i]);
      }

      //Automated Input Level Adjustment Initialization
      #ifdef AUTOMATED_INPUT_LEVEL_ADJUSTMENT
         gAudioIO->AILAInitialize();
      #endif

      int token = gAudioIO->StartStream(playbackTracks,
                                        newRecordingTracks,
#ifdef EXPERIMENTAL_MIDI_OUT
                                        midiTracks,
#endif
                                        t->GetTimeTrack(),
                                        p->GetRate(), t0, t1, p);

      bool success = (token != 0);

      if (success) {
         p->SetAudioIOToken(token);
         mBusyProject = p;
         SetVUMeters(p);
      }
      else {
         // msmeyer: Delete recently added tracks if opening stream fails
         if (!shifted) {
            for (unsigned int i = 0; i < newRecordingTracks.GetCount(); i++) {
               t->Remove(newRecordingTracks[i]);
               delete newRecordingTracks[i];
            }
         }

         // msmeyer: Show error message if stream could not be opened
         wxMessageBox(_("Error while opening sound device. Please check the recording device settings and the project sample rate."),
                      _("Error"), wxOK | wxICON_EXCLAMATION, this);

         SetPlay(false);
         SetStop(false);
         SetRecord(false);
      }
   }
}
void ControlToolBar::PlayPlayRegion(double t0, double t1,
                                    bool looped /* = false */)
{
   if (gAudioIO->IsBusy()) {
      mPlay->PopUp();
      #if (AUDACITY_BRANDING == BRAND_THINKLABS)
         mLoopPlay->PopUp();
      #elif (AUDACITY_BRANDING == BRAND_AUDIOTOUCH)
         mPlay->Show();
         mPause->Hide();
         this->EnablePauseCommand(false);
      #endif
      return;
   }
  
   mStop->Enable();
   mRewind->Disable();
   mRecord->Disable();
   mFF->Disable();
   mPause->Enable();
   this->EnablePauseCommand(true);
   
   AudacityProject *p = GetActiveProject();
   if (p) {
      TrackList *t = p->GetTracks();
      double maxofmins,minofmaxs;
      
      // JS: clarified how the final play region is computed;
      
      if (t1 == t0) {
         // msmeyer: When playing looped, we play the whole file, if
         // no range is selected. Otherwise, we play from t0 to end
         if (looped) {
            // msmeyer: always play from start
            t0 = t->GetStartTime();
         } else {
            // move t0 to valid range
            if (t0 < 0)
               t0 = t->GetStartTime();
            if (t0 > t->GetEndTime())
               t0 = t->GetEndTime();
         }
         
         // always play to end
         t1 = t->GetEndTime();
      }
      else {
         // always t0 < t1 right?

         // the set intersection between the play region and the
         // valid range maximum of lower bounds
         if (t0 < t->GetStartTime())
            maxofmins = t->GetStartTime();
         else
            maxofmins = t0;
         
         // minimum of upper bounds
         if (t1 > t->GetEndTime())
            minofmaxs = t->GetEndTime();
         else
            minofmaxs = t1;

         // we test if the intersection has no volume 
         if (minofmaxs <= maxofmins) {
            // no volume; play nothing
            return;
         }
         else {
            t0 = maxofmins;
            t1 = minofmaxs;
         }
      }

      bool success = false;
      if (t1 > t0) {
         int token =
            gAudioIO->StartStream(t->GetWaveTrackArray(false),
                                  WaveTrackArray(), t->GetTimeTrack(),
                                  p->GetRate(), t0, t1, looped);
         if (token != 0) {
            success = true;
            p->SetAudioIOToken(token);
            mBusyProject = p;
            SetVUMeters(p);
         }
         else {
            // msmeyer: Show error message if stream could not be opened
            wxMessageBox(_("Error while opening sound device. Please check the output "
                           "device settings and the project sample rate."),
                         _("Error"), wxOK | wxICON_EXCLAMATION, this);
         }
      }

      if (!success) {
         SetPlay(false);
         SetStop(false);
         SetRecord(false);
      }
      #if (AUDACITY_BRANDING == BRAND_AUDIOTOUCH)
         if (success)
         {
            mPlay->Hide();
            mPause->Show();
            this->EnablePauseCommand(true);

            this->SetBackgroundColour(*wxGREEN); // green for Playing
            this->Refresh();
         }
      #endif
   }
}
Exemple #3
0
void ControlToolBar::PlayPlayRegion(double t0, double t1,
                                    bool looped /* = false */,
                                    bool cutpreview /* = false */,
                                    TimeTrack *timetrack /* = NULL */)
{
   SetPlay(true, looped);

   if (gAudioIO->IsBusy()) {
      SetPlay(false);
      return;
   }

   if (cutpreview && t0==t1) {
      SetPlay(false);
      return; /* msmeyer: makes no sense */
   }

   AudacityProject *p = GetActiveProject();
   if (!p) {
      SetPlay(false);
      return;  // Should never happen, but...
   }

   TrackList *t = p->GetTracks();
   if (!t) {
      mPlay->PopUp();
      return;  // Should never happen, but...
   }

   bool hasaudio = false;
   TrackListIterator iter(t);
   for (Track *trk = iter.First(); trk; trk = iter.Next()) {
      if (trk->GetKind() == Track::Wave
#ifdef EXPERIMENTAL_MIDI_OUT
         || trk->GetKind() == Track::Note
#endif
         ) {
         hasaudio = true;
         break;
      }
   }

   if (!hasaudio) {
      SetPlay(false);
      return;  // No need to continue without audio tracks
   }

   double maxofmins,minofmaxs;
#if defined(EXPERIMENTAL_SEEK_BEHIND_CURSOR)
   double init_seek = 0.0;
#endif

   // JS: clarified how the final play region is computed;
   if (t1 == t0) {
      // msmeyer: When playing looped, we play the whole file, if
      // no range is selected. Otherwise, we play from t0 to end
      if (looped) {
         // msmeyer: always play from start
         t0 = t->GetStartTime();
      } else {
         // move t0 to valid range
         if (t0 < 0) {
            t0 = t->GetStartTime();
         }
         else if (t0 > t->GetEndTime()) {
            t0 = t->GetEndTime();
         }
#if defined(EXPERIMENTAL_SEEK_BEHIND_CURSOR)
         else {
            init_seek = t0;         //AC: init_seek is where playback will 'start'
            t0 = t->GetStartTime();
         }
#endif
      }

      // always play to end
      t1 = t->GetEndTime();
   }
   else {
      // always t0 < t1 right?

      // the set intersection between the play region and the
      // valid range maximum of lower bounds
      if (t0 < t->GetStartTime())
         maxofmins = t->GetStartTime();
      else
         maxofmins = t0;

      // minimum of upper bounds
      if (t1 > t->GetEndTime())
         minofmaxs = t->GetEndTime();
      else
         minofmaxs = t1;

      // we test if the intersection has no volume
      if (minofmaxs <= maxofmins) {
         // no volume; play nothing
         return;
      }
      else {
         t0 = maxofmins;
         t1 = minofmaxs;
      }
   }

   // Can't play before 0...either shifted or latencey corrected tracks
   if (t0 < 0.0) {
      t0 = 0.0;
   }

   bool success = false;
   if (t1 > t0) {
      int token;
      if (cutpreview) {
         double beforeLen, afterLen;
         gPrefs->Read(wxT("/AudioIO/CutPreviewBeforeLen"), &beforeLen, 2.0);
         gPrefs->Read(wxT("/AudioIO/CutPreviewAfterLen"), &afterLen, 1.0);
         double tcp0 = t0-beforeLen;
         double tcp1 = (t1+afterLen) - (t1-t0);
         SetupCutPreviewTracks(tcp0, t0, t1, tcp1);
         if (mCutPreviewTracks)
         {
            token = gAudioIO->StartStream(
               mCutPreviewTracks->GetWaveTrackArray(false),
               WaveTrackArray(),
#ifdef EXPERIMENTAL_MIDI_OUT
               NoteTrackArray(),
#endif
               NULL, p->GetRate(), tcp0, tcp1, p, false,
               t0, t1-t0);
         } else
         {
            // Cannot create cut preview tracks, clean up and exit
            SetPlay(false);
            SetStop(false);
            SetRecord(false);
            return;
         }
      } else {
         if (!timetrack) {
            timetrack = t->GetTimeTrack();
         }
         token = gAudioIO->StartStream(t->GetWaveTrackArray(false),
                                       WaveTrackArray(),
#ifdef EXPERIMENTAL_MIDI_OUT
                                       t->GetNoteTrackArray(false),
#endif
                                       timetrack,
                                       p->GetRate(), t0, t1, p, looped);
      }
      if (token != 0) {
         success = true;
         p->SetAudioIOToken(token);
         mBusyProject = p;
#if defined(EXPERIMENTAL_SEEK_BEHIND_CURSOR)
         //AC: If init_seek was set, now's the time to make it happen.
         gAudioIO->SeekStream(init_seek);
#endif
         SetVUMeters(p);
      }
      else {
         // msmeyer: Show error message if stream could not be opened
         wxMessageBox(_(
            "Error while opening sound device. "
            wxT("Please check the playback device settings and the project sample rate.")),
            _("Error"), wxOK | wxICON_EXCLAMATION, this);
      }
   }

   if (!success) {
      SetPlay(false);
      SetStop(false);
      SetRecord(false);
   }
}
void ControlToolBar::OnRecord(wxCommandEvent &evt)
{
   if (gAudioIO->IsBusy()) {
      #if (AUDACITY_BRANDING == BRAND_AUDIOTOUCH)
         if (mIsLocked) // Stop only if in locked mode. 
         {
            this->StopPlaying(); // Stop recording.
            mRecord->PopUp();
         }
         else
         {
            //v evt.GetClassInfo();
         }
      #else
         mRecord->PopUp();
      #endif
      return;
   }

   mPlay->Disable();
   #if (AUDACITY_BRANDING == BRAND_THINKLABS)
      mLoopPlay->Disable();
   #endif

   #if (AUDACITY_BRANDING == BRAND_AUDIOTOUCH)
      mStop->SetEnabled(mIsLocked);
   #else
      mStop->Enable();
   #endif
   mRewind->Disable();
   mFF->Disable();
   #if (AUDACITY_BRANDING == BRAND_AUDIOTOUCH)
      mPause->SetEnabled(mIsLocked);
      this->EnablePauseCommand(mIsLocked);
      this->SetRecord(mIsLocked); // If locked, push Record down, else up.
   #else
      mPause->Enable();
      mRecord->PushDown();
   #endif

   AudacityProject *p = GetActiveProject();
   if (p) {
      TrackList *t = p->GetTracks();

      // Don't do this for Audiotouch. Not necessary. The performance hit is in the track being recorded, below.
      #if (AUDACITY_BRANDING == BRAND_THINKLABS)
         // For versions that default to dual wave/spectrum display, 
         // switch all tracks to WaveformDisplay on Record, for performance.
         TrackListIterator iter(t);
         for (Track* pTrack = iter.First(); pTrack; pTrack = iter.Next())
            if (pTrack->GetKind() == Track::Wave)
               ((WaveTrack*)pTrack)->SetDisplay(WaveTrack::WaveformDisplay);
      #endif

      double t0 = p->GetSel0();
      double t1 = p->GetSel1();
      if (t1 == t0)
         t1 = 1000000000.0;     // record for a long, long time (tens of years)
      #if (AUDACITY_BRANDING == BRAND_AUDIOTOUCH)
         if (p->m_bWantAppendRecording)
         {
            t0 = t->GetEndTime();
            t1 = 1000000000.0;     // record for a long, long time (tens of years)
         }
         gAudioIO->SetWantLatencyCorrection(!p->m_bWantAppendRecording);
      #endif

      /* TODO: set up stereo tracks if that is how the user has set up
       * their preferences, and choose sample format based on prefs */
      WaveTrackArray newRecordingTracks, playbackTracks;

      bool duplex;
      gPrefs->Read("/AudioIO/Duplex", &duplex, true);
      int recordingChannels = gPrefs->Read("/AudioIO/RecordChannels", 1);

      if( duplex )
         playbackTracks = t->GetWaveTrackArray(false);
      else
         playbackTracks = WaveTrackArray();

      for( int c = 0; c < recordingChannels; c++ )
      {
         WaveTrack *newTrack = p->GetTrackFactory()->NewWaveTrack();
         newTrack->SetOffset(t0);
         newTrack->SetRate(p->GetRate());

         //v for performance     newTrack->SetDisplay(WaveTrack::WaveformAndSpectrumDisplay);
         newTrack->SetDisplay(WaveTrack::WaveformDisplay); 
         
         if( recordingChannels == 2 )
         {
            if( c == 0 )
            {
               newTrack->SetChannel(Track::LeftChannel);
               newTrack->SetLinked(true);
            }
            else
               newTrack->SetChannel(Track::RightChannel);
         }
         else
         {
            newTrack->SetChannel( Track::MonoChannel );
         }

         newRecordingTracks.Add(newTrack);
      }

      int token = gAudioIO->StartStream(playbackTracks,
                                        newRecordingTracks, t->GetTimeTrack(),
                                        p->GetRate(), t0, t1);

      bool success = (token != 0);
      for( unsigned int i = 0; i < newRecordingTracks.GetCount(); i++ )
         if (success)
            t->Add(newRecordingTracks[i]);
         else
            delete newRecordingTracks[i];

      if (success) {
         p->SetAudioIOToken(token);
         mBusyProject = p;
         SetVUMeters(p);
         #if (AUDACITY_BRANDING == BRAND_AUDIOTOUCH)
            this->SetBackgroundColour(*wxRED); // red for Recording
            this->Refresh();
         #endif
      }
      else {
         // msmeyer: Show error message if stream could not be opened
         wxMessageBox(_("Error while opening sound device. Please check the input "
                        "device settings and the project sample rate."),
                      _("Error"), wxOK | wxICON_EXCLAMATION, this);

         SetPlay(false);
         #if (AUDACITY_BRANDING == BRAND_AUDIOTOUCH)
            mStop->Enable(); // In case it was disabled above, based on mIsLocked.
         #endif
         SetStop(false);
         SetRecord(false);
      }

      #if (AUDACITY_BRANDING == BRAND_AUDIOTOUCH)
         p->OnZoomFitV();
      #endif
   }
}