Audacity  3.0.3
TrackMenus.cpp
Go to the documentation of this file.
1 
2 
3 #include "../CommonCommandFlags.h"
4 #include "../LabelTrack.h"
5 #include "../Menus.h"
6 #include "../Mix.h"
7 
8 #include "Prefs.h"
9 #include "../Project.h"
10 #include "../ProjectAudioIO.h"
11 #include "../ProjectHistory.h"
12 #include "../ProjectSettings.h"
13 #include "../PluginManager.h"
14 #include "../ProjectStatus.h"
15 #include "../ProjectWindow.h"
16 #include "../SelectUtilities.h"
17 #include "../ShuttleGui.h"
18 #include "../TimeTrack.h"
19 #include "../TrackPanelAx.h"
20 #include "../TrackPanel.h"
21 #include "../TrackUtilities.h"
22 #include "../UndoManager.h"
23 #include "../WaveClip.h"
24 #include "../ViewInfo.h"
25 #include "../WaveTrack.h"
26 #include "../commands/CommandContext.h"
27 #include "../commands/CommandManager.h"
28 #include "../effects/EffectManager.h"
29 #include "../effects/EffectUI.h"
30 #include "../prefs/QualitySettings.h"
31 #include "../tracks/playabletrack/wavetrack/ui/WaveTrackControls.h"
32 #include "../widgets/ASlider.h"
33 #include "../widgets/AudacityMessageBox.h"
34 #include "../widgets/ProgressDialog.h"
35 
36 #include <wx/combobox.h>
37 
38 #ifdef EXPERIMENTAL_SCOREALIGN
39 #include "../effects/ScoreAlignDialog.h"
40 #include "audioreader.h"
41 #include "scorealign.h"
42 #include "scorealign-glue.h"
43 #endif /* EXPERIMENTAL_SCOREALIGN */
44 
45 // private helper classes and functions
46 namespace {
47 
49 (AudacityProject &project, bool toNewTrack)
50 {
51  const auto &settings = ProjectSettings::Get( project );
52  auto &tracks = TrackList::Get( project );
53  auto &trackFactory = WaveTrackFactory::Get( project );
54  auto rate = settings.GetRate();
55  auto defaultFormat = QualitySettings::SampleFormatChoice();
56  auto &trackPanel = TrackPanel::Get( project );
57  auto &window = ProjectWindow::Get( project );
58 
59  WaveTrack::Holder uNewLeft, uNewRight;
61  &tracks, &trackFactory, rate, defaultFormat, 0.0, 0.0, uNewLeft, uNewRight);
62 
63  if (uNewLeft) {
64  // Remove originals, get stats on what tracks were mixed
65 
66  auto trackRange = tracks.Selected< WaveTrack >();
67 
68  // But before removing, determine the first track after the removal
69  auto last = *trackRange.rbegin();
70  auto insertionPoint = * ++ tracks.Find( last );
71 
72  auto selectedCount = (trackRange + &Track::IsLeader).size();
73  wxString firstName;
74  int firstColour = -1;
75  if (selectedCount > 0) {
76  firstName = (*trackRange.begin())->GetName();
77  firstColour = (*trackRange.begin())->GetWaveColorIndex();
78  }
79  if (!toNewTrack) {
80  // Beware iterator invalidation!
81  for (auto &it = trackRange.first, &end = trackRange.second; it != end;)
82  tracks.Remove( *it++ );
83  }
84 
85  // Add NEW tracks
86 
87  auto pNewLeft = tracks.Add( uNewLeft );
88  decltype(pNewLeft) pNewRight{};
89  if (uNewRight)
90  pNewRight = tracks.Add( uNewRight );
91 
92  // Do this only after adding tracks to the list
93  tracks.GroupChannels(*pNewLeft, pNewRight ? 2 : 1);
94 
95  // If we're just rendering (not mixing), keep the track name the same
96  if (selectedCount==1) {
97  pNewLeft->SetName(firstName);
98  if (pNewRight) {
99  pNewRight->SetName(firstName);
100  }
101  }
102 
103  // Bug 2218, remember more things...
104  if (selectedCount>=1) {
105  pNewLeft->SetWaveColorIndex(firstColour);
106  pNewLeft->SetSelected(!toNewTrack);
107  if (pNewRight) {
108  pNewRight->SetWaveColorIndex(firstColour);
109  pNewRight->SetSelected(!toNewTrack);
110  }
111  }
112 
113  // Permute the tracks as needed
114  // The new track appears after the old tracks (or where the old tracks
115  // had been) so that they are in the same sync-lock group
116  if (insertionPoint)
117  {
118  std::vector<TrackNodePointer> arr;
119  arr.reserve( tracks.size() );
120  size_t begin = 0, ii = 0;
121  for (auto iter = tracks.ListOfTracks::begin(),
122  end = tracks.ListOfTracks::end(); iter != end; ++iter) {
123  arr.push_back( {iter, &tracks} );
124  if ( iter->get() == insertionPoint )
125  begin = ii;
126  ++ii;
127  }
128  auto mid = arr.end();
129  std::advance( mid, -TrackList::Channels( pNewLeft ).size() );
130  std::rotate( arr.begin() + begin, mid, arr.end() );
131  tracks.Permute( arr );
132  }
133 
134  // Smart history/undo message
135  if (selectedCount==1) {
136  auto msg = XO("Rendered all audio in track '%s'").Format( firstName );
137  /* i18n-hint: Convert the audio into a more usable form, so apply
138  * panning and amplification and write to some external file.*/
139  ProjectHistory::Get( project ).PushState(msg, XO("Render"));
140  }
141  else {
142  auto msg = (pNewRight
143  ? XO("Mixed and rendered %d tracks into one new stereo track")
144  : XO("Mixed and rendered %d tracks into one new mono track")
145  )
146  .Format( (int)selectedCount );
147  ProjectHistory::Get( project ).PushState(msg, XO("Mix and Render"));
148  }
149 
150  trackPanel.SetFocus();
151  TrackFocus::Get( project ).Set( pNewLeft );
152  pNewLeft->EnsureVisible();
153  }
154 }
155 
156 void DoPanTracks(AudacityProject &project, float PanValue)
157 {
158  auto &tracks = TrackList::Get( project );
159  auto &window = ProjectWindow::Get( project );
160 
161  // count selected wave tracks
162  const auto range = tracks.Any< WaveTrack >();
163  const auto selectedRange = range + &Track::IsSelected;
164  auto count = selectedRange.size();
165 
166  // iter through them, all if none selected.
167  for (auto left : count == 0 ? range : selectedRange )
168  left->SetPan( PanValue );
169 
170  auto flags = UndoPush::NONE;
171  ProjectHistory::Get( project )
172  /*i18n-hint: One or more audio tracks have been panned*/
173  .PushState(XO("Panned audio track(s)"), XO("Pan Track"), flags);
174  flags = flags | UndoPush::CONSOLIDATE;
175 }
176 
177 enum {
183  // The next two are only in one subMenu, so more easily handled at the end.
186 };
187 
188 static const std::vector< ComponentInterfaceSymbol >
189 &alignLabels() { static std::vector< ComponentInterfaceSymbol > symbols{
190  { wxT("StartToZero"), XXO("Start to &Zero") },
191  { wxT("StartToSelStart"), XXO("Start to &Cursor/Selection Start") },
192  { wxT("StartToSelEnd"), XXO("Start to Selection &End") },
193  { wxT("EndToSelStart"), XXO("End to Cu&rsor/Selection Start") },
194  { wxT("EndToSelEnd"), XXO("End to Selection En&d") },
195 }; return symbols; }
196 
197 const size_t kAlignLabelsCount(){ return alignLabels().size(); }
198 
200 (AudacityProject &project, int index, bool moveSel)
201 {
202  auto &tracks = TrackList::Get( project );
203  auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
204  auto &window = ProjectWindow::Get( project );
205 
206  TranslatableString action, shortAction;
207  double delta = 0.0;
208  double newPos = -1.0;
209 
210  auto channelRange = tracks.Selected< AudioTrack >();
211  auto trackRange = tracks.SelectedLeaders< AudioTrack >();
212 
213  auto FindOffset = []( const Track *pTrack ) {
214  return TrackList::Channels(pTrack).min( &Track::GetOffset ); };
215 
216  auto firstTrackOffset = [&]{ return FindOffset( *trackRange.begin() ); };
217  auto minOffset = [&]{ return trackRange.min( FindOffset ); };
218  auto avgOffset = [&]{
219  return trackRange.sum( FindOffset ) /
220  std::max( size_t(1), trackRange.size() ); };
221 
222  auto maxEndOffset = [&]{
223  return std::max(0.0, channelRange.max( &Track::GetEndTime ) ); };
224 
225  switch(index) {
226  case kAlignStartZero:
227  delta = -minOffset();
228  action = moveSel
229  /* i18n-hint: In this and similar messages describing editing actions,
230  the starting or ending points of tracks are re-"aligned" to other
231  times, and the time selection may be "moved" too. The first
232  noun -- "start" in this example -- is the object of a verb (not of
233  an implied preposition "from"). */
234  ? XO("Aligned/Moved start to zero")
235  : XO("Aligned start to zero");
236  shortAction = moveSel
237  /* i18n-hint: This and similar messages give shorter descriptions of
238  the aligning and moving editing actions */
239  ? XO("Align/Move Start")
240  : XO("Align Start");
241  break;
242  case kAlignStartSelStart:
243  delta = selectedRegion.t0() - minOffset();
244  action = moveSel
245  ? XO("Aligned/Moved start to cursor/selection start")
246  : XO("Aligned start to cursor/selection start");
247  shortAction = moveSel
248  ? XO("Align/Move Start")
249  : XO("Align Start");
250  break;
251  case kAlignStartSelEnd:
252  delta = selectedRegion.t1() - minOffset();
253  action = moveSel
254  ? XO("Aligned/Moved start to selection end")
255  : XO("Aligned start to selection end");
256  shortAction = moveSel
257  ? XO("Align/Move Start")
258  : XO("Align Start");
259  break;
260  case kAlignEndSelStart:
261  delta = selectedRegion.t0() - maxEndOffset();
262  action = moveSel
263  ? XO("Aligned/Moved end to cursor/selection start")
264  : XO("Aligned end to cursor/selection start");
265  shortAction =
266  moveSel
267  ? XO("Align/Move End")
268  : XO("Align End");
269  break;
270  case kAlignEndSelEnd:
271  delta = selectedRegion.t1() - maxEndOffset();
272  action = moveSel
273  ? XO("Aligned/Moved end to selection end")
274  : XO("Aligned end to selection end");
275  shortAction =
276  moveSel
277  ? XO("Align/Move End")
278  : XO("Align End");
279  break;
280  // index set in alignLabelsNoSync
281  case kAlignEndToEnd:
282  newPos = firstTrackOffset();
283  action = moveSel
284  ? XO("Aligned/Moved end to end")
285  : XO("Aligned end to end");
286  shortAction =
287  moveSel
288  ? XO("Align/Move End to End")
289  : XO("Align End to End");
290  break;
291  case kAlignTogether:
292  newPos = avgOffset();
293  action = moveSel
294  ? XO("Aligned/Moved together")
295  : XO("Aligned together");
296  shortAction =
297  moveSel
298  ? XO("Align/Move Together")
299  : XO("Align Together");
300  }
301 
302  if ((unsigned)index >= kAlignLabelsCount()) {
303  // This is an alignLabelsNoSync command.
304  for (auto t : tracks.SelectedLeaders< AudioTrack >()) {
305  // This shifts different tracks in different ways, so no sync-lock
306  // move.
307  // Only align Wave and Note tracks end to end.
308  auto channels = TrackList::Channels(t);
309 
310  auto trackStart = channels.min( &Track::GetStartTime );
311  auto trackEnd = channels.max( &Track::GetEndTime );
312 
313  for (auto channel : channels)
314  // Move the track
315  channel->SetOffset(newPos + channel->GetStartTime() - trackStart);
316 
317  if (index == kAlignEndToEnd)
318  newPos += (trackEnd - trackStart);
319  }
320  if (index == kAlignEndToEnd)
321  window.DoZoomFit();
322  }
323 
324  if (delta != 0.0) {
325  // For a fixed-distance shift move sync-lock selected tracks also.
326  for (auto t : tracks.Any() + &Track::IsSelectedOrSyncLockSelected )
327  t->SetOffset(t->GetOffset() + delta);
328  }
329 
330  if (moveSel)
331  selectedRegion.move(delta);
332 
333  ProjectHistory::Get( project ).PushState(action, shortAction);
334 }
335 
336 #ifdef EXPERIMENTAL_SCOREALIGN
337 
338 // rough relative amount of time to compute one
339 // frame of audio or midi, or one cell of matrix, or one iteration
340 // of smoothing, measured on a 1.9GHz Core 2 Duo in 32-bit mode
341 // (see COLLECT_TIMING_DATA below)
342 #define AUDIO_WORK_UNIT 0.004F
343 #define MIDI_WORK_UNIT 0.0001F
344 #define MATRIX_WORK_UNIT 0.000002F
345 #define SMOOTHING_WORK_UNIT 0.000001F
346 
347 // Write timing data to a file; useful for calibrating AUDIO_WORK_UNIT,
348 // MIDI_WORK_UNIT, MATRIX_WORK_UNIT, and SMOOTHING_WORK_UNIT coefficients
349 // Data is written to timing-data.txt; look in
350 // audacity-src/win/Release/modules/
351 #define COLLECT_TIMING_DATA
352 
353 // Audacity Score Align Progress class -- progress reports come here
354 class ASAProgress final : public SAProgress {
355  private:
356  float mTotalWork;
357  float mFrames[2];
358  long mTotalCells; // how many matrix cells?
359  long mCellCount; // how many cells so far?
360  long mPrevCellCount; // cell_count last reported with Update()
361  Optional<ProgressDialog> mProgress;
362  #ifdef COLLECT_TIMING_DATA
363  FILE *mTimeFile;
364  wxDateTime mStartTime;
365  long iterations;
366  #endif
367 
368  public:
369  ASAProgress() {
370  smoothing = false;
371  #ifdef COLLECT_TIMING_DATA
372  mTimeFile = fopen("timing-data.txt", "w");
373  #endif
374  }
375  ~ASAProgress() {
376  #ifdef COLLECT_TIMING_DATA
377  fclose(mTimeFile);
378  #endif
379  }
380  void set_phase(int i) override {
381  float work[2]; // chromagram computation work estimates
382  float work2, work3 = 0; // matrix and smoothing work estimates
383  SAProgress::set_phase(i);
384  #ifdef COLLECT_TIMING_DATA
385  long ms = 0;
386  wxDateTime now = wxDateTime::UNow();
387  wxFprintf(mTimeFile, "Phase %d begins at %s\n",
388  i, now.FormatTime());
389  if (i != 0)
390  ms = now.Subtract(mStartTime).GetMilliseconds().ToLong();
391  mStartTime = now;
392  #endif
393  if (i == 0) {
394  mCellCount = 0;
395  for (int j = 0; j < 2; j++) {
396  mFrames[j] = durations[j] / frame_period;
397  }
398  mTotalWork = 0;
399  for (int j = 0; j < 2; j++) {
400  work[j] =
401  (is_audio[j] ? AUDIO_WORK_UNIT : MIDI_WORK_UNIT) * mFrames[j];
402  mTotalWork += work[j];
403  }
404  mTotalCells = mFrames[0] * mFrames[1];
405  work2 = mTotalCells * MATRIX_WORK_UNIT;
406  mTotalWork += work2;
407  // arbitrarily assume 60 iterations to fit smooth segments and
408  // per frame per iteration is SMOOTHING_WORK_UNIT
409  if (smoothing) {
410  work3 =
411  wxMax(mFrames[0], mFrames[1]) * SMOOTHING_WORK_UNIT * 40;
412  mTotalWork += work3;
413  }
414  #ifdef COLLECT_TIMING_DATA
415  wxFprintf(mTimeFile,
416  " mTotalWork (an estimate) = %g\n", mTotalWork);
417  wxFprintf(mTimeFile, " work0 = %g, frames %g, is_audio %d\n",
418  work[0], mFrames[0], is_audio[0]);
419  wxFprintf(mTimeFile, " work1 = %g, frames %g, is_audio %d\n",
420  work[1], mFrames[1], is_audio[1]);
421  wxFprintf(mTimeFile, "work2 = %g, work3 = %g\n", work2, work3);
422  #endif
423  mProgress.emplace(XO("Synchronize MIDI with Audio"),
424  XO("Synchronizing MIDI and Audio Tracks"));
425  } else if (i < 3) {
426  wxFprintf(mTimeFile,
427  "Phase %d took %d ms for %g frames, coefficient = %g s/frame\n",
428  i - 1, ms, mFrames[i - 1], (ms * 0.001) / mFrames[i - 1]);
429  } else if (i == 3) {
430  wxFprintf(mTimeFile,
431  "Phase 2 took %d ms for %d cells, coefficient = %g s/cell\n",
432  ms, mCellCount, (ms * 0.001) / mCellCount);
433  } else if (i == 4) {
434  wxFprintf(mTimeFile,
435  "Phase 3 took %d ms for %d iterations on %g frames, "
436  "coefficient = %g s per frame per iteration\n",
437  ms, iterations, wxMax(mFrames[0], mFrames[1]),
438  (ms * 0.001) / (wxMax(mFrames[0], mFrames[1]) * iterations));
439  }
440  }
441  bool set_feature_progress(float s) override {
442  float work;
443  if (phase == 0) {
444  float f = s / frame_period;
445  work = (is_audio[0] ? AUDIO_WORK_UNIT : MIDI_WORK_UNIT) * f;
446  } else if (phase == 1) {
447  float f = s / frame_period;
448  work = (is_audio[0] ? AUDIO_WORK_UNIT : MIDI_WORK_UNIT) * mFrames[0] +
449  (is_audio[1] ? AUDIO_WORK_UNIT : MIDI_WORK_UNIT) * f;
450  }
451  auto updateResult = mProgress->Update((int)(work), (int)(mTotalWork));
452  return (updateResult == ProgressResult::Success);
453  }
454  bool set_matrix_progress(int cells) override {
455  mCellCount += cells;
456  float work =
457  (is_audio[0] ? AUDIO_WORK_UNIT : MIDI_WORK_UNIT) * mFrames[0] +
458  (is_audio[1] ? AUDIO_WORK_UNIT : MIDI_WORK_UNIT) * mFrames[1];
459  work += mCellCount * MATRIX_WORK_UNIT;
460  auto updateResult = mProgress->Update((int)(work), (int)(mTotalWork));
461  return (updateResult == ProgressResult::Success);
462  }
463  bool set_smoothing_progress(int i) override {
464  iterations = i;
465  float work =
466  (is_audio[0] ? AUDIO_WORK_UNIT : MIDI_WORK_UNIT) * mFrames[0] +
467  (is_audio[1] ? AUDIO_WORK_UNIT : MIDI_WORK_UNIT) * mFrames[1] +
468  MATRIX_WORK_UNIT * mFrames[0] * mFrames[1];
469  work += i * wxMax(mFrames[0], mFrames[1]) * SMOOTHING_WORK_UNIT;
470  auto updateResult = mProgress->Update((int)(work), (int)(mTotalWork));
471  return (updateResult == ProgressResult::Success);
472  }
473 };
474 
475 
476 long mixer_process(void *mixer, float **buffer, long n)
477 {
478  Mixer *mix = (Mixer *) mixer;
479  long frame_count = mix->Process(std::max(0L, n));
480  *buffer = (float *) mix->GetBuffer();
481  return frame_count;
482 }
483 
484 #endif // EXPERIMENTAL_SCOREALIGN
485 
486 enum{
489 };
490 
491 void DoSortTracks( AudacityProject &project, int flags )
492 {
493  auto GetTime = [](const Track *t) {
494  return t->TypeSwitch< double >(
495  [&](const WaveTrack* w) {
496  auto stime = w->GetEndTime();
497 
498  int ndx;
499  for (ndx = 0; ndx < w->GetNumClips(); ndx++) {
500  const auto c = w->GetClipByIndex(ndx);
501  if (c->GetNumSamples() == 0)
502  continue;
503  stime = std::min(stime, c->GetStartTime());
504  }
505  return stime;
506  },
507  [&](const LabelTrack* l) {
508  return l->GetStartTime();
509  }
510  );
511  };
512 
513  size_t ndx = 0;
514  // This one place outside of TrackList where we must use undisguised
515  // std::list iterators! Avoid this elsewhere!
516  std::vector<TrackNodePointer> arr;
517  auto &tracks = TrackList::Get( project );
518  arr.reserve(tracks.size());
519 
520  // First find the permutation.
521  // This routine, very unusually, deals with the underlying stl list
522  // iterators, not with TrackIter! Dangerous!
523  for (auto iter = tracks.ListOfTracks::begin(),
524  end = tracks.ListOfTracks::end(); iter != end; ++iter) {
525  const auto &track = *iter;
526  if ( !track->IsLeader() )
527  // keep channels contiguous
528  ndx++;
529  else {
530  auto size = arr.size();
531  for (ndx = 0; ndx < size;) {
532  Track &arrTrack = **arr[ndx].first;
533  auto channels = TrackList::Channels(&arrTrack);
534  if(flags & kAudacitySortByName) {
535  //do case insensitive sort - cmpNoCase returns less than zero if
536  // the string is 'less than' its argument
537  //also if we have case insensitive equality, then we need to sort
538  // by case as well
539  //We sort 'b' before 'B' accordingly. We uncharacteristically
540  // use greater than for the case sensitive
541  //compare because 'b' is greater than 'B' in ascii.
542  auto cmpValue = track->GetName().CmpNoCase(arrTrack.GetName());
543  if ( cmpValue < 0 ||
544  ( 0 == cmpValue &&
545  track->GetName().CompareTo(arrTrack.GetName()) > 0 ) )
546  break;
547  }
548  //sort by time otherwise
549  else if(flags & kAudacitySortByTime) {
550  auto time1 = TrackList::Channels(track.get()).min( GetTime );
551 
552  //get candidate's (from sorted array) time
553  auto time2 = channels.min( GetTime );
554 
555  if (time1 < time2)
556  break;
557  }
558  ndx += channels.size();
559  }
560  }
561  arr.insert(arr.begin() + ndx, TrackNodePointer{iter, &tracks});
562  }
563 
564  // Now apply the permutation
565  tracks.Permute(arr);
566 }
567 
568 void SetTrackGain(AudacityProject &project, WaveTrack * wt, LWSlider * slider)
569 {
570  wxASSERT(wt);
571  float newValue = slider->Get();
572 
573  for (auto channel : TrackList::Channels(wt))
574  channel->SetGain(newValue);
575 
576  ProjectHistory::Get( project )
577  .PushState(XO("Adjusted gain"), XO("Gain"), UndoPush::CONSOLIDATE);
578 
579  TrackPanel::Get( project ).RefreshTrack(wt);
580 }
581 
582 void SetTrackPan(AudacityProject &project, WaveTrack * wt, LWSlider * slider)
583 {
584  wxASSERT(wt);
585  float newValue = slider->Get();
586 
587  for (auto channel : TrackList::Channels(wt))
588  channel->SetPan(newValue);
589 
590  ProjectHistory::Get( project )
591  .PushState(XO("Adjusted Pan"), XO("Pan"), UndoPush::CONSOLIDATE);
592 
593  TrackPanel::Get( project ).RefreshTrack(wt);
594 }
595 
596 }
597 
598 namespace TrackActions {
599 
600 // Menu handler functions
601 
603 
604 void OnNewWaveTrack(const CommandContext &context)
605 {
606  auto &project = context.project;
607  const auto &settings = ProjectSettings::Get( project );
608  auto &tracks = TrackList::Get( project );
609  auto &trackFactory = WaveTrackFactory::Get( project );
610  auto &window = ProjectWindow::Get( project );
611 
612  auto defaultFormat = QualitySettings::SampleFormatChoice();
613 
614  auto rate = settings.GetRate();
615 
616  auto t = tracks.Add( trackFactory.NewWaveTrack( defaultFormat, rate ) );
617  SelectUtilities::SelectNone( project );
618 
619  t->SetSelected(true);
620 
621  ProjectHistory::Get( project )
622  .PushState(XO("Created new audio track"), XO("New Track"));
623 
624  TrackFocus::Get(project).Set(t);
625  t->EnsureVisible();
626 }
627 
628 void OnNewStereoTrack(const CommandContext &context)
629 {
630  auto &project = context.project;
631  const auto &settings = ProjectSettings::Get( project );
632  auto &tracks = TrackList::Get( project );
633  auto &trackFactory = WaveTrackFactory::Get( project );
634  auto &window = ProjectWindow::Get( project );
635 
636  auto defaultFormat = QualitySettings::SampleFormatChoice();
637  auto rate = settings.GetRate();
638 
639  SelectUtilities::SelectNone( project );
640 
641  auto left = tracks.Add( trackFactory.NewWaveTrack( defaultFormat, rate ) );
642  left->SetSelected(true);
643 
644  auto right = tracks.Add( trackFactory.NewWaveTrack( defaultFormat, rate ) );
645  right->SetSelected(true);
646 
647  tracks.GroupChannels(*left, 2);
648 
649  ProjectHistory::Get( project )
650  .PushState(XO("Created new stereo audio track"), XO("New Track"));
651 
652  TrackFocus::Get(project).Set(left);
653  left->EnsureVisible();
654 }
655 
656 void OnNewLabelTrack(const CommandContext &context)
657 {
658  auto &project = context.project;
659  auto &tracks = TrackList::Get( project );
660  auto &trackFactory = WaveTrackFactory::Get( project );
661  auto &window = ProjectWindow::Get( project );
662 
663  auto t = tracks.Add( std::make_shared<LabelTrack>() );
664 
665  SelectUtilities::SelectNone( project );
666 
667  t->SetSelected(true);
668 
669  ProjectHistory::Get( project )
670  .PushState(XO("Created new label track"), XO("New Track"));
671 
672  TrackFocus::Get(project).Set(t);
673  t->EnsureVisible();
674 }
675 
676 void OnNewTimeTrack(const CommandContext &context)
677 {
678  auto &project = context.project;
679  auto &tracks = TrackList::Get( project );
680  auto &viewInfo = ViewInfo::Get( project );
681  auto &window = ProjectWindow::Get( project );
682 
683  if ( *tracks.Any<TimeTrack>().begin() ) {
685  XO(
686 "This version of Audacity only allows one time track for each project window.") );
687  return;
688  }
689 
690  auto t = tracks.AddToHead( std::make_shared<TimeTrack>(&viewInfo) );
691 
692  SelectUtilities::SelectNone( project );
693 
694  t->SetSelected(true);
695 
696  ProjectHistory::Get( project )
697  .PushState(XO("Created new time track"), XO("New Track"));
698 
699  TrackFocus::Get(project).Set(t);
700  t->EnsureVisible();
701 }
702 
703 void OnStereoToMono(const CommandContext &context)
704 {
706  EffectManager::Get().GetEffectByIdentifier(wxT("StereoToMono")),
707  context,
709 }
710 
711 void OnMixAndRender(const CommandContext &context)
712 {
713  auto &project = context.project;
714  DoMixAndRender(project, false);
715 }
716 
718 {
719  auto &project = context.project;
720  DoMixAndRender(project, true);
721 }
722 
723 void OnResample(const CommandContext &context)
724 {
725  auto &project = context.project;
726  const auto &settings = ProjectSettings::Get( project );
727  auto projectRate = settings.GetRate();
728  auto &tracks = TrackList::Get( project );
729  auto &undoManager = UndoManager::Get( project );
730  auto &window = ProjectWindow::Get( project );
731 
732  int newRate;
733 
734  while (true)
735  {
736  wxDialogWrapper dlg(&window, wxID_ANY, XO("Resample"));
737  ShuttleGui S(&dlg, eIsCreating);
738  wxString rate;
739  wxComboBox *cb;
740 
741  rate.Printf(wxT("%ld"), lrint(projectRate));
742 
743  wxArrayStringEx rates{
744  wxT("8000") ,
745  wxT("11025") ,
746  wxT("16000") ,
747  wxT("22050") ,
748  wxT("32000") ,
749  wxT("44100") ,
750  wxT("48000") ,
751  wxT("88200") ,
752  wxT("96000") ,
753  wxT("176400") ,
754  wxT("192000") ,
755  wxT("352800") ,
756  wxT("384000") ,
757  };
758 
759  S.StartVerticalLay(true);
760  {
761  S.AddSpace(-1, 15);
762 
763  S.StartHorizontalLay(wxCENTER, false);
764  {
765  cb = S.AddCombo(XXO("New sample rate (Hz):"),
766  rate,
767  rates);
768  }
769  S.EndHorizontalLay();
770 
771  S.AddSpace(-1, 15);
772 
773  S.AddStandardButtons();
774  }
775  S.EndVerticalLay();
776 
777  dlg.Layout();
778  dlg.Fit();
779  dlg.Center();
780 
781  if (dlg.ShowModal() != wxID_OK)
782  {
783  return; // user cancelled dialog
784  }
785 
786  long lrate;
787  if (cb->GetValue().ToLong(&lrate) && lrate >= 1 && lrate <= 1000000)
788  {
789  newRate = (int)lrate;
790  break;
791  }
792 
794  XO("The entered value is invalid"),
795  XO("Error"),
796  wxICON_ERROR,
797  &window);
798  }
799 
800  int ndx = 0;
801  auto flags = UndoPush::NONE;
802  for (auto wt : tracks.Selected< WaveTrack >())
803  {
804  auto msg = XO("Resampling track %d").Format( ++ndx );
805 
806  ProgressDialog progress(XO("Resample"), msg);
807 
808  // The resampling of a track may be stopped by the user. This might
809  // leave a track with multiple clips in a partially resampled state.
810  // But the thrown exception will cause rollback in the application
811  // level handler.
812 
813  wt->Resample(newRate, &progress);
814 
815  // Each time a track is successfully, completely resampled,
816  // commit that to the undo stack. The second and later times,
817  // consolidate.
818 
819  ProjectHistory::Get( project ).PushState(
820  XO("Resampled audio track(s)"), XO("Resample Track"), flags);
821  flags = flags | UndoPush::CONSOLIDATE;
822  }
823 
824  undoManager.StopConsolidating();
825 
826  // Need to reset
827  window.FinishAutoScroll();
828 }
829 
830 void OnRemoveTracks(const CommandContext &context)
831 {
833 }
834 
835 static void MuteTracks(const CommandContext &context, bool mute, bool selected)
836 {
837  auto &project = context.project;
838  const auto &settings = ProjectSettings::Get( project );
839  auto &tracks = TrackList::Get( project );
840  auto &window = ProjectWindow::Get( project );
841 
842  auto soloSimple = settings.IsSoloSimple();
843  auto soloNone = settings.IsSoloNone();
844 
845  auto iter = selected ? tracks.Selected<PlayableTrack>() : tracks.Any<PlayableTrack>();
846  for (auto pt : iter)
847  {
848  pt->SetMute(mute);
849  if (soloSimple || soloNone)
850  pt->SetSolo(false);
851  }
852 
853  ProjectHistory::Get( project ).ModifyState(true);
854 }
855 
856 void OnMuteAllTracks(const CommandContext &context)
857 {
858  MuteTracks(context, true, false);
859 }
860 
861 void OnUnmuteAllTracks(const CommandContext &context)
862 {
863  MuteTracks(context, false, false);
864 }
865 
867 {
868  MuteTracks(context, true, true);
869 }
870 
872 {
873  MuteTracks(context, false, true);
874 }
875 
876 void OnPanLeft(const CommandContext &context)
877 {
878  auto &project = context.project;
879  DoPanTracks( project, -1.0);
880 }
881 
882 void OnPanRight(const CommandContext &context)
883 {
884  auto &project = context.project;
885  DoPanTracks( project, 1.0);
886 }
887 
888 void OnPanCenter(const CommandContext &context)
889 {
890  auto &project = context.project;
891  DoPanTracks( project, 0.0);
892 }
893 
894 void OnAlignNoSync(const CommandContext &context)
895 {
896  auto &project = context.project;
897 
898  DoAlign(project,
899  context.index + kAlignLabelsCount(), false);
900 }
901 
902 void OnAlign(const CommandContext &context)
903 {
904  auto &project = context.project;
905 
906  bool bMoveWith;
907  gPrefs->Read(wxT("/GUI/MoveSelectionWithTracks"), &bMoveWith, false);
908  DoAlign(project, context.index, bMoveWith);
909 }
910 
911 /*
912 // Now handled in OnAlign.
913 void OnAlignMoveSel(int index)
914 {
915  DoAlign(index, true);
916 }
917 */
918 
919 void OnMoveSelectionWithTracks(const CommandContext &WXUNUSED(context) )
920 {
921  bool bMoveWith;
922  gPrefs->Read(wxT("/GUI/MoveSelectionWithTracks"), &bMoveWith, false);
923  gPrefs->Write(wxT("/GUI/MoveSelectionWithTracks"), !bMoveWith);
924  gPrefs->Flush();
925 
926 }
927 
928 #ifdef EXPERIMENTAL_SCOREALIGN
929 void OnScoreAlign(const CommandContext &context)
930 {
931  auto &project = context.project;
932  auto &tracks = TrackList::Get( project );
933  const auto rate = ProjectSettings::Get( project ).GetRate();
934 
935  int numWaveTracksSelected = 0;
936  int numNoteTracksSelected = 0;
937  int numOtherTracksSelected = 0;
938  double endTime = 0.0;
939 
940  // Iterate through once to make sure that there is exactly
941  // one WaveTrack and one NoteTrack selected.
942  tracks.Selected().Visit(
943  [&](WaveTrack *wt) {
944  numWaveTracksSelected++;
945  endTime = endTime > wt->GetEndTime() ? endTime : wt->GetEndTime();
946  },
947  [&](NoteTrack *) {
948  numNoteTracksSelected++;
949  },
950  [&](Track*) {
951  numOtherTracksSelected++;
952  }
953  );
954 
955  if(numWaveTracksSelected == 0 ||
956  numNoteTracksSelected != 1 ||
957  numOtherTracksSelected != 0){
959  XO("Please select at least one audio track and one MIDI track.") );
960  return;
961  }
962 
963  // Creating the dialog also stores dialog into gScoreAlignDialog so
964  // that it can be deleted by CloseScoreAlignDialog() either here or
965  // if the program is quit by the user while the dialog is up.
966  ScoreAlignParams params;
967 
968  // safe because the class maintains a global resource pointer
970 
971  CloseScoreAlignDialog();
972 
973  if (params.mStatus != wxID_OK) return;
974 
975  // We're going to do it.
976  //pushing the state before the change is wrong (I think)
977  //PushState(XO("Sync MIDI with Audio"), XO("Sync MIDI with Audio"));
978  // Make a copy of the note track in case alignment is canceled or fails
979  auto holder = nt->Duplicate();
980  auto alignedNoteTrack = static_cast<NoteTrack*>(holder.get());
981  // Remove offset from NoteTrack because audio is
982  // mixed starting at zero and incorporating clip offsets.
983  if (alignedNoteTrack->GetOffset() < 0) {
984  // remove the negative offset data before alignment
985  nt->Clear(alignedNoteTrack->GetOffset(), 0);
986  } else if (alignedNoteTrack->GetOffset() > 0) {
987  alignedNoteTrack->Shift(alignedNoteTrack->GetOffset());
988  }
989  alignedNoteTrack->SetOffset(0);
990 
991  WaveTrackConstArray waveTracks =
992  tracks->GetWaveTrackConstArray(true /* selectionOnly */);
993 
994  int result;
995  {
996  Mixer mix(
997  waveTracks, // const WaveTrackConstArray &inputTracks
998  false, // mayThrow -- is this right?
999  Mixer::WarpOptions{ *tracks },
1000  0.0, // double startTime
1001  endTime, // double stopTime
1002  2, // int numOutChannels
1003  44100u, // size_t outBufferSize
1004  true, // bool outInterleaved
1005  rate, // double outRate
1006  floatSample, // sampleFormat outFormat
1007  true, // bool highQuality = true
1008  NULL); // MixerSpec *mixerSpec = NULL
1009 
1010  ASAProgress progress;
1011 
1012  // There's a lot of adjusting made to incorporate the note track offset into
1013  // the note track while preserving the position of notes within beats and
1014  // measures. For debugging, you can see just the pre-scorealign note track
1015  // manipulation by setting SKIP_ACTUAL_SCORE_ALIGNMENT. You could then, for
1016  // example, save the modified note track in ".gro" form to read the details.
1017  //#define SKIP_ACTUAL_SCORE_ALIGNMENT 1
1018 #ifndef SKIP_ACTUAL_SCORE_ALIGNMENT
1019  result = scorealign((void *) &mix, &mixer_process,
1020  2 /* channels */, 44100.0 /* srate */, endTime,
1021  &alignedNoteTrack->GetSeq(), &progress, params);
1022 #else
1023  result = SA_SUCCESS;
1024 #endif
1025  }
1026 
1027  if (result == SA_SUCCESS) {
1028  tracks->Replace(nt, holder);
1030  XO("Alignment completed: MIDI from %.2f to %.2f secs, Audio from %.2f to %.2f secs.")
1031  .Format(
1032  params.mMidiStart, params.mMidiEnd,
1033  params.mAudioStart, params.mAudioEnd) );
1034  ProjectHistory::Get( project )
1035  .PushState(XO("Sync MIDI with Audio"), XO("Sync MIDI with Audio"));
1036  } else if (result == SA_TOOSHORT) {
1038  XO(
1039 "Alignment error: input too short: MIDI from %.2f to %.2f secs, Audio from %.2f to %.2f secs.")
1040  .Format(
1041  params.mMidiStart, params.mMidiEnd,
1042  params.mAudioStart, params.mAudioEnd) );
1043  } else if (result == SA_CANCEL) {
1044  // wrong way to recover...
1045  //project.OnUndo(); // recover any changes to note track
1046  return; // no message when user cancels alignment
1047  } else {
1048  //project.OnUndo(); // recover any changes to note track
1049  AudacityMessageBox( XO("Internal error reported by alignment process.") );
1050  }
1051 }
1052 #endif /* EXPERIMENTAL_SCOREALIGN */
1053 
1054 void OnSortTime(const CommandContext &context)
1055 {
1056  auto &project = context.project;
1058 
1059  ProjectHistory::Get( project )
1060  .PushState(XO("Tracks sorted by time"), XO("Sort by Time"));
1061 }
1062 
1063 void OnSortName(const CommandContext &context)
1064 {
1065  auto &project = context.project;
1067 
1068  ProjectHistory::Get( project )
1069  .PushState(XO("Tracks sorted by name"), XO("Sort by Name"));
1070 }
1071 
1072 void OnSyncLock(const CommandContext &context)
1073 {
1074  auto &project = context.project;
1075  auto &trackPanel = TrackPanel::Get( project );
1076 
1077  bool bSyncLockTracks;
1078  gPrefs->Read(wxT("/GUI/SyncLockTracks"), &bSyncLockTracks, false);
1079  gPrefs->Write(wxT("/GUI/SyncLockTracks"), !bSyncLockTracks);
1080  gPrefs->Flush();
1081 
1082  // Toolbar, project sync-lock handled within
1084 
1085  trackPanel.Refresh(false);
1086 }
1087 
1090 void OnTrackPan(const CommandContext &context)
1091 {
1092  auto &project = context.project;
1093  auto &trackPanel = TrackPanel::Get( project );
1094 
1095  const auto track = TrackFocus::Get( project ).Get();
1096  if (track) track->TypeSwitch( [&](WaveTrack *wt) {
1097  LWSlider *slider = WaveTrackControls::PanSlider( trackPanel, *wt );
1098  if (slider->ShowDialog())
1099  SetTrackPan(project, wt, slider);
1100  });
1101 }
1102 
1103 void OnTrackPanLeft(const CommandContext &context)
1104 {
1105  auto &project = context.project;
1106  auto &trackPanel = TrackPanel::Get( project );
1107 
1108  const auto track = TrackFocus::Get( project ).Get();
1109  if (track) track->TypeSwitch( [&](WaveTrack *wt) {
1110  LWSlider *slider = WaveTrackControls::PanSlider( trackPanel, *wt );
1111  slider->Decrease(1);
1112  SetTrackPan(project, wt, slider);
1113  });
1114 }
1115 
1116 void OnTrackPanRight(const CommandContext &context)
1117 {
1118  auto &project = context.project;
1119  auto &trackPanel = TrackPanel::Get( project );
1120 
1121  const auto track = TrackFocus::Get( project ).Get();
1122  if (track) track->TypeSwitch( [&](WaveTrack *wt) {
1123  LWSlider *slider = WaveTrackControls::PanSlider( trackPanel, *wt );
1124  slider->Increase(1);
1125  SetTrackPan(project, wt, slider);
1126  });
1127 }
1128 
1129 void OnTrackGain(const CommandContext &context)
1130 {
1131  auto &project = context.project;
1132  auto &trackPanel = TrackPanel::Get( project );
1133 
1135  const auto track = TrackFocus::Get( project ).Get();
1136  if (track) track->TypeSwitch( [&](WaveTrack *wt) {
1137  LWSlider *slider = WaveTrackControls::GainSlider( trackPanel, *wt );
1138  if (slider->ShowDialog())
1139  SetTrackGain(project, wt, slider);
1140  });
1141 }
1142 
1143 void OnTrackGainInc(const CommandContext &context)
1144 {
1145  auto &project = context.project;
1146  auto &trackPanel = TrackPanel::Get( project );
1147 
1148  const auto track = TrackFocus::Get( project ).Get();
1149  if (track) track->TypeSwitch( [&](WaveTrack *wt) {
1150  LWSlider *slider = WaveTrackControls::GainSlider( trackPanel, *wt );
1151  slider->Increase(1);
1152  SetTrackGain(project, wt, slider);
1153  });
1154 }
1155 
1156 void OnTrackGainDec(const CommandContext &context)
1157 {
1158  auto &project = context.project;
1159  auto &trackPanel = TrackPanel::Get( project );
1160 
1161  const auto track = TrackFocus::Get( project ).Get();
1162  if (track) track->TypeSwitch( [&](WaveTrack *wt) {
1163  LWSlider *slider = WaveTrackControls::GainSlider( trackPanel, *wt );
1164  slider->Decrease(1);
1165  SetTrackGain(project, wt, slider);
1166  });
1167 }
1168 
1169 void OnTrackMenu(const CommandContext &context)
1170 {
1171  auto &project = context.project;
1172  auto &trackPanel = TrackPanel::Get( project );
1173 
1174  trackPanel.OnTrackMenu();
1175 }
1176 
1177 void OnTrackMute(const CommandContext &context)
1178 {
1179  auto &project = context.project;
1180 
1181  const auto track = TrackFocus::Get( project ).Get();
1182  if (track) track->TypeSwitch( [&](PlayableTrack *t) {
1183  TrackUtilities::DoTrackMute(project, t, false);
1184  });
1185 }
1186 
1187 void OnTrackSolo(const CommandContext &context)
1188 {
1189  auto &project = context.project;
1190 
1191  const auto track = TrackFocus::Get( project ).Get();
1192  if (track) track->TypeSwitch( [&](PlayableTrack *t) {
1193  TrackUtilities::DoTrackSolo(project, t, false);
1194  });
1195 }
1196 
1197 void OnTrackClose(const CommandContext &context)
1198 {
1199  auto &project = context.project;
1200  auto &trackPanel = TrackPanel::Get( project );
1201 
1202  const auto t = TrackFocus::Get( project ).Get();
1203  if (!t)
1204  return;
1205 
1206  auto isAudioActive = ProjectAudioIO::Get( project ).IsAudioActive();
1207 
1208  if (isAudioActive)
1209  {
1210  ProjectStatus::Get( project ).Set(
1211  XO("Can't delete track with active audio"));
1212  wxBell();
1213  return;
1214  }
1215 
1216  TrackUtilities::DoRemoveTrack(project, t);
1217 
1218  trackPanel.UpdateViewIfNoTracks();
1219  trackPanel.Refresh(false);
1220 }
1221 
1222 void OnTrackMoveUp(const CommandContext &context)
1223 {
1224  auto &project = context.project;
1225  auto &trackPanel = TrackPanel::Get( project );
1226  auto &tracks = TrackList::Get( project );
1227 
1228  const auto focusedTrack = TrackFocus::Get( project ).Get();
1229  if (tracks.CanMoveUp(focusedTrack)) {
1230  DoMoveTrack(project, focusedTrack, TrackUtilities::OnMoveUpID);
1231  trackPanel.Refresh(false);
1232  }
1233 }
1234 
1235 void OnTrackMoveDown(const CommandContext &context)
1236 {
1237  auto &project = context.project;
1238  auto &trackPanel = TrackPanel::Get( project );
1239  auto &tracks = TrackList::Get( project );
1240 
1241  const auto focusedTrack = TrackFocus::Get( project ).Get();
1242  if (tracks.CanMoveDown(focusedTrack)) {
1243  DoMoveTrack(project, focusedTrack, TrackUtilities::OnMoveDownID);
1244  trackPanel.Refresh(false);
1245  }
1246 }
1247 
1248 void OnTrackMoveTop(const CommandContext &context)
1249 {
1250  auto &project = context.project;
1251  auto &trackPanel = TrackPanel::Get( project );
1252  auto &tracks = TrackList::Get( project );
1253 
1254  const auto focusedTrack = TrackFocus::Get( project ).Get();
1255  if (tracks.CanMoveUp(focusedTrack)) {
1256  DoMoveTrack(project, focusedTrack, TrackUtilities::OnMoveTopID);
1257  trackPanel.Refresh(false);
1258  }
1259 }
1260 
1261 void OnTrackMoveBottom(const CommandContext &context)
1262 {
1263  auto &project = context.project;
1264  auto &trackPanel = TrackPanel::Get( project );
1265  auto &tracks = TrackList::Get( project );
1266 
1267  const auto focusedTrack = TrackFocus::Get( project ).Get();
1268  if (tracks.CanMoveDown(focusedTrack)) {
1269  DoMoveTrack(project, focusedTrack, TrackUtilities::OnMoveBottomID);
1270  trackPanel.Refresh(false);
1271  }
1272 }
1273 
1274 }; // struct Handler
1275 
1276 } // namespace
1277 
1279  // Handler is not stateful. Doesn't need a factory registered with
1280  // AudacityProject.
1281  static TrackActions::Handler instance;
1282  return instance;
1283 };
1284 
1285 // Menu definitions
1286 
1287 #define FN(X) (& TrackActions::Handler :: X)
1288 
1289 // Under /MenuBar
1290 namespace {
1291 using namespace MenuTable;
1293 {
1294  // Tracks Menu (formerly Project Menu)
1296 
1297  static BaseItemSharedPtr menu{
1299  Menu( wxT("Tracks"), XXO("&Tracks"),
1300  Section( "Add",
1301  Menu( wxT("Add"), XXO("Add &New"),
1302  Command( wxT("NewMonoTrack"), XXO("&Mono Track"), FN(OnNewWaveTrack),
1303  AudioIONotBusyFlag(), wxT("Ctrl+Shift+N") ),
1304  Command( wxT("NewStereoTrack"), XXO("&Stereo Track"),
1305  FN(OnNewStereoTrack), AudioIONotBusyFlag() ),
1306  Command( wxT("NewLabelTrack"), XXO("&Label Track"),
1307  FN(OnNewLabelTrack), AudioIONotBusyFlag() ),
1308  Command( wxT("NewTimeTrack"), XXO("&Time Track"),
1309  FN(OnNewTimeTrack), AudioIONotBusyFlag() )
1310  )
1311  ),
1312 
1314 
1315  Section( "",
1316  Menu( wxT("Mix"), XXO("Mi&x"),
1317  // Delayed evaluation
1318  // Stereo to Mono is an oddball command that is also subject to control
1319  // by the plug-in manager, as if an effect. Decide whether to show or
1320  // hide it.
1321  [](AudacityProject&) -> BaseItemPtr {
1322  const PluginID ID =
1323  EffectManager::Get().GetEffectByIdentifier(wxT("StereoToMono"));
1324  const PluginDescriptor *plug = PluginManager::Get().GetPlugin(ID);
1325  if (plug && plug->IsEnabled())
1326  return Command( wxT("Stereo to Mono"),
1327  XXO("Mix Stereo Down to &Mono"), FN(OnStereoToMono),
1330  else
1331  return {};
1332  },
1333  Command( wxT("MixAndRender"), XXO("Mi&x and Render"),
1334  FN(OnMixAndRender),
1336  Command( wxT("MixAndRenderToNewTrack"),
1337  XXO("Mix and Render to Ne&w Track"),
1338  FN(OnMixAndRenderToNewTrack),
1339  AudioIONotBusyFlag() | WaveTracksSelectedFlag(), wxT("Ctrl+Shift+M") )
1340  ),
1341 
1342  Command( wxT("Resample"), XXO("&Resample..."), FN(OnResample),
1344  ),
1345 
1346  Section( "",
1347  Command( wxT("RemoveTracks"), XXO("Remo&ve Tracks"), FN(OnRemoveTracks),
1349  ),
1350 
1351  Section( "",
1352  Menu( wxT("Mute"), XXO("M&ute/Unmute"),
1353  Command( wxT("MuteAllTracks"), XXO("&Mute All Tracks"),
1354  FN(OnMuteAllTracks), TracksExistFlag(), wxT("Ctrl+U") ),
1355  Command( wxT("UnmuteAllTracks"), XXO("&Unmute All Tracks"),
1356  FN(OnUnmuteAllTracks), TracksExistFlag(), wxT("Ctrl+Shift+U") ),
1357  Command( wxT("MuteTracks"), XXO("Mut&e Tracks"),
1358  FN(OnMuteSelectedTracks), EditableTracksSelectedFlag(), wxT("Ctrl+Alt+U") ),
1359  Command( wxT("UnmuteTracks"), XXO("U&nmute Tracks"),
1360  FN(OnUnmuteSelectedTracks), EditableTracksSelectedFlag(), wxT("Ctrl+Alt+Shift+U") )
1361  ),
1362 
1363  Menu( wxT("Pan"), XXO("&Pan"),
1364  // As Pan changes are not saved on Undo stack,
1365  // pan settings for all tracks
1366  // in the project could very easily be lost unless we
1367  // require the tracks to be selected.
1368  Command( wxT("PanLeft"), XXO("&Left"), FN(OnPanLeft),
1370  Options{}.LongName( XO("Pan Left") ) ),
1371  Command( wxT("PanRight"), XXO("&Right"), FN(OnPanRight),
1373  Options{}.LongName( XO("Pan Right") ) ),
1374  Command( wxT("PanCenter"), XXO("&Center"), FN(OnPanCenter),
1376  Options{}.LongName( XO("Pan Center") ) )
1377  )
1378  ),
1379 
1380  Section( "",
1381  Menu( wxT("Align"), XXO("&Align Tracks"), // XO("Just Move Tracks"),
1382  Section( "",
1383  // Mutual alignment of tracks independent of selection or zero
1384  CommandGroup(wxT("Align"),
1385  {
1386  { wxT("EndToEnd"), XXO("&Align End to End") },
1387  { wxT("Together"), XXO("Align &Together") },
1388  },
1389  FN(OnAlignNoSync), AudioIONotBusyFlag() | EditableTracksSelectedFlag())
1390  ),
1391 
1392  Section( "",
1393  // Alignment commands using selection or zero
1394  CommandGroup(wxT("Align"),
1395  alignLabels(),
1397  ),
1398 
1399  Section( "",
1400  Command( wxT("MoveSelectionWithTracks"),
1401  XXO("&Move Selection with Tracks (on/off)"),
1402  FN(OnMoveSelectionWithTracks),
1404  Options{}.CheckTest( wxT("/GUI/MoveSelectionWithTracks"), false ) )
1405  )
1406  ),
1407 
1408  #if 0
1409  // TODO: Can these labels be made clearer?
1410  // Do we need this sub-menu at all?
1411  Menu( wxT("MoveSelectionAndTracks"), XO("Move Sele&ction and Tracks"), {
1412  CommandGroup(wxT("AlignMove"), alignLabels(),
1413  FN(OnAlignMoveSel), AudioIONotBusyFlag() | EditableTracksSelectedFlag()),
1414  } ),
1415  #endif
1416 
1418 
1419  #ifdef EXPERIMENTAL_SCOREALIGN
1420  Command( wxT("ScoreAlign"), XXO("Synchronize MIDI with Audio"),
1421  FN(OnScoreAlign),
1423  #endif // EXPERIMENTAL_SCOREALIGN
1424 
1426 
1427  Menu( wxT("Sort"), XXO("S&ort Tracks"),
1428  Command( wxT("SortByTime"), XXO("By &Start Time"), FN(OnSortTime),
1429  TracksExistFlag(),
1430  Options{}.LongName( XO("Sort by Time") ) ),
1431  Command( wxT("SortByName"), XXO("By &Name"), FN(OnSortName),
1432  TracksExistFlag(),
1433  Options{}.LongName( XO("Sort by Name") ) )
1434  )
1435 
1437  )
1438 
1439 #ifdef EXPERIMENTAL_SYNC_LOCK
1440  ,
1441 
1442  Section( "",
1443  Command( wxT("SyncLock"), XXO("Sync-&Lock Tracks (on/off)"),
1444  FN(OnSyncLock), AlwaysEnabledFlag,
1445  Options{}.CheckTest( wxT("/GUI/SyncLockTracks"), false ) )
1446  )
1447 
1448 #endif
1449 
1450  ) ) };
1451  return menu;
1452 }
1453 
1455  wxT(""),
1456  Shared( TracksMenu() )
1457 };
1458 
1460 {
1462  static BaseItemSharedPtr menu{
1464  Menu( wxT("Track"), XXO("&Track"),
1465  Command( wxT("TrackPan"), XXO("Change P&an on Focused Track..."),
1466  FN(OnTrackPan),
1467  TrackPanelHasFocus() | TracksExistFlag(), wxT("Shift+P") ),
1468  Command( wxT("TrackPanLeft"), XXO("Pan &Left on Focused Track"),
1469  FN(OnTrackPanLeft),
1470  TrackPanelHasFocus() | TracksExistFlag(), wxT("Alt+Shift+Left") ),
1471  Command( wxT("TrackPanRight"), XXO("Pan &Right on Focused Track"),
1472  FN(OnTrackPanRight),
1473  TrackPanelHasFocus() | TracksExistFlag(), wxT("Alt+Shift+Right") ),
1474  Command( wxT("TrackGain"), XXO("Change Gai&n on Focused Track..."),
1475  FN(OnTrackGain),
1476  TrackPanelHasFocus() | TracksExistFlag(), wxT("Shift+G") ),
1477  Command( wxT("TrackGainInc"), XXO("&Increase Gain on Focused Track"),
1478  FN(OnTrackGainInc),
1479  TrackPanelHasFocus() | TracksExistFlag(), wxT("Alt+Shift+Up") ),
1480  Command( wxT("TrackGainDec"), XXO("&Decrease Gain on Focused Track"),
1481  FN(OnTrackGainDec),
1482  TrackPanelHasFocus() | TracksExistFlag(), wxT("Alt+Shift+Down") ),
1483  Command( wxT("TrackMenu"), XXO("Op&en Menu on Focused Track..."),
1484  FN(OnTrackMenu),
1486  Options{ wxT("Shift+M") }.SkipKeyDown() ),
1487  Command( wxT("TrackMute"), XXO("M&ute/Unmute Focused Track"),
1488  FN(OnTrackMute),
1489  TracksExistFlag() | TrackPanelHasFocus(), wxT("Shift+U") ),
1490  Command( wxT("TrackSolo"), XXO("&Solo/Unsolo Focused Track"),
1491  FN(OnTrackSolo),
1492  TracksExistFlag() | TrackPanelHasFocus(), wxT("Shift+S") ),
1493  Command( wxT("TrackClose"), XXO("&Close Focused Track"),
1494  FN(OnTrackClose),
1496  wxT("Shift+C") ),
1497  Command( wxT("TrackMoveUp"), XXO("Move Focused Track U&p"),
1498  FN(OnTrackMoveUp),
1500  Command( wxT("TrackMoveDown"), XXO("Move Focused Track Do&wn"),
1501  FN(OnTrackMoveDown),
1503  Command( wxT("TrackMoveTop"), XXO("Move Focused Track to T&op"),
1504  FN(OnTrackMoveTop),
1506  Command( wxT("TrackMoveBottom"), XXO("Move Focused Track to &Bottom"),
1507  FN(OnTrackMoveBottom),
1509  ) ) };
1510  return menu;
1511 }
1512 
1514  wxT("Optional/Extra/Part2"),
1515  Shared( ExtraTrackMenu() )
1516 };
1517 
1518 }
1519 
1520 #undef FN
anonymous_namespace{TrackMenus.cpp}::sAttachment1
AttachedItem sAttachment1
Definition: TrackMenus.cpp:1454
Optional::emplace
X & emplace(Args &&... args)
Definition: MemoryX.h:193
ProjectHistory::ModifyState
void ModifyState(bool bWantsAutoSave)
Definition: ProjectHistory.cpp:124
TranslatableString
Holds a msgid for the translation catalog; may also bind format arguments.
Definition: TranslatableString.h:32
ViewInfo::Get
static ViewInfo & Get(AudacityProject &project)
Definition: ViewInfo.cpp:156
TrackActions::Handler::OnMoveSelectionWithTracks
void OnMoveSelectionWithTracks(const CommandContext &WXUNUSED(context))
Definition: TrackMenus.cpp:919
WaveTrackConstArray
std::vector< std::shared_ptr< const WaveTrack > > WaveTrackConstArray
Definition: AudioIO.h:59
eIsCreating
@ eIsCreating
Definition: ShuttleGui.h:38
TrackActions::Handler::OnPanCenter
void OnPanCenter(const CommandContext &context)
Definition: TrackMenus.cpp:888
WaveTrackFactory::Get
static WaveTrackFactory & Get(AudacityProject &project)
Definition: WaveTrack.cpp:2799
Mixer::GetBuffer
samplePtr GetBuffer()
Retrieve the main buffer or the interleaved buffer.
Definition: Mix.cpp:716
ShuttleGuiBase::StartVerticalLay
void StartVerticalLay(int iProp=1)
Definition: ShuttleGui.cpp:1184
WaveTrack
A Track that contains audio waveform data.
Definition: WaveTrack.h:69
AudacityMessageBox
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption=XO("Message"), long style=wxOK|wxCENTRE, wxWindow *parent=NULL, int x=wxDefaultCoord, int y=wxDefaultCoord)
Definition: AudacityMessageBox.h:20
BasicUI::ProgressResult::Success
@ Success
Optional
Like a smart pointer, allows for object to not exist (nullptr)
Definition: MemoryX.h:144
TrackActions::Handler::OnSortTime
void OnSortTime(const CommandContext &context)
Definition: TrackMenus.cpp:1054
MenuTable::FinderScope
Definition: CommandManager.h:472
anonymous_namespace{TrackMenus.cpp}::kAudacitySortByTime
@ kAudacitySortByTime
Definition: TrackMenus.cpp:487
gPrefs
FileConfig * gPrefs
Definition: Prefs.cpp:70
ClientData::Site::Find
Subclass * Find(const RegisteredFactory &key)
Get a (bare) pointer to an attachment, or null, down-cast it to Subclass *; will not create on demand...
Definition: ClientData.h:333
Track::GetEndTime
virtual double GetEndTime() const =0
WaveTrack::GetEndTime
double GetEndTime() const override
Get the time at which the last clip in the track ends, plus recorded stuff.
Definition: WaveTrack.cpp:1800
TrackActions::Handler::OnStereoToMono
void OnStereoToMono(const CommandContext &context)
Definition: TrackMenus.cpp:703
Track::GetName
wxString GetName() const
Definition: Track.h:410
Track::EnsureVisible
void EnsureVisible(bool modifyState=false)
Definition: Track.cpp:101
TrackActions::Handler::OnTrackPanLeft
void OnTrackPanLeft(const CommandContext &context)
Definition: TrackMenus.cpp:1103
anonymous_namespace{TrackMenus.cpp}::alignLabels
static const std::vector< ComponentInterfaceSymbol > & alignLabels()
Definition: TrackMenus.cpp:189
TrackActions::Handler::OnMuteAllTracks
void OnMuteAllTracks(const CommandContext &context)
Definition: TrackMenus.cpp:856
ClientData::Site::Get
Subclass & Get(const RegisteredFactory &key)
Get reference to an attachment, creating on demand if not present, down-cast it to Subclass.
Definition: ClientData.h:309
AudioIONotBusyFlag
const ReservedCommandFlag & AudioIONotBusyFlag()
Definition: CommonCommandFlags.cpp:127
Mixer::WarpOptions
Definition: Mix.h:85
anonymous_namespace{TrackMenus.cpp}::kAlignLabelsCount
const size_t kAlignLabelsCount()
Definition: TrackMenus.cpp:197
TrackActions::Handler::OnUnmuteSelectedTracks
void OnUnmuteSelectedTracks(const CommandContext &context)
Definition: TrackMenus.cpp:871
TrackList::Channels
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
Definition: Track.h:1468
Format
Abstract base class used in importing a file.
TrackActions::Handler::OnPanLeft
void OnPanLeft(const CommandContext &context)
Definition: TrackMenus.cpp:876
TrackActions::Handler::OnResample
void OnResample(const CommandContext &context)
Definition: TrackMenus.cpp:723
ScoreAlignDialog
ScoreAlignDialog is \TODO.
EffectManager::kConfigured
@ kConfigured
Definition: EffectManager.h:53
TrackActions::Handler::OnTrackMoveBottom
void OnTrackMoveBottom(const CommandContext &context)
Definition: TrackMenus.cpp:1261
Registry::Shared
std::unique_ptr< SharedItem > Shared(const BaseItemSharedPtr &ptr)
Definition: Registry.h:93
ShuttleGui::AddSpace
wxSizerItem * AddSpace(int width, int height, int prop=0)
Definition: ShuttleGui.cpp:2447
anonymous_namespace{TrackMenus.cpp}::DoPanTracks
void DoPanTracks(AudacityProject &project, float PanValue)
Definition: TrackMenus.cpp:156
TrackPanel::Get
static TrackPanel & Get(AudacityProject &project)
Definition: TrackPanel.cpp:221
UndoPush::NONE
@ NONE
XO
#define XO(s)
Definition: Internat.h:31
TrackActions::Handler::OnTrackMenu
void OnTrackMenu(const CommandContext &context)
Definition: TrackMenus.cpp:1169
LWSlider::Decrease
void Decrease(float steps)
Definition: ASlider.cpp:1504
ClientData::Site::size
size_t size() const
How many attachment pointers are in the Site.
Definition: ClientData.h:251
ProjectSettings::Get
static ProjectSettings & Get(AudacityProject &project)
Definition: ProjectSettings.cpp:40
TrackActions::Handler::OnNewLabelTrack
void OnNewLabelTrack(const CommandContext &context)
Definition: TrackMenus.cpp:656
LabelTrack
A LabelTrack is a Track that holds labels (LabelStruct).
Definition: LabelTrack.h:88
TrackUtilities::OnMoveDownID
@ OnMoveDownID
Definition: TrackUtilities.h:20
NoteTracksSelectedFlag
const ReservedCommandFlag & NoteTracksSelectedFlag()
Definition: CommonCommandFlags.cpp:299
TrackActions::Handler::OnUnmuteAllTracks
void OnUnmuteAllTracks(const CommandContext &context)
Definition: TrackMenus.cpp:861
Track::Any
bool Any() const
Definition: Track.cpp:361
ProjectWindow::Get
static ProjectWindow & Get(AudacityProject &project)
Definition: ProjectWindow.cpp:533
anonymous_namespace{TrackMenus.cpp}::kAlignStartSelEnd
@ kAlignStartSelEnd
Definition: TrackMenus.cpp:180
AlwaysEnabledFlag
constexpr CommandFlag AlwaysEnabledFlag
Definition: CommandFlag.h:35
TrackActions
Definition: TrackMenus.cpp:598
MenuTable::AttachedItem
Definition: CommandManager.h:695
EffectManager::Get
static EffectManager & Get()
Definition: EffectManager.cpp:42
MenuManager::ModifyAllProjectToolbarMenus
static void ModifyAllProjectToolbarMenus()
Definition: Menus.cpp:583
TrackActions::Handler::MuteTracks
static void MuteTracks(const CommandContext &context, bool mute, bool selected)
Definition: TrackMenus.cpp:835
ProjectAudioIO::Get
static ProjectAudioIO & Get(AudacityProject &project)
Definition: ProjectAudioIO.cpp:23
EditableTracksSelectedFlag
const ReservedCommandFlag & EditableTracksSelectedFlag()
Definition: CommonCommandFlags.cpp:180
TrackUtilities::DoTrackSolo
void DoTrackSolo(AudacityProject &project, Track *t, bool exclusive)
Definition: TrackUtilities.cpp:112
wxArrayStringEx
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.
Definition: wxArrayStringEx.h:18
WaveTracksSelectedFlag
const ReservedCommandFlag & WaveTracksSelectedFlag()
Definition: CommonCommandFlags.cpp:164
ProjectAudioIO::IsAudioActive
bool IsAudioActive() const
Definition: ProjectAudioIO.cpp:52
anonymous_namespace{TrackMenus.cpp}::DoSortTracks
void DoSortTracks(AudacityProject &project, int flags)
Definition: TrackMenus.cpp:491
anonymous_namespace{TrackMenus.cpp}::kAlignTogether
@ kAlignTogether
Definition: TrackMenus.cpp:185
TrackActions::Handler::OnAlignNoSync
void OnAlignNoSync(const CommandContext &context)
Definition: TrackMenus.cpp:894
TrackActions::Handler::OnNewTimeTrack
void OnNewTimeTrack(const CommandContext &context)
Definition: TrackMenus.cpp:676
TrackActions::Handler::OnTrackSolo
void OnTrackSolo(const CommandContext &context)
Definition: TrackMenus.cpp:1187
floatSample
@ floatSample
Definition: SampleFormat.h:34
TrackActions::Handler::OnTrackMoveDown
void OnTrackMoveDown(const CommandContext &context)
Definition: TrackMenus.cpp:1235
WaveTrack::Holder
std::shared_ptr< WaveTrack > Holder
Definition: WaveTrack.h:94
LWSlider::Get
float Get(bool convert=true)
Definition: ASlider.cpp:1456
Track::GetStartTime
virtual double GetStartTime() const =0
TrackActions::Handler::OnSortName
void OnSortName(const CommandContext &context)
Definition: TrackMenus.cpp:1063
TrackActions::Handler::OnTrackGainDec
void OnTrackGainDec(const CommandContext &context)
Definition: TrackMenus.cpp:1156
NoteTrack::Clear
void Clear(double t0, double t1) override
Definition: NoteTrack.cpp:527
TrackActions::Handler::OnMixAndRender
void OnMixAndRender(const CommandContext &context)
Definition: TrackMenus.cpp:711
ProjectStatus::Set
void Set(const TranslatableString &msg, StatusBarField field=mainStatusBarField)
Definition: ProjectStatus.cpp:65
ViewInfo::selectedRegion
NotifyingSelectedRegion selectedRegion
Definition: ViewInfo.h:200
XXO
#define XXO(s)
Definition: Internat.h:44
Registry::BaseItemPtr
std::unique_ptr< BaseItem > BaseItemPtr
Definition: Registry.h:71
anonymous_namespace{TrackMenus.cpp}::kAlignEndSelEnd
@ kAlignEndSelEnd
Definition: TrackMenus.cpp:182
ShuttleGuiBase::EndHorizontalLay
void EndHorizontalLay()
Definition: ShuttleGui.cpp:1177
ProgressDialog
ProgressDialog Class.
Definition: ProgressDialog.h:51
anonymous_namespace{TrackMenus.cpp}::kAlignEndToEnd
@ kAlignEndToEnd
Definition: TrackMenus.cpp:184
anonymous_namespace{TrackMenus.cpp}::sAttachment2
AttachedItem sAttachment2
Definition: TrackMenus.cpp:1513
CommandContext
CommandContext provides additional information to an 'Apply()' command. It provides the project,...
Definition: CommandContext.h:22
LWSlider
Lightweight version of ASlider. In other words it does not have a window permanently associated with ...
Definition: ASlider.h:62
ShuttleGuiBase::StartHorizontalLay
void StartHorizontalLay(int PositionFlags=wxALIGN_CENTRE, int iProp=1)
Definition: ShuttleGui.cpp:1167
MenuTable::CommandGroup
std::unique_ptr< CommandGroupItem > CommandGroup(const Identifier &name, std::vector< ComponentInterfaceSymbol > items, void(Handler::*pmf)(const CommandContext &), CommandFlag flags, bool isEffect=false, CommandHandlerFinder finder=FinderScope::DefaultFinder())
Definition: CommandManager.h:675
TrackActions::Handler::OnMixAndRenderToNewTrack
void OnMixAndRenderToNewTrack(const CommandContext &context)
Definition: TrackMenus.cpp:717
ShuttleGuiBase::EndVerticalLay
void EndVerticalLay()
Definition: ShuttleGui.cpp:1203
Registry::BaseItemSharedPtr
std::shared_ptr< BaseItem > BaseItemSharedPtr
Definition: Registry.h:72
PluginID
wxString PluginID
Definition: EffectManager.h:30
Track::GetOffset
virtual double GetOffset() const =0
AnyTracksSelectedFlag
const ReservedCommandFlag & AnyTracksSelectedFlag()
Definition: CommonCommandFlags.cpp:188
TrackNodePointer
std::pair< ListOfTracks::iterator, ListOfTracks * > TrackNodePointer
Pairs a std::list iterator and a pointer to a list, for comparison purposes.
Definition: Track.h:59
AudioTrack
Track subclass holding data representing sound (as notes, or samples, or ...)
Definition: Track.h:822
Track::IsSelected
bool IsSelected() const
Definition: Track.cpp:364
ProgressDialog::Update
ProgressResult Update(int value, const TranslatableString &message={})
Definition: ProgressDialog.cpp:1327
WaveTrackControls::GainSlider
static LWSlider * GainSlider(CellularPanel &panel, const WaveTrack &wt)
Definition: WaveTrackControls.cpp:1143
TrackUtilities::OnMoveTopID
@ OnMoveTopID
Definition: TrackUtilities.h:20
TrackActions::Handler::OnTrackClose
void OnTrackClose(const CommandContext &context)
Definition: TrackMenus.cpp:1197
anonymous_namespace{TrackMenus.cpp}::DoMixAndRender
void DoMixAndRender(AudacityProject &project, bool toNewTrack)
Definition: TrackMenus.cpp:49
TrackFocus::Get
Track * Get()
Definition: TrackPanelAx.cpp:755
TrackActions::Handler::OnAlign
void OnAlign(const CommandContext &context)
Definition: TrackMenus.cpp:902
PluginManager::GetPlugin
const PluginDescriptor * GetPlugin(const PluginID &ID) const
Definition: PluginManager.cpp:1445
PluginDescriptor
Definition: PluginManager.h:44
anonymous_namespace{TrackMenus.cpp}::SetTrackGain
void SetTrackGain(AudacityProject &project, WaveTrack *wt, LWSlider *slider)
Definition: TrackMenus.cpp:568
LWSlider::ShowDialog
bool ShowDialog()
Definition: ASlider.cpp:1068
anonymous_namespace{TrackMenus.cpp}::TracksMenu
BaseItemSharedPtr TracksMenu()
Definition: TrackMenus.cpp:1292
TracksExistFlag
const ReservedCommandFlag & TracksExistFlag()
Definition: CommonCommandFlags.cpp:173
PlayableTrack
AudioTrack subclass that can also be audibly replayed by the program.
Definition: Track.h:838
TrackUtilities::DoRemoveTracks
void DoRemoveTracks(AudacityProject &project)
Definition: TrackUtilities.cpp:22
TrackActions::Handler::OnTrackGainInc
void OnTrackGainInc(const CommandContext &context)
Definition: TrackMenus.cpp:1143
FN
#define FN(X)
Definition: TrackMenus.cpp:1287
anonymous_namespace{TrackMenus.cpp}::kAlignEndSelStart
@ kAlignEndSelStart
Definition: TrackMenus.cpp:181
anonymous_namespace{TrackMenus.cpp}::DoAlign
void DoAlign(AudacityProject &project, int index, bool moveSel)
Definition: TrackMenus.cpp:200
min
int min(int a, int b)
Definition: CompareAudioCommand.cpp:106
ProjectHistory::PushState
void PushState(const TranslatableString &desc, const TranslatableString &shortDesc)
Definition: ProjectHistory.cpp:90
wxDialogWrapper
Definition: wxPanelWrapper.h:81
PluginManager::Get
static PluginManager & Get()
Definition: PluginManager.cpp:695
StereoRequiredFlag
const ReservedCommandFlag & StereoRequiredFlag()
Definition: CommonCommandFlags.cpp:139
MixAndRender
void MixAndRender(TrackList *tracks, WaveTrackFactory *trackFactory, double rate, sampleFormat format, double startTime, double endTime, WaveTrack::Holder &uLeft, WaveTrack::Holder &uRight)
Mixes together all input tracks, applying any envelopes, amplitude gain, panning, and real-time effec...
Definition: Mix.cpp:43
TrackPanelHasFocus
const ReservedCommandFlag & TrackPanelHasFocus()
Definition: CommonCommandFlags.cpp:196
TrackUtilities::DoRemoveTrack
void DoRemoveTrack(AudacityProject &project, Track *toRemove)
Definition: TrackUtilities.cpp:163
FileConfig::Flush
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
Definition: FileConfig.cpp:143
TrackList::Get
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:495
PluginDescriptor::IsEnabled
bool IsEnabled() const
Definition: PluginManager.cpp:130
anonymous_namespace{TrackMenus.cpp}::SetTrackPan
void SetTrackPan(AudacityProject &project, WaveTrack *wt, LWSlider *slider)
Definition: TrackMenus.cpp:582
Track
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:239
Track::IsLeader
bool IsLeader() const
Definition: Track.cpp:370
TrackUtilities::DoTrackMute
void DoTrackMute(AudacityProject &project, Track *t, bool exclusive)
Definition: TrackUtilities.cpp:64
CommandContext::index
int index
Definition: CommandContext.h:55
UndoManager::Get
static UndoManager & Get(AudacityProject &project)
Definition: UndoManager.cpp:57
MenuTable::Command
std::unique_ptr< CommandItem > Command(const CommandID &name, const TranslatableString &label_in, void(Handler::*pmf)(const CommandContext &), CommandFlag flags, const CommandManager::Options &options={}, CommandHandlerFinder finder=FinderScope::DefaultFinder())
Definition: CommandManager.h:662
ProjectStatus::Get
static ProjectStatus & Get(AudacityProject &project)
Definition: ProjectStatus.cpp:23
QualitySettings::SampleFormatChoice
AUDACITY_DLL_API sampleFormat SampleFormatChoice()
Definition: QualitySettings.cpp:38
AudacityProject
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:113
TrackActions::Handler::OnTrackGain
void OnTrackGain(const CommandContext &context)
Definition: TrackMenus.cpp:1129
findCommandHandler
static CommandHandlerObject & findCommandHandler(AudacityProject &)
Definition: TrackMenus.cpp:1278
TrackActions::Handler::OnTrackPan
void OnTrackPan(const CommandContext &context)
Definition: TrackMenus.cpp:1090
ProjectSettings::GetRate
double GetRate() const
Definition: ProjectSettings.cpp:168
anonymous_namespace{TrackMenus.cpp}::kAlignStartZero
@ kAlignStartZero
Definition: TrackMenus.cpp:178
SelectUtilities::SelectNone
void SelectNone(AudacityProject &project)
Definition: SelectUtilities.cpp:72
TrackUtilities::OnMoveBottomID
@ OnMoveBottomID
Definition: TrackUtilities.h:20
WaveTrackControls::PanSlider
static LWSlider * PanSlider(CellularPanel &panel, const WaveTrack &wt)
Definition: WaveTrackControls.cpp:1199
CommandHandlerObject
wxEvtHandler CommandHandlerObject
Definition: CommandFunctors.h:28
MenuTable::Menu
std::unique_ptr< MenuItem > Menu(const Identifier &internalName, const TranslatableString &title, Args &&... args)
Definition: CommandManager.h:610
TrackUtilities::OnMoveUpID
@ OnMoveUpID
Definition: TrackUtilities.h:20
EffectManager::GetEffectByIdentifier
const PluginID & GetEffectByIdentifier(const CommandID &strTarget)
Definition: EffectManager.cpp:821
TrackActions::Handler::OnNewWaveTrack
void OnNewWaveTrack(const CommandContext &context)
Definition: TrackMenus.cpp:604
UndoPush::CONSOLIDATE
@ CONSOLIDATE
EffectUI::DoEffect
AUDACITY_DLL_API bool DoEffect(const PluginID &ID, const CommandContext &context, unsigned flags)
'Repeat Last Effect'.
Definition: EffectUI.cpp:1860
ShuttleGui::AddStandardButtons
void AddStandardButtons(long buttons=eOkButton|eCancelButton, wxWindow *extra=NULL)
Definition: ShuttleGui.cpp:2432
MenuTable::Section
std::unique_ptr< MenuPart > Section(const Identifier &internalName, Args &&... args)
Definition: CommandManager.h:598
Track::IsSelectedOrSyncLockSelected
bool IsSelectedOrSyncLockSelected() const
Definition: Track.cpp:367
TrackActions::Handler::OnTrackMoveTop
void OnTrackMoveTop(const CommandContext &context)
Definition: TrackMenus.cpp:1248
TrackActions::Handler::OnTrackMoveUp
void OnTrackMoveUp(const CommandContext &context)
Definition: TrackMenus.cpp:1222
TrackActions::Handler::OnTrackMute
void OnTrackMute(const CommandContext &context)
Definition: TrackMenus.cpp:1177
Prefs.h
params
EffectDistortion::Params params
Definition: Distortion.cpp:99
anonymous_namespace{TrackMenus.cpp}::kAlignStartSelStart
@ kAlignStartSelStart
Definition: TrackMenus.cpp:179
TrackActions::Handler::OnMuteSelectedTracks
void OnMuteSelectedTracks(const CommandContext &context)
Definition: TrackMenus.cpp:866
MenuTable
Definition: CommandManager.h:403
TrackActions::Handler::OnPanRight
void OnPanRight(const CommandContext &context)
Definition: TrackMenus.cpp:882
PlayableTrack::SetMute
void SetMute(bool m)
Definition: Track.cpp:318
anonymous_namespace{TrackMenus.cpp}::kAudacitySortByName
@ kAudacitySortByName
Definition: TrackMenus.cpp:488
TrackActions::Handler
Definition: TrackMenus.cpp:602
TrackActions::Handler::OnTrackPanRight
void OnTrackPanRight(const CommandContext &context)
Definition: TrackMenus.cpp:1116
TrackActions::Handler::OnNewStereoTrack
void OnNewStereoTrack(const CommandContext &context)
Definition: TrackMenus.cpp:628
safenew
#define safenew
Definition: MemoryX.h:10
settings
static Settings & settings()
Definition: TrackInfo.cpp:86
lrint
#define lrint(dbl)
Definition: float_cast.h:169
TrackUtilities::DoMoveTrack
void DoMoveTrack(AudacityProject &project, Track *target, MoveChoice choice)
Move a track up, down, to top or to bottom.
Definition: TrackUtilities.cpp:199
CommandContext::project
AudacityProject & project
Definition: CommandContext.h:52
anonymous_namespace{Menus.cpp}::Options
std::vector< CommandFlagOptions > & Options()
Definition: Menus.cpp:526
anonymous_namespace{TrackMenus.cpp}::ExtraTrackMenu
BaseItemSharedPtr ExtraTrackMenu()
Definition: TrackMenus.cpp:1459
Mixer
Functions for doing the mixdown of the tracks.
Definition: Mix.h:80
LWSlider::Increase
void Increase(float steps)
Definition: ASlider.cpp:1481
ShuttleGuiBase::AddCombo
wxComboBox * AddCombo(const TranslatableString &Prompt, const wxString &Selected, const wxArrayStringEx &choices)
Definition: ShuttleGui.cpp:517
TimeTrack
A kind of Track used to 'warp time'.
Definition: TimeTrack.h:24
TrackPanel::RefreshTrack
void RefreshTrack(Track *trk, bool refreshbacking=true)
Definition: TrackPanel.cpp:749
ProjectHistory::Get
static ProjectHistory & Get(AudacityProject &project)
Definition: ProjectHistory.cpp:26
TrackActions::Handler::OnSyncLock
void OnSyncLock(const CommandContext &context)
Definition: TrackMenus.cpp:1072
NoteTrack
A Track that is used for Midi notes. (Somewhat old code).
Definition: NoteTrack.h:66
Mixer::Process
size_t Process(size_t maxSamples)
Definition: Mix.cpp:630
ShuttleGui
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:631
TrackActions::Handler::OnRemoveTracks
void OnRemoveTracks(const CommandContext &context)
Definition: TrackMenus.cpp:830