Audacity  2.2.2
ChangeSpeed.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  ChangeSpeed.cpp
6 
7  Vaughan Johnson, Dominic Mazzoni
8 
9 *******************************************************************//*******************************************************************/
15 
16 #include "../Audacity.h"
17 #include "ChangeSpeed.h"
18 
19 #include <math.h>
20 
21 #include <wx/intl.h>
22 
23 #include "../LabelTrack.h"
24 #include "../Prefs.h"
25 #include "../Project.h"
26 #include "../Resample.h"
27 #include "../ShuttleGui.h"
28 #include "../widgets/valnum.h"
29 
30 #include "TimeWarper.h"
31 #include "../WaveTrack.h"
32 
33 enum
34 {
40 };
41 
42 // the standard vinyl rpm choices
43 // If the percent change is not one of these ratios, the choice control gets "n/a".
44 enum kVinyl
45 {
51 };
52 
53 static const wxChar *kVinylStrings[nVinyl] =
54 {
55  wxT("33\u2153"),
56  wxT("45"),
57  wxT("78"),
58  /* i18n-hint: n/a is an English abbreviation meaning "not applicable". */
59  XO("n/a"),
60 };
61 
62 // Soundtouch is not reasonable below -99% or above 3000%.
63 
64 // Define keys, defaults, minimums, and maximums for the effect parameters
65 //
66 // Name Type Key Def Min Max Scale
67 Param( Percentage, double, wxT("Percentage"), 0.0, -99.0, 4900.0, 1 );
68 
69 // We warp the slider to go up to 400%, but user can enter higher values
70 static const double kSliderMax = 100.0; // warped above zero to actually go up to 400%
71 static const double kSliderWarp = 1.30105; // warp power takes max from 100 to 400.
72 
73 //
74 // EffectChangeSpeed
75 //
76 
77 BEGIN_EVENT_TABLE(EffectChangeSpeed, wxEvtHandler)
78  EVT_TEXT(ID_PercentChange, EffectChangeSpeed::OnText_PercentChange)
79  EVT_TEXT(ID_Multiplier, EffectChangeSpeed::OnText_Multiplier)
80  EVT_SLIDER(ID_PercentChange, EffectChangeSpeed::OnSlider_PercentChange)
81  EVT_CHOICE(ID_FromVinyl, EffectChangeSpeed::OnChoice_Vinyl)
82  EVT_CHOICE(ID_ToVinyl, EffectChangeSpeed::OnChoice_Vinyl)
83  EVT_TEXT(ID_ToLength, EffectChangeSpeed::OnTimeCtrl_ToLength)
84  EVT_COMMAND(ID_ToLength, EVT_TIMETEXTCTRL_UPDATED, EffectChangeSpeed::OnTimeCtrlUpdate)
86 
88 {
89  // effect parameters
90  m_PercentChange = DEF_Percentage;
91 
92  mFromVinyl = kVinyl_33AndAThird;
93  mToVinyl = kVinyl_33AndAThird;
94  mFromLength = 0.0;
95  mToLength = 0.0;
97  mbLoopDetect = false;
98 
99  SetLinearEffectFlag(true);
100 }
101 
103 {
104 }
105 
106 // IdentInterface implementation
107 
109 {
111 }
112 
114 {
115  return _("Changes the speed of a track, also changing its pitch");
116 }
117 
119 {
120  return wxT("Change_Speed");
121 }
122 
123 
124 // EffectDefinitionInterface implementation
125 
127 {
128  return EffectTypeProcess;
129 }
130 
131 // EffectClientInterface implementation
133  S.SHUTTLE_PARAM( m_PercentChange, Percentage );
134  return true;
135 }
136 
138 {
139  parms.Write(KEY_Percentage, m_PercentChange);
140 
141  return true;
142 }
143 
145 {
146  ReadAndVerifyDouble(Percentage);
147 
148  m_PercentChange = Percentage;
149 
150  return true;
151 }
152 
154 {
157 
159 }
160 
161 // Effect implementation
162 
164 {
165  return (m_PercentChange == 0.0);
166 }
167 
168 double EffectChangeSpeed::CalcPreviewInputLength(double previewLength)
169 {
170  return previewLength * (100.0 + m_PercentChange) / 100.0;
171 }
172 
174 {
175  wxString base = wxT("/Effects/ChangeSpeed/");
176 
177  // Migrate settings from 2.1.0 or before
178 
179  // Already migrated, so bail
180  if (gPrefs->Exists(base + wxT("Migrated")))
181  {
182  return true;
183  }
184 
185  // Load the old "current" settings
186  if (gPrefs->Exists(base))
187  {
188  // Retrieve last used control values
189  gPrefs->Read(base + wxT("PercentChange"), &m_PercentChange, 0);
190 
191  wxString format;
192  gPrefs->Read(base + wxT("TimeFormat"), &format, wxString{});
194 
195  gPrefs->Read(base + wxT("VinylChoice"), &mFromVinyl, 0);
196  if (mFromVinyl == kVinyl_NA)
197  {
199  }
200 
201  SetPrivateConfig(GetCurrentSettingsGroup(), wxT("TimeFormat"), mFormat.Internal());
202  SetPrivateConfig(GetCurrentSettingsGroup(), wxT("VinylChoice"), mFromVinyl);
203 
205 
206  // Do not migrate again
207  gPrefs->Write(base + wxT("Migrated"), true);
208  gPrefs->Flush();
209  }
210 
211  return true;
212 }
213 
215 {
216  // The selection might have changed since the last time EffectChangeSpeed
217  // was invoked, so recalculate the Length parameters.
218  mFromLength = mT1 - mT0;
219  return true;
220 }
221 
223 {
224  // Similar to EffectSoundTouch::Process()
225 
226  // Iterate over each track.
227  // Track::All is needed because this effect needs to introduce
228  // silence in the sync-lock group tracks to keep sync
229  CopyInputTracks(Track::All); // Set up mOutputTracks.
230  bool bGoodResult = true;
231 
232  TrackListIterator iter(mOutputTracks.get());
233  Track* t;
234  mCurTrackNum = 0;
235  mMaxNewLength = 0.0;
236 
237  mFactor = 100.0 / (100.0 + m_PercentChange);
238 
239  t = iter.First();
240  while (t != NULL)
241  {
242  if (t->GetKind() == Track::Label) {
243  if (t->GetSelected() || t->IsSyncLockSelected())
244  {
245  if (!ProcessLabelTrack(static_cast<LabelTrack*>(t))) {
246  bGoodResult = false;
247  break;
248  }
249  }
250  }
251  else if (t->GetKind() == Track::Wave && t->GetSelected())
252  {
253  WaveTrack *pOutWaveTrack = (WaveTrack*)t;
254  //Get start and end times from track
255  mCurT0 = pOutWaveTrack->GetStartTime();
256  mCurT1 = pOutWaveTrack->GetEndTime();
257 
258  //Set the current bounds to whichever left marker is
259  //greater and whichever right marker is less:
260  mCurT0 = wxMax(mT0, mCurT0);
261  mCurT1 = wxMin(mT1, mCurT1);
262 
263  // Process only if the right marker is to the right of the left marker
264  if (mCurT1 > mCurT0) {
265  //Transform the marker timepoints to samples
266  auto start = pOutWaveTrack->TimeToLongSamples(mCurT0);
267  auto end = pOutWaveTrack->TimeToLongSamples(mCurT1);
268 
269  //ProcessOne() (implemented below) processes a single track
270  if (!ProcessOne(pOutWaveTrack, start, end))
271  {
272  bGoodResult = false;
273  break;
274  }
275  }
276  mCurTrackNum++;
277  }
278  else if (t->IsSyncLockSelected())
279  {
280  t->SyncLockAdjust(mT1, mT0 + (mT1 - mT0) * mFactor);
281  }
282 
283  //Iterate to the next track
284  t=iter.Next();
285  }
286 
287  if (bGoodResult)
288  ReplaceProcessedTracks(bGoodResult);
289 
290  // Update selection.
291  mT1 = mT0 + (((mT1 - mT0) * 100.0) / (100.0 + m_PercentChange));
292 
293  return bGoodResult;
294 }
295 
297 {
298  {
299  wxString formatId;
300  GetPrivateConfig(GetCurrentSettingsGroup(), wxT("TimeFormat"),
301  formatId, mFormat.Internal());
303  NumericConverter::TIME, formatId );
304  }
306 
307  S.SetBorder(5);
308 
309  S.StartVerticalLay(0);
310  {
311  S.AddSpace(0, 5);
312  S.AddTitle(_("Change Speed, affecting both Tempo and Pitch"));
313  S.AddSpace(0, 10);
314 
315  // Speed multiplier and percent change controls.
316  S.StartMultiColumn(4, wxCENTER);
317  {
318  FloatingPointValidator<double> vldMultiplier(3, &mMultiplier, NumValidatorStyle::THREE_TRAILING_ZEROES);
319  vldMultiplier.SetRange(MIN_Percentage / 100.0, ((MAX_Percentage / 100.0) + 1));
321  S.Id(ID_Multiplier).AddTextBox(_("Speed Multiplier:"), wxT(""), 12);
322  mpTextCtrl_Multiplier->SetValidator(vldMultiplier);
323 
324  FloatingPointValidator<double> vldPercentage(3, &m_PercentChange, NumValidatorStyle::THREE_TRAILING_ZEROES);
325  vldPercentage.SetRange(MIN_Percentage, MAX_Percentage);
327  S.Id(ID_PercentChange).AddTextBox(_("Percent Change:"), wxT(""), 12);
328  mpTextCtrl_PercentChange->SetValidator(vldPercentage);
329  }
330  S.EndMultiColumn();
331 
332  // Percent change slider.
333  S.StartHorizontalLay(wxEXPAND);
334  {
335  S.SetStyle(wxSL_HORIZONTAL);
337  S.Id(ID_PercentChange).AddSlider( {}, 0, (int)kSliderMax, (int)MIN_Percentage);
338  mpSlider_PercentChange->SetName(_("Percent Change"));
339  }
340  S.EndHorizontalLay();
341 
342  // Vinyl rpm controls.
343  S.StartMultiColumn(5, wxCENTER);
344  {
345  /* i18n-hint: "rpm" is an English abbreviation meaning "revolutions per minute". */
346  S.AddUnits(_("Standard Vinyl rpm:"));
347 
348  wxASSERT(nVinyl == WXSIZEOF(kVinylStrings));
349 
350  wxArrayString vinylChoices;
351  for (int i = 0; i < nVinyl; i++)
352  {
353  if (i == kVinyl_NA)
354  {
355  vinylChoices.Add(wxGetTranslation(kVinylStrings[i]));
356  }
357  else
358  {
359  vinylChoices.Add(kVinylStrings[i]);
360  }
361  }
362 
364  S.Id(ID_FromVinyl).AddChoice(_("from"), wxT(""), &vinylChoices);
365  mpChoice_FromVinyl->SetName(_("From rpm"));
366  mpChoice_FromVinyl->SetSizeHints(100, -1);
367 
369  S.Id(ID_ToVinyl).AddChoice(_("to"), wxT(""), &vinylChoices);
370  mpChoice_ToVinyl->SetName(_("To rpm"));
371  mpChoice_ToVinyl->SetSizeHints(100, -1);
372  }
373  S.EndMultiColumn();
374 
375  // From/To time controls.
376  S.StartStatic(_("Selection Length"), 0);
377  {
378  S.StartMultiColumn(2, wxALIGN_LEFT);
379  {
380  S.AddPrompt(_("Current Length:"));
381 
383  NumericTextCtrl(S.GetParent(), wxID_ANY,
385  mFormat,
386  mFromLength,
387  mProjectRate,
389  .ReadOnly(true)
390  .MenuEnabled(false));
391 
392  mpFromLengthCtrl->SetName(_("from"));
393  mpFromLengthCtrl->SetToolTip(_("Current length of selection."));
394  S.AddWindow(mpFromLengthCtrl, wxALIGN_LEFT);
395 
396  S.AddPrompt(_("New Length:"));
397 
401  mFormat,
402  mToLength,
403  mProjectRate);
404 
405  mpToLengthCtrl->SetName(_("to"));
406  S.AddWindow(mpToLengthCtrl, wxALIGN_LEFT);
407  }
408  S.EndMultiColumn();
409  }
410  S.EndStatic();
411  }
412  S.EndVerticalLay();
413 }
414 
416 {
417  mbLoopDetect = true;
418 
419  if (!mUIParent->TransferDataToWindow())
420  {
421  return false;
422  }
423 
424  if (mFromVinyl == kVinyl_NA)
425  {
427  }
428 
433 
434  // Set from/to Vinyl controls - mFromVinyl must be set first.
435  mpChoice_FromVinyl->SetSelection(mFromVinyl);
436  // Then update to get correct mToVinyl.
437  Update_Vinyl();
438  // Then update ToVinyl control.
439  mpChoice_ToVinyl->SetSelection(mToVinyl);
440 
441  // Set From Length control.
442  // Set the format first so we can get sample accuracy.
445 
446  mbLoopDetect = false;
447 
448  return true;
449 }
450 
452 {
453  // mUIParent->TransferDataFromWindow() loses some precision, so save and restore it.
454  double exactPercent = m_PercentChange;
455  if (!mUIParent->Validate() || !mUIParent->TransferDataFromWindow())
456  {
457  return false;
458  }
459  m_PercentChange = exactPercent;
460 
461  SetPrivateConfig(GetCurrentSettingsGroup(), wxT("TimeFormat"), mFormat.Internal());
462  SetPrivateConfig(GetCurrentSettingsGroup(), wxT("VinylChoice"), mFromVinyl);
463 
464  return true;
465 }
466 
467 // EffectChangeSpeed implementation
468 
469 // Labels are time-scaled linearly inside the affected region, and labels after
470 // the region are shifted along according to how the region size changed.
472 {
473  RegionTimeWarper warper { mT0, mT1,
474  std::make_unique<LinearTimeWarper>(mT0, mT0,
475  mT1, mT0 + (mT1-mT0)*mFactor) };
476  lt->WarpLabels(warper);
477  return true;
478 }
479 
480 // ProcessOne() takes a track, transforms it to bunch of buffer-blocks,
481 // and calls libsamplerate code on these blocks.
483  sampleCount start, sampleCount end)
484 {
485  if (track == NULL)
486  return false;
487 
488  // initialization, per examples of Mixer::Mixer and
489  // EffectSoundTouch::ProcessOne
490 
491  auto outputTrack = mFactory->NewWaveTrack(track->GetSampleFormat(),
492  track->GetRate());
493 
494  //Get the length of the selection (as double). len is
495  //used simple to calculate a progress meter, so it is easier
496  //to make it a double now than it is to do it later
497  auto len = (end - start).as_double();
498 
499  // Initiate processing buffers, most likely shorter than
500  // the length of the selection being processed.
501  auto inBufferSize = track->GetMaxBlockSize();
502 
503  Floats inBuffer{ inBufferSize };
504 
505  // mFactor is at most 100-fold so this shouldn't overflow size_t
506  auto outBufferSize = size_t( mFactor * inBufferSize + 10 );
507  Floats outBuffer{ outBufferSize };
508 
509  // Set up the resampling stuff for this track.
510  Resample resample(true, mFactor, mFactor); // constant rate resampling
511 
512  //Go through the track one buffer at a time. samplePos counts which
513  //sample the current buffer starts at.
514  bool bResult = true;
515  auto samplePos = start;
516  while (samplePos < end) {
517  //Get a blockSize of samples (smaller than the size of the buffer)
518  auto blockSize = limitSampleBufferSize(
519  track->GetBestBlockSize(samplePos),
520  end - samplePos
521  );
522 
523  //Get the samples from the track and put them in the buffer
524  track->Get((samplePtr) inBuffer.get(), floatSample, samplePos, blockSize);
525 
526  const auto results = resample.Process(mFactor,
527  inBuffer.get(),
528  blockSize,
529  ((samplePos + blockSize) >= end),
530  outBuffer.get(),
531  outBufferSize);
532  const auto outgen = results.second;
533 
534  if (outgen > 0)
535  outputTrack->Append((samplePtr)outBuffer.get(), floatSample,
536  outgen);
537 
538  // Increment samplePos
539  samplePos += results.first;
540 
541  // Update the Progress meter
542  if (TrackProgress(mCurTrackNum, (samplePos - start).as_double() / len)) {
543  bResult = false;
544  break;
545  }
546  }
547 
548  // Flush the output WaveTrack (since it's buffered, too)
549  outputTrack->Flush();
550 
551  // Take the output track and insert it in place of the original
552  // sample data
553  double newLength = outputTrack->GetEndTime();
554  if (bResult)
555  {
556  LinearTimeWarper warper { mCurT0, mCurT0, mCurT1, mCurT0 + newLength };
557  track->ClearAndPaste(
558  mCurT0, mCurT1, outputTrack.get(), true, false, &warper);
559  }
560 
561  if (newLength > mMaxNewLength)
562  mMaxNewLength = newLength;
563 
564  return bResult;
565 }
566 
567 // handler implementations for EffectChangeSpeed
568 
569 void EffectChangeSpeed::OnText_PercentChange(wxCommandEvent & WXUNUSED(evt))
570 {
571  if (mbLoopDetect)
572  return;
573 
574  mpTextCtrl_PercentChange->GetValidator()->TransferFromWindow();
575  UpdateUI();
576 
577  mbLoopDetect = true;
580  Update_Vinyl();
582  mbLoopDetect = false;
583 }
584 
585 void EffectChangeSpeed::OnText_Multiplier(wxCommandEvent & WXUNUSED(evt))
586 {
587  if (mbLoopDetect)
588  return;
589 
590  mpTextCtrl_Multiplier->GetValidator()->TransferFromWindow();
591  m_PercentChange = 100 * (mMultiplier - 1);
592  UpdateUI();
593 
594  mbLoopDetect = true;
597  Update_Vinyl();
599  mbLoopDetect = false;
600 }
601 
602 void EffectChangeSpeed::OnSlider_PercentChange(wxCommandEvent & WXUNUSED(evt))
603 {
604  if (mbLoopDetect)
605  return;
606 
607  m_PercentChange = (double)(mpSlider_PercentChange->GetValue());
608  // Warp positive values to actually go up faster & further than negatives.
609  if (m_PercentChange > 0.0)
610  m_PercentChange = pow(m_PercentChange, kSliderWarp);
611  UpdateUI();
612 
613  mbLoopDetect = true;
616  Update_Vinyl();
618  mbLoopDetect = false;
619 }
620 
621 void EffectChangeSpeed::OnChoice_Vinyl(wxCommandEvent & WXUNUSED(evt))
622 {
623  // Treat mpChoice_FromVinyl and mpChoice_ToVinyl as one control since we need
624  // both to calculate Percent Change.
625  mFromVinyl = mpChoice_FromVinyl->GetSelection();
626  mToVinyl = mpChoice_ToVinyl->GetSelection();
627  // Use this as the 'preferred' choice.
628  if (mFromVinyl != kVinyl_NA) {
629  SetPrivateConfig(GetCurrentSettingsGroup(), wxT("VinylChoice"), mFromVinyl);
630  }
631 
632  // If mFromVinyl & mToVinyl are set, then there's a NEW percent change.
633  if ((mFromVinyl != kVinyl_NA) && (mToVinyl != kVinyl_NA))
634  {
635  double fromRPM;
636  double toRPM;
637  switch (mFromVinyl) {
638  default:
639  case kVinyl_33AndAThird: fromRPM = 33.0 + (1.0 / 3.0); break;
640  case kVinyl_45: fromRPM = 45.0; break;
641  case kVinyl_78: fromRPM = 78; break;
642  }
643  switch (mToVinyl) {
644  default:
645  case kVinyl_33AndAThird: toRPM = 33.0 + (1.0 / 3.0); break;
646  case kVinyl_45: toRPM = 45.0; break;
647  case kVinyl_78: toRPM = 78; break;
648  }
649  m_PercentChange = ((toRPM * 100.0) / fromRPM) - 100.0;
650  UpdateUI();
651 
652  mbLoopDetect = true;
657  }
658  mbLoopDetect = false;
659 }
660 
661 void EffectChangeSpeed::OnTimeCtrl_ToLength(wxCommandEvent & WXUNUSED(evt))
662 {
663  if (mbLoopDetect)
664  return;
665 
667  // Division by (double) 0.0 is not an error and we want to show "infinite" in
668  // text controls, so take care that we handle infinite values when they occur.
669  m_PercentChange = ((mFromLength * 100.0) / mToLength) - 100.0;
670  UpdateUI();
671 
672  mbLoopDetect = true;
673 
677  Update_Vinyl();
678 
679  mbLoopDetect = false;
680 }
681 
682 void EffectChangeSpeed::OnTimeCtrlUpdate(wxCommandEvent & evt)
683 {
685  NumericConverter::TIME, evt.GetString() );
686 
688  // Update From/To Length controls (precision has changed).
691 }
692 
693 // helper functions
694 
696 // Update Text Percent control from percent change.
697 {
698  mpTextCtrl_PercentChange->GetValidator()->TransferToWindow();
699 }
700 
702 // Update Multiplier control from percent change.
703 {
704  mMultiplier = 1 + (m_PercentChange) / 100.0;
705  mpTextCtrl_Multiplier->GetValidator()->TransferToWindow();
706 }
707 
709 // Update Slider Percent control from percent change.
710 {
711  auto unwarped = std::min<double>(m_PercentChange, MAX_Percentage);
712  if (unwarped > 0.0)
713  // Un-warp values above zero to actually go up to kSliderMax.
714  unwarped = pow(m_PercentChange, (1.0 / kSliderWarp));
715 
716  // Caution: m_PercentChange could be infinite.
717  int unwarpedi = (int)(unwarped + 0.5);
718  unwarpedi = std::min<int>(unwarpedi, (int)kSliderMax);
719 
720  mpSlider_PercentChange->SetValue(unwarpedi);
721 }
722 
724 // Update Vinyl controls from percent change.
725 {
726  // Match Vinyl rpm when within 0.01% of a standard ratio.
727  // Ratios calculated as: ((toRPM / fromRPM) - 1) * 100 * 100
728 
729  // Caution: m_PercentChange could be infinite
730  int ratio = (int)((m_PercentChange * 100) + 0.5);
731 
732  switch (ratio)
733  {
734  case 0: // toRPM is the same as fromRPM
735  if (mFromVinyl != kVinyl_NA) {
736  mpChoice_ToVinyl->SetSelection(mpChoice_FromVinyl->GetSelection());
737  } else {
738  // Use the last saved option.
739  GetPrivateConfig(GetCurrentSettingsGroup(), wxT("VinylChoice"), mFromVinyl, 0);
740  mpChoice_FromVinyl->SetSelection(mFromVinyl);
741  mpChoice_ToVinyl->SetSelection(mFromVinyl);
742  }
743  break;
744  case 3500:
745  mpChoice_FromVinyl->SetSelection(kVinyl_33AndAThird);
746  mpChoice_ToVinyl->SetSelection(kVinyl_45);
747  break;
748  case 13400:
749  mpChoice_FromVinyl->SetSelection(kVinyl_33AndAThird);
750  mpChoice_ToVinyl->SetSelection(kVinyl_78);
751  break;
752  case -2593:
753  mpChoice_FromVinyl->SetSelection(kVinyl_45);
754  mpChoice_ToVinyl->SetSelection(kVinyl_33AndAThird);
755  break;
756  case 7333:
757  mpChoice_FromVinyl->SetSelection(kVinyl_45);
758  mpChoice_ToVinyl->SetSelection(kVinyl_78);
759  break;
760  case -5727:
761  mpChoice_FromVinyl->SetSelection(kVinyl_78);
762  mpChoice_ToVinyl->SetSelection(kVinyl_33AndAThird);
763  break;
764  case -4231:
765  mpChoice_FromVinyl->SetSelection(kVinyl_78);
766  mpChoice_ToVinyl->SetSelection(kVinyl_45);
767  break;
768  default:
769  mpChoice_ToVinyl->SetSelection(kVinyl_NA);
770  }
771  // and update variables.
772  mFromVinyl = mpChoice_FromVinyl->GetSelection();
773  mToVinyl = mpChoice_ToVinyl->GetSelection();
774 }
775 
777 // Update ToLength control from percent change.
778 {
779  mToLength = (mFromLength * 100.0) / (100.0 + m_PercentChange);
780 
781  // Set the format first so we can get sample accuracy.
783  // Negative times do not make sense.
784  // 359999 = 99h:59m:59s which is a little less disturbing than overflow characters
785  // though it may still look a bit strange with some formats.
786  mToLength = TrapDouble(mToLength, 0.0, 359999.0);
788 }
789 
791 // Disable OK and Preview if not in sensible range.
792 {
793  EnableApply(m_PercentChange >= MIN_Percentage && m_PercentChange <= MAX_Percentage);
794 }
bool GetAutomationParameters(CommandParameters &parms) override
static const wxChar * kVinylStrings[nVinyl]
Definition: ChangeSpeed.cpp:53
wxString ManualPage() override
double mT1
Definition: Effect.h:461
AudacityPrefs * gPrefs
Definition: Prefs.cpp:73
bool SaveUserPreset(const wxString &name) override
Definition: Effect.cpp:600
void Update_Slider_PercentChange()
EVT_COMMAND(wxID_ANY, EVT_FREQUENCYTEXTCTRL_UPDATED, LabelDialog::OnFreqUpdate) LabelDialog
Definition: LabelDialog.cpp:89
bool TrackProgress(int whichTrack, double frac, const wxString &=wxEmptyString)
Definition: Effect.cpp:1985
static const double kSliderMax
Definition: ChangeSpeed.cpp:70
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI...
Definition: ShuttleGui.h:409
bool GetPrivateConfig(const wxString &group, const wxString &key, wxString &value, const wxString &defval=wxEmptyString) override
Definition: Effect.cpp:897
wxString GetCurrentSettingsGroup() override
Definition: Effect.cpp:801
void CopyInputTracks()
Definition: Effect.cpp:2036
wxWindow * AddWindow(wxWindow *pWindow, int Flags=wxALIGN_CENTRE|wxALL)
Definition: ShuttleGui.cpp:288
bool TransferDataToWindow() override
void ReplaceProcessedTracks(const bool bGoodResult)
Definition: Effect.cpp:2162
void OnTimeCtrlUpdate(wxCommandEvent &evt)
void EndMultiColumn()
wxTextCtrl * mpTextCtrl_Multiplier
Definition: ChangeSpeed.h:107
void ClearAndPaste(double t0, double t1, const Track *src, bool preserve=true, bool merge=true, const TimeWarper *effectWarper=NULL)
Definition: WaveTrack.cpp:782
wxSlider * mpSlider_PercentChange
Definition: ChangeSpeed.h:108
void Update_TimeCtrl_ToLength()
double m_PercentChange
Definition: ChangeSpeed.h:94
#define XO(s)
Definition: Internat.h:33
bool ProcessOne(WaveTrack *t, sampleCount start, sampleCount end)
double GetEndTime() const override
Get the time at which the last clip in the track ends, plus recorded stuff.
Definition: WaveTrack.cpp:1873
An Effect that affects both pitch & speed.
Definition: ChangeSpeed.h:30
wxChoice * mpChoice_FromVinyl
Definition: ChangeSpeed.h:109
Shuttle that deals with parameters. This is a base class with lots of virtual functions that do nothi...
Definition: Shuttle.h:60
size_t GetBestBlockSize(sampleCount t) const
Definition: WaveTrack.cpp:1607
bool SetPrivateConfig(const wxString &group, const wxString &key, const wxString &value) override
Definition: Effect.cpp:922
No change before the specified region; during the region, warp according to the given warper; after t...
Definition: TimeWarper.h:192
#define safenew
Definition: Audacity.h:230
wxTextCtrl * mpTextCtrl_PercentChange
Definition: ChangeSpeed.h:106
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
Definition: Types.h:178
void EndHorizontalLay()
bool TransferDataFromWindow() override
A LabelTrack is a Track that holds labels (LabelStruct).
Definition: LabelTrack.h:113
void PopulateOrExchange(ShuttleGui &S) override
void AddUnits(const wxString &Prompt)
Left aligned text string.
Definition: ShuttleGui.cpp:260
void AddPrompt(const wxString &Prompt)
Right aligned text string.
Definition: ShuttleGui.cpp:239
void Update_Text_PercentChange()
Contains declarations for TimeWarper, IdentityTimeWarper, ShiftTimeWarper, LinearTimeWarper, LinearInputRateSlideTimeWarper, LinearOutputRateSlideTimeWarper, LinearInputInverseRateTimeWarper, GeometricInputRateTimeWarper, GeometricOutputRateTimeWarper classes.
NumericTextCtrl * mpFromLengthCtrl
Definition: ChangeSpeed.h:111
void EndVerticalLay()
double GetStartTime() const override
Get the time at which the first clip in the track starts.
Definition: WaveTrack.cpp:1853
static const double kSliderWarp
Definition: ChangeSpeed.cpp:71
Linear scaling, initialised by giving two points on the line.
Definition: TimeWarper.h:86
Param(Percentage, double, wxT("Percentage"), 0.0,-99.0, 4900.0, 1)
bool Init() override
wxTextCtrl * AddTextBox(const wxString &Caption, const wxString &Value, const int nChars)
Definition: ShuttleGui.cpp:540
int format
Definition: ExportPCM.cpp:56
static NumericFormatId LookupFormat(Type type, const wxString &id)
virtual ~EffectChangeSpeed()
wxWindow * GetParent()
Definition: ShuttleGui.h:294
void StartHorizontalLay(int PositionFlags=wxALIGN_CENTRE, int iProp=1)
void StartMultiColumn(int nCols, int PositionFlags=wxALIGN_LEFT)
void WarpLabels(const TimeWarper &warper)
Definition: LabelTrack.cpp:256
Options & MenuEnabled(bool value)
wxChoice * AddChoice(const wxString &Prompt, const wxString &Selected, const wxArrayString *pChoices)
Definition: ShuttleGui.cpp:371
CommandParameters, derived from wxFileConfig, is essentially doing the same things as the Shuttle cla...
void OnChoice_Vinyl(wxCommandEvent &evt)
char * samplePtr
Definition: Types.h:203
A Track that contains audio waveform data.
Definition: WaveTrack.h:60
ShuttleGui & Id(int id)
bool SetAutomationParameters(CommandParameters &parms) override
void OnTimeCtrl_ToLength(wxCommandEvent &evt)
Fundamental data object of Audacity, placed in the TrackPanel. Classes derived form it include the Wa...
Definition: Track.h:101
void SetStyle(int Style)
Definition: ShuttleGui.h:287
#define ReadAndVerifyDouble(name)
Definition: Effect.h:798
void AddTitle(const wxString &Prompt)
Centred text string.
Definition: ShuttleGui.cpp:274
NumericFormatId mFormat
Definition: ChangeSpeed.h:118
IdentInterfaceSymbol pairs a persistent string identifier used internally with an optional...
size_t GetMaxBlockSize() const
Definition: WaveTrack.cpp:1625
void SetValue(double newValue)
wxChoice * mpChoice_ToVinyl
Definition: ChangeSpeed.h:110
std::unique_ptr< WaveTrack > NewWaveTrack(sampleFormat format=(sampleFormat) 0, double rate=0)
Definition: WaveTrack.cpp:78
wxWindow * mUIParent
Definition: Effect.h:472
An iterator for a TrackList.
Definition: Track.h:401
double TrapDouble(double x, double min, double max)
Definition: Effect.h:729
void SetFormatName(const NumericFormatId &formatName)
double mProjectRate
Definition: Effect.h:453
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom")).Raw()), OnMoveTrack)#define SET_TRACK_NAME_PLUGIN_SYMBOLclass SetTrackNameCommand:public AudacityCommand
TrackFactory * mFactory
Definition: Effect.h:457
void OnText_Multiplier(wxCommandEvent &evt)
Options & ReadOnly(bool value)
double CalcPreviewInputLength(double previewLength) override
#define CHANGESPEED_PLUGIN_SYMBOL
Definition: ChangeSpeed.h:28
EffectType GetType() override
EffectType
Interface to libsoxr.
Definition: Resample.h:32
double mMaxNewLength
Definition: ChangeSpeed.h:89
IdentInterfaceSymbol GetSymbol() override
bool CheckWhetherSkipEffect() override
sampleCount TimeToLongSamples(double t0) const
Convert correctly between an (absolute) time in seconds and a number of samples.
Definition: WaveTrack.cpp:1843
const wxString & Internal() const
sampleFormat GetSampleFormat() const
Definition: WaveTrack.h:146
bool LoadFactoryDefaults() override
Definition: Effect.cpp:636
wxStaticBox * StartStatic(const wxString &Str, int iProp=0)
Definition: ShuttleGui.cpp:763
bool Startup() override
void OnSlider_PercentChange(wxCommandEvent &evt)
bool ProcessLabelTrack(LabelTrack *t)
void OnText_PercentChange(wxCommandEvent &evt)
std::pair< size_t, size_t > Process(double factor, float *inBuffer, size_t inBufferLen, bool lastFlag, float *outBuffer, size_t outBufferLen)
Main processing function. Resamples from the input buffer to the output buffer.
Definition: Resample.cpp:106
bool DefineParams(ShuttleParams &S) override
bool LoadFactoryDefaults() override
static NumericFormatId DefaultSelectionFormat()
wxString GetDescription() override
kVinyl
Definition: ChangeSpeed.cpp:44
END_EVENT_TABLE()
wxSizerItem * AddSpace(int width, int height)
double GetRate() const
Definition: WaveTrack.cpp:398
bool Get(samplePtr buffer, sampleFormat format, sampleCount start, size_t len, fillFormat fill=fillZero, bool mayThrow=true, sampleCount *pNumCopied=nullptr) const
Definition: WaveTrack.cpp:1971
void SetBorder(int Border)
Definition: ShuttleGui.h:286
std::shared_ptr< TrackList > mOutputTracks
Definition: Effect.h:459
void Update_Text_Multiplier()
virtual bool EnableApply(bool enable=true)
Definition: Effect.cpp:1886
double mT0
Definition: Effect.h:460
bool Process() override
NumericTextCtrl * mpToLengthCtrl
Definition: ChangeSpeed.h:112
wxSlider * AddSlider(const wxString &Prompt, int pos, int Max, int Min=0)
Definition: ShuttleGui.cpp:497
void StartVerticalLay(int iProp=1)