Audacity  3.0.3
StereoToMono.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  StereoToMono.cpp
6 
7  Lynn Allan
8 
9 *******************************************************************//*******************************************************************/
15 
16 
17 #include "StereoToMono.h"
18 #include "LoadEffects.h"
19 
20 #include <wx/intl.h>
21 
22 #include "../Mix.h"
23 #include "../Project.h"
24 #include "../WaveTrack.h"
25 #include "../widgets/ProgressDialog.h"
26 
28 { XO("Stereo To Mono") };
29 
31 
33 {
34 }
35 
37 {
38 }
39 
40 // ComponentInterface implementation
41 
43 {
44  return Symbol;
45 }
46 
48 {
49  return XO("Converts stereo tracks to mono");
50 }
51 
52 // EffectDefinitionInterface implementation
53 
55 {
56  // Really EffectTypeProcess, but this prevents it from showing in the Effect Menu
57  return EffectTypeHidden;
58 }
59 
61 {
62  return false;
63 }
64 
65 // EffectClientInterface implementation
66 
68 {
69  return 2;
70 }
71 
73 {
74  return 1;
75 }
76 
77 // Effect implementation
78 
80 {
81  // Do not use mWaveTracks here. We will possibly DELETE tracks,
82  // so we must use the "real" tracklist.
83  this->CopyInputTracks(); // Set up mOutputTracks.
84  bool bGoodResult = true;
85 
86  // Determine the total time (in samples) used by all of the target tracks
87  sampleCount totalTime = 0;
88 
89  auto trackRange = mOutputTracks->SelectedLeaders< WaveTrack >();
90  while (trackRange.first != trackRange.second)
91  {
92  auto left = *trackRange.first;
93  auto channels = TrackList::Channels(left);
94  if (channels.size() > 1)
95  {
96  auto right = *channels.rbegin();
97  auto leftRate = left->GetRate();
98  auto rightRate = right->GetRate();
99 
100  if (leftRate != rightRate)
101  {
102  if (leftRate != mProjectRate)
103  {
104  mProgress->SetMessage(XO("Resampling left channel"));
105  left->Resample(mProjectRate, mProgress);
106  leftRate = mProjectRate;
107  }
108  if (rightRate != mProjectRate)
109  {
110  mProgress->SetMessage(XO("Resampling right channel"));
111  right->Resample(mProjectRate, mProgress);
112  rightRate = mProjectRate;
113  }
114  }
115  {
116  auto start = wxMin(left->TimeToLongSamples(left->GetStartTime()),
117  right->TimeToLongSamples(right->GetStartTime()));
118  auto end = wxMax(left->TimeToLongSamples(left->GetEndTime()),
119  right->TimeToLongSamples(right->GetEndTime()));
120 
121  totalTime += (end - start);
122  }
123  }
124 
125  ++trackRange.first;
126  }
127 
128  // Process each stereo track
129  sampleCount curTime = 0;
130  bool refreshIter = false;
131 
132  mProgress->SetMessage(XO("Mixing down to mono"));
133 
134  trackRange = mOutputTracks->SelectedLeaders< WaveTrack >();
135  while (trackRange.first != trackRange.second)
136  {
137  auto left = *trackRange.first;
138  auto channels = TrackList::Channels(left);
139  if (channels.size() > 1)
140  {
141  auto right = *channels.rbegin();
142 
143  bGoodResult = ProcessOne(curTime, totalTime, left, right);
144  if (!bGoodResult)
145  {
146  break;
147  }
148 
149  // The right channel has been deleted, so we must restart from the beginning
150  refreshIter = true;
151  }
152 
153  if (refreshIter)
154  {
155  trackRange = mOutputTracks->SelectedLeaders< WaveTrack >();
156  refreshIter = false;
157  }
158  else
159  {
160  ++trackRange.first;
161  }
162  }
163 
164  this->ReplaceProcessedTracks(bGoodResult);
165  return bGoodResult;
166 }
167 
169 {
170  auto idealBlockLen = left->GetMaxBlockSize() * 2;
171  bool bResult = true;
172  sampleCount processed = 0;
173 
174  auto start = wxMin(left->GetStartTime(), right->GetStartTime());
175  auto end = wxMax(left->GetEndTime(), right->GetEndTime());
176 
177  WaveTrackConstArray tracks;
178  tracks.push_back(left->SharedPointer< const WaveTrack >());
179  tracks.push_back(right->SharedPointer< const WaveTrack >());
180 
181  Mixer mixer(tracks,
182  true, // Throw to abort mix-and-render if read fails:
184  start,
185  end,
186  1,
187  idealBlockLen,
188  false, // Not interleaved
189  left->GetRate(), // Process() checks that left and right
190  // rates are the same
191  floatSample);
192 
193  auto outTrack = left->EmptyCopy();
194  outTrack->ConvertToSampleFormat(floatSample);
195 
196  while (auto blockLen = mixer.Process(idealBlockLen))
197  {
198  auto buffer = mixer.GetBuffer();
199  for (auto i = 0; i < blockLen; i++)
200  {
201  ((float *)buffer)[i] /= 2.0;
202  }
203  outTrack->Append(buffer, floatSample, blockLen);
204 
205  curTime += blockLen;
206  if (TotalProgress(curTime.as_double() / totalTime.as_double()))
207  {
208  return false;
209  }
210  }
211  outTrack->Flush();
212 
213  double minStart = wxMin(left->GetStartTime(), right->GetStartTime());
214  left->Clear(left->GetStartTime(), left->GetEndTime());
215  left->Paste(minStart, outTrack.get());
216  mOutputTracks->GroupChannels(*left, 1);
217  mOutputTracks->Remove(right);
218 
219  return bResult;
220 }
221 
223 {
224  return true;
225 }
TranslatableString
Definition: Types.h:290
WaveTrackConstArray
std::vector< std::shared_ptr< const WaveTrack > > WaveTrackConstArray
Definition: AudioIO.h:63
WaveTrack
A Track that contains audio waveform data.
Definition: WaveTrack.h:68
Effect::mProgress
ProgressDialog * mProgress
Definition: Effect.h:456
WaveTrack::GetEndTime
double GetEndTime() const override
Get the time at which the last clip in the track ends, plus recorded stuff.
Definition: WaveTrack.cpp:1797
Effect::CopyInputTracks
void CopyInputTracks(bool allSyncLockSelected=false)
Definition: Effect.cpp:2070
Mixer::WarpOptions
Definition: Mix.h:83
TrackList::Channels
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
Definition: Track.h:1467
EffectStereoToMono::ProcessOne
bool ProcessOne(sampleCount &curTime, sampleCount totalTime, WaveTrack *left, WaveTrack *right)
Definition: StereoToMono.cpp:168
Track::SharedPointer
std::shared_ptr< Subclass > SharedPointer()
Definition: Track.h:279
XO
#define XO(s)
Definition: Internat.h:32
floatSample
@ floatSample
Definition: Types.h:714
EffectStereoToMono::GetSymbol
ComponentInterfaceSymbol GetSymbol() override
Definition: StereoToMono.cpp:42
WaveTrack::EmptyCopy
Holder EmptyCopy(const SampleBlockFactoryPtr &pFactory={}) const
Definition: WaveTrack.cpp:574
ComponentInterfaceSymbol
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
Definition: ComponentInterface.h:60
StereoToMono.h
ProgressDialog::SetMessage
void SetMessage(const TranslatableString &message)
Definition: ProgressDialog.cpp:1510
EffectStereoToMono::Process
bool Process() override
Definition: StereoToMono.cpp:79
Effect::mProjectRate
double mProjectRate
Definition: Effect.h:457
WaveTrack::Clear
void Clear(double t0, double t1) override
Definition: WaveTrack.cpp:654
Effect::inputTracks
const TrackList * inputTracks() const
Definition: Effect.h:462
sampleCount::as_double
double as_double() const
Definition: Types.h:608
EffectStereoToMono::IsHidden
bool IsHidden() override
Definition: StereoToMono.cpp:222
Effect::ReplaceProcessedTracks
void ReplaceProcessedTracks(const bool bGoodResult)
Definition: Effect.cpp:2192
WaveTrack::Paste
void Paste(double t0, const Track *src) override
Definition: WaveTrack.cpp:1171
EffectStereoToMono::GetAudioInCount
unsigned GetAudioInCount() override
Definition: StereoToMono.cpp:67
WaveTrack::GetStartTime
double GetStartTime() const override
Get the time at which the first clip in the track starts.
Definition: WaveTrack.cpp:1777
EffectTypeHidden
@ EffectTypeHidden
Definition: EffectInterface.h:57
Effect::mOutputTracks
std::shared_ptr< TrackList > mOutputTracks
Definition: Effect.h:464
LoadEffects.h
WaveTrack::GetMaxBlockSize
size_t GetMaxBlockSize() const
Definition: WaveTrack.cpp:1578
anonymous_namespace{StereoToMono.cpp}::reg
BuiltinEffectsModule::Registration< EffectStereoToMono > reg
Definition: StereoToMono.cpp:30
BuiltinEffectsModule::Registration
Definition: LoadEffects.h:40
EffectStereoToMono::EffectStereoToMono
EffectStereoToMono()
Definition: StereoToMono.cpp:32
sampleCount
Definition: Types.h:581
EffectStereoToMono::GetAudioOutCount
unsigned GetAudioOutCount() override
Definition: StereoToMono.cpp:72
EffectStereoToMono::GetType
EffectType GetType() override
Definition: StereoToMono.cpp:54
EffectStereoToMono::~EffectStereoToMono
virtual ~EffectStereoToMono()
Definition: StereoToMono.cpp:36
Effect::TotalProgress
bool TotalProgress(double frac, const TranslatableString &={})
Definition: Effect.cpp:2016
EffectType
EffectType
Definition: EffectInterface.h:55
EffectStereoToMono::IsInteractive
bool IsInteractive() override
Definition: StereoToMono.cpp:60
EffectStereoToMono::GetDescription
TranslatableString GetDescription() override
Definition: StereoToMono.cpp:47
Mixer
Functions for doing the mixdown of the tracks.
Definition: Mix.h:78
EffectStereoToMono::Symbol
static const ComponentInterfaceSymbol Symbol
Definition: StereoToMono.h:19
WaveTrack::GetRate
double GetRate() const
Definition: WaveTrack.cpp:360