Audacity  3.0.3
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 
17 #include "ChangeSpeed.h"
18 #include "LoadEffects.h"
19 
20 #include <math.h>
21 
22 #include <wx/choice.h>
23 #include <wx/intl.h>
24 #include <wx/slider.h>
25 
26 #include "../LabelTrack.h"
27 #include "Prefs.h"
28 #include "Resample.h"
29 #include "../Shuttle.h"
30 #include "../ShuttleGui.h"
31 #include "../widgets/NumericTextCtrl.h"
32 #include "../widgets/valnum.h"
33 
34 #include "TimeWarper.h"
35 #include "../WaveClip.h"
36 #include "../WaveTrack.h"
37 
38 enum
39 {
45 };
46 
47 // the standard vinyl rpm choices
48 // If the percent change is not one of these ratios, the choice control gets "n/a".
49 enum kVinyl
50 {
54  kVinyl_NA
55 };
56 
58  XO("33\u2153"),
59  XO("45"),
60  XO("78"),
61  /* i18n-hint: n/a is an English abbreviation meaning "not applicable". */
62  XO("n/a"),
63 };
64 
65 // Soundtouch is not reasonable below -99% or above 3000%.
66 
67 // Define keys, defaults, minimums, and maximums for the effect parameters
68 //
69 // Name Type Key Def Min Max Scale
70 Param( Percentage, double, wxT("Percentage"), 0.0, -99.0, 4900.0, 1 );
71 
72 // We warp the slider to go up to 400%, but user can enter higher values
73 static const double kSliderMax = 100.0; // warped above zero to actually go up to 400%
74 static const double kSliderWarp = 1.30105; // warp power takes max from 100 to 400.
75 
76 //
77 // EffectChangeSpeed
78 //
79 
81 { XO("Change Speed") };
82 
84 
85 BEGIN_EVENT_TABLE(EffectChangeSpeed, wxEvtHandler)
94 
96 {
97  // effect parameters
98  m_PercentChange = DEF_Percentage;
99 
100  mFromVinyl = kVinyl_33AndAThird;
101  mToVinyl = kVinyl_33AndAThird;
102  mFromLength = 0.0;
103  mToLength = 0.0;
105  mbLoopDetect = false;
106 
107  SetLinearEffectFlag(true);
108 }
109 
111 {
112 }
113 
114 // ComponentInterface implementation
115 
117 {
118  return Symbol;
119 }
120 
122 {
123  return XO("Changes the speed of a track, also changing its pitch");
124 }
125 
127 {
128  return L"Change_Speed";
129 }
130 
131 
132 // EffectDefinitionInterface implementation
133 
135 {
136  return EffectTypeProcess;
137 }
138 
139 // EffectClientInterface implementation
141  S.SHUTTLE_PARAM( m_PercentChange, Percentage );
142  return true;
143 }
144 
146 {
147  parms.Write(KEY_Percentage, m_PercentChange);
148 
149  return true;
150 }
151 
153 {
154  ReadAndVerifyDouble(Percentage);
155 
156  m_PercentChange = Percentage;
157 
158  return true;
159 }
160 
162 {
165 
167 }
168 
169 // Effect implementation
170 
172 {
173  return (m_PercentChange == 0.0);
174 }
175 
176 double EffectChangeSpeed::CalcPreviewInputLength(double previewLength)
177 {
178  return previewLength * (100.0 + m_PercentChange) / 100.0;
179 }
180 
182 {
183  wxString base = wxT("/Effects/ChangeSpeed/");
184 
185  // Migrate settings from 2.1.0 or before
186 
187  // Already migrated, so bail
188  if (gPrefs->Exists(base + wxT("Migrated")))
189  {
190  return true;
191  }
192 
193  // Load the old "current" settings
194  if (gPrefs->Exists(base))
195  {
196  // Retrieve last used control values
197  gPrefs->Read(base + wxT("PercentChange"), &m_PercentChange, 0);
198 
199  wxString format;
200  gPrefs->Read(base + wxT("TimeFormat"), &format, wxString{});
202 
203  gPrefs->Read(base + wxT("VinylChoice"), &mFromVinyl, 0);
204  if (mFromVinyl == kVinyl_NA)
205  {
207  }
208 
209  SetPrivateConfig(GetCurrentSettingsGroup(), wxT("TimeFormat"), mFormat.Internal());
210  SetPrivateConfig(GetCurrentSettingsGroup(), wxT("VinylChoice"), mFromVinyl);
211 
213 
214  // Do not migrate again
215  gPrefs->Write(base + wxT("Migrated"), true);
216  gPrefs->Flush();
217  }
218 
219  return true;
220 }
221 
223 {
224  // The selection might have changed since the last time EffectChangeSpeed
225  // was invoked, so recalculate the Length parameters.
226  mFromLength = mT1 - mT0;
227  return true;
228 }
229 
231 {
232  // Similar to EffectSoundTouch::Process()
233 
234  // Iterate over each track.
235  // All needed because this effect needs to introduce
236  // silence in the sync-lock group tracks to keep sync
237  CopyInputTracks(true); // Set up mOutputTracks.
238  bool bGoodResult = true;
239 
240  mCurTrackNum = 0;
241  mMaxNewLength = 0.0;
242 
243  mFactor = 100.0 / (100.0 + m_PercentChange);
244 
245  mOutputTracks->Any().VisitWhile( bGoodResult,
246  [&](LabelTrack *lt) {
247  if (lt->GetSelected() || lt->IsSyncLockSelected())
248  {
249  if (!ProcessLabelTrack(lt))
250  bGoodResult = false;
251  }
252  },
253  [&](WaveTrack *pOutWaveTrack, const Track::Fallthrough &fallthrough) {
254  if (!pOutWaveTrack->GetSelected())
255  return fallthrough();
256 
257  //Get start and end times from track
258  mCurT0 = pOutWaveTrack->GetStartTime();
259  mCurT1 = pOutWaveTrack->GetEndTime();
260 
261  //Set the current bounds to whichever left marker is
262  //greater and whichever right marker is less:
263  mCurT0 = wxMax(mT0, mCurT0);
264  mCurT1 = wxMin(mT1, mCurT1);
265 
266  // Process only if the right marker is to the right of the left marker
267  if (mCurT1 > mCurT0) {
268  //Transform the marker timepoints to samples
269  auto start = pOutWaveTrack->TimeToLongSamples(mCurT0);
270  auto end = pOutWaveTrack->TimeToLongSamples(mCurT1);
271 
272  //ProcessOne() (implemented below) processes a single track
273  if (!ProcessOne(pOutWaveTrack, start, end))
274  bGoodResult = false;
275  }
276  mCurTrackNum++;
277  },
278  [&](Track *t) {
279  if (t->IsSyncLockSelected())
280  t->SyncLockAdjust(mT1, mT0 + (mT1 - mT0) * mFactor);
281  }
282  );
283 
284  if (bGoodResult)
285  ReplaceProcessedTracks(bGoodResult);
286 
287  // Update selection.
288  mT1 = mT0 + (((mT1 - mT0) * 100.0) / (100.0 + m_PercentChange));
289 
290  return bGoodResult;
291 }
292 
294 {
295  {
296  wxString formatId;
297  GetPrivateConfig(GetCurrentSettingsGroup(), wxT("TimeFormat"),
298  formatId, mFormat.Internal());
300  NumericConverter::TIME, formatId );
301  }
303 
304  S.SetBorder(5);
305 
306  S.StartVerticalLay(0);
307  {
308  S.AddSpace(0, 5);
309  S.AddTitle(XO("Change Speed, affecting both Tempo and Pitch"));
310  S.AddSpace(0, 10);
311 
312  // Speed multiplier and percent change controls.
313  S.StartMultiColumn(4, wxCENTER);
314  {
316  .Validator<FloatingPointValidator<double>>(
317  3, &mMultiplier,
318  NumValidatorStyle::THREE_TRAILING_ZEROES,
319  MIN_Percentage / 100.0, ((MAX_Percentage / 100.0) + 1)
320  )
321  .AddTextBox(XXO("&Speed Multiplier:"), wxT(""), 12);
322 
324  .Validator<FloatingPointValidator<double>>(
325  3, &m_PercentChange,
326  NumValidatorStyle::THREE_TRAILING_ZEROES,
327  MIN_Percentage, MAX_Percentage
328  )
329  .AddTextBox(XXO("Percent C&hange:"), wxT(""), 12);
330  }
331  S.EndMultiColumn();
332 
333  // Percent change slider.
334  S.StartHorizontalLay(wxEXPAND);
335  {
337  .Name(XO("Percent Change"))
338  .Style(wxSL_HORIZONTAL)
339  .AddSlider( {}, 0, (int)kSliderMax, (int)MIN_Percentage);
340  }
341  S.EndHorizontalLay();
342 
343  // Vinyl rpm controls.
344  S.StartMultiColumn(5, wxCENTER);
345  {
346  /* i18n-hint: "rpm" is an English abbreviation meaning "revolutions per minute".
347  "vinyl" refers to old-fashioned phonograph records */
348  S.AddUnits(XO("Standard Vinyl rpm:"));
349 
351  /* i18n-hint: changing speed of audio "from" one value "to" another
352  "rpm" means "revolutions per minute" as on a vinyl record turntable
353  */
354  .Name(XO("From rpm"))
355  .MinSize( { 100, -1 } )
356  /* i18n-hint: changing speed of audio "from" one value "to" another */
357  .AddChoice(XXC("&from", "change speed"), kVinylStrings);
358 
360  /* i18n-hint: changing speed of audio "from" one value "to" another
361  "rpm" means "revolutions per minute" as on a vinyl record turntable
362  */
363  .Name(XO("To rpm"))
364  .MinSize( { 100, -1 } )
365  /* i18n-hint: changing speed of audio "from" one value "to" another */
366  .AddChoice(XXC("&to", "change speed"), kVinylStrings);
367  }
368  S.EndMultiColumn();
369 
370  // From/To time controls.
371  S.StartStatic(XO("Selection Length"), 0);
372  {
373  S.StartMultiColumn(2, wxALIGN_LEFT);
374  {
375  S.AddPrompt(XXO("C&urrent Length:"));
376 
378  NumericTextCtrl(S.GetParent(), wxID_ANY,
380  mFormat,
381  mFromLength,
382  mProjectRate,
384  .ReadOnly(true)
385  .MenuEnabled(false));
386 
387  S.ToolTip(XO("Current length of selection."))
388  /* i18n-hint: changing speed of audio "from" one value "to" another */
389  .Name(XC("from", "change speed"))
390  .Position(wxALIGN_LEFT)
392 
393  S.AddPrompt(XXO("&New Length:"));
394 
398  mFormat,
399  mToLength,
400  mProjectRate);
401 
402  /* i18n-hint: changing speed of audio "from" one value "to" another */
403  S.Name(XC("to", "change speed"))
404  .Position(wxALIGN_LEFT)
406  }
407  S.EndMultiColumn();
408  }
409  S.EndStatic();
410  }
411  S.EndVerticalLay();
412 }
413 
415 {
416  mbLoopDetect = true;
417 
418  if (!mUIParent->TransferDataToWindow())
419  {
420  return false;
421  }
422 
423  if (mFromVinyl == kVinyl_NA)
424  {
426  }
427 
432 
433  // Set from/to Vinyl controls - mFromVinyl must be set first.
434  mpChoice_FromVinyl->SetSelection(mFromVinyl);
435  // Then update to get correct mToVinyl.
436  Update_Vinyl();
437  // Then update ToVinyl control.
438  mpChoice_ToVinyl->SetSelection(mToVinyl);
439 
440  // Set From Length control.
441  // Set the format first so we can get sample accuracy.
444 
445  mbLoopDetect = false;
446 
447  return true;
448 }
449 
451 {
452  // mUIParent->TransferDataFromWindow() loses some precision, so save and restore it.
453  double exactPercent = m_PercentChange;
454  if (!mUIParent->Validate() || !mUIParent->TransferDataFromWindow())
455  {
456  return false;
457  }
458  m_PercentChange = exactPercent;
459 
460  SetPrivateConfig(GetCurrentSettingsGroup(), wxT("TimeFormat"), mFormat.Internal());
461  SetPrivateConfig(GetCurrentSettingsGroup(), wxT("VinylChoice"), mFromVinyl);
462 
463  return true;
464 }
465 
466 // EffectChangeSpeed implementation
467 
468 // Labels are time-scaled linearly inside the affected region, and labels after
469 // the region are shifted along according to how the region size changed.
471 {
472  RegionTimeWarper warper { mT0, mT1,
473  std::make_unique<LinearTimeWarper>(mT0, mT0,
474  mT1, mT0 + (mT1-mT0)*mFactor) };
475  lt->WarpLabels(warper);
476  return true;
477 }
478 
479 // ProcessOne() takes a track, transforms it to bunch of buffer-blocks,
480 // and calls libsamplerate code on these blocks.
482  sampleCount start, sampleCount end)
483 {
484  if (track == NULL)
485  return false;
486 
487  // initialization, per examples of Mixer::Mixer and
488  // EffectSoundTouch::ProcessOne
489 
490 
491  auto outputTrack = track->EmptyCopy();
492 
493  //Get the length of the selection (as double). len is
494  //used simple to calculate a progress meter, so it is easier
495  //to make it a double now than it is to do it later
496  auto len = (end - start).as_double();
497 
498  // Initiate processing buffers, most likely shorter than
499  // the length of the selection being processed.
500  auto inBufferSize = track->GetMaxBlockSize();
501 
502  Floats inBuffer{ inBufferSize };
503 
504  // mFactor is at most 100-fold so this shouldn't overflow size_t
505  auto outBufferSize = size_t( mFactor * inBufferSize + 10 );
506  Floats outBuffer{ outBufferSize };
507 
508  // Set up the resampling stuff for this track.
509  Resample resample(true, mFactor, mFactor); // constant rate resampling
510 
511  //Go through the track one buffer at a time. samplePos counts which
512  //sample the current buffer starts at.
513  bool bResult = true;
514  auto samplePos = start;
515  while (samplePos < end) {
516  //Get a blockSize of samples (smaller than the size of the buffer)
517  auto blockSize = limitSampleBufferSize(
518  track->GetBestBlockSize(samplePos),
519  end - samplePos
520  );
521 
522  //Get the samples from the track and put them in the buffer
523  track->GetFloats(inBuffer.get(), samplePos, blockSize);
524 
525  const auto results = resample.Process(mFactor,
526  inBuffer.get(),
527  blockSize,
528  ((samplePos + blockSize) >= end),
529  outBuffer.get(),
530  outBufferSize);
531  const auto outgen = results.second;
532 
533  if (outgen > 0)
534  outputTrack->Append((samplePtr)outBuffer.get(), floatSample,
535  outgen);
536 
537  // Increment samplePos
538  samplePos += results.first;
539 
540  // Update the Progress meter
541  if (TrackProgress(mCurTrackNum, (samplePos - start).as_double() / len)) {
542  bResult = false;
543  break;
544  }
545  }
546 
547  // Flush the output WaveTrack (since it's buffered, too)
548  outputTrack->Flush();
549 
550  // Take the output track and insert it in place of the original
551  // sample data
552  double newLength = outputTrack->GetEndTime();
553  if (bResult)
554  {
555  // Silenced samples will be inserted in gaps between clips, so capture where these
556  // gaps are for later deletion
557  std::vector<std::pair<double, double>> gaps;
558  double last = mCurT0;
559  auto clips = track->SortedClipArray();
560  auto front = clips.front();
561  auto back = clips.back();
562  for (auto &clip : clips) {
563  auto st = clip->GetPlayStartTime();
564  auto et = clip->GetPlayEndTime();
565 
566  if (st >= mCurT0 || et < mCurT1) {
567  if (mCurT0 < st && clip == front) {
568  gaps.push_back(std::make_pair(mCurT0, st));
569  }
570  else if (last < st && mCurT0 <= last ) {
571  gaps.push_back(std::make_pair(last, st));
572  }
573 
574  if (et < mCurT1 && clip == back) {
575  gaps.push_back(std::make_pair(et, mCurT1));
576  }
577  }
578  last = et;
579  }
580 
581  LinearTimeWarper warper { mCurT0, mCurT0, mCurT1, mCurT0 + newLength };
582 
583  // Take the output track and insert it in place of the original sample data
584  track->ClearAndPaste(mCurT0, mCurT1, outputTrack.get(), true, true, &warper);
585 
586  // Finally, recreate the gaps
587  for (auto gap : gaps) {
588  auto st = track->LongSamplesToTime(track->TimeToLongSamples(gap.first));
589  auto et = track->LongSamplesToTime(track->TimeToLongSamples(gap.second));
590  if (st >= mCurT0 && et <= mCurT1 && st != et)
591  {
592  track->SplitDelete(warper.Warp(st), warper.Warp(et));
593  }
594  }
595  }
596 
597  if (newLength > mMaxNewLength)
598  mMaxNewLength = newLength;
599 
600  return bResult;
601 }
602 
603 // handler implementations for EffectChangeSpeed
604 
605 void EffectChangeSpeed::OnText_PercentChange(wxCommandEvent & WXUNUSED(evt))
606 {
607  if (mbLoopDetect)
608  return;
609 
610  mpTextCtrl_PercentChange->GetValidator()->TransferFromWindow();
611  UpdateUI();
612 
613  mbLoopDetect = true;
616  Update_Vinyl();
618  mbLoopDetect = false;
619 }
620 
621 void EffectChangeSpeed::OnText_Multiplier(wxCommandEvent & WXUNUSED(evt))
622 {
623  if (mbLoopDetect)
624  return;
625 
626  mpTextCtrl_Multiplier->GetValidator()->TransferFromWindow();
627  m_PercentChange = 100 * (mMultiplier - 1);
628  UpdateUI();
629 
630  mbLoopDetect = true;
633  Update_Vinyl();
635  mbLoopDetect = false;
636 }
637 
638 void EffectChangeSpeed::OnSlider_PercentChange(wxCommandEvent & WXUNUSED(evt))
639 {
640  if (mbLoopDetect)
641  return;
642 
643  m_PercentChange = (double)(mpSlider_PercentChange->GetValue());
644  // Warp positive values to actually go up faster & further than negatives.
645  if (m_PercentChange > 0.0)
647  UpdateUI();
648 
649  mbLoopDetect = true;
652  Update_Vinyl();
654  mbLoopDetect = false;
655 }
656 
657 void EffectChangeSpeed::OnChoice_Vinyl(wxCommandEvent & WXUNUSED(evt))
658 {
659  // Treat mpChoice_FromVinyl and mpChoice_ToVinyl as one control since we need
660  // both to calculate Percent Change.
661  mFromVinyl = mpChoice_FromVinyl->GetSelection();
662  mToVinyl = mpChoice_ToVinyl->GetSelection();
663  // Use this as the 'preferred' choice.
664  if (mFromVinyl != kVinyl_NA) {
665  SetPrivateConfig(GetCurrentSettingsGroup(), wxT("VinylChoice"), mFromVinyl);
666  }
667 
668  // If mFromVinyl & mToVinyl are set, then there's a NEW percent change.
669  if ((mFromVinyl != kVinyl_NA) && (mToVinyl != kVinyl_NA))
670  {
671  double fromRPM;
672  double toRPM;
673  switch (mFromVinyl) {
674  default:
675  case kVinyl_33AndAThird: fromRPM = 33.0 + (1.0 / 3.0); break;
676  case kVinyl_45: fromRPM = 45.0; break;
677  case kVinyl_78: fromRPM = 78; break;
678  }
679  switch (mToVinyl) {
680  default:
681  case kVinyl_33AndAThird: toRPM = 33.0 + (1.0 / 3.0); break;
682  case kVinyl_45: toRPM = 45.0; break;
683  case kVinyl_78: toRPM = 78; break;
684  }
685  m_PercentChange = ((toRPM * 100.0) / fromRPM) - 100.0;
686  UpdateUI();
687 
688  mbLoopDetect = true;
693  }
694  mbLoopDetect = false;
695 }
696 
697 void EffectChangeSpeed::OnTimeCtrl_ToLength(wxCommandEvent & WXUNUSED(evt))
698 {
699  if (mbLoopDetect)
700  return;
701 
703  // Division by (double) 0.0 is not an error and we want to show "infinite" in
704  // text controls, so take care that we handle infinite values when they occur.
705  m_PercentChange = ((mFromLength * 100.0) / mToLength) - 100.0;
706  UpdateUI();
707 
708  mbLoopDetect = true;
709 
713  Update_Vinyl();
714 
715  mbLoopDetect = false;
716 }
717 
718 void EffectChangeSpeed::OnTimeCtrlUpdate(wxCommandEvent & evt)
719 {
721  NumericConverter::TIME, evt.GetString() );
722 
724  // Update From/To Length controls (precision has changed).
727 }
728 
729 // helper functions
730 
732 // Update Text Percent control from percent change.
733 {
734  mpTextCtrl_PercentChange->GetValidator()->TransferToWindow();
735 }
736 
738 // Update Multiplier control from percent change.
739 {
740  mMultiplier = 1 + (m_PercentChange) / 100.0;
741  mpTextCtrl_Multiplier->GetValidator()->TransferToWindow();
742 }
743 
745 // Update Slider Percent control from percent change.
746 {
747  auto unwarped = std::min<double>(m_PercentChange, MAX_Percentage);
748  if (unwarped > 0.0)
749  // Un-warp values above zero to actually go up to kSliderMax.
750  unwarped = pow(m_PercentChange, (1.0 / kSliderWarp));
751 
752  // Caution: m_PercentChange could be infinite.
753  int unwarpedi = (int)(unwarped + 0.5);
754  unwarpedi = std::min<int>(unwarpedi, (int)kSliderMax);
755 
756  mpSlider_PercentChange->SetValue(unwarpedi);
757 }
758 
760 // Update Vinyl controls from percent change.
761 {
762  // Match Vinyl rpm when within 0.01% of a standard ratio.
763  // Ratios calculated as: ((toRPM / fromRPM) - 1) * 100 * 100
764 
765  // Caution: m_PercentChange could be infinite
766  int ratio = (int)((m_PercentChange * 100) + 0.5);
767 
768  switch (ratio)
769  {
770  case 0: // toRPM is the same as fromRPM
771  if (mFromVinyl != kVinyl_NA) {
772  mpChoice_ToVinyl->SetSelection(mpChoice_FromVinyl->GetSelection());
773  } else {
774  // Use the last saved option.
775  GetPrivateConfig(GetCurrentSettingsGroup(), wxT("VinylChoice"), mFromVinyl, 0);
776  mpChoice_FromVinyl->SetSelection(mFromVinyl);
777  mpChoice_ToVinyl->SetSelection(mFromVinyl);
778  }
779  break;
780  case 3500:
781  mpChoice_FromVinyl->SetSelection(kVinyl_33AndAThird);
782  mpChoice_ToVinyl->SetSelection(kVinyl_45);
783  break;
784  case 13400:
785  mpChoice_FromVinyl->SetSelection(kVinyl_33AndAThird);
786  mpChoice_ToVinyl->SetSelection(kVinyl_78);
787  break;
788  case -2593:
789  mpChoice_FromVinyl->SetSelection(kVinyl_45);
790  mpChoice_ToVinyl->SetSelection(kVinyl_33AndAThird);
791  break;
792  case 7333:
793  mpChoice_FromVinyl->SetSelection(kVinyl_45);
794  mpChoice_ToVinyl->SetSelection(kVinyl_78);
795  break;
796  case -5727:
797  mpChoice_FromVinyl->SetSelection(kVinyl_78);
798  mpChoice_ToVinyl->SetSelection(kVinyl_33AndAThird);
799  break;
800  case -4231:
801  mpChoice_FromVinyl->SetSelection(kVinyl_78);
802  mpChoice_ToVinyl->SetSelection(kVinyl_45);
803  break;
804  default:
805  mpChoice_ToVinyl->SetSelection(kVinyl_NA);
806  }
807  // and update variables.
808  mFromVinyl = mpChoice_FromVinyl->GetSelection();
809  mToVinyl = mpChoice_ToVinyl->GetSelection();
810 }
811 
813 // Update ToLength control from percent change.
814 {
815  mToLength = (mFromLength * 100.0) / (100.0 + m_PercentChange);
816 
817  // Set the format first so we can get sample accuracy.
819  // Negative times do not make sense.
820  // 359999 = 99h:59m:59s which is a little less disturbing than overflow characters
821  // though it may still look a bit strange with some formats.
822  mToLength = TrapDouble(mToLength, 0.0, 359999.0);
824 }
825 
827 // Disable OK and Preview if not in sensible range.
828 {
829  EnableApply(m_PercentChange >= MIN_Percentage && m_PercentChange <= MAX_Percentage);
830 }
EffectChangeSpeed::mpChoice_FromVinyl
wxChoice * mpChoice_FromVinyl
Definition: ChangeSpeed.h:105
EffectChangeSpeed::OnTimeCtrlUpdate
void OnTimeCtrlUpdate(wxCommandEvent &evt)
Definition: ChangeSpeed.cpp:718
EffectChangeSpeed::ProcessOne
bool ProcessOne(WaveTrack *t, sampleCount start, sampleCount end)
Definition: ChangeSpeed.cpp:481
EffectChangeSpeed::Update_Text_Multiplier
void Update_Text_Multiplier()
Definition: ChangeSpeed.cpp:737
TranslatableString
Holds a msgid for the translation catalog; may also bind format arguments.
Definition: TranslatableString.h:32
kSliderMax
static const double kSliderMax
Definition: ChangeSpeed.cpp:73
CommandParameters
CommandParameters, derived from wxFileConfig, is essentially doing the same things as the Shuttle cla...
Definition: EffectAutomationParameters.h:67
NumericTextCtrl::SetFormatName
bool SetFormatName(const NumericFormatSymbol &formatName)
Definition: NumericTextCtrl.cpp:1445
EffectChangeSpeed::Startup
bool Startup() override
Definition: ChangeSpeed.cpp:181
ShuttleGuiBase::StartVerticalLay
void StartVerticalLay(int iProp=1)
Definition: ShuttleGui.cpp:1184
WaveTrack
A Track that contains audio waveform data.
Definition: WaveTrack.h:69
EffectTypeProcess
@ EffectTypeProcess
Definition: EffectInterface.h:59
EffectChangeSpeed::ProcessLabelTrack
bool ProcessLabelTrack(LabelTrack *t)
Definition: ChangeSpeed.cpp:470
EffectChangeSpeed::GetAutomationParameters
bool GetAutomationParameters(CommandParameters &parms) override
Definition: ChangeSpeed.cpp:145
Effect::EnableApply
virtual bool EnableApply(bool enable=true)
Definition: Effect.cpp:1926
EffectChangeSpeed::Symbol
static const ComponentInterfaceSymbol Symbol
Definition: ChangeSpeed.h:27
ID_Multiplier
@ ID_Multiplier
Definition: ChangeSpeed.cpp:41
ShuttleGuiBase::AddTitle
void AddTitle(const TranslatableString &Prompt, int wrapWidth=0)
Centred text string.
Definition: ShuttleGui.cpp:281
gPrefs
FileConfig * gPrefs
Definition: Prefs.cpp:70
kVinyl_NA
@ kVinyl_NA
Definition: ChangeSpeed.cpp:54
EffectChangeSpeed::mToVinyl
int mToVinyl
Definition: ChangeSpeed.h:112
EVT_COMMAND
EVT_COMMAND(wxID_ANY, EVT_FREQUENCYTEXTCTRL_UPDATED, LabelDialog::OnFreqUpdate) LabelDialog
Definition: LabelDialog.cpp:92
TranslatableStrings
std::vector< TranslatableString > TranslatableStrings
Definition: TranslatableString.h:295
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
EffectChangeSpeed::mbLoopDetect
bool mbLoopDetect
Definition: ChangeSpeed.h:99
ShuttleGui::ToolTip
ShuttleGui & ToolTip(const TranslatableString &tip)
Definition: ShuttleGui.h:656
Effect::CopyInputTracks
void CopyInputTracks(bool allSyncLockSelected=false)
Definition: Effect.cpp:2071
kVinyl_33AndAThird
@ kVinyl_33AndAThird
Definition: ChangeSpeed.cpp:51
TimeWarper.h
Contains declarations for TimeWarper, IdentityTimeWarper, ShiftTimeWarper, LinearTimeWarper,...
EffectChangeSpeed::mpToLengthCtrl
NumericTextCtrl * mpToLengthCtrl
Definition: ChangeSpeed.h:108
Effect::mT1
double mT1
Definition: Effect.h:467
EffectChangeSpeed::~EffectChangeSpeed
virtual ~EffectChangeSpeed()
Definition: ChangeSpeed.cpp:110
ShuttleGui::AddSpace
wxSizerItem * AddSpace(int width, int height, int prop=0)
Definition: ShuttleGui.cpp:2459
XO
#define XO(s)
Definition: Internat.h:31
XC
#define XC(s, c)
Definition: Internat.h:37
EffectChangeSpeed::GetSymbol
ComponentInterfaceSymbol GetSymbol() override
Definition: ChangeSpeed.cpp:116
Effect::SetPrivateConfig
bool SetPrivateConfig(const RegistryPath &group, const RegistryPath &key, const wxString &value) override
Definition: Effect.cpp:987
ShuttleParams
Shuttle that deals with parameters. This is a base class with lots of virtual functions that do nothi...
Definition: Shuttle.h:62
LabelTrack
A LabelTrack is a Track that holds labels (LabelStruct).
Definition: LabelTrack.h:88
ShuttleGuiBase::EndMultiColumn
void EndMultiColumn()
Definition: ShuttleGui.cpp:1238
gap
static const int gap
Definition: MeterPanel.cpp:257
EffectChangeSpeed::Init
bool Init() override
Definition: ChangeSpeed.cpp:222
WaveTrack::ClearAndPaste
void ClearAndPaste(double t0, double t1, const Track *src, bool preserve=true, bool merge=true, const TimeWarper *effectWarper=NULL)
Definition: WaveTrack.cpp:848
Effect::SaveUserPreset
bool SaveUserPreset(const RegistryPath &name) override
Definition: Effect.cpp:570
NumericTextCtrl
Definition: NumericTextCtrl.h:172
EffectChangeSpeed::mpTextCtrl_PercentChange
wxTextCtrl * mpTextCtrl_PercentChange
Definition: ChangeSpeed.h:102
EffectChangeSpeed::ManualPage
ManualPageID ManualPage() override
Definition: ChangeSpeed.cpp:126
NumericTextCtrl::SetValue
void SetValue(double newValue)
Definition: NumericTextCtrl.cpp:1474
Track::IsSyncLockSelected
bool IsSyncLockSelected() const
Definition: Track.cpp:254
ID_FromVinyl
@ ID_FromVinyl
Definition: ChangeSpeed.cpp:42
kSliderWarp
static const double kSliderWarp
Definition: ChangeSpeed.cpp:74
EffectChangeSpeed::Update_Vinyl
void Update_Vinyl()
Definition: ChangeSpeed.cpp:759
WaveTrack::EmptyCopy
Holder EmptyCopy(const SampleBlockFactoryPtr &pFactory={}) const
Definition: WaveTrack.cpp:671
ComponentInterfaceSymbol
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
Definition: ComponentInterfaceSymbol.h:27
NumericTextCtrl::Options
Definition: NumericTextCtrl.h:178
ShuttleGui::Id
ShuttleGui & Id(int id)
Definition: ShuttleGui.cpp:2274
kVinyl
kVinyl
Definition: ChangeSpeed.cpp:50
WaveTrack::SplitDelete
void SplitDelete(double t0, double t1)
Definition: WaveTrack.cpp:1012
WaveTrack::SortedClipArray
WaveClipPointers SortedClipArray()
Definition: WaveTrack.cpp:2595
EffectChangeSpeed::Update_Slider_PercentChange
void Update_Slider_PercentChange()
Definition: ChangeSpeed.cpp:744
EffectChangeSpeed::CheckWhetherSkipEffect
bool CheckWhetherSkipEffect() override
Definition: ChangeSpeed.cpp:171
anonymous_namespace{ChangeSpeed.cpp}::reg
BuiltinEffectsModule::Registration< EffectChangeSpeed > reg
Definition: ChangeSpeed.cpp:83
floatSample
@ floatSample
Definition: SampleFormat.h:34
EffectChangeSpeed::mCurTrackNum
int mCurTrackNum
Definition: ChangeSpeed.h:84
ID_ToLength
@ ID_ToLength
Definition: ChangeSpeed.cpp:44
EffectChangeSpeed::mToLength
double mToLength
Definition: ChangeSpeed.h:113
EffectChangeSpeed::SetAutomationParameters
bool SetAutomationParameters(CommandParameters &parms) override
Definition: ChangeSpeed.cpp:152
ChangeSpeed.h
Effect::mProjectRate
double mProjectRate
Definition: Effect.h:458
NumericConverter::DefaultSelectionFormat
static NumericFormatSymbol DefaultSelectionFormat()
Definition: NumericTextCtrl.cpp:690
NumericConverter::LookupFormat
static NumericFormatSymbol LookupFormat(Type type, const wxString &id)
Definition: NumericTextCtrl.cpp:704
EffectChangeSpeed::mCurT0
double mCurT0
Definition: ChangeSpeed.h:86
XXO
#define XXO(s)
Definition: Internat.h:44
EffectChangeSpeed::m_PercentChange
double m_PercentChange
Definition: ChangeSpeed.h:90
ShuttleGuiBase::EndHorizontalLay
void EndHorizontalLay()
Definition: ShuttleGui.cpp:1177
Effect::mT0
double mT0
Definition: Effect.h:466
EffectChangeSpeed::mCurT1
double mCurT1
Definition: ChangeSpeed.h:87
EffectChangeSpeed::mMaxNewLength
double mMaxNewLength
Definition: ChangeSpeed.h:85
ShuttleGuiBase::StartHorizontalLay
void StartHorizontalLay(int PositionFlags=wxALIGN_CENTRE, int iProp=1)
Definition: ShuttleGui.cpp:1167
WaveTrack::LongSamplesToTime
double LongSamplesToTime(sampleCount pos) const
Convert correctly between a number of samples and an (absolute) time in seconds.
Definition: WaveTrack.cpp:1862
EffectChangeSpeed::mpChoice_ToVinyl
wxChoice * mpChoice_ToVinyl
Definition: ChangeSpeed.h:106
ShuttleGuiBase::StartMultiColumn
void StartMultiColumn(int nCols, int PositionFlags=wxALIGN_LEFT)
Definition: ShuttleGui.cpp:1229
ShuttleGuiBase::EndVerticalLay
void EndVerticalLay()
Definition: ShuttleGui.cpp:1203
EffectChangeSpeed::mFormat
NumericFormatSymbol mFormat
Definition: ChangeSpeed.h:114
ID_PercentChange
@ ID_PercentChange
Definition: ChangeSpeed.cpp:40
RegionTimeWarper
No change before the specified region; during the region, warp according to the given warper; after t...
Definition: TimeWarper.h:192
Effect::LoadFactoryDefaults
bool LoadFactoryDefaults() override
Definition: Effect.cpp:606
ShuttleGuiBase::AddUnits
void AddUnits(const TranslatableString &Prompt, int wrapWidth=0)
Left aligned text string.
Definition: ShuttleGui.cpp:263
LabelTrack::WarpLabels
void WarpLabels(const TimeWarper &warper)
Definition: LabelTrack.cpp:257
Effect::ReplaceProcessedTracks
void ReplaceProcessedTracks(const bool bGoodResult)
Definition: Effect.cpp:2193
NumericConverter::TIME
@ TIME
Definition: NumericTextCtrl.h:52
Track::Fallthrough
Continuation<> Fallthrough
Type of arguments passed as optional second parameter to TypeSwitch<void>() cases.
Definition: Track.h:504
format
int format
Definition: ExportPCM.cpp:56
EffectChangeSpeed::TransferDataFromWindow
bool TransferDataFromWindow() override
Definition: ChangeSpeed.cpp:450
ShuttleGuiBase::GetParent
wxWindow * GetParent()
Definition: ShuttleGui.h:496
EffectChangeSpeed::OnText_Multiplier
void OnText_Multiplier(wxCommandEvent &evt)
Definition: ChangeSpeed.cpp:621
ShuttleGui::Validator
ShuttleGui & Validator(const Factory &f)
Definition: ShuttleGui.h:678
EffectChangeSpeed::LoadFactoryDefaults
bool LoadFactoryDefaults() override
Definition: ChangeSpeed.cpp:161
ShuttleGuiBase::AddWindow
wxWindow * AddWindow(wxWindow *pWindow, int PositionFlags=wxALIGN_CENTRE)
Definition: ShuttleGui.cpp:299
NumericTextCtrl::Options::MenuEnabled
Options & MenuEnabled(bool enable)
Definition: NumericTextCtrl.h:192
WaveTrack::GetStartTime
double GetStartTime() const override
Get the time at which the first clip in the track starts.
Definition: WaveTrack.cpp:1867
Param
Param(Percentage, double, wxT("Percentage"), 0.0, -99.0, 4900.0, 1)
Resample
Interface to libsoxr.
Definition: Resample.h:27
Effect::mOutputTracks
std::shared_ptr< TrackList > mOutputTracks
Definition: Effect.h:465
ReadAndVerifyDouble
#define ReadAndVerifyDouble(name)
Definition: Effect.h:633
EffectChangeSpeed::OnTimeCtrl_ToLength
void OnTimeCtrl_ToLength(wxCommandEvent &evt)
Definition: ChangeSpeed.cpp:697
ShuttleGuiBase::AddSlider
wxSlider * AddSlider(const TranslatableString &Prompt, int pos, int Max, int Min=0)
Definition: ShuttleGui.cpp:589
EffectChangeSpeed
An Effect that affects both pitch & speed.
Definition: ChangeSpeed.h:25
kVinyl_78
@ kVinyl_78
Definition: ChangeSpeed.cpp:53
Effect::GetCurrentSettingsGroup
RegistryPath GetCurrentSettingsGroup() override
Definition: Effect.cpp:866
Track::GetSelected
bool GetSelected() const
Definition: Track.h:431
EffectChangeSpeed::OnSlider_PercentChange
void OnSlider_PercentChange(wxCommandEvent &evt)
Definition: ChangeSpeed.cpp:638
LoadEffects.h
samplePtr
char * samplePtr
Definition: SampleFormat.h:49
ShuttleGuiBase::StartStatic
wxStaticBox * StartStatic(const TranslatableString &Str, int iProp=0)
Definition: ShuttleGui.cpp:893
EffectChangeSpeed::Update_Text_PercentChange
void Update_Text_PercentChange()
Definition: ChangeSpeed.cpp:731
WaveTrack::GetMaxBlockSize
size_t GetMaxBlockSize() const
Definition: WaveTrack.cpp:1661
EffectChangeSpeed::GetType
EffectType GetType() override
Definition: ChangeSpeed.cpp:134
ShuttleGui::Name
ShuttleGui & Name(const TranslatableString &name)
Definition: ShuttleGui.h:663
EffectChangeSpeed::mMultiplier
double mMultiplier
Definition: ChangeSpeed.h:97
EffectChangeSpeed::mFromLength
double mFromLength
Definition: ChangeSpeed.h:95
EffectChangeSpeed::OnText_PercentChange
void OnText_PercentChange(wxCommandEvent &evt)
Definition: ChangeSpeed.cpp:605
EffectChangeSpeed::PopulateOrExchange
void PopulateOrExchange(ShuttleGui &S) override
Definition: ChangeSpeed.cpp:293
EffectChangeSpeed::OnChoice_Vinyl
void OnChoice_Vinyl(wxCommandEvent &evt)
Definition: ChangeSpeed.cpp:657
FileConfig::Flush
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
Definition: FileConfig.cpp:143
WaveTrack::TimeToLongSamples
sampleCount TimeToLongSamples(double t0) const
Convert correctly between an (absolute) time in seconds and a number of samples.
Definition: WaveTrack.cpp:1857
BuiltinEffectsModule::Registration
Definition: LoadEffects.h:40
ID_ToVinyl
@ ID_ToVinyl
Definition: ChangeSpeed.cpp:43
ShuttleGui::Position
ShuttleGui & Position(int flags)
Definition: ShuttleGui.h:712
Track
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:239
EffectChangeSpeed::mpFromLengthCtrl
NumericTextCtrl * mpFromLengthCtrl
Definition: ChangeSpeed.h:107
Effect::mUIParent
wxWindow * mUIParent
Definition: Effect.h:478
TaggedIdentifier< ManualPageIDTag >
kVinyl_45
@ kVinyl_45
Definition: ChangeSpeed.cpp:52
sampleCount
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:18
LinearTimeWarper
Linear scaling, initialised by giving two points on the line.
Definition: TimeWarper.h:87
NumericTextCtrl::Options::ReadOnly
Options & ReadOnly(bool enable)
Definition: NumericTextCtrl.h:191
ComponentInterfaceSymbol::Internal
const wxString & Internal() const
Definition: ComponentInterfaceSymbol.h:55
XXC
#define XXC(s, c)
Definition: Internat.h:47
EffectChangeSpeed::mFactor
double mFactor
Definition: ChangeSpeed.h:94
EffectChangeSpeed::GetDescription
TranslatableString GetDescription() override
Definition: ChangeSpeed.cpp:121
EffectChangeSpeed::Process
bool Process() override
Definition: ChangeSpeed.cpp:230
Resample::Process
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:88
TrapDouble
double TrapDouble(double x, double min, double max)
Definition: Effect.h:564
WaveTrack::GetBestBlockSize
size_t GetBestBlockSize(sampleCount t) const
Definition: WaveTrack.cpp:1643
Prefs.h
ShuttleGuiBase::AddPrompt
void AddPrompt(const TranslatableString &Prompt, int wrapWidth=0)
Right aligned text string.
Definition: ShuttleGui.cpp:238
ShuttleGuiBase::SetBorder
void SetBorder(int Border)
Definition: ShuttleGui.h:489
EffectChangeSpeed::CalcPreviewInputLength
double CalcPreviewInputLength(double previewLength) override
Definition: ChangeSpeed.cpp:176
ShuttleGuiBase::EndStatic
void EndStatic()
Definition: ShuttleGui.cpp:922
EffectType
EffectType
Definition: EffectInterface.h:55
safenew
#define safenew
Definition: MemoryX.h:10
EffectChangeSpeed::mFromVinyl
int mFromVinyl
Definition: ChangeSpeed.h:93
Effect::GetPrivateConfig
bool GetPrivateConfig(const RegistryPath &group, const RegistryPath &key, wxString &value, const wxString &defval={}) override
Definition: Effect.cpp:962
limitSampleBufferSize
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
Definition: SampleCount.cpp:23
WaveTrack::GetFloats
bool GetFloats(float *buffer, sampleCount start, size_t len, fillFormat fill=fillZero, bool mayThrow=true, sampleCount *pNumWithinClips=nullptr) const
Retrieve samples from a track in floating-point format, regardless of the storage format.
Definition: WaveTrack.h:266
NumericConverter::GetValue
double GetValue()
Definition: NumericTextCtrl.cpp:1174
kVinylStrings
static const TranslatableStrings kVinylStrings
Definition: ChangeSpeed.cpp:57
END_EVENT_TABLE
END_EVENT_TABLE()
Effect::TrackProgress
bool TrackProgress(int whichTrack, double frac, const TranslatableString &={})
Definition: Effect.cpp:2025
ArrayOf< float >
EffectChangeSpeed::TransferDataToWindow
bool TransferDataToWindow() override
Definition: ChangeSpeed.cpp:414
EffectChangeSpeed::mpTextCtrl_Multiplier
wxTextCtrl * mpTextCtrl_Multiplier
Definition: ChangeSpeed.h:103
Resample.h
EffectChangeSpeed::UpdateUI
void UpdateUI()
Definition: ChangeSpeed.cpp:826
EffectChangeSpeed::Update_TimeCtrl_ToLength
void Update_TimeCtrl_ToLength()
Definition: ChangeSpeed.cpp:812
ShuttleGui
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:631
EffectChangeSpeed::DefineParams
bool DefineParams(ShuttleParams &S) override
Definition: ChangeSpeed.cpp:140
EffectChangeSpeed::mpSlider_PercentChange
wxSlider * mpSlider_PercentChange
Definition: ChangeSpeed.h:104