1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-22 15:20:15 +02:00

Move mute and solo state into PlayableTrack

This commit is contained in:
Paul Licameli 2017-03-29 11:25:05 -04:00
parent ed0088491c
commit 6c4cf46c06
13 changed files with 165 additions and 84 deletions

View File

@ -7088,8 +7088,9 @@ void AudacityProject::OnMuteAllTracks()
while (t)
{
if (t->GetKind() == Track::Wave)
t->SetMute(true);
auto pt = dynamic_cast<PlayableTrack *>(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<PlayableTrack *>(t);
if (pt)
pt->SetMute(false);
t = iter.Next();
}

View File

@ -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<PlayableTrack *>( pTrack );
if (pPlayable && pPlayable->GetSolo())
return true;
}
return false;
}

View File

@ -3655,6 +3655,8 @@ void AudacityProject::WriteXML(XMLWriter &xmlFile, bool bWantSaveCompressed)
while (t) {
if ((t->GetKind() == Track::Wave) && bWantSaveCompressed)
{
auto wt = static_cast<const WaveTrack *>(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<WaveTrack*>(pTrack);
auto pSavedWaveTrack = static_cast<const WaveTrack*>(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<PlayableTrack *>(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<PlayableTrack *>( 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<PlayableTrack *>( 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<PlayableTrack *>( 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<PlayableTrack *>( 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<PlayableTrack *>( 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<PlayableTrack *>( 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<PlayableTrack *>( i );
if (pi) {
pi->SetSolo(!bWasSolo);
if( IsSoloSimple() )
pi->SetMute(false);
}
}
}
else
{
i->SetSolo(false);
if( IsSoloSimple() )
i->SetMute(!bWasSolo);
auto pi = dynamic_cast<PlayableTrack *>( i );
if (pi) {
pi->SetSolo(false);
if( IsSoloSimple() )
pi->SetMute(!bWasSolo);
}
}
i = iter.Next();
}

View File

@ -50,8 +50,6 @@ Track::Track(const std::shared_ptr<DirManager> &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<const PlayableTrack *>(&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<const WaveTrack *>(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<const WaveTrack *>(&*track);
if (track->GetKind() == Track::Wave &&
(includeMuted || !track->GetMute()) &&
(includeMuted || !wt->GetMute()) &&
(track->GetSelected() || !selectionOnly)) {
waveTrackArray.push_back(static_cast<WaveTrack*>(track.get()));
}

View File

@ -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<DirManager> 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<DirManager> &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 */

View File

@ -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<const PlayableTrack *>(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<const NoteTrack *>(t);
bool muted = false;
#ifdef EXPERIMENTAL_MIDI_OUT
muted = (hasSolo || nt->GetMute()) && !nt->GetSolo();
#endif
DrawNoteTrack((NoteTrack *)t, dc, rect, selectedRegion, zoomInfo, muted);
break;
}

View File

@ -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<const PlayableTrack *>(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

View File

@ -363,7 +363,8 @@ wxAccStatus TrackPanelAx::GetName( int childId, wxString* name )
#endif
// LLL: Remove these during "refactor"
if( t->GetMute() )
auto pt = dynamic_cast<PlayableTrack *>(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<PlayableTrack *>(t);
if( pt && pt->GetMute() )
{
strValue->Append( _( " Mute On" ) );
}
if( t->GetSolo() )
if( pt && pt->GetSolo() )
{
strValue->Append( _( " Solo On" ) );
}

View File

@ -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<const PlayableTrack *>(track);
return pt && pt->GetSolo();
}
bool GetProjectInfoCommand::testMute(const Track * track) const
{
return track->GetMute();
auto pt = dynamic_cast<const PlayableTrack *>(track);
return pt && pt->GetMute();
}

View File

@ -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<const PlayableTrack *>(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<const PlayableTrack *>(t);
if (pt)
SendBooleanStatus(pt->GetMute());
else
SendBooleanStatus(false);
}

View File

@ -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<PlayableTrack *>(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<PlayableTrack *>(trk);
if (pt)
pt->SetMute(param);
}

View File

@ -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<const WaveTrack *>(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<const WaveTrack *>(t);
if( t->GetKind() == Track::Wave && ( t->GetSelected() || !selectedOnly ) &&
!wt->GetMute() )
{
numTracks++;
const wxString sTrackName = (t->GetName()).Left(20);

View File

@ -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<const WaveTrack *>(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<const WaveTrack *>(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<const WaveTrack *>(tr);
if ((tr->GetKind() != Track::Wave) || (wt->GetMute())) {
continue;
}