void VampEffect::AddFeatures(LabelTrack *ltrack, Vamp::Plugin::FeatureSet &features) { for (Vamp::Plugin::FeatureList::iterator fli = features[mOutput].begin(); fli != features[mOutput].end(); ++fli) { Vamp::RealTime ftime0 = fli->timestamp; double ltime0 = ftime0.sec + (double(ftime0.nsec) / 1000000000.0); Vamp::RealTime ftime1 = ftime0; if (fli->hasDuration) ftime1 = ftime0 + fli->duration; double ltime1 = ftime1.sec + (double(ftime1.nsec) / 1000000000.0); wxString label = LAT1CTOWX(fli->label.c_str()); if (label == wxString()) { if (fli->values.empty()) { label = wxString::Format(LAT1CTOWX("%.3f"), ltime0); } else { label = wxString::Format(LAT1CTOWX("%.3f"), *fli->values.begin()); } } ltrack->AddLabel(SelectedRegion(ltime0, ltime1), label, -2); } }
void ControlToolBar::PlayCurrentRegion(bool looped /* = false */, bool cutpreview /* = false */) { if (!CanStopAudioStream()) return; AudacityProject *p = GetActiveProject(); if (p) { double playRegionStart, playRegionEnd; p->GetPlayRegion(&playRegionStart, &playRegionEnd); AudioIOStartStreamOptions options(p->GetDefaultPlayOptions()); options.playLooped = looped; if (cutpreview) options.timeTrack = NULL; ControlToolBar::PlayAppearance appearance = cutpreview ? ControlToolBar::PlayAppearance::CutPreview : looped ? ControlToolBar::PlayAppearance::Looped : ControlToolBar::PlayAppearance::Straight; PlayPlayRegion(SelectedRegion(playRegionStart, playRegionEnd), options, (looped ? PlayMode::loopedPlay : PlayMode::normalPlay), appearance); } }
// Come here from button clicks, or commands void TranscriptionToolBar::PlayAtSpeed(bool looped, bool cutPreview) { // Can't do anything without an active project AudacityProject * p = GetActiveProject(); if (!p) { return; } // Create a TimeTrack if we haven't done so already if (!mTimeTrack) { mTimeTrack = p->GetTrackFactory()->NewTimeTrack(); if (!mTimeTrack) { return; } } // Pop up the button SetButton(false, mButtons[TTB_PlaySpeed]); // If IO is busy, abort immediately if (gAudioIO->IsBusy()) { p->GetControlToolBar()->StopPlaying(); } // Set the speed range //mTimeTrack->SetRangeUpper((double)mPlaySpeed / 100.0); //mTimeTrack->SetRangeLower((double)mPlaySpeed / 100.0); mTimeTrack->GetEnvelope()->Flatten((double)mPlaySpeed / 100.0); // Get the current play region double playRegionStart, playRegionEnd; p->GetPlayRegion(&playRegionStart, &playRegionEnd); // Start playing if (playRegionStart >= 0) { // playRegionEnd = playRegionStart + (playRegionEnd-playRegionStart)* 100.0/mPlaySpeed; #ifdef EXPERIMENTAL_MIDI_OUT gAudioIO->SetMidiPlaySpeed(mPlaySpeed); #endif AudioIOStartStreamOptions options(p->GetDefaultPlayOptions()); options.playLooped = looped; options.timeTrack = mTimeTrack.get(); ControlToolBar::PlayAppearance appearance = cutPreview ? ControlToolBar::PlayAppearance::CutPreview : looped ? ControlToolBar::PlayAppearance::Looped : ControlToolBar::PlayAppearance::Straight; p->GetControlToolBar()->PlayPlayRegion (SelectedRegion(playRegionStart, playRegionEnd), options, PlayMode::normalPlay, appearance); } }
void LabelDialog::OnInsert(wxCommandEvent &event) { int cnt = mData.size(); int row = 0; int index = 0; // Make sure the edit control isn't active before inserting any rows if (mGrid->IsCellEditControlShown()) { mGrid->HideCellEditControl(); } // Attempt to guess which track the label should reside on if (cnt > 0) { row = mGrid->GetGridCursorRow(); if (row > 0 && row >= cnt) { index = mTrackNames.Index(mGrid->GetCellValue(row - 1, Col_Track)); } else { index = mTrackNames.Index(mGrid->GetCellValue(row, Col_Track)); } } // Insert NEW label before or after the current row if (event.GetId() == ID_INSERTA && row < cnt) { row++; } mData.insert(mData.begin() + row, RowData(index, wxT(""), SelectedRegion())); // Repopulate the grid TransferDataToWindow(); // Reposition cursor to NEW row/col and put user into edit mode to // set the label name mGrid->SetGridCursor(row, Col_Label); mGrid->EnableCellEditControl(true); mGrid->ShowCellEditControl(); }
void TranscriptionToolBar::OnMakeLabel(wxCommandEvent & WXUNUSED(event)) { AudacityProject *p = GetActiveProject(); SetButton(false, mButtons[TTB_MakeLabel]); p->DoAddLabel(SelectedRegion(p->GetSel0(), p->GetSel1())); }
void TranscriptionToolBar::OnAutomateSelection(wxCommandEvent & WXUNUSED(event)) { //If IO is busy, abort immediately if (gAudioIO->IsBusy()) { SetButton(false,mButtons[TTB_EndOff]); return; } wxBusyCursor busy; mVk->AdjustThreshold(GetSensitivity()); AudacityProject *p = GetActiveProject(); TrackList *tl = p->GetTracks(); TrackListIterator iter(tl); Track *t = iter.First(); //Make a track if(t) { sampleCount start,len; GetSamples((WaveTrack*)t, &start,&len); //Adjust length to end if selection is null if(len == 0) { len = start; start = 0; } int lastlen = 0; sampleCount newStart, newEnd; double newStartPos, newEndPos; //This is the minumum word size in samples (.05 is 50 ms) int minWordSize = (int)(((WaveTrack*)t)->GetRate() * .05); //Continue until we have processed the entire //region, or we are making no progress. while(len > 0 && lastlen != len) { lastlen = len; newStart = mVk->OnForward(*(WaveTrack*)t,start,len); //JKC: If no start found then don't add any labels. if( newStart==start) break; //Adjust len by the NEW start position len -= (newStart - start); //Adjust len by the minimum word size len -= minWordSize; //OK, now we have found a NEW starting point. A 'word' should be at least //50 ms long, so jump ahead minWordSize newEnd = mVk->OffForward(*(WaveTrack*)t,newStart+minWordSize, len); //If newEnd didn't move, we should give up, because // there isn't another end before the end of the selection. if(newEnd == (newStart + minWordSize)) break; //Adjust len by the NEW word end len -= (newEnd - newStart); //Calculate the start and end of the words, in seconds newStartPos = newStart / ((WaveTrack*)t)->GetRate(); newEndPos = newEnd / ((WaveTrack*)t)->GetRate(); //Increment start = newEnd; p->DoAddLabel(SelectedRegion(newStartPos, newEndPos)); p->RedrawProject(); } SetButton(false, mButtons[TTB_AutomateSelection]); } }
bool AudacityPrintout::OnPrintPage(int WXUNUSED(page)) { wxDC *dc = GetDC(); if (!dc) return false; int width, height; dc->GetSize(&width, &height); int rulerScreenHeight = 40; int screenTotalHeight = mTracks->GetHeight() + rulerScreenHeight; double scale = height / (double)screenTotalHeight; int rulerPageHeight = (int)(rulerScreenHeight * scale); Ruler ruler; ruler.SetBounds(0, 0, width, rulerPageHeight); ruler.SetOrientation(wxHORIZONTAL); ruler.SetRange(0.0, mTracks->GetEndTime()); ruler.SetFormat(Ruler::TimeFormat); ruler.SetLabelEdges(true); ruler.Draw(*dc); TrackArtist artist; artist.SetBackgroundBrushes(*wxWHITE_BRUSH, *wxWHITE_BRUSH, *wxWHITE_PEN, *wxWHITE_PEN); const double screenDuration = mTracks->GetEndTime(); ZoomInfo zoomInfo(0.0, width / screenDuration); int y = rulerPageHeight; TrackListIterator iter(mTracks); Track *n = iter.First(); while (n) { wxRect r; r.x = 0; r.y = y; r.width = width; r.height = (int)(n->GetHeight() * scale); artist.DrawTrack(n, *dc, r, SelectedRegion(), zoomInfo, false, false, false, false); dc->SetPen(*wxBLACK_PEN); AColor::Line(*dc, 0, r.y, width, r.y); #ifdef EXPERIMENTAL_OUTPUT_DISPLAY if(MONO_WAVE_PAN(n)){ y += r.height; r.x = 0; r.y = y; r.width = width; r.height = (int)(n->GetHeight(true) * scale); artist.DrawTrack( n, *dc, r, SelectedRegion{}, zoomInfo, false, false, false, false); dc->SetPen(*wxBLACK_PEN); AColor::Line(*dc, 0, r.y, width, r.y); } #endif n = iter.Next(); y += r.height; }; return true; }
bool EffectFindClipping::ProcessOne(LabelTrack * l, int count, WaveTrack * t, sampleCount start, sampleCount len) { bool bGoodResult = true; sampleCount s = 0; sampleCount blockSize = (sampleCount) (mStart * 1000); if (len < mStart) { return true; } float *buffer = new float[blockSize]; float *ptr = buffer; sampleCount startrun = 0; sampleCount stoprun = 0; sampleCount samps = 0; sampleCount block = 0; double startTime = -1.0; while (s < len) { if (block == 0) { if (TrackProgress(count, s / (double) len)) { bGoodResult = false; break; } block = s + blockSize > len ? len - s : blockSize; t->Get((samplePtr)buffer, floatSample, start + s, block); ptr = buffer; } float v = fabs(*ptr++); if (v >= MAX_AUDIO) { if (startrun == 0) { startTime = t->LongSamplesToTime(start + s); samps = 0; } else { stoprun = 0; } startrun++; samps++; } else { if (startrun >= mStart) { stoprun++; samps++; if (stoprun >= mStop) { l->AddLabel(SelectedRegion(startTime, t->LongSamplesToTime(start + s - mStop)), wxString::Format(wxT("%lld of %lld"), (long long) startrun, (long long) (samps - mStop))); startrun = 0; stoprun = 0; samps = 0; } } else { startrun = 0; } } s++; block--; } delete [] buffer; return bGoodResult; }
bool Scrubber::MaybeStartScrubbing(const wxMouseEvent &event) { if (mScrubStartPosition < 0) return false; if (IsScrubbing()) return false; else { const bool busy = gAudioIO->IsBusy(); if (busy && gAudioIO->GetNumCaptureChannels() > 0) { // Do not stop recording, and don't try to start scrubbing after // recording stops mScrubStartPosition = -1; return false; } wxCoord position = event.m_x; if (abs(mScrubStartPosition - position) >= SCRUBBING_PIXEL_TOLERANCE) { const ViewInfo &viewInfo = mProject->GetViewInfo(); TrackPanel *const trackPanel = mProject->GetTrackPanel(); ControlToolBar * const ctb = mProject->GetControlToolBar(); double maxTime = mProject->GetTracks()->GetEndTime(); const int leftOffset = trackPanel->GetLeftOffset(); double time0 = std::min(maxTime, viewInfo.PositionToTime(mScrubStartPosition, leftOffset) ); double time1 = std::min(maxTime, viewInfo.PositionToTime(position, leftOffset) ); if (time1 != time0) { if (busy) ctb->StopPlaying(); AudioIOStartStreamOptions options(mProject->GetDefaultPlayOptions()); options.timeTrack = NULL; options.scrubDelay = (kTimerInterval / 1000.0); options.scrubStartClockTimeMillis = mScrubStartClockTimeMillis; options.minScrubStutter = 0.2; #if 0 if (!mAlwaysSeeking) { // Take the starting speed limit from the transcription toolbar, // but it may be varied during the scrub. mMaxScrubSpeed = options.maxScrubSpeed = p->GetTranscriptionToolBar()->GetPlaySpeed(); } #else // That idea seems unpopular... just make it one mMaxScrubSpeed = options.maxScrubSpeed = 1.0; #endif options.maxScrubTime = mProject->GetTracks()->GetEndTime(); ControlToolBar::PlayAppearance appearance = ControlToolBar::PlayAppearance::Scrub; const bool cutPreview = false; const bool backwards = time1 < time0; #ifdef EXPERIMENTAL_SCRUBBING_SCROLL_WHEEL static const double maxScrubSpeedBase = pow(2.0, 1.0 / ScrubSpeedStepsPerOctave); mLogMaxScrubSpeed = floor(0.5 + log(mMaxScrubSpeed) / log(maxScrubSpeedBase) ); #endif mScrubSpeedDisplayCountdown = 0; mScrubToken = ctb->PlayPlayRegion(SelectedRegion(time0, time1), options, PlayMode::normalPlay, appearance, backwards); } } else // Wait to test again mScrubStartClockTimeMillis = ::wxGetLocalTimeMillis(); if (IsScrubbing()) mScrubHasFocus = true; // Return true whether we started scrub, or are still waiting to decide. return true; } }
bool SelectCommand::Apply(CommandExecutionContext context) { wxString mode = GetString(wxT("Mode")); if (mode.IsSameAs(wxT("None"))) { // select none context.GetProject()->OnSelectNone(); } else if (mode.IsSameAs(wxT("All"))) { // select all context.GetProject()->OnSelectAll(); } else if (mode.IsSameAs(wxT("Range"))) { // select range double t0 = GetDouble(wxT("StartTime")); double t1 = GetDouble(wxT("EndTime")); TrackList *tracks = context.GetProject()->GetTracks(); if (t0 < context.GetProject()->GetTracks()->GetMinOffset()) { Error(wxT("Start time is before start of track!")); return false; } if (t1 > context.GetProject()->GetTracks()->GetEndTime()) { Error(wxT("End time is after end of track!")); return false; } // PRL: to do: only setting time boundaries of current selection. // Should other fields be left alone, or rather // defaulted, as in the second branch? // Or should this command take more parameters? #if 1 context.GetProject()->mViewInfo.selectedRegion.setTimes(t0, t1); #else context.GetProject()->mViewInfo.selectedRegion = SelectedRegion(t0, t1); #endif // select specified tracks long firstTrack = GetLong(wxT("FirstTrack")); long lastTrack = GetLong(wxT("LastTrack")); if (firstTrack < 0) { Error(wxT("Trying to select a negatively numbered track!")); return false; } if (lastTrack >= tracks->GetCount()) { Error(wxT("Trying to select higher number track than exists!")); return false; } int index = 0; TrackListIterator iter(tracks); Track *t = iter.First(); while (t) { bool sel = firstTrack <= index && index <= lastTrack; t->SetSelected(sel); if (sel) Status(wxT("Selected track '") + t->GetName() + wxT("'")); t = iter.Next(); ++index; } wxASSERT(index >= lastTrack); } else if (mode.IsSameAs(wxT("Name"))) { wxString name = GetString(wxT("TrackName")); TrackList *tracks = context.GetProject()->GetTracks(); TrackListIterator iter(tracks); Track *t = iter.First(); while (t) { bool sel = t->GetName().IsSameAs(name); t->SetSelected(sel); if (sel) Status(wxT("Selected track '") + t->GetName() + wxT("'")); t = iter.Next(); } } else { Error(wxT("Invalid selection mode!")); return false; } return true; }
// Come here from button clicks, or commands void TranscriptionToolBar::PlayAtSpeed(bool looped, bool cutPreview) { // Can't do anything without an active project AudacityProject * p = GetActiveProject(); if (!p) { return; } // Fixed speed play is the old method, that uses a time track. // VariSpeed play reuses Scrubbing. bool bFixedSpeedPlay = !gPrefs->ReadBool(wxT("/AudioIO/VariSpeedPlay"), true); // Scrubbing doesn't support note tracks, but the fixed-speed method using time tracks does. if (p->GetTracks()->Any<NoteTrack>()) bFixedSpeedPlay = true; // Scrubbing only supports straight through play. // So if looped or cutPreview, we have to fall back to fixed speed. bFixedSpeedPlay = bFixedSpeedPlay || looped || cutPreview; if (bFixedSpeedPlay) { // Create a TimeTrack if we haven't done so already if (!mTimeTrack) { mTimeTrack = p->GetTrackFactory()->NewTimeTrack(); if (!mTimeTrack) { return; } } // Set the speed range //mTimeTrack->SetRangeUpper((double)mPlaySpeed / 100.0); //mTimeTrack->SetRangeLower((double)mPlaySpeed / 100.0); mTimeTrack->GetEnvelope()->Flatten((double)mPlaySpeed / 100.0); } // Pop up the button SetButton(false, mButtons[TTB_PlaySpeed]); // If IO is busy, abort immediately if (gAudioIO->IsBusy()) { p->GetControlToolBar()->StopPlaying(); } // Get the current play region double playRegionStart, playRegionEnd; p->GetPlayRegion(&playRegionStart, &playRegionEnd); // Start playing if (playRegionStart < 0) return; if (bFixedSpeedPlay) { AudioIOStartStreamOptions options(p->GetDefaultPlayOptions()); options.playLooped = looped; // No need to set cutPreview options. // Due to a rather hacky approach, the appearance is used // to signal use of cutpreview to code below. options.timeTrack = mTimeTrack.get(); ControlToolBar::PlayAppearance appearance = cutPreview ? ControlToolBar::PlayAppearance::CutPreview : looped ? ControlToolBar::PlayAppearance::Looped : ControlToolBar::PlayAppearance::Straight; p->GetControlToolBar()->PlayPlayRegion (SelectedRegion(playRegionStart, playRegionEnd), options, PlayMode::normalPlay, appearance); } else { Scrubber &Scrubber = p->GetScrubber(); Scrubber.StartSpeedPlay(GetPlaySpeed(), playRegionStart, playRegionEnd); } }