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 "ProjectRate.h"
13 #include "../ProjectSettings.h"
14 #include "../PluginManager.h"
15 #include "ProjectStatus.h"
16 #include "../ProjectWindow.h"
17 #include "../SelectUtilities.h"
18 #include "../ShuttleGui.h"
19 #include "../TimeTrack.h"
20 #include "../TrackPanelAx.h"
21 #include "../TrackPanel.h"
22 #include "../TrackUtilities.h"
23 #include "../UndoManager.h"
24 #include "../WaveClip.h"
25 #include "ViewInfo.h"
26 #include "../WaveTrack.h"
27 #include "../commands/CommandContext.h"
28 #include "../commands/CommandManager.h"
29 #include "../effects/EffectManager.h"
30 #include "../effects/EffectUI.h"
31 #include "QualitySettings.h"
32 #include "../tracks/playabletrack/wavetrack/ui/WaveTrackControls.h"
33 #include "../widgets/ASlider.h"
34 #include "../widgets/AudacityMessageBox.h"
35 #include "../widgets/ProgressDialog.h"
36 
37 #include <wx/combobox.h>
38 
39 #ifdef EXPERIMENTAL_SCOREALIGN
40 #include "../effects/ScoreAlignDialog.h"
41 #include "audioreader.h"
42 #include "scorealign.h"
43 #include "scorealign-glue.h"
44 #endif /* EXPERIMENTAL_SCOREALIGN */
45 
46 // private helper classes and functions
47 namespace {
48 
50 (AudacityProject &project, bool toNewTrack)
51 {
52  auto &tracks = TrackList::Get( project );
53  auto &trackFactory = WaveTrackFactory::Get( project );
54  auto rate = ProjectRate::Get(project).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  {
91  pNewRight = tracks.Add(uNewRight);
92  tracks.MakeMultiChannelTrack(*pNewLeft, 2, true);
93  }
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 #ifdef USE_MIDI
339 static const ReservedCommandFlag&
340  NoteTracksSelectedFlag() { static ReservedCommandFlag flag{
341  [](const AudacityProject &project){
342  return !TrackList::Get( project ).Selected<const NoteTrack>().empty();
343  }
344  }; return flag; } //gsw
345 #endif
346 
347 // rough relative amount of time to compute one
348 // frame of audio or midi, or one cell of matrix, or one iteration
349 // of smoothing, measured on a 1.9GHz Core 2 Duo in 32-bit mode
350 // (see COLLECT_TIMING_DATA below)
351 #define AUDIO_WORK_UNIT 0.004F
352 #define MIDI_WORK_UNIT 0.0001F
353 #define MATRIX_WORK_UNIT 0.000002F
354 #define SMOOTHING_WORK_UNIT 0.000001F
355 
356 // Write timing data to a file; useful for calibrating AUDIO_WORK_UNIT,
357 // MIDI_WORK_UNIT, MATRIX_WORK_UNIT, and SMOOTHING_WORK_UNIT coefficients
358 // Data is written to timing-data.txt; look in
359 // audacity-src/win/Release/modules/
360 #define COLLECT_TIMING_DATA
361 
362 // Audacity Score Align Progress class -- progress reports come here
363 class ASAProgress final : public SAProgress {
364  private:
365  float mTotalWork;
366  float mFrames[2];
367  long mTotalCells; // how many matrix cells?
368  long mCellCount; // how many cells so far?
369  long mPrevCellCount; // cell_count last reported with Update()
370  Optional<ProgressDialog> mProgress;
371  #ifdef COLLECT_TIMING_DATA
372  FILE *mTimeFile;
373  wxDateTime mStartTime;
374  long iterations;
375  #endif
376 
377  public:
378  ASAProgress() {
379  smoothing = false;
380  #ifdef COLLECT_TIMING_DATA
381  mTimeFile = fopen("timing-data.txt", "w");
382  #endif
383  }
384  ~ASAProgress() {
385  #ifdef COLLECT_TIMING_DATA
386  fclose(mTimeFile);
387  #endif
388  }
389  void set_phase(int i) override {
390  float work[2]; // chromagram computation work estimates
391  float work2, work3 = 0; // matrix and smoothing work estimates
392  SAProgress::set_phase(i);
393  #ifdef COLLECT_TIMING_DATA
394  long ms = 0;
395  wxDateTime now = wxDateTime::UNow();
396  wxFprintf(mTimeFile, "Phase %d begins at %s\n",
397  i, now.FormatTime());
398  if (i != 0)
399  ms = now.Subtract(mStartTime).GetMilliseconds().ToLong();
400  mStartTime = now;
401  #endif
402  if (i == 0) {
403  mCellCount = 0;
404  for (int j = 0; j < 2; j++) {
405  mFrames[j] = durations[j] / frame_period;
406  }
407  mTotalWork = 0;
408  for (int j = 0; j < 2; j++) {
409  work[j] =
410  (is_audio[j] ? AUDIO_WORK_UNIT : MIDI_WORK_UNIT) * mFrames[j];
411  mTotalWork += work[j];
412  }
413  mTotalCells = mFrames[0] * mFrames[1];
414  work2 = mTotalCells * MATRIX_WORK_UNIT;
415  mTotalWork += work2;
416  // arbitrarily assume 60 iterations to fit smooth segments and
417  // per frame per iteration is SMOOTHING_WORK_UNIT
418  if (smoothing) {
419  work3 =
420  wxMax(mFrames[0], mFrames[1]) * SMOOTHING_WORK_UNIT * 40;
421  mTotalWork += work3;
422  }
423  #ifdef COLLECT_TIMING_DATA
424  wxFprintf(mTimeFile,
425  " mTotalWork (an estimate) = %g\n", mTotalWork);
426  wxFprintf(mTimeFile, " work0 = %g, frames %g, is_audio %d\n",
427  work[0], mFrames[0], is_audio[0]);
428  wxFprintf(mTimeFile, " work1 = %g, frames %g, is_audio %d\n",
429  work[1], mFrames[1], is_audio[1]);
430  wxFprintf(mTimeFile, "work2 = %g, work3 = %g\n", work2, work3);
431  #endif
432  mProgress.emplace(XO("Synchronize MIDI with Audio"),
433  XO("Synchronizing MIDI and Audio Tracks"));
434  } else if (i < 3) {
435  wxFprintf(mTimeFile,
436  "Phase %d took %d ms for %g frames, coefficient = %g s/frame\n",
437  i - 1, ms, mFrames[i - 1], (ms * 0.001) / mFrames[i - 1]);
438  } else if (i == 3) {
439  wxFprintf(mTimeFile,
440  "Phase 2 took %d ms for %d cells, coefficient = %g s/cell\n",
441  ms, mCellCount, (ms * 0.001) / mCellCount);
442  } else if (i == 4) {
443  wxFprintf(mTimeFile,
444  "Phase 3 took %d ms for %d iterations on %g frames, "
445  "coefficient = %g s per frame per iteration\n",
446  ms, iterations, wxMax(mFrames[0], mFrames[1]),
447  (ms * 0.001) / (wxMax(mFrames[0], mFrames[1]) * iterations));
448  }
449  }
450  bool set_feature_progress(float s) override {
451  float work;
452  if (phase == 0) {
453  float f = s / frame_period;
454  work = (is_audio[0] ? AUDIO_WORK_UNIT : MIDI_WORK_UNIT) * f;
455  } else if (phase == 1) {
456  float f = s / frame_period;
457  work = (is_audio[0] ? AUDIO_WORK_UNIT : MIDI_WORK_UNIT) * mFrames[0] +
458  (is_audio[1] ? AUDIO_WORK_UNIT : MIDI_WORK_UNIT) * f;
459  }
460  auto updateResult = mProgress->Update((int)(work), (int)(mTotalWork));
461  return (updateResult == ProgressResult::Success);
462  }
463  bool set_matrix_progress(int cells) override {
464  mCellCount += cells;
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  work += mCellCount * MATRIX_WORK_UNIT;
469  auto updateResult = mProgress->Update((int)(work), (int)(mTotalWork));
470  return (updateResult == ProgressResult::Success);
471  }
472  bool set_smoothing_progress(int i) override {
473  iterations = i;
474  float work =
475  (is_audio[0] ? AUDIO_WORK_UNIT : MIDI_WORK_UNIT) * mFrames[0] +
476  (is_audio[1] ? AUDIO_WORK_UNIT : MIDI_WORK_UNIT) * mFrames[1] +
477  MATRIX_WORK_UNIT * mFrames[0] * mFrames[1];
478  work += i * wxMax(mFrames[0], mFrames[1]) * SMOOTHING_WORK_UNIT;
479  auto updateResult = mProgress->Update((int)(work), (int)(mTotalWork));
480  return (updateResult == ProgressResult::Success);
481  }
482 };
483 
484 
485 long mixer_process(void *mixer, float **buffer, long n)
486 {
487  Mixer *mix = (Mixer *) mixer;
488  long frame_count = mix->Process(std::max(0L, n));
489  *buffer = (float *) mix->GetBuffer();
490  return frame_count;
491 }
492 
493 #endif // EXPERIMENTAL_SCOREALIGN
494 
495 enum{
498 };
499 
500 void DoSortTracks( AudacityProject &project, int flags )
501 {
502  auto GetTime = [](const Track *t) {
503  return t->TypeSwitch< double >(
504  [&](const WaveTrack* w) {
505  auto stime = w->GetEndTime();
506 
507  int ndx;
508  for (ndx = 0; ndx < w->GetNumClips(); ndx++) {
509  const auto c = w->GetClipByIndex(ndx);
510  if (c->GetPlaySamplesCount() == 0)
511  continue;
512  stime = std::min(stime, c->GetPlayStartTime());
513  }
514  return stime;
515  },
516  [&](const LabelTrack* l) {
517  return l->GetStartTime();
518  }
519  );
520  };
521 
522  size_t ndx = 0;
523  // This one place outside of TrackList where we must use undisguised
524  // std::list iterators! Avoid this elsewhere!
525  std::vector<TrackNodePointer> arr;
526  auto &tracks = TrackList::Get( project );
527  arr.reserve(tracks.size());
528 
529  // First find the permutation.
530  // This routine, very unusually, deals with the underlying stl list
531  // iterators, not with TrackIter! Dangerous!
532  for (auto iter = tracks.ListOfTracks::begin(),
533  end = tracks.ListOfTracks::end(); iter != end; ++iter) {
534  const auto &track = *iter;
535  if ( !track->IsLeader() )
536  // keep channels contiguous
537  ndx++;
538  else {
539  auto size = arr.size();
540  for (ndx = 0; ndx < size;) {
541  Track &arrTrack = **arr[ndx].first;
542  auto channels = TrackList::Channels(&arrTrack);
543  if(flags & kAudacitySortByName) {
544  //do case insensitive sort - cmpNoCase returns less than zero if
545  // the string is 'less than' its argument
546  //also if we have case insensitive equality, then we need to sort
547  // by case as well
548  //We sort 'b' before 'B' accordingly. We uncharacteristically
549  // use greater than for the case sensitive
550  //compare because 'b' is greater than 'B' in ascii.
551  auto cmpValue = track->GetName().CmpNoCase(arrTrack.GetName());
552  if ( cmpValue < 0 ||
553  ( 0 == cmpValue &&
554  track->GetName().CompareTo(arrTrack.GetName()) > 0 ) )
555  break;
556  }
557  //sort by time otherwise
558  else if(flags & kAudacitySortByTime) {
559  auto time1 = TrackList::Channels(track.get()).min( GetTime );
560 
561  //get candidate's (from sorted array) time
562  auto time2 = channels.min( GetTime );
563 
564  if (time1 < time2)
565  break;
566  }
567  ndx += channels.size();
568  }
569  }
570  arr.insert(arr.begin() + ndx, TrackNodePointer{iter, &tracks});
571  }
572 
573  // Now apply the permutation
574  tracks.Permute(arr);
575 }
576 
577 void SetTrackGain(AudacityProject &project, WaveTrack * wt, LWSlider * slider)
578 {
579  wxASSERT(wt);
580  float newValue = slider->Get();
581 
582  for (auto channel : TrackList::Channels(wt))
583  channel->SetGain(newValue);
584 
585  ProjectHistory::Get( project )
586  .PushState(XO("Adjusted gain"), XO("Gain"), UndoPush::CONSOLIDATE);
587 
588  TrackPanel::Get( project ).RefreshTrack(wt);
589 }
590 
591 void SetTrackPan(AudacityProject &project, WaveTrack * wt, LWSlider * slider)
592 {
593  wxASSERT(wt);
594  float newValue = slider->Get();
595 
596  for (auto channel : TrackList::Channels(wt))
597  channel->SetPan(newValue);
598 
599  ProjectHistory::Get( project )
600  .PushState(XO("Adjusted Pan"), XO("Pan"), UndoPush::CONSOLIDATE);
601 
602  TrackPanel::Get( project ).RefreshTrack(wt);
603 }
604 
605 }
606 
607 namespace TrackActions {
608 
609 // Menu handler functions
610 
612 
613 void OnNewWaveTrack(const CommandContext &context)
614 {
615  auto &project = context.project;
616  auto &tracks = TrackList::Get( project );
617  auto &trackFactory = WaveTrackFactory::Get( project );
618  auto &window = ProjectWindow::Get( project );
619 
620  auto defaultFormat = QualitySettings::SampleFormatChoice();
621 
622  auto rate = ProjectRate::Get(project).GetRate();
623 
624  auto t = tracks.Add( trackFactory.NewWaveTrack( defaultFormat, rate ) );
625  SelectUtilities::SelectNone( project );
626 
627  t->SetSelected(true);
628 
629  ProjectHistory::Get( project )
630  .PushState(XO("Created new audio track"), XO("New Track"));
631 
632  TrackFocus::Get(project).Set(t);
633  t->EnsureVisible();
634 }
635 
636 void OnNewStereoTrack(const CommandContext &context)
637 {
638  auto &project = context.project;
639  auto &tracks = TrackList::Get( project );
640  auto &trackFactory = WaveTrackFactory::Get( project );
641  auto &window = ProjectWindow::Get( project );
642 
643  auto defaultFormat = QualitySettings::SampleFormatChoice();
644  auto rate = ProjectRate::Get(project).GetRate();
645 
646  SelectUtilities::SelectNone( project );
647 
648  auto left = tracks.Add( trackFactory.NewWaveTrack( defaultFormat, rate ) );
649  left->SetSelected(true);
650 
651  auto right = tracks.Add( trackFactory.NewWaveTrack( defaultFormat, rate ) );
652  right->SetSelected(true);
653 
654  tracks.MakeMultiChannelTrack(*left, 2, true);
655 
656  ProjectHistory::Get( project )
657  .PushState(XO("Created new stereo audio track"), XO("New Track"));
658 
659  TrackFocus::Get(project).Set(left);
660  left->EnsureVisible();
661 }
662 
663 void OnNewLabelTrack(const CommandContext &context)
664 {
665  auto &project = context.project;
666  auto &tracks = TrackList::Get( project );
667  auto &trackFactory = WaveTrackFactory::Get( project );
668  auto &window = ProjectWindow::Get( project );
669 
670  auto t = tracks.Add( std::make_shared<LabelTrack>() );
671 
672  SelectUtilities::SelectNone( project );
673 
674  t->SetSelected(true);
675 
676  ProjectHistory::Get( project )
677  .PushState(XO("Created new label track"), XO("New Track"));
678 
679  TrackFocus::Get(project).Set(t);
680  t->EnsureVisible();
681 }
682 
683 void OnNewTimeTrack(const CommandContext &context)
684 {
685  auto &project = context.project;
686  auto &tracks = TrackList::Get( project );
687  auto &viewInfo = ViewInfo::Get( project );
688  auto &window = ProjectWindow::Get( project );
689 
690  if ( *tracks.Any<TimeTrack>().begin() ) {
692  XO(
693 "This version of Audacity only allows one time track for each project window.") );
694  return;
695  }
696 
697  auto t = tracks.AddToHead( std::make_shared<TimeTrack>(&viewInfo) );
698 
699  SelectUtilities::SelectNone( project );
700 
701  t->SetSelected(true);
702 
703  ProjectHistory::Get( project )
704  .PushState(XO("Created new time track"), XO("New Track"));
705 
706  TrackFocus::Get(project).Set(t);
707  t->EnsureVisible();
708 }
709 
710 void OnStereoToMono(const CommandContext &context)
711 {
713  EffectManager::Get().GetEffectByIdentifier(wxT("StereoToMono")),
714  context,
716 }
717 
718 void OnMixAndRender(const CommandContext &context)
719 {
720  auto &project = context.project;
721  DoMixAndRender(project, false);
722 }
723 
725 {
726  auto &project = context.project;
727  DoMixAndRender(project, true);
728 }
729 
730 void OnResample(const CommandContext &context)
731 {
732  auto &project = context.project;
733  auto projectRate = ProjectRate::Get(project).GetRate();
734  auto &tracks = TrackList::Get( project );
735  auto &undoManager = UndoManager::Get( project );
736  auto &window = ProjectWindow::Get( project );
737 
738  int newRate;
739 
740  while (true)
741  {
742  wxDialogWrapper dlg(&window, wxID_ANY, XO("Resample"));
743  ShuttleGui S(&dlg, eIsCreating);
744  wxString rate;
745  wxComboBox *cb;
746 
747  rate.Printf(wxT("%ld"), lrint(projectRate));
748 
749  wxArrayStringEx rates{
750  wxT("8000") ,
751  wxT("11025") ,
752  wxT("16000") ,
753  wxT("22050") ,
754  wxT("32000") ,
755  wxT("44100") ,
756  wxT("48000") ,
757  wxT("88200") ,
758  wxT("96000") ,
759  wxT("176400") ,
760  wxT("192000") ,
761  wxT("352800") ,
762  wxT("384000") ,
763  };
764 
765  S.StartVerticalLay(true);
766  {
767  S.AddSpace(-1, 15);
768 
769  S.StartHorizontalLay(wxCENTER, false);
770  {
771  cb = S.AddCombo(XXO("New sample rate (Hz):"),
772  rate,
773  rates);
774  }
775  S.EndHorizontalLay();
776 
777  S.AddSpace(-1, 15);
778 
779  S.AddStandardButtons();
780  }
781  S.EndVerticalLay();
782 
783  dlg.Layout();
784  dlg.Fit();
785  dlg.Center();
786 
787  if (dlg.ShowModal() != wxID_OK)
788  {
789  return; // user cancelled dialog
790  }
791 
792  long lrate;
793  if (cb->GetValue().ToLong(&lrate) && lrate >= 1 && lrate <= 1000000)
794  {
795  newRate = (int)lrate;
796  break;
797  }
798 
800  XO("The entered value is invalid"),
801  XO("Error"),
802  wxICON_ERROR,
803  &window);
804  }
805 
806  int ndx = 0;
807  auto flags = UndoPush::NONE;
808  for (auto wt : tracks.Selected< WaveTrack >())
809  {
810  auto msg = XO("Resampling track %d").Format( ++ndx );
811 
812  ProgressDialog progress(XO("Resample"), msg);
813 
814  // The resampling of a track may be stopped by the user. This might
815  // leave a track with multiple clips in a partially resampled state.
816  // But the thrown exception will cause rollback in the application
817  // level handler.
818 
819  wt->Resample(newRate, &progress);
820 
821  // Each time a track is successfully, completely resampled,
822  // commit that to the undo stack. The second and later times,
823  // consolidate.
824 
825  ProjectHistory::Get( project ).PushState(
826  XO("Resampled audio track(s)"), XO("Resample Track"), flags);
827  flags = flags | UndoPush::CONSOLIDATE;
828  }
829 
830  undoManager.StopConsolidating();
831 
832  // Need to reset
833  window.FinishAutoScroll();
834 }
835 
836 void OnRemoveTracks(const CommandContext &context)
837 {
839 }
840 
841 static void MuteTracks(const CommandContext &context, bool mute, bool selected)
842 {
843  auto &project = context.project;
844  const auto &settings = ProjectSettings::Get( project );
845  auto &tracks = TrackList::Get( project );
846  auto &window = ProjectWindow::Get( project );
847 
848  auto soloSimple = settings.IsSoloSimple();
849  auto soloNone = settings.IsSoloNone();
850 
851  auto iter = selected ? tracks.Selected<PlayableTrack>() : tracks.Any<PlayableTrack>();
852  for (auto pt : iter)
853  {
854  pt->SetMute(mute);
855  if (soloSimple || soloNone)
856  pt->SetSolo(false);
857  }
858 
859  ProjectHistory::Get( project ).ModifyState(true);
860 }
861 
862 void OnMuteAllTracks(const CommandContext &context)
863 {
864  MuteTracks(context, true, false);
865 }
866 
867 void OnUnmuteAllTracks(const CommandContext &context)
868 {
869  MuteTracks(context, false, false);
870 }
871 
873 {
874  MuteTracks(context, true, true);
875 }
876 
878 {
879  MuteTracks(context, false, true);
880 }
881 
882 void OnPanLeft(const CommandContext &context)
883 {
884  auto &project = context.project;
885  DoPanTracks( project, -1.0);
886 }
887 
888 void OnPanRight(const CommandContext &context)
889 {
890  auto &project = context.project;
891  DoPanTracks( project, 1.0);
892 }
893 
894 void OnPanCenter(const CommandContext &context)
895 {
896  auto &project = context.project;
897  DoPanTracks( project, 0.0);
898 }
899 
900 void OnAlignNoSync(const CommandContext &context)
901 {
902  auto &project = context.project;
903 
904  DoAlign(project,
905  context.index + kAlignLabelsCount(), false);
906 }
907 
908 void OnAlign(const CommandContext &context)
909 {
910  auto &project = context.project;
911 
912  bool bMoveWith;
913  gPrefs->Read(wxT("/GUI/MoveSelectionWithTracks"), &bMoveWith, false);
914  DoAlign(project, context.index, bMoveWith);
915 }
916 
917 /*
918 // Now handled in OnAlign.
919 void OnAlignMoveSel(int index)
920 {
921  DoAlign(index, true);
922 }
923 */
924 
925 void OnMoveSelectionWithTracks(const CommandContext &WXUNUSED(context) )
926 {
927  bool bMoveWith;
928  gPrefs->Read(wxT("/GUI/MoveSelectionWithTracks"), &bMoveWith, false);
929  gPrefs->Write(wxT("/GUI/MoveSelectionWithTracks"), !bMoveWith);
930  gPrefs->Flush();
931 
932 }
933 
934 #ifdef EXPERIMENTAL_SCOREALIGN
935 void OnScoreAlign(const CommandContext &context)
936 {
937  auto &project = context.project;
938  auto &tracks = TrackList::Get( project );
939  const auto rate = ProjectSettings::Get( project ).GetRate();
940 
941  int numWaveTracksSelected = 0;
942  int numNoteTracksSelected = 0;
943  int numOtherTracksSelected = 0;
944  double endTime = 0.0;
945 
946  // Iterate through once to make sure that there is exactly
947  // one WaveTrack and one NoteTrack selected.
948  tracks.Selected().Visit(
949  [&](WaveTrack *wt) {
950  numWaveTracksSelected++;
951  endTime = endTime > wt->GetEndTime() ? endTime : wt->GetEndTime();
952  },
953  [&](NoteTrack *) {
954  numNoteTracksSelected++;
955  },
956  [&](Track*) {
957  numOtherTracksSelected++;
958  }
959  );
960 
961  if(numWaveTracksSelected == 0 ||
962  numNoteTracksSelected != 1 ||
963  numOtherTracksSelected != 0){
965  XO("Please select at least one audio track and one MIDI track.") );
966  return;
967  }
968 
969  // Creating the dialog also stores dialog into gScoreAlignDialog so
970  // that it can be deleted by CloseScoreAlignDialog() either here or
971  // if the program is quit by the user while the dialog is up.
972  ScoreAlignParams params;
973 
974  // safe because the class maintains a global resource pointer
976 
977  CloseScoreAlignDialog();
978 
979  if (params.mStatus != wxID_OK) return;
980 
981  // We're going to do it.
982  //pushing the state before the change is wrong (I think)
983  //PushState(XO("Sync MIDI with Audio"), XO("Sync MIDI with Audio"));
984  // Make a copy of the note track in case alignment is canceled or fails
985  auto holder = nt->Duplicate();
986  auto alignedNoteTrack = static_cast<NoteTrack*>(holder.get());
987  // Remove offset from NoteTrack because audio is
988  // mixed starting at zero and incorporating clip offsets.
989  if (alignedNoteTrack->GetOffset() < 0) {
990  // remove the negative offset data before alignment
991  nt->Clear(alignedNoteTrack->GetOffset(), 0);
992  } else if (alignedNoteTrack->GetOffset() > 0) {
993  alignedNoteTrack->Shift(alignedNoteTrack->GetOffset());
994  }
995  alignedNoteTrack->SetOffset(0);
996 
997  WaveTrackConstArray waveTracks =
998  tracks->GetWaveTrackConstArray(true /* selectionOnly */);
999 
1000  int result;
1001  {
1002  Mixer mix(
1003  waveTracks, // const WaveTrackConstArray &inputTracks
1004  false, // mayThrow -- is this right?
1005  Mixer::WarpOptions{ *tracks },
1006  0.0, // double startTime
1007  endTime, // double stopTime
1008  2, // int numOutChannels
1009  44100u, // size_t outBufferSize
1010  true, // bool outInterleaved
1011  rate, // double outRate
1012  floatSample, // sampleFormat outFormat
1013  true, // bool highQuality = true
1014  NULL); // MixerSpec *mixerSpec = NULL
1015 
1016  ASAProgress progress;
1017 
1018  // There's a lot of adjusting made to incorporate the note track offset into
1019  // the note track while preserving the position of notes within beats and
1020  // measures. For debugging, you can see just the pre-scorealign note track
1021  // manipulation by setting SKIP_ACTUAL_SCORE_ALIGNMENT. You could then, for
1022  // example, save the modified note track in ".gro" form to read the details.
1023  //#define SKIP_ACTUAL_SCORE_ALIGNMENT 1
1024 #ifndef SKIP_ACTUAL_SCORE_ALIGNMENT
1025  result = scorealign((void *) &mix, &mixer_process,
1026  2 /* channels */, 44100.0 /* srate */, endTime,
1027  &alignedNoteTrack->GetSeq(), &progress, params);
1028 #else
1029  result = SA_SUCCESS;
1030 #endif
1031  }
1032 
1033  if (result == SA_SUCCESS) {
1034  tracks->Replace(nt, holder);
1036  XO("Alignment completed: MIDI from %.2f to %.2f secs, Audio from %.2f to %.2f secs.")
1037  .Format(
1038  params.mMidiStart, params.mMidiEnd,
1039  params.mAudioStart, params.mAudioEnd) );
1040  ProjectHistory::Get( project )
1041  .PushState(XO("Sync MIDI with Audio"), XO("Sync MIDI with Audio"));
1042  } else if (result == SA_TOOSHORT) {
1044  XO(
1045 "Alignment error: input too short: MIDI from %.2f to %.2f secs, Audio from %.2f to %.2f secs.")
1046  .Format(
1047  params.mMidiStart, params.mMidiEnd,
1048  params.mAudioStart, params.mAudioEnd) );
1049  } else if (result == SA_CANCEL) {
1050  // wrong way to recover...
1051  //project.OnUndo(); // recover any changes to note track
1052  return; // no message when user cancels alignment
1053  } else {
1054  //project.OnUndo(); // recover any changes to note track
1055  AudacityMessageBox( XO("Internal error reported by alignment process.") );
1056  }
1057 }
1058 #endif /* EXPERIMENTAL_SCOREALIGN */
1059 
1060 void OnSortTime(const CommandContext &context)
1061 {
1062  auto &project = context.project;
1064 
1065  ProjectHistory::Get( project )
1066  .PushState(XO("Tracks sorted by time"), XO("Sort by Time"));
1067 }
1068 
1069 void OnSortName(const CommandContext &context)
1070 {
1071  auto &project = context.project;
1073 
1074  ProjectHistory::Get( project )
1075  .PushState(XO("Tracks sorted by name"), XO("Sort by Name"));
1076 }
1077 
1078 void OnSyncLock(const CommandContext &context)
1079 {
1080  auto &project = context.project;
1081  auto &trackPanel = TrackPanel::Get( project );
1082 
1083  bool bSyncLockTracks;
1084  gPrefs->Read(wxT("/GUI/SyncLockTracks"), &bSyncLockTracks, false);
1085  gPrefs->Write(wxT("/GUI/SyncLockTracks"), !bSyncLockTracks);
1086  gPrefs->Flush();
1087 
1088  // Toolbar, project sync-lock handled within
1090 
1091  trackPanel.Refresh(false);
1092 }
1093 
1096 void OnTrackPan(const CommandContext &context)
1097 {
1098  auto &project = context.project;
1099  auto &trackPanel = TrackPanel::Get( project );
1100 
1101  const auto track = TrackFocus::Get( project ).Get();
1102  if (track) track->TypeSwitch( [&](WaveTrack *wt) {
1103  LWSlider *slider = WaveTrackControls::PanSlider( trackPanel, *wt );
1104  if (slider->ShowDialog())
1105  SetTrackPan(project, wt, slider);
1106  });
1107 }
1108 
1109 void OnTrackPanLeft(const CommandContext &context)
1110 {
1111  auto &project = context.project;
1112  auto &trackPanel = TrackPanel::Get( project );
1113 
1114  const auto track = TrackFocus::Get( project ).Get();
1115  if (track) track->TypeSwitch( [&](WaveTrack *wt) {
1116  LWSlider *slider = WaveTrackControls::PanSlider( trackPanel, *wt );
1117  slider->Decrease(1);
1118  SetTrackPan(project, wt, slider);
1119  });
1120 }
1121 
1122 void OnTrackPanRight(const CommandContext &context)
1123 {
1124  auto &project = context.project;
1125  auto &trackPanel = TrackPanel::Get( project );
1126 
1127  const auto track = TrackFocus::Get( project ).Get();
1128  if (track) track->TypeSwitch( [&](WaveTrack *wt) {
1129  LWSlider *slider = WaveTrackControls::PanSlider( trackPanel, *wt );
1130  slider->Increase(1);
1131  SetTrackPan(project, wt, slider);
1132  });
1133 }
1134 
1135 void OnTrackGain(const CommandContext &context)
1136 {
1137  auto &project = context.project;
1138  auto &trackPanel = TrackPanel::Get( project );
1139 
1141  const auto track = TrackFocus::Get( project ).Get();
1142  if (track) track->TypeSwitch( [&](WaveTrack *wt) {
1143  LWSlider *slider = WaveTrackControls::GainSlider( trackPanel, *wt );
1144  if (slider->ShowDialog())
1145  SetTrackGain(project, wt, slider);
1146  });
1147 }
1148 
1149 void OnTrackGainInc(const CommandContext &context)
1150 {
1151  auto &project = context.project;
1152  auto &trackPanel = TrackPanel::Get( project );
1153 
1154  const auto track = TrackFocus::Get( project ).Get();
1155  if (track) track->TypeSwitch( [&](WaveTrack *wt) {
1156  LWSlider *slider = WaveTrackControls::GainSlider( trackPanel, *wt );
1157  slider->Increase(1);
1158  SetTrackGain(project, wt, slider);
1159  });
1160 }
1161 
1162 void OnTrackGainDec(const CommandContext &context)
1163 {
1164  auto &project = context.project;
1165  auto &trackPanel = TrackPanel::Get( project );
1166 
1167  const auto track = TrackFocus::Get( project ).Get();
1168  if (track) track->TypeSwitch( [&](WaveTrack *wt) {
1169  LWSlider *slider = WaveTrackControls::GainSlider( trackPanel, *wt );
1170  slider->Decrease(1);
1171  SetTrackGain(project, wt, slider);
1172  });
1173 }
1174 
1175 void OnTrackMenu(const CommandContext &context)
1176 {
1177  auto &project = context.project;
1178  auto &trackPanel = TrackPanel::Get( project );
1179 
1180  trackPanel.OnTrackMenu();
1181 }
1182 
1183 void OnTrackMute(const CommandContext &context)
1184 {
1185  auto &project = context.project;
1186 
1187  // Use the temporary selection if it is specified, else the track focus
1188  auto track = context.temporarySelection.pTrack;
1189  if (!track)
1190  track = TrackFocus::Get( project ).Get();
1191 
1192  if (track) track->TypeSwitch( [&](PlayableTrack *t) {
1193  TrackUtilities::DoTrackMute(project, t, false);
1194  });
1195 }
1196 
1197 void OnTrackSolo(const CommandContext &context)
1198 {
1199  auto &project = context.project;
1200 
1201  const auto track = TrackFocus::Get( project ).Get();
1202  if (track) track->TypeSwitch( [&](PlayableTrack *t) {
1203  TrackUtilities::DoTrackSolo(project, t, false);
1204  });
1205 }
1206 
1207 void OnTrackClose(const CommandContext &context)
1208 {
1209  auto &project = context.project;
1210  auto &trackPanel = TrackPanel::Get( project );
1211 
1212  const auto t = TrackFocus::Get( project ).Get();
1213  if (!t)
1214  return;
1215 
1216  auto isAudioActive = ProjectAudioIO::Get( project ).IsAudioActive();
1217 
1218  if (isAudioActive)
1219  {
1220  ProjectStatus::Get( project ).Set(
1221  XO("Can't delete track with active audio"));
1222  wxBell();
1223  return;
1224  }
1225 
1226  TrackUtilities::DoRemoveTrack(project, t);
1227 
1228  trackPanel.UpdateViewIfNoTracks();
1229  trackPanel.Refresh(false);
1230 }
1231 
1232 void OnTrackMoveUp(const CommandContext &context)
1233 {
1234  auto &project = context.project;
1235  auto &trackPanel = TrackPanel::Get( project );
1236  auto &tracks = TrackList::Get( project );
1237 
1238  const auto focusedTrack = TrackFocus::Get( project ).Get();
1239  if (tracks.CanMoveUp(focusedTrack)) {
1240  DoMoveTrack(project, focusedTrack, TrackUtilities::OnMoveUpID);
1241  trackPanel.Refresh(false);
1242  }
1243 }
1244 
1245 void OnTrackMoveDown(const CommandContext &context)
1246 {
1247  auto &project = context.project;
1248  auto &trackPanel = TrackPanel::Get( project );
1249  auto &tracks = TrackList::Get( project );
1250 
1251  const auto focusedTrack = TrackFocus::Get( project ).Get();
1252  if (tracks.CanMoveDown(focusedTrack)) {
1253  DoMoveTrack(project, focusedTrack, TrackUtilities::OnMoveDownID);
1254  trackPanel.Refresh(false);
1255  }
1256 }
1257 
1258 void OnTrackMoveTop(const CommandContext &context)
1259 {
1260  auto &project = context.project;
1261  auto &trackPanel = TrackPanel::Get( project );
1262  auto &tracks = TrackList::Get( project );
1263 
1264  const auto focusedTrack = TrackFocus::Get( project ).Get();
1265  if (tracks.CanMoveUp(focusedTrack)) {
1266  DoMoveTrack(project, focusedTrack, TrackUtilities::OnMoveTopID);
1267  trackPanel.Refresh(false);
1268  }
1269 }
1270 
1271 void OnTrackMoveBottom(const CommandContext &context)
1272 {
1273  auto &project = context.project;
1274  auto &trackPanel = TrackPanel::Get( project );
1275  auto &tracks = TrackList::Get( project );
1276 
1277  const auto focusedTrack = TrackFocus::Get( project ).Get();
1278  if (tracks.CanMoveDown(focusedTrack)) {
1279  DoMoveTrack(project, focusedTrack, TrackUtilities::OnMoveBottomID);
1280  trackPanel.Refresh(false);
1281  }
1282 }
1283 
1284 }; // struct Handler
1285 
1286 } // namespace
1287 
1289  // Handler is not stateful. Doesn't need a factory registered with
1290  // AudacityProject.
1291  static TrackActions::Handler instance;
1292  return instance;
1293 };
1294 
1295 // Menu definitions
1296 
1297 #define FN(X) (& TrackActions::Handler :: X)
1298 
1299 // Under /MenuBar
1300 namespace {
1301 using namespace MenuTable;
1303 {
1304  // Tracks Menu (formerly Project Menu)
1306 
1307  static BaseItemSharedPtr menu{
1309  Menu( wxT("Tracks"), XXO("&Tracks"),
1310  Section( "Add",
1311  Menu( wxT("Add"), XXO("Add &New"),
1312  Command( wxT("NewMonoTrack"), XXO("&Mono Track"), FN(OnNewWaveTrack),
1313  AudioIONotBusyFlag(), wxT("Ctrl+Shift+N") ),
1314  Command( wxT("NewStereoTrack"), XXO("&Stereo Track"),
1315  FN(OnNewStereoTrack), AudioIONotBusyFlag() ),
1316  Command( wxT("NewLabelTrack"), XXO("&Label Track"),
1317  FN(OnNewLabelTrack), AudioIONotBusyFlag() ),
1318  Command( wxT("NewTimeTrack"), XXO("&Time Track"),
1319  FN(OnNewTimeTrack), AudioIONotBusyFlag() )
1320  )
1321  ),
1322 
1324 
1325  Section( "",
1326  Menu( wxT("Mix"), XXO("Mi&x"),
1327  // Delayed evaluation
1328  // Stereo to Mono is an oddball command that is also subject to control
1329  // by the plug-in manager, as if an effect. Decide whether to show or
1330  // hide it.
1331  [](AudacityProject&) -> BaseItemPtr {
1332  const PluginID ID =
1333  EffectManager::Get().GetEffectByIdentifier(wxT("StereoToMono"));
1334  const PluginDescriptor *plug = PluginManager::Get().GetPlugin(ID);
1335  if (plug && plug->IsEnabled())
1336  return Command( wxT("Stereo to Mono"),
1337  XXO("Mix Stereo Down to &Mono"), FN(OnStereoToMono),
1340  else
1341  return {};
1342  },
1343  Command( wxT("MixAndRender"), XXO("Mi&x and Render"),
1344  FN(OnMixAndRender),
1346  Command( wxT("MixAndRenderToNewTrack"),
1347  XXO("Mix and Render to Ne&w Track"),
1348  FN(OnMixAndRenderToNewTrack),
1349  AudioIONotBusyFlag() | WaveTracksSelectedFlag(), wxT("Ctrl+Shift+M") )
1350  ),
1351 
1352  Command( wxT("Resample"), XXO("&Resample..."), FN(OnResample),
1354  ),
1355 
1356  Section( "",
1357  Command( wxT("RemoveTracks"), XXO("Remo&ve Tracks"), FN(OnRemoveTracks),
1359  ),
1360 
1361  Section( "",
1362  Menu( wxT("Mute"), XXO("M&ute/Unmute"),
1363  Command( wxT("MuteAllTracks"), XXO("&Mute All Tracks"),
1364  FN(OnMuteAllTracks), TracksExistFlag(), wxT("Ctrl+U") ),
1365  Command( wxT("UnmuteAllTracks"), XXO("&Unmute All Tracks"),
1366  FN(OnUnmuteAllTracks), TracksExistFlag(), wxT("Ctrl+Shift+U") ),
1367  Command( wxT("MuteTracks"), XXO("Mut&e Tracks"),
1368  FN(OnMuteSelectedTracks), EditableTracksSelectedFlag(), wxT("Ctrl+Alt+U") ),
1369  Command( wxT("UnmuteTracks"), XXO("U&nmute Tracks"),
1370  FN(OnUnmuteSelectedTracks), EditableTracksSelectedFlag(), wxT("Ctrl+Alt+Shift+U") )
1371  ),
1372 
1373  Menu( wxT("Pan"), XXO("&Pan"),
1374  // As Pan changes are not saved on Undo stack,
1375  // pan settings for all tracks
1376  // in the project could very easily be lost unless we
1377  // require the tracks to be selected.
1378  Command( wxT("PanLeft"), XXO("&Left"), FN(OnPanLeft),
1380  Options{}.LongName( XO("Pan Left") ) ),
1381  Command( wxT("PanRight"), XXO("&Right"), FN(OnPanRight),
1383  Options{}.LongName( XO("Pan Right") ) ),
1384  Command( wxT("PanCenter"), XXO("&Center"), FN(OnPanCenter),
1386  Options{}.LongName( XO("Pan Center") ) )
1387  )
1388  ),
1389 
1390  Section( "",
1391  Menu( wxT("Align"), XXO("&Align Tracks"), // XO("Just Move Tracks"),
1392  Section( "",
1393  // Mutual alignment of tracks independent of selection or zero
1394  CommandGroup(wxT("Align"),
1395  {
1396  { wxT("EndToEnd"), XXO("&Align End to End") },
1397  { wxT("Together"), XXO("Align &Together") },
1398  },
1399  FN(OnAlignNoSync), AudioIONotBusyFlag() | EditableTracksSelectedFlag())
1400  ),
1401 
1402  Section( "",
1403  // Alignment commands using selection or zero
1404  CommandGroup(wxT("Align"),
1405  alignLabels(),
1407  ),
1408 
1409  Section( "",
1410  Command( wxT("MoveSelectionWithTracks"),
1411  XXO("&Move Selection with Tracks (on/off)"),
1412  FN(OnMoveSelectionWithTracks),
1414  Options{}.CheckTest( wxT("/GUI/MoveSelectionWithTracks"), false ) )
1415  )
1416  ),
1417 
1418  #if 0
1419  // TODO: Can these labels be made clearer?
1420  // Do we need this sub-menu at all?
1421  Menu( wxT("MoveSelectionAndTracks"), XO("Move Sele&ction and Tracks"), {
1422  CommandGroup(wxT("AlignMove"), alignLabels(),
1423  FN(OnAlignMoveSel), AudioIONotBusyFlag() | EditableTracksSelectedFlag()),
1424  } ),
1425  #endif
1426 
1428 
1429  #ifdef EXPERIMENTAL_SCOREALIGN
1430  Command( wxT("ScoreAlign"), XXO("Synchronize MIDI with Audio"),
1431  FN(OnScoreAlign),
1432  AudioIONotBusyFlag() | NoteTracksSelectedFlag() | WaveTracksSelectedFlag() ),
1433  #endif // EXPERIMENTAL_SCOREALIGN
1434 
1436 
1437  Menu( wxT("Sort"), XXO("S&ort Tracks"),
1438  Command( wxT("SortByTime"), XXO("By &Start Time"), FN(OnSortTime),
1439  TracksExistFlag(),
1440  Options{}.LongName( XO("Sort by Time") ) ),
1441  Command( wxT("SortByName"), XXO("By &Name"), FN(OnSortName),
1442  TracksExistFlag(),
1443  Options{}.LongName( XO("Sort by Name") ) )
1444  )
1445 
1447  )
1448 
1449 #ifdef EXPERIMENTAL_SYNC_LOCK
1450  ,
1451 
1452  Section( "",
1453  Command( wxT("SyncLock"), XXO("Sync-&Lock Tracks (on/off)"),
1454  FN(OnSyncLock), AlwaysEnabledFlag,
1455  Options{}.CheckTest( wxT("/GUI/SyncLockTracks"), false ) )
1456  )
1457 
1458 #endif
1459 
1460  ) ) };
1461  return menu;
1462 }
1463 
1465  wxT(""),
1466  Shared( TracksMenu() )
1467 };
1468 
1470 {
1472  static BaseItemSharedPtr menu{
1474  Menu( wxT("Track"), XXO("&Track"),
1475  Command( wxT("TrackPan"), XXO("Change P&an on Focused Track..."),
1476  FN(OnTrackPan),
1477  TrackPanelHasFocus() | TracksExistFlag(), wxT("Shift+P") ),
1478  Command( wxT("TrackPanLeft"), XXO("Pan &Left on Focused Track"),
1479  FN(OnTrackPanLeft),
1480  TrackPanelHasFocus() | TracksExistFlag(), wxT("Alt+Shift+Left") ),
1481  Command( wxT("TrackPanRight"), XXO("Pan &Right on Focused Track"),
1482  FN(OnTrackPanRight),
1483  TrackPanelHasFocus() | TracksExistFlag(), wxT("Alt+Shift+Right") ),
1484  Command( wxT("TrackGain"), XXO("Change Gai&n on Focused Track..."),
1485  FN(OnTrackGain),
1486  TrackPanelHasFocus() | TracksExistFlag(), wxT("Shift+G") ),
1487  Command( wxT("TrackGainInc"), XXO("&Increase Gain on Focused Track"),
1488  FN(OnTrackGainInc),
1489  TrackPanelHasFocus() | TracksExistFlag(), wxT("Alt+Shift+Up") ),
1490  Command( wxT("TrackGainDec"), XXO("&Decrease Gain on Focused Track"),
1491  FN(OnTrackGainDec),
1492  TrackPanelHasFocus() | TracksExistFlag(), wxT("Alt+Shift+Down") ),
1493  Command( wxT("TrackMenu"), XXO("Op&en Menu on Focused Track..."),
1494  FN(OnTrackMenu),
1496  Options{ wxT("Shift+M") }.SkipKeyDown() ),
1497  Command( wxT("TrackMute"), XXO("M&ute/Unmute Focused Track"),
1498  FN(OnTrackMute),
1499  TracksExistFlag() | TrackPanelHasFocus(), wxT("Shift+U") ),
1500  Command( wxT("TrackSolo"), XXO("&Solo/Unsolo Focused Track"),
1501  FN(OnTrackSolo),
1502  TracksExistFlag() | TrackPanelHasFocus(), wxT("Shift+S") ),
1503  Command( wxT("TrackClose"), XXO("&Close Focused Track"),
1504  FN(OnTrackClose),
1506  wxT("Shift+C") ),
1507  Command( wxT("TrackMoveUp"), XXO("Move Focused Track U&p"),
1508  FN(OnTrackMoveUp),
1510  Command( wxT("TrackMoveDown"), XXO("Move Focused Track Do&wn"),
1511  FN(OnTrackMoveDown),
1513  Command( wxT("TrackMoveTop"), XXO("Move Focused Track to T&op"),
1514  FN(OnTrackMoveTop),
1516  Command( wxT("TrackMoveBottom"), XXO("Move Focused Track to &Bottom"),
1517  FN(OnTrackMoveBottom),
1519  ) ) };
1520  return menu;
1521 }
1522 
1524  wxT("Optional/Extra/Part2"),
1525  Shared( ExtraTrackMenu() )
1526 };
1527 
1528 }
1529 
1530 #undef FN
size
size_t size
Definition: ffmpeg-2.3.6-single-header.h:412
anonymous_namespace{TrackMenus.cpp}::sAttachment1
AttachedItem sAttachment1
Definition: TrackMenus.cpp:1464
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:241
TrackActions::Handler::OnMoveSelectionWithTracks
void OnMoveSelectionWithTracks(const CommandContext &WXUNUSED(context))
Definition: TrackMenus.cpp:925
WaveTrackConstArray
std::vector< std::shared_ptr< const WaveTrack > > WaveTrackConstArray
Definition: AudioIO.h:49
eIsCreating
@ eIsCreating
Definition: ShuttleGui.h:38
TrackActions::Handler::OnPanCenter
void OnPanCenter(const CommandContext &context)
Definition: TrackMenus.cpp:894
WaveTrackFactory::Get
static WaveTrackFactory & Get(AudacityProject &project)
Definition: WaveTrack.cpp:2890
ProjectStatus.h
TemporarySelection::pTrack
Track * pTrack
Definition: CommandContext.h:31
ShuttleGuiBase::StartVerticalLay
void StartVerticalLay(int iProp=1)
Definition: ShuttleGui.cpp:1184
WaveTrack
A Track that contains audio waveform data.
Definition: WaveTrack.h:69
BasicUI::ProgressResult::Success
@ Success
Optional
Like a smart pointer, allows for object to not exist (nullptr)
Definition: MemoryX.h:144
AudacityMessageBox
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
Definition: AudacityMessageBox.cpp:17
TrackActions::Handler::OnSortTime
void OnSortTime(const CommandContext &context)
Definition: TrackMenus.cpp:1060
MenuTable::FinderScope
Definition: CommandManager.h:485
anonymous_namespace{TrackMenus.cpp}::kAudacitySortByTime
@ kAudacitySortByTime
Definition: TrackMenus.cpp:496
flag
static std::once_flag flag
Definition: WaveformView.cpp:1119
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:1887
TrackActions::Handler::OnStereoToMono
void OnStereoToMono(const CommandContext &context)
Definition: TrackMenus.cpp:710
Track::GetName
wxString GetName() const
Definition: Track.h:426
Project.h
Track::EnsureVisible
void EnsureVisible(bool modifyState=false)
Definition: Track.cpp:100
ProjectRate::Get
static ProjectRate & Get(AudacityProject &project)
Definition: ProjectRate.cpp:42
TrackActions::Handler::OnTrackPanLeft
void OnTrackPanLeft(const CommandContext &context)
Definition: TrackMenus.cpp:1109
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:862
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:81
anonymous_namespace{TrackMenus.cpp}::kAlignLabelsCount
const size_t kAlignLabelsCount()
Definition: TrackMenus.cpp:197
TrackActions::Handler::OnUnmuteSelectedTracks
void OnUnmuteSelectedTracks(const CommandContext &context)
Definition: TrackMenus.cpp:877
TrackList::Channels
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
Definition: Track.h:1484
Format
Abstract base class used in importing a file.
TrackActions::Handler::OnPanLeft
void OnPanLeft(const CommandContext &context)
Definition: TrackMenus.cpp:882
TrackActions::Handler::OnResample
void OnResample(const CommandContext &context)
Definition: TrackMenus.cpp:730
ScoreAlignDialog
ScoreAlignDialog is \TODO.
ReservedCommandFlag
Definition: CommandFlag.h:89
EffectManager::kConfigured
@ kConfigured
Definition: EffectManager.h:53
TrackActions::Handler::OnTrackMoveBottom
void OnTrackMoveBottom(const CommandContext &context)
Definition: TrackMenus.cpp:1271
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:2459
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:227
UndoPush::NONE
@ NONE
XO
#define XO(s)
Definition: Internat.h:31
TrackActions::Handler::OnTrackMenu
void OnTrackMenu(const CommandContext &context)
Definition: TrackMenus.cpp:1175
LWSlider::Decrease
void Decrease(float steps)
Definition: ASlider.cpp:1505
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:44
TrackActions::Handler::OnNewLabelTrack
void OnNewLabelTrack(const CommandContext &context)
Definition: TrackMenus.cpp:663
LabelTrack
A LabelTrack is a Track that holds labels (LabelStruct).
Definition: LabelTrack.h:88
TrackUtilities::OnMoveDownID
@ OnMoveDownID
Definition: TrackUtilities.h:20
TrackActions::Handler::OnUnmuteAllTracks
void OnUnmuteAllTracks(const CommandContext &context)
Definition: TrackMenus.cpp:867
Track::Any
bool Any() const
Definition: Track.cpp:370
ProjectWindow::Get
static ProjectWindow & Get(AudacityProject &project)
Definition: ProjectWindow.cpp:535
anonymous_namespace{TrackMenus.cpp}::kAlignStartSelEnd
@ kAlignStartSelEnd
Definition: TrackMenus.cpp:180
AlwaysEnabledFlag
constexpr CommandFlag AlwaysEnabledFlag
Definition: CommandFlag.h:35
TrackActions
Definition: TrackMenus.cpp:607
MenuTable::AttachedItem
Definition: CommandManager.h:708
EffectManager::Get
static EffectManager & Get()
Definition: EffectManager.cpp:42
MenuManager::ModifyAllProjectToolbarMenus
static void ModifyAllProjectToolbarMenus()
Definition: Menus.cpp:584
TrackActions::Handler::MuteTracks
static void MuteTracks(const CommandContext &context, bool mute, bool selected)
Definition: TrackMenus.cpp:841
ProjectAudioIO::Get
static ProjectAudioIO & Get(AudacityProject &project)
Definition: ProjectAudioIO.cpp:22
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:51
anonymous_namespace{TrackMenus.cpp}::DoSortTracks
void DoSortTracks(AudacityProject &project, int flags)
Definition: TrackMenus.cpp:500
anonymous_namespace{TrackMenus.cpp}::kAlignTogether
@ kAlignTogether
Definition: TrackMenus.cpp:185
TrackActions::Handler::OnAlignNoSync
void OnAlignNoSync(const CommandContext &context)
Definition: TrackMenus.cpp:900
TrackActions::Handler::OnNewTimeTrack
void OnNewTimeTrack(const CommandContext &context)
Definition: TrackMenus.cpp:683
TrackActions::Handler::OnTrackSolo
void OnTrackSolo(const CommandContext &context)
Definition: TrackMenus.cpp:1197
floatSample
@ floatSample
Definition: SampleFormat.h:34
TrackActions::Handler::OnTrackMoveDown
void OnTrackMoveDown(const CommandContext &context)
Definition: TrackMenus.cpp:1245
WaveTrack::Holder
std::shared_ptr< WaveTrack > Holder
Definition: WaveTrack.h:96
LWSlider::Get
float Get(bool convert=true)
Definition: ASlider.cpp:1457
Track::GetStartTime
virtual double GetStartTime() const =0
TrackActions::Handler::OnSortName
void OnSortName(const CommandContext &context)
Definition: TrackMenus.cpp:1069
TrackActions::Handler::OnTrackGainDec
void OnTrackGainDec(const CommandContext &context)
Definition: TrackMenus.cpp:1162
NoteTrack::Clear
void Clear(double t0, double t1) override
Definition: NoteTrack.cpp:527
TrackActions::Handler::OnMixAndRender
void OnMixAndRender(const CommandContext &context)
Definition: TrackMenus.cpp:718
ProjectStatus::Set
void Set(const TranslatableString &msg, StatusBarField field=mainStatusBarField)
Definition: ProjectStatus.cpp:77
ViewInfo::selectedRegion
NotifyingSelectedRegion selectedRegion
Definition: ViewInfo.h:229
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:1523
CommandContext
CommandContext provides additional information to an 'Apply()' command. It provides the project,...
Definition: CommandContext.h:34
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:688
TrackActions::Handler::OnMixAndRenderToNewTrack
void OnMixAndRenderToNewTrack(const CommandContext &context)
Definition: TrackMenus.cpp:724
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:838
Track::IsSelected
bool IsSelected() const
Definition: Track.cpp:373
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:1130
TrackUtilities::OnMoveTopID
@ OnMoveTopID
Definition: TrackUtilities.h:20
TrackActions::Handler::OnTrackClose
void OnTrackClose(const CommandContext &context)
Definition: TrackMenus.cpp:1207
anonymous_namespace{TrackMenus.cpp}::DoMixAndRender
void DoMixAndRender(AudacityProject &project, bool toNewTrack)
Definition: TrackMenus.cpp:50
TrackFocus::Get
Track * Get()
Definition: TrackPanelAx.cpp:755
TrackActions::Handler::OnAlign
void OnAlign(const CommandContext &context)
Definition: TrackMenus.cpp:908
PluginManager::GetPlugin
const PluginDescriptor * GetPlugin(const PluginID &ID) const
Definition: PluginManager.cpp:1445
PluginDescriptor
Definition: PluginManager.h:44
ProjectRate::GetRate
double GetRate() const
Definition: ProjectRate.cpp:68
anonymous_namespace{TrackMenus.cpp}::SetTrackGain
void SetTrackGain(AudacityProject &project, WaveTrack *wt, LWSlider *slider)
Definition: TrackMenus.cpp:577
LWSlider::ShowDialog
bool ShowDialog()
Definition: ASlider.cpp:1068
anonymous_namespace{TrackMenus.cpp}::TracksMenu
BaseItemSharedPtr TracksMenu()
Definition: TrackMenus.cpp:1302
TracksExistFlag
const ReservedCommandFlag & TracksExistFlag()
Definition: CommonCommandFlags.cpp:173
PlayableTrack
AudioTrack subclass that can also be audibly replayed by the program.
Definition: Track.h:854
ViewInfo.h
TrackUtilities::DoRemoveTracks
void DoRemoveTracks(AudacityProject &project)
Definition: TrackUtilities.cpp:22
TrackActions::Handler::OnTrackGainInc
void OnTrackGainInc(const CommandContext &context)
Definition: TrackMenus.cpp:1149
FN
#define FN(X)
Definition: TrackMenus.cpp:1297
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
QualitySettings.h
TrackList::Get
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:506
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:591
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:379
TrackUtilities::DoTrackMute
void DoTrackMute(AudacityProject &project, Track *t, bool exclusive)
Definition: TrackUtilities.cpp:64
CommandContext::index
int index
Definition: CommandContext.h:67
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:675
ProjectStatus::Get
static ProjectStatus & Get(AudacityProject &project)
Definition: ProjectStatus.cpp:35
QualitySettings::SampleFormatChoice
PROJECT_RATE_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:92
TrackActions::Handler::OnTrackGain
void OnTrackGain(const CommandContext &context)
Definition: TrackMenus.cpp:1135
findCommandHandler
static CommandHandlerObject & findCommandHandler(AudacityProject &)
Definition: TrackMenus.cpp:1288
TrackActions::Handler::OnTrackPan
void OnTrackPan(const CommandContext &context)
Definition: TrackMenus.cpp:1096
anonymous_namespace{TrackMenus.cpp}::kAlignStartZero
@ kAlignStartZero
Definition: TrackMenus.cpp:178
SelectUtilities::SelectNone
void SelectNone(AudacityProject &project)
Definition: SelectUtilities.cpp:78
TrackUtilities::OnMoveBottomID
@ OnMoveBottomID
Definition: TrackUtilities.h:20
WaveTrackControls::PanSlider
static LWSlider * PanSlider(CellularPanel &panel, const WaveTrack &wt)
Definition: WaveTrackControls.cpp:1186
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:623
TrackUtilities::OnMoveUpID
@ OnMoveUpID
Definition: TrackUtilities.h:20
ProjectRate.h
an object holding per-project preferred sample rate
EffectManager::GetEffectByIdentifier
const PluginID & GetEffectByIdentifier(const CommandID &strTarget)
Definition: EffectManager.cpp:821
TrackActions::Handler::OnNewWaveTrack
void OnNewWaveTrack(const CommandContext &context)
Definition: TrackMenus.cpp:613
UndoPush::CONSOLIDATE
@ CONSOLIDATE
EffectUI::DoEffect
AUDACITY_DLL_API bool DoEffect(const PluginID &ID, const CommandContext &context, unsigned flags)
'Repeat Last Effect'.
Definition: EffectUI.cpp:1868
ShuttleGui::AddStandardButtons
void AddStandardButtons(long buttons=eOkButton|eCancelButton, wxWindow *extra=NULL)
Definition: ShuttleGui.cpp:2444
MenuTable::Section
std::unique_ptr< MenuPart > Section(const Identifier &internalName, Args &&... args)
Definition: CommandManager.h:611
Track::IsSelectedOrSyncLockSelected
bool IsSelectedOrSyncLockSelected() const
Definition: Track.cpp:376
TrackActions::Handler::OnTrackMoveTop
void OnTrackMoveTop(const CommandContext &context)
Definition: TrackMenus.cpp:1258
TrackActions::Handler::OnTrackMoveUp
void OnTrackMoveUp(const CommandContext &context)
Definition: TrackMenus.cpp:1232
Mixer::GetBuffer
constSamplePtr GetBuffer()
Retrieve the main buffer or the interleaved buffer.
Definition: Mix.cpp:713
TrackActions::Handler::OnTrackMute
void OnTrackMute(const CommandContext &context)
Definition: TrackMenus.cpp:1183
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:872
MenuTable
Definition: CommandManager.h:416
TrackActions::Handler::OnPanRight
void OnPanRight(const CommandContext &context)
Definition: TrackMenus.cpp:888
PlayableTrack::SetMute
void SetMute(bool m)
Definition: Track.cpp:327
anonymous_namespace{TrackMenus.cpp}::kAudacitySortByName
@ kAudacitySortByName
Definition: TrackMenus.cpp:497
TrackActions::Handler
Definition: TrackMenus.cpp:611
TrackActions::Handler::OnTrackPanRight
void OnTrackPanRight(const CommandContext &context)
Definition: TrackMenus.cpp:1122
TrackActions::Handler::OnNewStereoTrack
void OnNewStereoTrack(const CommandContext &context)
Definition: TrackMenus.cpp:636
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:64
TrackList::Selected
auto Selected() -> TrackIterRange< TrackType >
Definition: Track.h:1388
anonymous_namespace{Menus.cpp}::Options
std::vector< CommandFlagOptions > & Options()
Definition: Menus.cpp:527
anonymous_namespace{TrackMenus.cpp}::ExtraTrackMenu
BaseItemSharedPtr ExtraTrackMenu()
Definition: TrackMenus.cpp:1469
Mixer
Functions for doing the mixdown of the tracks.
Definition: Mix.h:76
LWSlider::Increase
void Increase(float steps)
Definition: ASlider.cpp:1482
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:755
ProjectHistory::Get
static ProjectHistory & Get(AudacityProject &project)
Definition: ProjectHistory.cpp:26
TrackActions::Handler::OnSyncLock
void OnSyncLock(const CommandContext &context)
Definition: TrackMenus.cpp:1078
NoteTrack
A Track that is used for Midi notes. (Somewhat old code).
Definition: NoteTrack.h:67
Mixer::Process
size_t Process(size_t maxSamples)
Definition: Mix.cpp:627
ShuttleGui
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:631
CommandContext::temporarySelection
TemporarySelection temporarySelection
Definition: CommandContext.h:71
TrackActions::Handler::OnRemoveTracks
void OnRemoveTracks(const CommandContext &context)
Definition: TrackMenus.cpp:836