diff --git a/src/Menus.cpp b/src/Menus.cpp index a1f28b552..970602c62 100644 --- a/src/Menus.cpp +++ b/src/Menus.cpp @@ -7088,8 +7088,9 @@ void AudacityProject::OnMuteAllTracks() while (t) { - if (t->GetKind() == Track::Wave) - t->SetMute(true); + auto pt = dynamic_cast(t); + if (pt) + pt->SetMute(true); t = iter.Next(); } @@ -7107,7 +7108,9 @@ void AudacityProject::OnUnMuteAllTracks() while (t) { - t->SetMute(false); + auto pt = dynamic_cast(t); + if (pt) + pt->SetMute(false); t = iter.Next(); } diff --git a/src/MixerBoard.cpp b/src/MixerBoard.cpp index 949402439..2b3ffef51 100644 --- a/src/MixerBoard.cpp +++ b/src/MixerBoard.cpp @@ -1110,9 +1110,11 @@ bool MixerBoard::HasSolo() { TrackListIterator iterTracks(mTracks); Track* pTrack; - for (pTrack = iterTracks.First(); pTrack; pTrack = iterTracks.Next()) - if (pTrack->GetSolo()) + for (pTrack = iterTracks.First(); pTrack; pTrack = iterTracks.Next()) { + auto pPlayable = dynamic_cast( pTrack ); + if (pPlayable && pPlayable->GetSolo()) return true; + } return false; } diff --git a/src/Project.cpp b/src/Project.cpp index 4cb842b53..0683c5f3c 100644 --- a/src/Project.cpp +++ b/src/Project.cpp @@ -3655,6 +3655,8 @@ void AudacityProject::WriteXML(XMLWriter &xmlFile, bool bWantSaveCompressed) while (t) { if ((t->GetKind() == Track::Wave) && bWantSaveCompressed) { + auto wt = static_cast(t); + //vvv This should probably be a method, WaveTrack::WriteCompressedTrackXML(). xmlFile.StartTag(wxT("import")); xmlFile.WriteAttr(wxT("filename"), mStrOtherNamesArray[ndx]); // Assumes mTracks order hasn't changed! @@ -3665,8 +3667,8 @@ void AudacityProject::WriteXML(XMLWriter &xmlFile, bool bWantSaveCompressed) // xmlFile.WriteAttr(wxT("linked"), t->GetLinked()); xmlFile.WriteAttr(wxT("offset"), t->GetOffset(), 8); - xmlFile.WriteAttr(wxT("mute"), t->GetMute()); - xmlFile.WriteAttr(wxT("solo"), t->GetSolo()); + xmlFile.WriteAttr(wxT("mute"), wt->GetMute()); + xmlFile.WriteAttr(wxT("solo"), wt->GetSolo()); xmlFile.WriteAttr(wxT("height"), t->GetActualHeight()); xmlFile.WriteAttr(wxT("minimized"), t->GetMinimized()); @@ -3975,10 +3977,12 @@ bool AudacityProject::Save(bool overwrite /* = true */ , ((pTrack != NULL) && (pSavedTrack != NULL)); pTrack = iter.Next(), pSavedTrack = savedTrackIter.Next()) { - pWaveTrack = (WaveTrack*)pTrack; + pWaveTrack = static_cast(pTrack); + auto pSavedWaveTrack = static_cast(pSavedTrack); + pWaveTrack->SetSelected(pSavedTrack->GetSelected()); - pWaveTrack->SetMute(pSavedTrack->GetMute()); - pWaveTrack->SetSolo(pSavedTrack->GetSolo()); + pWaveTrack->SetMute(pSavedWaveTrack->GetMute()); + pWaveTrack->SetSolo(pSavedWaveTrack->GetSolo()); pWaveTrack->SetGain(((WaveTrack*)pSavedTrack)->GetGain()); pWaveTrack->SetPan(((WaveTrack*)pSavedTrack)->GetPan()); @@ -5430,36 +5434,45 @@ void AudacityProject::HandleTrackMute(Track *t, const bool exclusive) if (exclusive) { TrackListIterator iter(GetTracks()); - Track *i = iter.First(); - while (i) { - if (i == t) { - i->SetMute(true); - if(i->GetLinked()) { // also mute the linked track - i = iter.Next(); + Track *it = iter.First(); + while (it) { + auto i = dynamic_cast(it); + if (i) { + if (i == t) { i->SetMute(true); + if(i->GetLinked()) { // also mute the linked track + it = iter.Next(); + i->SetMute(true); + } } + else { + i->SetMute(false); + } + i->SetSolo(false); } - else { - i->SetMute(false); - } - i->SetSolo(false); - i = iter.Next(); + it = iter.Next(); } } else { // Normal click toggles this track. - t->SetMute(!t->GetMute()); + auto pt = dynamic_cast( t ); + if (!pt) + return; + + pt->SetMute(!pt->GetMute()); if(t->GetLinked()) // set mute the same on both, if a pair { - bool muted = t->GetMute(); + bool muted = pt->GetMute(); TrackListIterator iter(GetTracks()); Track *i = iter.First(); while (i != t) { // search for this track i = iter.Next(); } i = iter.Next(); // get the next one, since linked - i->SetMute(muted); // and mute it as well + auto pi = dynamic_cast( i ); + if (pi) + pi->SetMute(muted); // and mute it as well } if (IsSoloSimple() || IsSoloNone()) @@ -5471,18 +5484,23 @@ void AudacityProject::HandleTrackMute(Track *t, const bool exclusive) // We also set a solo indicator if we have just one track / stereo pair playing. // otherwise clear solo on everything. while (i) { - if( !i->GetMute()) - { - nPlaying += 1; - if(i->GetLinked()) - i = iter.Next(); // don't count this one as it is linked + auto pi = dynamic_cast( i ); + if (pi) { + if( !pi->GetMute()) + { + nPlaying += 1; + if(i->GetLinked()) + i = iter.Next(); // don't count this one as it is linked + } } i = iter.Next(); } i = iter.First(); while (i) { - i->SetSolo( (nPlaying==1) && !i->GetMute() ); // will set both of a stereo pair + auto pi = dynamic_cast( i ); + if (pi) + pi->SetSolo( (nPlaying==1) && !pi->GetMute() ); // will set both of a stereo pair i = iter.Next(); } } @@ -5492,8 +5510,12 @@ void AudacityProject::HandleTrackMute(Track *t, const bool exclusive) // Type of solo (standard or simple) follows the set preference, unless // alternate == true, which causes the opposite behavior. -void AudacityProject::HandleTrackSolo(Track *t, const bool alternate) +void AudacityProject::HandleTrackSolo(Track *const t, const bool alternate) { + const auto pt = dynamic_cast( t ); + if (!pt) + return; + bool bSoloMultiple = !IsSoloSimple() ^ alternate; // Standard and Simple solo have opposite defaults: @@ -5503,17 +5525,19 @@ void AudacityProject::HandleTrackSolo(Track *t, const bool alternate) // when in standard radio button mode. if ( bSoloMultiple ) { - t->SetSolo( !t->GetSolo() ); + pt->SetSolo( !pt->GetSolo() ); if(t->GetLinked()) { - bool soloed = t->GetSolo(); + bool soloed = pt->GetSolo(); TrackListIterator iter(GetTracks()); Track *i = iter.First(); while (i != t) { // search for this track i = iter.Next(); } i = iter.Next(); // get the next one, since linked - i->SetSolo(soloed); // and solo it as well + auto pi = dynamic_cast( i ); + if (pi) + pi->SetSolo(soloed); // and solo it as well } } else @@ -5522,26 +5546,32 @@ void AudacityProject::HandleTrackSolo(Track *t, const bool alternate) // OR unmute and unsolo everything. TrackListIterator iter(GetTracks()); Track *i = iter.First(); - bool bWasSolo = t->GetSolo(); + bool bWasSolo = pt->GetSolo(); while (i) { if( i==t ) { - i->SetSolo(!bWasSolo); + pt->SetSolo(!bWasSolo); if( IsSoloSimple() ) - i->SetMute(false); + pt->SetMute(false); if(t->GetLinked()) { i = iter.Next(); - i->SetSolo(!bWasSolo); - if( IsSoloSimple() ) - i->SetMute(false); + auto pi = dynamic_cast( i ); + if (pi) { + pi->SetSolo(!bWasSolo); + if( IsSoloSimple() ) + pi->SetMute(false); + } } } else { - i->SetSolo(false); - if( IsSoloSimple() ) - i->SetMute(!bWasSolo); + auto pi = dynamic_cast( i ); + if (pi) { + pi->SetSolo(false); + if( IsSoloSimple() ) + pi->SetMute(!bWasSolo); + } } i = iter.Next(); } diff --git a/src/Track.cpp b/src/Track.cpp index 7a5d93a82..166b2393b 100644 --- a/src/Track.cpp +++ b/src/Track.cpp @@ -50,8 +50,6 @@ Track::Track(const std::shared_ptr &projDirManager) mList = NULL; mSelected = false; mLinked = false; - mMute = false; - mSolo = false; mY = 0; mHeight = 150; @@ -92,8 +90,6 @@ void Track::Init(const Track &orig) mSelected = orig.mSelected; mLinked = orig.mLinked; - mMute = orig.mMute; - mSolo = orig.mSolo; mHeight = orig.mHeight; mMinimized = orig.mMinimized; mChannel = orig.mChannel; @@ -112,8 +108,6 @@ void Track::SetSelected(bool s) void Track::Merge(const Track &orig) { mSelected = orig.mSelected; - mMute = orig.mMute; - mSolo = orig.mSolo; } Track::~Track() @@ -331,6 +325,22 @@ bool Track::SyncLockAdjust(double oldT1, double newT1) return true; } +void PlayableTrack::Init( const PlayableTrack &orig ) +{ + mMute = orig.mMute; + mSolo = orig.mSolo; + AudioTrack::Init( orig ); +} + +void PlayableTrack::Merge( const Track &orig ) +{ + auto pOrig = dynamic_cast(&orig); + wxASSERT( pOrig ); + mMute = pOrig->mMute; + mSolo = pOrig->mSolo; + AudioTrack::Merge( *pOrig ); +} + // TrackListIterator TrackListIterator::TrackListIterator(TrackList * val) : l(val) @@ -1208,7 +1218,9 @@ unsigned TrackList::GetNumExportChannels(bool selectionOnly) const for (tr = iter.First(this); tr != NULL; tr = iter.Next()) { // Want only unmuted wave tracks. - if ((tr->GetKind() != Track::Wave) || tr->GetMute()) + auto wt = static_cast(tr); + if ((tr->GetKind() != Track::Wave) || + wt->GetMute()) continue; // do we only want selected ones? @@ -1265,8 +1277,9 @@ namespace { for (; p != end; ++p) { const auto &track = *p; + auto wt = static_cast(&*track); if (track->GetKind() == Track::Wave && - (includeMuted || !track->GetMute()) && + (includeMuted || !wt->GetMute()) && (track->GetSelected() || !selectionOnly)) { waveTrackArray.push_back(static_cast(track.get())); } diff --git a/src/Track.h b/src/Track.h index fb527aa94..39a994168 100644 --- a/src/Track.h +++ b/src/Track.h @@ -140,8 +140,6 @@ class AUDACITY_DLL_API Track /* not final */ : public XMLTagHandler protected: int mChannel; double mOffset; - bool mMute; - bool mSolo; mutable std::shared_ptr mDirManager; @@ -189,14 +187,10 @@ class AUDACITY_DLL_API Track /* not final */ : public XMLTagHandler void SetDefaultName( const wxString &n ) { mDefaultName = n; } bool GetSelected() const { return mSelected; } - bool GetMute () const { return mMute; } bool GetLinked () const { return mLinked; } - bool GetSolo () const { return mSolo; } virtual void SetSelected(bool s); - void SetMute (bool m) { mMute = m; } void SetLinked (bool l); - void SetSolo (bool s) { mSolo = s; } int GetChannel() const { return mChannel; } virtual double GetOffset() const = 0; @@ -265,6 +259,18 @@ public: PlayableTrack(const std::shared_ptr &projDirManager) : AudioTrack{ projDirManager } {} PlayableTrack(const Track &orig) : AudioTrack{ orig } {} + + bool GetMute () const { return mMute; } + bool GetSolo () const { return mSolo; } + void SetMute (bool m) { mMute = m; } + void SetSolo (bool s) { mSolo = s; } + + void Init( const PlayableTrack &init ); + void Merge( const Track &init ) override; + +protected: + bool mMute { false }; + bool mSolo { false }; }; class AUDACITY_DLL_API TrackListIterator /* not final */ diff --git a/src/TrackArtist.cpp b/src/TrackArtist.cpp index 7ed78c988..559c41280 100644 --- a/src/TrackArtist.cpp +++ b/src/TrackArtist.cpp @@ -336,7 +336,8 @@ void TrackArtist::DrawTracks(TrackList * tracks, bool hasSolo = false; for (t = iter.First(); t; t = iter.Next()) { - if (t->GetSolo()) { + auto pt = dynamic_cast(t); + if (pt && pt->GetSolo()) { hasSolo = true; break; } @@ -457,7 +458,8 @@ void TrackArtist::DrawTrack(const Track * t, clip->ClearDisplayRect(); } - bool muted = (hasSolo || t->GetMute()) && !t->GetSolo(); + bool muted = (hasSolo || wt->GetMute()) && + !wt->GetSolo(); #if defined(__WXMAC__) wxAntialiasMode aamode = dc.GetGraphicsContext()->GetAntialiasMode(); @@ -493,7 +495,11 @@ void TrackArtist::DrawTrack(const Track * t, #ifdef USE_MIDI case Track::Note: { - bool muted = (hasSolo || t->GetMute()) && !t->GetSolo(); + auto nt = static_cast(t); + bool muted = false; +#ifdef EXPERIMENTAL_MIDI_OUT + muted = (hasSolo || nt->GetMute()) && !nt->GetSolo(); +#endif DrawNoteTrack((NoteTrack *)t, dc, rect, selectedRegion, zoomInfo, muted); break; } diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index a9e947079..14a71406e 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -9288,18 +9288,19 @@ void TrackInfo::DrawMuteSolo(wxDC * dc, const wxRect & rect, Track * t, return; // don't draw mute and solo buttons, because they don't fit into track label AColor::MediumTrackInfo( dc, t->GetSelected()); + auto pt = dynamic_cast(t); if( solo ) { - if( t->GetSolo() ) + if( pt && pt->GetSolo() ) { - AColor::Solo(dc, t->GetSolo(), t->GetSelected()); + AColor::Solo(dc, pt->GetSolo(), t->GetSelected()); } } else { - if( t->GetMute() ) + if( pt && pt->GetMute() ) { - AColor::Mute(dc, t->GetMute(), t->GetSelected(), t->GetSolo()); + AColor::Mute(dc, pt->GetMute(), t->GetSelected(), pt->GetSolo()); } } //(solo) ? AColor::Solo(dc, t->GetSolo(), t->GetSelected()) : @@ -9318,7 +9319,11 @@ void TrackInfo::DrawMuteSolo(wxDC * dc, const wxRect & rect, Track * t, dc->GetTextExtent(str, &textWidth, &textHeight); dc->DrawText(str, bev.x + (bev.width - textWidth) / 2, bev.y + (bev.height - textHeight) / 2); - AColor::BevelTrackInfo(*dc, (solo?t->GetSolo():t->GetMute()) == down, bev); + AColor::BevelTrackInfo( + *dc, + (solo ? pt->GetSolo() : (pt && pt->GetMute())) == down, + bev + ); if (solo && !down) { // Update the mute button, which may be grayed out depending on diff --git a/src/TrackPanelAx.cpp b/src/TrackPanelAx.cpp index bf9a4ec7c..3f8774428 100644 --- a/src/TrackPanelAx.cpp +++ b/src/TrackPanelAx.cpp @@ -363,7 +363,8 @@ wxAccStatus TrackPanelAx::GetName( int childId, wxString* name ) #endif // LLL: Remove these during "refactor" - if( t->GetMute() ) + auto pt = dynamic_cast(t); + if( pt && pt->GetMute() ) { // The following comment also applies to the solo, selected, // and synclockselected states. @@ -376,7 +377,7 @@ wxAccStatus TrackPanelAx::GetName( int childId, wxString* name ) name->Append( wxT(" ") + wxString(_( " Mute On" )) ); } - if( t->GetSolo() ) + if( pt && pt->GetSolo() ) { /* i18n-hint: This is for screen reader software and indicates that on this track solo is on.*/ @@ -547,12 +548,13 @@ wxAccStatus TrackPanelAx::GetValue( int WXUNUSED(childId), wxString* WXUNUSED(st } // LLL: Remove these during "refactor" - if( t->GetMute() ) + auto pt = dynamic_cast(t); + if( pt && pt->GetMute() ) { strValue->Append( _( " Mute On" ) ); } - if( t->GetSolo() ) + if( pt && pt->GetSolo() ) { strValue->Append( _( " Solo On" ) ); } diff --git a/src/commands/GetProjectInfoCommand.cpp b/src/commands/GetProjectInfoCommand.cpp index 047809c90..5d34168a6 100644 --- a/src/commands/GetProjectInfoCommand.cpp +++ b/src/commands/GetProjectInfoCommand.cpp @@ -161,10 +161,12 @@ bool GetProjectInfoCommand::testLinked(const Track * track) const bool GetProjectInfoCommand::testSolo(const Track * track) const { - return track->GetSolo(); + auto pt = dynamic_cast(track); + return pt && pt->GetSolo(); } bool GetProjectInfoCommand::testMute(const Track * track) const { - return track->GetMute(); + auto pt = dynamic_cast(track); + return pt && pt->GetMute(); } diff --git a/src/commands/GetTrackInfoCommand.cpp b/src/commands/GetTrackInfoCommand.cpp index f0889e837..455a799d8 100644 --- a/src/commands/GetTrackInfoCommand.cpp +++ b/src/commands/GetTrackInfoCommand.cpp @@ -127,15 +127,17 @@ bool GetTrackInfoCommand::Apply(CommandExecutionContext context) } else if (mode.IsSameAs(wxT("Solo"))) { - if (t->GetKind() == Track::Wave) - SendBooleanStatus(t->GetSolo()); + auto pt = dynamic_cast(t); + if (pt) + SendBooleanStatus(pt->GetSolo()); else SendBooleanStatus(false); } else if (mode.IsSameAs(wxT("Mute"))) { - if (t->GetKind() == Track::Wave) - SendBooleanStatus(t->GetMute()); + auto pt = dynamic_cast(t); + if (pt) + SendBooleanStatus(pt->GetMute()); else SendBooleanStatus(false); } diff --git a/src/commands/SetProjectInfoCommand.cpp b/src/commands/SetProjectInfoCommand.cpp index 0ae857f8e..d15180cfd 100644 --- a/src/commands/SetProjectInfoCommand.cpp +++ b/src/commands/SetProjectInfoCommand.cpp @@ -98,12 +98,14 @@ void SetProjectInfoCommand::setSelected(Track * trk, bool param) const void SetProjectInfoCommand::setSolo(Track * trk, bool param) const { - if(trk->GetKind() == Track::Wave) - trk->SetSolo(param); + auto pt = dynamic_cast(trk); + if (pt) + pt->SetSolo(param); } void SetProjectInfoCommand::setMute(Track * trk, bool param) const { - if(trk->GetKind() == Track::Wave) - trk->SetMute(param); + auto pt = dynamic_cast(trk); + if (pt) + pt->SetMute(param); } diff --git a/src/export/Export.cpp b/src/export/Export.cpp index e92a7cbda..a4dde5947 100644 --- a/src/export/Export.cpp +++ b/src/export/Export.cpp @@ -425,7 +425,9 @@ bool Exporter::ExamineTracks() while (tr) { if (tr->GetKind() == Track::Wave) { - if ( (tr->GetSelected() || !mSelectedOnly) && !tr->GetMute() ) { // don't count muted tracks + auto wt = static_cast(tr); + if ( (tr->GetSelected() || !mSelectedOnly) && + !wt->GetMute() ) { // don't count muted tracks mNumSelected++; if (tr->GetChannel() == Track::LeftChannel) { @@ -1255,7 +1257,9 @@ ExportMixerDialog::ExportMixerDialog( const TrackList *tracks, bool selectedOnly for( const Track *t = iter.First(); t; t = iter.Next() ) { - if( t->GetKind() == Track::Wave && ( t->GetSelected() || !selectedOnly ) && !t->GetMute() ) + auto wt = static_cast(t); + if( t->GetKind() == Track::Wave && ( t->GetSelected() || !selectedOnly ) && + !wt->GetMute() ) { numTracks++; const wxString sTrackName = (t->GetName()).Left(20); diff --git a/src/export/ExportMultiple.cpp b/src/export/ExportMultiple.cpp index 0c1dddb21..928c881a1 100644 --- a/src/export/ExportMultiple.cpp +++ b/src/export/ExportMultiple.cpp @@ -154,7 +154,8 @@ void ExportMultiple::CountTracksAndLabels() // Count WaveTracks, and for linked pairs, count only the second of the pair. case Track::Wave: { - if (!pTrack->GetMute() && !pTrack->GetLinked()) // Don't count muted tracks. + auto wt = static_cast(pTrack); + if (!wt->GetMute() && !pTrack->GetLinked()) // Don't count muted tracks. mNumWaveTracks++; break; } @@ -811,7 +812,9 @@ ProgressResult ExportMultiple::ExportMultipleByTrack(bool byName, for (tr = iter.First(mTracks); tr != NULL; tr = iter.Next()) { // Want only non-muted wave tracks. - if ((tr->GetKind() != Track::Wave) || tr->GetMute()) + auto wt = static_cast(tr); + if ((tr->GetKind() != Track::Wave) || + wt->GetMute()) continue; // Get the times for the track @@ -898,7 +901,8 @@ ProgressResult ExportMultiple::ExportMultipleByTrack(bool byName, for (tr = iter.First(mTracks); tr != NULL; tr = iter.Next()) { // Want only non-muted wave tracks. - if ((tr->GetKind() != Track::Wave) || (tr->GetMute() == true)) { + auto wt = static_cast(tr); + if ((tr->GetKind() != Track::Wave) || (wt->GetMute())) { continue; }