Audacity  2.2.2
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 #include "../Audacity.h"
17 #include "StereoToMono.h"
18 
19 #include <wx/intl.h>
20 
21 #include "../Project.h"
22 #include "../WaveTrack.h"
23 
25 {
26 }
27 
29 {
30 }
31 
32 // IdentInterface implementation
33 
35 {
37 }
38 
40 {
41  return _("Converts stereo tracks to mono");
42 }
43 
44 // EffectDefinitionInterface implementation
45 
47 {
48  // Really EffectTypeProcess, but this prevents it from showing in the Effect Menu
49  return EffectTypeHidden;
50 }
51 
53 {
54  return false;
55 }
56 
57 // EffectClientInterface implementation
58 
60 {
61  return 2;
62 }
63 
65 {
66  return 1;
67 }
68 
69 // Effect implementation
70 
72 {
73  // Do not use mWaveTracks here. We will possibly DELETE tracks,
74  // so we must use the "real" tracklist.
75  this->CopyInputTracks(); // Set up mOutputTracks.
76  bool bGoodResult = true;
77 
79  mLeftTrack = (WaveTrack *)iter.First();
80  bool refreshIter = false;
81 
82  if(mLeftTrack)
83  {
84  // create a NEW WaveTrack to hold all of the output
86  mOutTrack = p->GetTrackFactory()->NewWaveTrack(floatSample, mLeftTrack->GetRate());
87  }
88 
89  int count = 0;
90  while (mLeftTrack) {
91  if (mLeftTrack->GetKind() == Track::Wave &&
92  mLeftTrack->GetSelected() &&
93  mLeftTrack->GetLinked()) {
94 
95  // Assume linked track is wave
96  mRightTrack = static_cast<WaveTrack*>(iter.Next());
97 
98  if ((mLeftTrack->GetRate() == mRightTrack->GetRate())) {
99  auto leftTrackStart = mLeftTrack->TimeToLongSamples(mLeftTrack->GetStartTime());
100  auto rightTrackStart = mRightTrack->TimeToLongSamples(mRightTrack->GetStartTime());
101  mStart = wxMin(leftTrackStart, rightTrackStart);
102 
103  auto leftTrackEnd = mLeftTrack->TimeToLongSamples(mLeftTrack->GetEndTime());
104  auto rightTrackEnd = mRightTrack->TimeToLongSamples(mRightTrack->GetEndTime());
105  mEnd = wxMax(leftTrackEnd, rightTrackEnd);
106 
107  bGoodResult = ProcessOne(count);
108  if (!bGoodResult)
109  break;
110 
111  mOutTrack->Clear(mOutTrack->GetStartTime(), mOutTrack->GetEndTime());
112 
113  // The right channel has been deleted, so we must restart from the beginning
114  refreshIter = true;
115  }
116  }
117 
118  if (refreshIter) {
119  mLeftTrack = (WaveTrack *)iter.First();
120  refreshIter = false;
121  }
122  else {
123  mLeftTrack = (WaveTrack *)iter.Next();
124  }
125  count++;
126  }
127 
128  this->ReplaceProcessedTracks(bGoodResult);
129  return bGoodResult;
130 }
131 
133 {
134  mOutTrack.reset();
135 }
136 
138 {
139  float curLeftFrame;
140  float curRightFrame;
141  float curMonoFrame;
142 
143  auto idealBlockLen = mLeftTrack->GetMaxBlockSize() * 2;
144  auto index = mStart;
145  Floats leftBuffer { idealBlockLen };
146  Floats rightBuffer{ idealBlockLen };
147  bool bResult = true;
148 
149  while (index < mEnd) {
150  bResult &= mLeftTrack->Get((samplePtr)leftBuffer.get(), floatSample, index, idealBlockLen);
151  bResult &= mRightTrack->Get((samplePtr)rightBuffer.get(), floatSample, index, idealBlockLen);
152  auto limit = limitSampleBufferSize( idealBlockLen, mEnd - index );
153  for (decltype(limit) i = 0; i < limit; ++i) {
154  index++;
155  curLeftFrame = leftBuffer[i];
156  curRightFrame = rightBuffer[i];
157  curMonoFrame = (curLeftFrame + curRightFrame) / 2.0;
158  leftBuffer[i] = curMonoFrame;
159  }
160  mOutTrack->Append((samplePtr)leftBuffer.get(), floatSample, limit);
161  if (TrackProgress(count, 2.*(index.as_double() / (mEnd - mStart).as_double())))
162  return false;
163  }
164 
165  double minStart = wxMin(mLeftTrack->GetStartTime(), mRightTrack->GetStartTime());
167  mOutTrack->Flush();
168  mLeftTrack->Paste(minStart, mOutTrack.get());
169  mLeftTrack->SetLinked(false);
170  mRightTrack->SetLinked(false);
172  mOutputTracks->Remove(mRightTrack);
173 
174  return bResult;
175 }
176 
178 {
179  return true;
180 }
181 
bool ProcessOne(int count)
bool TrackProgress(int whichTrack, double frac, const wxString &=wxEmptyString)
Definition: Effect.cpp:1985
void CopyInputTracks()
Definition: Effect.cpp:2036
void SetLinked(bool l)
Definition: Track.cpp:244
bool IsHidden() override
std::unique_ptr< WaveTrack > mOutTrack
Definition: StereoToMono.h:57
void ReplaceProcessedTracks(const bool bGoodResult)
Definition: Effect.cpp:2162
IdentInterfaceSymbol GetSymbol() override
void Clear(double t0, double t1) override
Definition: WaveTrack.cpp:678
double GetEndTime() const override
Get the time at which the last clip in the track ends, plus recorded stuff.
Definition: WaveTrack.cpp:1873
sampleCount mStart
Definition: StereoToMono.h:53
void SetChannel(int c)
Definition: Track.h:291
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
Definition: Types.h:178
AudacityProject provides the main window, with tools and tracks contained within it.
Definition: Project.h:176
#define STEREOTOMONO_PLUGIN_SYMBOL
Definition: StereoToMono.h:18
double GetStartTime() const override
Get the time at which the first clip in the track starts.
Definition: WaveTrack.cpp:1853
wxString GetDescription() override
bool Process() override
unsigned GetAudioOutCount() override
EffectType GetType() override
char * samplePtr
Definition: Types.h:203
A Track that contains audio waveform data.
Definition: WaveTrack.h:60
void Paste(double t0, const Track *src) override
Definition: WaveTrack.cpp:1192
IdentInterfaceSymbol pairs a persistent string identifier used internally with an optional...
size_t GetMaxBlockSize() const
Definition: WaveTrack.cpp:1625
std::unique_ptr< WaveTrack > NewWaveTrack(sampleFormat format=(sampleFormat) 0, double rate=0)
Definition: WaveTrack.cpp:78
unsigned GetAudioInCount() override
_("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
EffectType
sampleCount TimeToLongSamples(double t0) const
Convert correctly between an (absolute) time in seconds and a number of samples.
Definition: WaveTrack.cpp:1843
void End() override
WaveTrack * mLeftTrack
Definition: StereoToMono.h:55
WaveTrack * mRightTrack
Definition: StereoToMono.h:56
AUDACITY_DLL_API AudacityProject * GetActiveProject()
Definition: Project.cpp:308
virtual ~EffectStereoToMono()
bool IsInteractive() override
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
std::shared_ptr< TrackList > mOutputTracks
Definition: Effect.h:459
TrackFactory * GetTrackFactory()
Definition: Project.cpp:1427
sampleCount mEnd
Definition: StereoToMono.h:54