1
0
mirror of https://github.com/cookiengineer/audacity synced 2026-01-02 06:08:44 +01:00
Files
audacity/src/effects/StereoToMono.cpp
James Crook 466e9c179e Create ComponentInterface
It combines the old IdentInterface with the ParamsInterface, providing an identifier and parameters (if needed).
The main purpose of the change is to make the class hierarchy (as viewed via doxygen) much easier to follow.
2018-11-02 17:04:43 +00:00

171 lines
4.5 KiB
C++

/**********************************************************************
Audacity: A Digital Audio Editor
StereoToMono.cpp
Lynn Allan
*******************************************************************//**
\class EffectStereoToMono
\brief An Effect to convert stereo to mono.
*//*******************************************************************/
#include "../Audacity.h"
#include "StereoToMono.h"
#include <wx/intl.h>
#include "../Project.h"
#include "../WaveTrack.h"
EffectStereoToMono::EffectStereoToMono()
{
}
EffectStereoToMono::~EffectStereoToMono()
{
}
// ComponentInterface implementation
ComponentInterfaceSymbol EffectStereoToMono::GetSymbol()
{
return STEREOTOMONO_PLUGIN_SYMBOL;
}
wxString EffectStereoToMono::GetDescription()
{
return _("Converts stereo tracks to mono");
}
// EffectDefinitionInterface implementation
EffectType EffectStereoToMono::GetType()
{
// Really EffectTypeProcess, but this prevents it from showing in the Effect Menu
return EffectTypeHidden;
}
bool EffectStereoToMono::IsInteractive()
{
return false;
}
// EffectClientInterface implementation
unsigned EffectStereoToMono::GetAudioInCount()
{
return 2;
}
unsigned EffectStereoToMono::GetAudioOutCount()
{
return 1;
}
// Effect implementation
bool EffectStereoToMono::Process()
{
// Do not use mWaveTracks here. We will possibly DELETE tracks,
// so we must use the "real" tracklist.
this->CopyInputTracks(); // Set up mOutputTracks.
bool bGoodResult = true;
auto trackRange = mOutputTracks->SelectedLeaders< WaveTrack >();
bool refreshIter = false;
int count = 0;
while ( trackRange.first != trackRange.second ) {
mLeftTrack = *trackRange.first;
auto channels = TrackList::Channels( mLeftTrack );
if (channels.size() != 2) {
// TODO: more-than-two-channels
++ trackRange.first;
continue;
}
mRightTrack = * channels.rbegin();
if ((mLeftTrack->GetRate() == mRightTrack->GetRate())) {
auto leftTrackStart = mLeftTrack->TimeToLongSamples(mLeftTrack->GetStartTime());
auto rightTrackStart = mRightTrack->TimeToLongSamples(mRightTrack->GetStartTime());
mStart = wxMin(leftTrackStart, rightTrackStart);
auto leftTrackEnd = mLeftTrack->TimeToLongSamples(mLeftTrack->GetEndTime());
auto rightTrackEnd = mRightTrack->TimeToLongSamples(mRightTrack->GetEndTime());
mEnd = wxMax(leftTrackEnd, rightTrackEnd);
bGoodResult = ProcessOne(count);
if (!bGoodResult)
break;
// The right channel has been deleted, so we must restart from the beginning
refreshIter = true;
}
if (refreshIter) {
trackRange = mOutputTracks->SelectedLeaders< WaveTrack >();
refreshIter = false;
}
else
++trackRange.first;
count++;
}
this->ReplaceProcessedTracks(bGoodResult);
return bGoodResult;
}
bool EffectStereoToMono::ProcessOne(int count)
{
float curLeftFrame;
float curRightFrame;
float curMonoFrame;
auto idealBlockLen = mLeftTrack->GetMaxBlockSize() * 2;
auto index = mStart;
Floats leftBuffer { idealBlockLen };
Floats rightBuffer{ idealBlockLen };
bool bResult = true;
AudacityProject *p = GetActiveProject();
auto outTrack =
p->GetTrackFactory()->NewWaveTrack(floatSample, mLeftTrack->GetRate());
while (index < mEnd) {
bResult &= mLeftTrack->Get((samplePtr)leftBuffer.get(), floatSample, index, idealBlockLen);
bResult &= mRightTrack->Get((samplePtr)rightBuffer.get(), floatSample, index, idealBlockLen);
auto limit = limitSampleBufferSize( idealBlockLen, mEnd - index );
for (decltype(limit) i = 0; i < limit; ++i) {
index++;
curLeftFrame = leftBuffer[i];
curRightFrame = rightBuffer[i];
curMonoFrame = (curLeftFrame + curRightFrame) / 2.0;
leftBuffer[i] = curMonoFrame;
}
outTrack->Append((samplePtr)leftBuffer.get(), floatSample, limit);
if (TrackProgress(count, 2.*(index.as_double() / (mEnd - mStart).as_double())))
return false;
}
double minStart = wxMin(mLeftTrack->GetStartTime(), mRightTrack->GetStartTime());
mLeftTrack->Clear(mLeftTrack->GetStartTime(), mLeftTrack->GetEndTime());
outTrack->Flush();
mLeftTrack->Paste(minStart, outTrack.get());
mOutputTracks->GroupChannels( *mLeftTrack, 1 );
mOutputTracks->Remove(mRightTrack);
return bResult;
}
bool EffectStereoToMono::IsHidden()
{
return true;
}