1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-07-13 23:27:43 +02:00

Iterations over channels where more general messages may be needed...

... but otherwise the logic generalizes without a problem.

All these places have the comment:

// TODO: more-than-two-channels-message
This commit is contained in:
Paul Licameli 2018-09-30 11:04:48 -04:00
commit 70f7b0f6ef
5 changed files with 221 additions and 230 deletions

View File

@ -3856,13 +3856,14 @@ double MenuCommandHandler::OnClipMove
auto t0 = selectedRegion.t0(); auto t0 = selectedRegion.t0();
state.capturedClip = wt->GetClipAtTime( t0 ); // Find the first channel that has a clip at time t0
if (state.capturedClip == nullptr && track->GetLinked() && track->GetLink()) { for (auto channel : TrackList::Channels(wt) ) {
// the clips in the right channel may be different from the left if( nullptr != (state.capturedClip = channel->GetClipAtTime( t0 )) ) {
track = track->GetLink(); wt = channel;
wt = static_cast<WaveTrack*>(track); break;
state.capturedClip = wt->GetClipAtTime(t0);
} }
}
if (state.capturedClip == nullptr) if (state.capturedClip == nullptr)
return 0.0; return 0.0;
@ -6906,25 +6907,23 @@ int MenuCommandHandler::FindClips
std::vector<FoundClip> results; std::vector<FoundClip> results;
int nTracksSearched = 0; int nTracksSearched = 0;
int trackNum = 1; auto leaders = tracks->Leaders();
for (auto track : tracks->Leaders()) { auto range = leaders.Filter<const WaveTrack>();
if (track->GetKind() == Track::Wave && (!anyWaveTracksSelected || track->GetSelected())) { if (anyWaveTracksSelected)
auto waveTrack = static_cast<const WaveTrack*>(track); range = range + &Track::GetSelected;
bool stereoAndDiff = waveTrack->GetLinked() && !ChannelsHaveSameClipBoundaries(waveTrack); for (auto waveTrack : range) {
bool stereoAndDiff = ChannelsHaveDifferentClipBoundaries(waveTrack);
auto result = next ? FindNextClip(project, waveTrack, t0, t1) : auto range = stereoAndDiff
FindPrevClip(project, waveTrack, t0, t1); ? TrackList::Channels( waveTrack )
: TrackList::SingletonRange( waveTrack );
for ( auto wt : range ) {
auto result = next ? FindNextClip(project, wt, t0, t1) :
FindPrevClip(project, wt, t0, t1);
if (result.found) { if (result.found) {
result.trackNum = trackNum; result.trackNum =
result.channel = stereoAndDiff; 1 + std::distance( leaders.begin(), leaders.find( waveTrack ) );
results.push_back(result);
}
if (stereoAndDiff) {
auto waveTrack2 = static_cast<const WaveTrack*>(track->GetLink());
auto result = next ? FindNextClip(project, waveTrack2, t0, t1) :
FindPrevClip(project, waveTrack2, t0, t1);
if (result.found) {
result.trackNum = trackNum;
result.channel = stereoAndDiff; result.channel = stereoAndDiff;
results.push_back(result); results.push_back(result);
} }
@ -6933,9 +6932,6 @@ int MenuCommandHandler::FindClips
nTracksSearched++; nTracksSearched++;
} }
trackNum++;
}
if (results.size() > 0) { if (results.size() > 0) {
// if any clips were found, // if any clips were found,
@ -6974,14 +6970,13 @@ int MenuCommandHandler::FindClips
return nTracksSearched; // can be used for screen reader messages if required return nTracksSearched; // can be used for screen reader messages if required
} }
// Whether the two channels of a stereo track have the same clips namespace {
bool MenuCommandHandler::ChannelsHaveSameClipBoundaries(const WaveTrack* wt) bool TwoChannelsHaveSameBoundaries
{ ( const WaveTrack *first, const WaveTrack *second )
{
bool sameClips = false; bool sameClips = false;
auto& left = first->GetClips();
if (wt->GetLinked() && wt->GetLink()) { auto& right = second->GetClips();
auto& left = wt->GetClips();
auto& right = static_cast<const WaveTrack*>(wt->GetLink())->GetClips();
if (left.size() == right.size()) { if (left.size() == right.size()) {
sameClips = true; sameClips = true;
for (unsigned int i = 0; i < left.size(); i++) { for (unsigned int i = 0; i < left.size(); i++) {
@ -6992,9 +6987,24 @@ bool MenuCommandHandler::ChannelsHaveSameClipBoundaries(const WaveTrack* wt)
} }
} }
} }
return sameClips;
}
}
bool MenuCommandHandler::ChannelsHaveDifferentClipBoundaries(
const WaveTrack* wt)
{
// This is quadratic in the number of channels
auto channels = TrackList::Channels(wt);
while (!channels.empty()) {
auto channel = *channels.first++;
for (auto other : channels) {
if (!TwoChannelsHaveSameBoundaries(channel, other))
return true;
}
} }
return sameClips; return false;
} }
void MenuCommandHandler::OnSelectPrevClip(const CommandContext &context) void MenuCommandHandler::OnSelectPrevClip(const CommandContext &context)
@ -8120,25 +8130,23 @@ int MenuCommandHandler::FindClipBoundaries
std::vector<FoundClipBoundary> results; std::vector<FoundClipBoundary> results;
int nTracksSearched = 0; int nTracksSearched = 0;
int trackNum = 1; auto leaders = tracks->Leaders();
for (auto track : tracks->Leaders()) { auto range = leaders.Filter<const WaveTrack>();
if (track->GetKind() == Track::Wave && (!anyWaveTracksSelected || track->GetSelected())) { if (anyWaveTracksSelected)
auto waveTrack = static_cast<const WaveTrack*>(track); range = range + &Track::GetSelected;
bool stereoAndDiff = waveTrack->GetLinked() && !ChannelsHaveSameClipBoundaries(waveTrack); for (auto waveTrack : range) {
bool stereoAndDiff = ChannelsHaveDifferentClipBoundaries(waveTrack);
auto result = next ? FindNextClipBoundary(waveTrack, time) : auto range = stereoAndDiff
FindPrevClipBoundary(waveTrack, time); ? TrackList::Channels( waveTrack )
: TrackList::SingletonRange(waveTrack);
for (auto wt : range) {
auto result = next ? FindNextClipBoundary(wt, time) :
FindPrevClipBoundary(wt, time);
if (result.nFound > 0) { if (result.nFound > 0) {
result.trackNum = trackNum; result.trackNum =
result.channel = stereoAndDiff; 1 + std::distance( leaders.begin(), leaders.find( waveTrack ) );
results.push_back(result);
}
if (stereoAndDiff) {
waveTrack = static_cast<const WaveTrack*>(track->GetLink());
result = next ? FindNextClipBoundary(waveTrack, time) :
FindPrevClipBoundary(waveTrack, time);
if (result.nFound > 0) {
result.trackNum = trackNum;
result.channel = stereoAndDiff; result.channel = stereoAndDiff;
results.push_back(result); results.push_back(result);
} }
@ -8147,9 +8155,6 @@ int MenuCommandHandler::FindClipBoundaries
nTracksSearched++; nTracksSearched++;
} }
trackNum++;
}
if (results.size() > 0) { if (results.size() > 0) {
// If any clip boundaries were found // If any clip boundaries were found
@ -8215,7 +8220,8 @@ wxString MenuCommandHandler::FoundTrack::ComposeTrackName() const
: name; : name;
auto longName = shortName; auto longName = shortName;
if (channel) { if (channel) {
if ( waveTrack->GetLinked() ) // TODO: more-than-two-channels-message
if ( waveTrack->IsLeader() )
/* i18n-hint: given the name of a track, specify its left channel */ /* i18n-hint: given the name of a track, specify its left channel */
longName = wxString::Format(_("%s left"), shortName); longName = wxString::Format(_("%s left"), shortName);
else else

View File

@ -357,7 +357,7 @@ FoundClip FindPrevClip
int FindClips int FindClips
(AudacityProject &project, (AudacityProject &project,
double t0, double t1, bool next, std::vector<FoundClip>& results); double t0, double t1, bool next, std::vector<FoundClip>& results);
bool ChannelsHaveSameClipBoundaries(const WaveTrack* wt); bool ChannelsHaveDifferentClipBoundaries(const WaveTrack* wt);
void OnSelectPrevClip(const CommandContext &context ); void OnSelectPrevClip(const CommandContext &context );
void OnSelectNextClip(const CommandContext &context ); void OnSelectNextClip(const CommandContext &context );
void OnSelectClip(AudacityProject &project, bool next); void OnSelectClip(AudacityProject &project, bool next);

View File

@ -1078,23 +1078,17 @@ void TrackPanel::RefreshTrack(Track *trk, bool refreshbacking)
if (!trk) if (!trk)
return; return;
Track *link = trk->GetLink(); trk = *GetTracks()->FindLeader(trk);
auto height =
if (link && !trk->GetLinked()) { TrackList::Channels(trk).sum( &Track::GetHeight )
trk = link; - kTopInset - kShadowThickness;
link = trk->GetLink();
}
// subtract insets and shadows from the rectangle, but not border // subtract insets and shadows from the rectangle, but not border
// This matters because some separators do paint over the border // This matters because some separators do paint over the border
wxRect rect(kLeftInset, wxRect rect(kLeftInset,
-mViewInfo->vpos + trk->GetY() + kTopInset, -mViewInfo->vpos + trk->GetY() + kTopInset,
GetRect().GetWidth() - kLeftInset - kRightInset - kShadowThickness, GetRect().GetWidth() - kLeftInset - kRightInset - kShadowThickness,
trk->GetHeight() - kTopInset - kShadowThickness); height);
if (link) {
rect.height += link->GetHeight();
}
if( refreshbacking ) if( refreshbacking )
{ {
@ -1184,41 +1178,24 @@ void TrackPanel::DrawEverythingElse(TrackPanelDrawingContext &context,
trackRect.y = t->GetY() - mViewInfo->vpos; trackRect.y = t->GetY() - mViewInfo->vpos;
trackRect.height = t->GetHeight(); trackRect.height = t->GetHeight();
// If this track is linked to the next one, display a common auto leaderTrack = *GetTracks()->FindLeader( t );
// border for both, otherwise draw a normal border
wxRect rect = trackRect;
bool skipBorder = false;
Track *l = t->GetLink();
if (l && t->GetLinked()) {
rect.height += l->GetHeight();
}
else if (l && trackRect.y >= 0) {
skipBorder = true;
}
// If the previous track is linked to this one but isn't on the screen // If the previous track is linked to this one but isn't on the screen
// (and thus would have been skipped) we need to draw that track's border // (and thus would have been skipped) we need to draw that track's border
// instead. // instead.
const Track *borderTrack = t; bool drawBorder = (t == leaderTrack || trackRect.y < 0);
wxRect borderRect = rect;
if (l && !t->GetLinked() && trackRect.y < 0) if (drawBorder) {
{ wxRect teamRect = trackRect;
borderTrack = l; teamRect.y = leaderTrack->GetY() - mViewInfo->vpos;
// danger with pending tracks?
teamRect.height =
TrackList::Channels(leaderTrack)
.sum( &Track::GetHeight );
borderRect = trackRect;
borderRect.y = l->GetY() - mViewInfo->vpos;
borderRect.height = l->GetHeight();
borderRect.height += t->GetHeight();
}
if (!skipBorder) {
if (mAx->IsFocused(t)) { if (mAx->IsFocused(t)) {
focusRect = borderRect; focusRect = teamRect;
} }
DrawOutside(context, borderTrack, borderRect); DrawOutside(context, leaderTrack, teamRect);
} }
// Believe it or not, we can speed up redrawing if we don't // Believe it or not, we can speed up redrawing if we don't
@ -1675,7 +1652,9 @@ void TrackInfo::Status1DrawFunction
/// stereo and what sample rate it's using. /// stereo and what sample rate it's using.
auto rate = wt ? wt->GetRate() : 44100.0; auto rate = wt ? wt->GetRate() : 44100.0;
wxString s; wxString s;
if (!wt || (wt->GetLinked())) if (!pTrack || TrackList::Channels(pTrack).size() > 1)
// TODO: more-than-two-channels-message
// more appropriate strings
s = _("Stereo, %dHz"); s = _("Stereo, %dHz");
else { else {
if (wt->GetChannel() == Track::MonoChannel) if (wt->GetChannel() == Track::MonoChannel)
@ -1714,6 +1693,15 @@ void TrackPanel::DrawOutside
wxRect rect = rec; wxRect rect = rec;
DrawOutsideOfTrack(context, t, rect); DrawOutsideOfTrack(context, t, rect);
{
auto channels = TrackList::Channels(t);
// omit last (perhaps, only) channel
--channels.second;
for (auto channel : channels)
// draw the sash below this channel
DrawSash(channel, dc, rect);
}
// Now exclude left, right, and top insets // Now exclude left, right, and top insets
rect.x += kLeftInset; rect.x += kLeftInset;
rect.y += kTopInset; rect.y += kTopInset;
@ -1733,7 +1721,16 @@ void TrackPanel::DrawOutside
// TrackArtist::DrawSyncLockTiles(dc, tileFill); // TrackArtist::DrawSyncLockTiles(dc, tileFill);
//} //}
DrawBordersAroundTrack(t, dc, rect, labelw, vrul); DrawBordersAroundTrack(dc, rect, vrul);
{
auto channels = TrackList::Channels(t);
// omit last (perhaps, only) channel
--channels.second;
for (auto channel : channels)
// draw the sash below this channel
DrawBordersAroundSash(channel, dc, rect, labelw);
}
DrawShadow(t, dc, rect); DrawShadow(t, dc, rect);
} }
@ -1777,16 +1774,17 @@ void TrackPanel::DrawOutsideOfTrack
side.x += side.width - kRightInset; side.x += side.width - kRightInset;
side.width = kRightInset; side.width = kRightInset;
dc->DrawRectangle(side); dc->DrawRectangle(side);
}
// Area between tracks of stereo group void TrackPanel::DrawSash(const Track * t, wxDC * dc, const wxRect & rect)
if (t->GetLinked()) { {
// Paint the channel separator over (what would be) the shadow of the top // Area between channels of a group
// channel, and the top inset of the bottom channel // Paint the channel separator over (what would be) the shadow of this
side = rect; // channel, and the top inset of the following channel
side.y += t->GetHeight() - kShadowThickness; wxRect side = rect;
side.y = t->GetY() - mViewInfo->vpos + t->GetHeight() - kShadowThickness;
side.height = kTopInset + kShadowThickness; side.height = kTopInset + kShadowThickness;
dc->DrawRectangle(side); dc->DrawRectangle(side);
}
} }
void TrackPanel::SetBackgroundCell void TrackPanel::SetBackgroundCell
@ -1979,8 +1977,8 @@ void TrackPanel::VerticalScroll( float fracPosition){
// Given rectangle excludes the insets left, right, and top // Given rectangle excludes the insets left, right, and top
// Draw a rectangular border and also a vertical separator of track controls // Draw a rectangular border and also a vertical separator of track controls
// from the rest (ruler and proper track area) // from the rest (ruler and proper track area)
void TrackPanel::DrawBordersAroundTrack(const Track * t, wxDC * dc, void TrackPanel::DrawBordersAroundTrack(wxDC * dc,
const wxRect & rect, const int labelw, const wxRect & rect,
const int vrul) const int vrul)
{ {
// Border around track and label area // Border around track and label area
@ -1991,21 +1989,21 @@ void TrackPanel::DrawBordersAroundTrack(const Track * t, wxDC * dc,
rect.width - kShadowThickness, rect.width - kShadowThickness,
rect.height - kShadowThickness); rect.height - kShadowThickness);
// between vruler and TrackInfo // between vruler and TrackInfo
AColor::Line(*dc, vrul, rect.y, vrul, rect.y + rect.height - 1); AColor::Line(*dc, vrul, rect.y, vrul, rect.y + rect.height - 1);
}
// The lines at bottom of 1st track and top of second track of stereo group void TrackPanel::DrawBordersAroundSash(const Track * t, wxDC * dc,
// Possibly replace with DrawRectangle to add left border. const wxRect & rect, const int labelw)
if (t->GetLinked()) { {
// The given rect has had the top inset subtracted int h1 = t->GetY() - mViewInfo->vpos + t->GetHeight();
int h1 = rect.y + t->GetHeight() - kTopInset; // h1 is the top coordinate of the following channel's rectangle
// h1 is the top coordinate of the second tracks' rectangle
// Draw (part of) the bottom border of the top channel and top border of the bottom // Draw (part of) the bottom border of the top channel and top border of the bottom
// At left it extends between the vertical rulers too // At left it extends between the vertical rulers too
// These lines stroke over what is otherwise "border" of each channel // These lines stroke over what is otherwise "border" of each channel
AColor::Line(*dc, labelw, h1 - kBottomMargin, rect.x + rect.width - 1, h1 - kBottomMargin); AColor::Line(*dc, labelw, h1 - kBottomMargin, rect.x + rect.width - 1, h1 - kBottomMargin);
AColor::Line(*dc, labelw, h1 + kTopInset, rect.x + rect.width - 1, h1 + kTopInset); AColor::Line(*dc, labelw, h1 + kTopInset, rect.x + rect.width - 1, h1 + kTopInset);
}
} }
// Given rectangle has insets subtracted left, right, and top // Given rectangle has insets subtracted left, right, and top

View File

@ -373,16 +373,20 @@ protected:
void DrawEverythingElse(TrackPanelDrawingContext &context, void DrawEverythingElse(TrackPanelDrawingContext &context,
const wxRegion & region, const wxRegion & region,
const wxRect & clip); const wxRect & clip);
void DrawOutside void DrawOutside(
(TrackPanelDrawingContext &context, TrackPanelDrawingContext &context,
const Track *t, const wxRect & rec); const Track *leaderTrack, const wxRect & teamRect);
void HighlightFocusedTrack (wxDC* dc, const wxRect &rect); void HighlightFocusedTrack (wxDC* dc, const wxRect &rect);
void DrawShadow (const Track *t, wxDC* dc, const wxRect & rect); void DrawShadow (const Track *t, wxDC* dc, const wxRect & rect);
void DrawBordersAroundTrack(const Track *t, wxDC* dc, const wxRect & rect, const int labelw, const int vrul); void DrawBordersAroundTrack(wxDC* dc, const wxRect & rect,
void DrawOutsideOfTrack const int vrul);
(TrackPanelDrawingContext &context, void DrawBordersAroundSash (const Track *t, wxDC* dc, const wxRect & rect,
const int labelw);
void DrawOutsideOfTrack (
TrackPanelDrawingContext &context,
const Track *t, const wxRect & rect); const Track *t, const wxRect & rect);
void DrawSash (const Track *t, wxDC* dc, const wxRect & rect);
public: public:
// Set the object that performs catch-all event handling when the pointer // Set the object that performs catch-all event handling when the pointer

View File

@ -219,10 +219,6 @@ bool EffectNormalize::Process()
//Iterate over each track //Iterate over each track
this->CopyInputTracks(); // Set up mOutputTracks. this->CopyInputTracks(); // Set up mOutputTracks.
bool bGoodResult = true; bool bGoodResult = true;
SelectedTrackListOfKindIterator iter(Track::Wave, mOutputTracks.get());
WaveTrack *track = (WaveTrack *) iter.First();
WaveTrack *prevTrack;
prevTrack = track;
double progress = 0; double progress = 0;
wxString topMsg; wxString topMsg;
if(mDC && mGain) if(mDC && mGain)
@ -234,8 +230,10 @@ bool EffectNormalize::Process()
else if(!mDC && !mGain) else if(!mDC && !mGain)
topMsg = _("Not doing anything...\n"); // shouldn't get here topMsg = _("Not doing anything...\n"); // shouldn't get here
while (track) { for ( auto track : mOutputTracks->Selected< WaveTrack >()
+ ( mStereoInd ? &Track::Any : &Track::IsLeader ) ) {
//Get start and end times from track //Get start and end times from track
// PRL: No accounting for multiple channels?
double trackStart = track->GetStartTime(); double trackStart = track->GetStartTime();
double trackEnd = track->GetEndTime(); double trackEnd = track->GetEndTime();
@ -244,28 +242,65 @@ bool EffectNormalize::Process()
mCurT0 = mT0 < trackStart? trackStart: mT0; mCurT0 = mT0 < trackStart? trackStart: mT0;
mCurT1 = mT1 > trackEnd? trackEnd: mT1; mCurT1 = mT1 > trackEnd? trackEnd: mT1;
auto range = mStereoInd
? TrackList::SingletonRange(track)
: TrackList::Channels(track);
// Process only if the right marker is to the right of the left marker // Process only if the right marker is to the right of the left marker
if (mCurT1 > mCurT0) { if (mCurT1 > mCurT0) {
wxString msg; wxString trackName = track->GetName();
auto trackName = track->GetName();
if(!track->GetLinked() || mStereoInd) float extent;
msg = #ifdef EXPERIMENTAL_R128_NORM
topMsg + wxString::Format( _("Analyzing: %s"), trackName ); if (mUseLoudness)
// Loudness: use sum of both tracks.
// As a result, stereo tracks appear about 3 LUFS louder,
// as specified.
extent = 0;
else else
msg = #endif
topMsg + wxString::Format( _("Analyzing first track of stereo pair: %s"), trackName ); // Will compute a maximum
float offset, extent; extent = std::numeric_limits<float>::lowest();
bGoodResult = AnalyseTrack(track, msg, progress, offset, extent); std::vector<float> offsets;
if (!bGoodResult )
break; wxString msg;
if(!track->GetLinked() || mStereoInd) { if (range.size() == 1)
// mono or 'stereo tracks independently' // mono or 'stereo tracks independently'
if( (extent > 0) && mGain ) msg = topMsg +
{ wxString::Format( _("Analyzing: %s"), trackName );
else
msg = topMsg +
// TODO: more-than-two-channels-message
wxString::Format( _("Analyzing first track of stereo pair: %s"), trackName);
// Analysis loop over channels collects offsets and extent
for (auto channel : range) {
float offset, extent2;
bGoodResult =
AnalyseTrack( channel, msg, progress, offset, extent2 );
if ( ! bGoodResult )
goto break2;
#ifdef EXPERIMENTAL_R128_NORM
if (mUseLoudness)
extent += extent2;
else
#endif
extent = std::max( extent, extent2 );
offsets.push_back(offset);
// TODO: more-than-two-channels-message
msg = topMsg +
wxString::Format( _("Analyzing second track of stereo pair: %s"), trackName );
}
// Compute the multiplier using extent
if( (extent > 0) && mGain ) {
mMult = ratio / extent; mMult = ratio / extent;
#ifdef EXPERIMENTAL_R128_NORM #ifdef EXPERIMENTAL_R128_NORM
if(mUseLoudness) { if(mUseLoudness) {
// PRL: See commit 9cbb67a for the origin of the next line,
// which has no effect because mMult is again overwritten. What
// was the intent?
// LUFS is defined as -0.691 dB + 10*log10(sum(channels)) // LUFS is defined as -0.691 dB + 10*log10(sum(channels))
mMult /= 0.8529037031; mMult /= 0.8529037031;
// LUFS are related to square values so the multiplier must be the root. // LUFS are related to square values so the multiplier must be the root.
@ -276,88 +311,36 @@ bool EffectNormalize::Process()
else else
mMult = 1.0; mMult = 1.0;
msg = if (range.size() == 1) {
topMsg + wxString::Format( _("Processing: %s"), trackName ); if (TrackList::Channels(track).size() == 1)
// really mono
if(track->GetLinked() || prevTrack->GetLinked()) // only get here if there is a linked track but we are processing independently msg = topMsg +
msg = wxString::Format( _("Processing: %s"), trackName );
topMsg + wxString::Format( _("Processing stereo channels independently: %s"), trackName ); else
//'stereo tracks independently'
if (!ProcessOne(track, msg, progress, offset)) // TODO: more-than-two-channels-message
{ msg = topMsg +
bGoodResult = false; wxString::Format( _("Processing stereo channels independently: %s"), trackName);
break;
}
}
else {
// we have a linked stereo track
// so we need to find it's min, max and offset
// as they are needed to calc the multiplier for both tracks
track = (WaveTrack *) iter.Next(); // get the next one
msg =
topMsg + wxString::Format( _("Analyzing second track of stereo pair: %s"), trackName );
float offset2, extent2;
bGoodResult = AnalyseTrack(track, msg, progress, offset2, extent2);
if ( !bGoodResult )
break;
#ifdef EXPERIMENTAL_R128_NORM
if (mUseLoudness) {
// Loudness: use sum of both tracks.
// As a result, stereo tracks appear about 3 LUFS louder, as specified.
extent = extent + extent2;
// LUFS is defined as -0.691 dB + 10*log10(sum(channels))
extent *= 0.8529037031;
}
else {
// Peak: use maximum of both tracks.
extent = fmax(extent, extent2);
}
#else
// Peak: use maximum of both tracks.
extent = fmax(extent, extent2);
#endif
if( (extent > 0) && mGain )
{
mMult = ratio / extent; // we need to use this for both linked tracks
#ifdef EXPERIMENTAL_R128_NORM
if(mUseLoudness) {
// LUFS are related to square values so the multiplier must be the root.
mMult = sqrt(mMult);
}
#endif
} }
else else
mMult = 1.0; msg = topMsg +
// TODO: more-than-two-channels-message
wxString::Format( _("Processing first track of stereo pair: %s"), trackName);
track = (WaveTrack *) iter.Prev(); // go back to the first linked one // Use multiplier in the second, processing loop over channels
msg = auto pOffset = offsets.begin();
topMsg + wxString::Format( _("Processing first track of stereo pair: %s"), trackName ); for (auto channel : range) {
if (false ==
if (!ProcessOne(track, msg, progress, offset)) (bGoodResult = ProcessOne(channel, msg, progress, *pOffset++)) )
{ goto break2;
bGoodResult = false; // TODO: more-than-two-channels-message
break; msg = topMsg +
} wxString::Format( _("Processing second track of stereo pair: %s"), trackName);
track = (WaveTrack *) iter.Next(); // go to the second linked one
msg =
topMsg + wxString::Format( _("Processing second track of stereo pair: %s"), trackName );
if (!ProcessOne(track, msg, progress, offset2))
{
bGoodResult = false;
break;
} }
} }
} }
//Iterate to the next track break2:
prevTrack = track;
track = (WaveTrack *) iter.Next();
}
this->ReplaceProcessedTracks(bGoodResult); this->ReplaceProcessedTracks(bGoodResult);
return bGoodResult; return bGoodResult;