1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-08-16 08:34:10 +02:00

Simplify MixerBoard.cpp using the PlayableTrack type

This commit is contained in:
Paul Licameli 2017-03-27 10:12:32 -04:00
parent f1bec85675
commit b2ab9b5087
6 changed files with 140 additions and 343 deletions

View File

@ -6889,8 +6889,9 @@ void AudacityProject::OnRemoveTracks()
while (t) { while (t) {
if (t->GetSelected()) { if (t->GetSelected()) {
if (mMixerBoard && (t->GetKind() == Track::Wave)) auto playable = dynamic_cast<PlayableTrack*>(t);
mMixerBoard->RemoveTrackCluster((WaveTrack*)t); if (mMixerBoard && playable)
mMixerBoard->RemoveTrackCluster(playable);
if (!f) if (!f)
f = l; // Capture the track preceeding the first removed track f = l; // Capture the track preceeding the first removed track
t = iter.RemoveCurrent(); t = iter.RemoveCurrent();

View File

@ -23,9 +23,9 @@
#include "AColor.h" #include "AColor.h"
#include "AudioIO.h" #include "AudioIO.h"
#ifdef EXPERIMENTAL_MIDI_OUT
#include "NoteTrack.h" #include "NoteTrack.h"
#endif
#include "Project.h" #include "Project.h"
#include "TrackPanel.h" // for EVT_TRACK_PANEL_TIMER #include "TrackPanel.h" // for EVT_TRACK_PANEL_TIMER
#include "UndoManager.h" #include "UndoManager.h"
@ -155,30 +155,17 @@ END_EVENT_TABLE()
MixerTrackCluster::MixerTrackCluster(wxWindow* parent, MixerTrackCluster::MixerTrackCluster(wxWindow* parent,
MixerBoard* grandParent, AudacityProject* project, MixerBoard* grandParent, AudacityProject* project,
WaveTrack* pLeftTrack, WaveTrack* pRightTrack /*= NULL*/, PlayableTrack* pTrack,
const wxPoint& pos /*= wxDefaultPosition*/, const wxPoint& pos /*= wxDefaultPosition*/,
const wxSize& size /*= wxDefaultSize*/) const wxSize& size /*= wxDefaultSize*/)
: wxPanelWrapper(parent, -1, pos, size) : wxPanelWrapper(parent, -1, pos, size)
, mTrack{ pTrack }
{ {
mMixerBoard = grandParent; mMixerBoard = grandParent;
mProject = project; mProject = project;
#ifdef EXPERIMENTAL_MIDI_OUT wxASSERT( pTrack );
if (pLeftTrack->GetKind() == Track::Note) {
mLeftTrack = NULL;
mNoteTrack = (NoteTrack*) pLeftTrack;
mTrack = pLeftTrack;
} else {
wxASSERT(pLeftTrack->GetKind() == Track::Wave);
mTrack = mLeftTrack = pLeftTrack;
mNoteTrack = NULL;
}
#else
wxASSERT(pLeftTrack->GetKind() == Track::Wave);
mLeftTrack = pLeftTrack;
#endif
mRightTrack = pRightTrack;
SetName(mLeftTrack->GetName()); SetName(mTrack->GetName());
this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE)); this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
@ -191,13 +178,8 @@ MixerTrackCluster::MixerTrackCluster(wxWindow* parent,
wxPoint ctrlPos(kDoubleInset, kDoubleInset); wxPoint ctrlPos(kDoubleInset, kDoubleInset);
wxSize ctrlSize(size.GetWidth() - kQuadrupleInset, TRACK_NAME_HEIGHT); wxSize ctrlSize(size.GetWidth() - kQuadrupleInset, TRACK_NAME_HEIGHT);
mStaticText_TrackName = mStaticText_TrackName =
#ifdef EXPERIMENTAL_MIDI_OUT
safenew wxStaticText(this, -1, mTrack->GetName(), ctrlPos, ctrlSize, safenew wxStaticText(this, -1, mTrack->GetName(), ctrlPos, ctrlSize,
wxALIGN_CENTRE | wxST_NO_AUTORESIZE | wxSUNKEN_BORDER); wxALIGN_CENTRE | wxST_NO_AUTORESIZE | wxSUNKEN_BORDER);
#else
safenew wxStaticText(this, -1, mLeftTrack->GetName(), ctrlPos, ctrlSize,
wxALIGN_CENTRE | 0x0001 | wxBORDER_SUNKEN);
#endif
//v Useful when different tracks are different colors, but not now. //v Useful when different tracks are different colors, but not now.
// mStaticText_TrackName->SetBackgroundColour(this->GetTrackColor()); // mStaticText_TrackName->SetBackgroundColour(this->GetTrackColor());
@ -208,8 +190,8 @@ MixerTrackCluster::MixerTrackCluster(wxWindow* parent,
const int nGainSliderHeight = const int nGainSliderHeight =
size.GetHeight() - ctrlPos.y - kQuadrupleInset; size.GetHeight() - ctrlPos.y - kQuadrupleInset;
ctrlSize.Set(kLeftSideStackWidth - kQuadrupleInset, nGainSliderHeight); ctrlSize.Set(kLeftSideStackWidth - kQuadrupleInset, nGainSliderHeight);
#ifdef EXPERIMENTAL_MIDI_OUT
if (mNoteTrack) { if (GetNote()) {
mSlider_Gain = mSlider_Gain =
safenew MixerTrackSlider( safenew MixerTrackSlider(
this, ID_SLIDER_GAIN, this, ID_SLIDER_GAIN,
@ -217,8 +199,8 @@ MixerTrackCluster::MixerTrackCluster(wxWindow* parent,
_("Velocity"), _("Velocity"),
ctrlPos, ctrlSize, VEL_SLIDER, true, ctrlPos, ctrlSize, VEL_SLIDER, true,
true, 0.0, wxVERTICAL); true, 0.0, wxVERTICAL);
} else }
#endif else
mSlider_Gain = mSlider_Gain =
safenew MixerTrackSlider( safenew MixerTrackSlider(
this, ID_SLIDER_GAIN, this, ID_SLIDER_GAIN,
@ -226,6 +208,7 @@ MixerTrackCluster::MixerTrackCluster(wxWindow* parent,
_("Gain"), _("Gain"),
ctrlPos, ctrlSize, DB_SLIDER, true, ctrlPos, ctrlSize, DB_SLIDER, true,
true, 0.0, wxVERTICAL); true, 0.0, wxVERTICAL);
mSlider_Gain->SetName(_("Gain")); mSlider_Gain->SetName(_("Gain"));
this->UpdateGain(); this->UpdateGain();
@ -236,11 +219,7 @@ MixerTrackCluster::MixerTrackCluster(wxWindow* parent,
// musical instrument image // musical instrument image
ctrlPos.x += kLeftSideStackWidth + kInset; // + kInset to center it in right side stack ctrlPos.x += kLeftSideStackWidth + kInset; // + kInset to center it in right side stack
ctrlSize.Set(MUSICAL_INSTRUMENT_HEIGHT_AND_WIDTH, MUSICAL_INSTRUMENT_HEIGHT_AND_WIDTH); ctrlSize.Set(MUSICAL_INSTRUMENT_HEIGHT_AND_WIDTH, MUSICAL_INSTRUMENT_HEIGHT_AND_WIDTH);
#ifdef EXPERIMENTAL_MIDI_OUT wxBitmap* bitmap = mMixerBoard->GetMusicalInstrumentBitmap(mTrack);
wxBitmap* bitmap = mMixerBoard->GetMusicalInstrumentBitmap(mTrack->GetName());
#else
wxBitmap* bitmap = mMixerBoard->GetMusicalInstrumentBitmap(mLeftTrack);
#endif
wxASSERT(bitmap); wxASSERT(bitmap);
mBitmapButton_MusicalInstrument = mBitmapButton_MusicalInstrument =
safenew wxBitmapButton(this, ID_BITMAPBUTTON_MUSICAL_INSTRUMENT, *bitmap, safenew wxBitmapButton(this, ID_BITMAPBUTTON_MUSICAL_INSTRUMENT, *bitmap,
@ -306,9 +285,9 @@ MixerTrackCluster::MixerTrackCluster(wxWindow* parent,
(PAN_HEIGHT + kDoubleInset) - (PAN_HEIGHT + kDoubleInset) -
(MUTE_SOLO_HEIGHT + (bSoloNone ? 0 : MUTE_SOLO_HEIGHT) + kDoubleInset); (MUTE_SOLO_HEIGHT + (bSoloNone ? 0 : MUTE_SOLO_HEIGHT) + kDoubleInset);
ctrlSize.Set(kRightSideStackWidth, nMeterHeight); ctrlSize.Set(kRightSideStackWidth, nMeterHeight);
#ifdef EXPERIMENTAL_MIDI_OUT
if (mLeftTrack) { mMeter = NULL;
#endif if (GetWave()) {
mMeter = mMeter =
safenew Meter(GetActiveProject(), // AudacityProject* project, safenew Meter(GetActiveProject(), // AudacityProject* project,
this, -1, // wxWindow* parent, wxWindowID id, this, -1, // wxWindow* parent, wxWindowID id,
@ -316,23 +295,13 @@ MixerTrackCluster::MixerTrackCluster(wxWindow* parent,
ctrlPos, ctrlSize, // const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, ctrlPos, ctrlSize, // const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
Meter::MixerTrackCluster); // Style style = HorizontalStereo, Meter::MixerTrackCluster); // Style style = HorizontalStereo,
mMeter->SetName(_("Signal Level Meter")); mMeter->SetName(_("Signal Level Meter"));
#ifdef EXPERIMENTAL_MIDI_OUT
} else {
mMeter = NULL;
} }
#endif
#if wxUSE_TOOLTIPS #if wxUSE_TOOLTIPS
#ifdef EXPERIMENTAL_MIDI_OUT
mStaticText_TrackName->SetToolTip(mTrack->GetName()); mStaticText_TrackName->SetToolTip(mTrack->GetName());
#else
mStaticText_TrackName->SetToolTip(mLeftTrack->GetName());
#endif
mToggleButton_Mute->SetToolTip(_("Mute")); mToggleButton_Mute->SetToolTip(_("Mute"));
mToggleButton_Solo->SetToolTip(_("Solo")); mToggleButton_Solo->SetToolTip(_("Solo"));
#ifdef EXPERIMENTAL_MIDI_OUT if (GetWave())
if (mLeftTrack)
#endif
mMeter->SetToolTip(_("Signal Level Meter")); mMeter->SetToolTip(_("Signal Level Meter"));
#endif // wxUSE_TOOLTIPS #endif // wxUSE_TOOLTIPS
@ -344,8 +313,28 @@ MixerTrackCluster::MixerTrackCluster(wxWindow* parent,
#endif #endif
} }
WaveTrack *MixerTrackCluster::GetWave() const
{
return dynamic_cast< WaveTrack * >( mTrack );
}
WaveTrack *MixerTrackCluster::GetRight() const
{
auto left = GetWave();
if (left)
return static_cast<WaveTrack*>(left);
else
return nullptr;
}
NoteTrack *MixerTrackCluster::GetNote() const
{
return dynamic_cast< NoteTrack * >( mTrack );
}
void MixerTrackCluster::UpdatePrefs() void MixerTrackCluster::UpdatePrefs()
{ {
if (mMeter)
mMeter->UpdatePrefs(); // in case meter range has changed mMeter->UpdatePrefs(); // in case meter range has changed
HandleResize(); // in case prefs "/GUI/Solo" changed HandleResize(); // in case prefs "/GUI/Solo" changed
} }
@ -382,30 +371,24 @@ void MixerTrackCluster::HandleResize() // For wxSizeEvents, update gain slider a
TRACK_NAME_HEIGHT + kDoubleInset + TRACK_NAME_HEIGHT + kDoubleInset +
nRequiredHeightAboveMeter; nRequiredHeightAboveMeter;
const int nMeterHeight = nGainSliderHeight - nRequiredHeightAboveMeter; const int nMeterHeight = nGainSliderHeight - nRequiredHeightAboveMeter;
#ifdef EXPERIMENTAL_MIDI_OUT
if (mMeter) if (mMeter)
#endif
mMeter->SetSize(-1, nMeterY, -1, nMeterHeight); mMeter->SetSize(-1, nMeterY, -1, nMeterHeight);
} }
void MixerTrackCluster::HandleSliderGain(const bool bWantPushState /*= false*/) void MixerTrackCluster::HandleSliderGain(const bool bWantPushState /*= false*/)
{ {
float fValue = mSlider_Gain->Get(); float fValue = mSlider_Gain->Get();
if (mLeftTrack) if (GetWave())
mLeftTrack->SetGain(fValue); GetWave()->SetGain(fValue);
#ifdef EXPERIMENTAL_MIDI_OUT #ifdef EXPERIMENTAL_MIDI_OUT
else else
mNoteTrack->SetVelocity(fValue); GetNote()->SetVelocity(fValue);
#endif #endif
if (mRightTrack) if (GetRight())
mRightTrack->SetGain(fValue); GetRight()->SetGain(fValue);
// Update the TrackPanel correspondingly. // Update the TrackPanel correspondingly.
#ifdef EXPERIMENTAL_MIDI_OUT
mProject->RefreshTPTrack(mTrack); mProject->RefreshTPTrack(mTrack);
#else
mProject->RefreshTPTrack(mLeftTrack);
#endif
if (bWantPushState) if (bWantPushState)
mProject->TP_PushState(_("Moved gain slider"), _("Gain"), UndoPush::CONSOLIDATE ); mProject->TP_PushState(_("Moved gain slider"), _("Gain"), UndoPush::CONSOLIDATE );
} }
@ -413,17 +396,13 @@ void MixerTrackCluster::HandleSliderGain(const bool bWantPushState /*= false*/)
void MixerTrackCluster::HandleSliderPan(const bool bWantPushState /*= false*/) void MixerTrackCluster::HandleSliderPan(const bool bWantPushState /*= false*/)
{ {
float fValue = mSlider_Pan->Get(); float fValue = mSlider_Pan->Get();
if (mLeftTrack) // test in case track is a NoteTrack if (GetWave()) // test in case track is a NoteTrack
mLeftTrack->SetPan(fValue); GetWave()->SetPan(fValue);
if (mRightTrack) if (GetRight())
mRightTrack->SetPan(fValue); GetRight()->SetPan(fValue);
// Update the TrackPanel correspondingly. // Update the TrackPanel correspondingly.
#ifdef EXPERIMENTAL_MIDI_OUT
mProject->RefreshTPTrack(mTrack); mProject->RefreshTPTrack(mTrack);
#else
mProject->RefreshTPTrack(mLeftTrack);
#endif
if (bWantPushState) if (bWantPushState)
mProject->TP_PushState(_("Moved pan slider"), _("Pan"), UndoPush::CONSOLIDATE ); mProject->TP_PushState(_("Moved pan slider"), _("Pan"), UndoPush::CONSOLIDATE );
@ -431,10 +410,8 @@ void MixerTrackCluster::HandleSliderPan(const bool bWantPushState /*= false*/)
void MixerTrackCluster::ResetMeter(const bool bResetClipping) void MixerTrackCluster::ResetMeter(const bool bResetClipping)
{ {
#ifdef EXPERIMENTAL_MIDI_OUT
if (mMeter) if (mMeter)
#endif mMeter->Reset(GetWave()->GetRate(), bResetClipping);
mMeter->Reset(mLeftTrack->GetRate(), bResetClipping);
} }
@ -450,33 +427,20 @@ void MixerTrackCluster::UpdateForStateChange()
void MixerTrackCluster::UpdateName() void MixerTrackCluster::UpdateName()
{ {
#ifdef EXPERIMENTAL_MIDI_OUT
const wxString newName = mTrack->GetName(); const wxString newName = mTrack->GetName();
#else
const wxString newName = mLeftTrack->GetName();
#endif
SetName(newName); SetName(newName);
mStaticText_TrackName->SetLabel(newName); mStaticText_TrackName->SetLabel(newName);
#if wxUSE_TOOLTIPS #if wxUSE_TOOLTIPS
mStaticText_TrackName->SetToolTip(newName); mStaticText_TrackName->SetToolTip(newName);
#endif #endif
mBitmapButton_MusicalInstrument->SetBitmapLabel( mBitmapButton_MusicalInstrument->SetBitmapLabel(
#ifdef EXPERIMENTAL_MIDI_OUT *(mMixerBoard->GetMusicalInstrumentBitmap(mTrack)));
*(mMixerBoard->GetMusicalInstrumentBitmap(newName)));
#else
*(mMixerBoard->GetMusicalInstrumentBitmap(mLeftTrack)));
#endif
} }
void MixerTrackCluster::UpdateMute() void MixerTrackCluster::UpdateMute()
{ {
#ifdef EXPERIMENTAL_MIDI_OUT
mToggleButton_Mute->SetAlternateIdx(mTrack->GetSolo() ? 1 : 0); mToggleButton_Mute->SetAlternateIdx(mTrack->GetSolo() ? 1 : 0);
if (mTrack->GetMute()) if (mTrack->GetMute())
#else
mToggleButton_Mute->SetAlternateIdx(mLeftTrack->GetSolo() ? 1 : 0);
if (mLeftTrack->GetMute())
#endif
mToggleButton_Mute->PushDown(); mToggleButton_Mute->PushDown();
else else
mToggleButton_Mute->PopUp(); mToggleButton_Mute->PopUp();
@ -484,11 +448,7 @@ void MixerTrackCluster::UpdateMute()
void MixerTrackCluster::UpdateSolo() void MixerTrackCluster::UpdateSolo()
{ {
#ifdef EXPERIMENTAL_MIDI_OUT
bool bIsSolo = mTrack->GetSolo(); bool bIsSolo = mTrack->GetSolo();
#else
bool bIsSolo = mLeftTrack->GetSolo();
#endif
if (bIsSolo) if (bIsSolo)
mToggleButton_Solo->PushDown(); mToggleButton_Solo->PushDown();
else else
@ -499,55 +459,36 @@ void MixerTrackCluster::UpdateSolo()
void MixerTrackCluster::UpdatePan() void MixerTrackCluster::UpdatePan()
{ {
#ifdef EXPERIMENTAL_MIDI_OUT #ifdef EXPERIMENTAL_MIDI_OUT
if (mNoteTrack) { if (!GetWave()) {
mSlider_Pan->Hide(); mSlider_Pan->Hide();
return; return;
} }
#endif #endif
mSlider_Pan->Set(mLeftTrack->GetPan()); mSlider_Pan->Set(GetWave()->GetPan());
} }
void MixerTrackCluster::UpdateGain() void MixerTrackCluster::UpdateGain()
{ {
#ifdef EXPERIMENTAL_MIDI_OUT #ifdef EXPERIMENTAL_MIDI_OUT
if (mNoteTrack) { if (!GetWave()) {
mSlider_Gain->SetStyle(VEL_SLIDER); mSlider_Gain->SetStyle(VEL_SLIDER);
mSlider_Gain->Set(mNoteTrack->GetVelocity()); mSlider_Gain->Set(GetNote()->GetVelocity());
return; return;
} }
mSlider_Gain->SetStyle(DB_SLIDER); mSlider_Gain->SetStyle(DB_SLIDER);
#endif #endif
mSlider_Gain->Set(mLeftTrack->GetGain()); mSlider_Gain->Set(GetWave()->GetGain());
} }
void MixerTrackCluster::UpdateMeter(const double t0, const double t1) void MixerTrackCluster::UpdateMeter(const double t0, const double t1)
{ {
#ifdef EXPERIMENTAL_MIDI_OUT
// NoteTracks do not (currently) register on meters. It would probably be // NoteTracks do not (currently) register on meters. It would probably be
// a good idea to display 16 channel "active" lights rather than a meter // a good idea to display 16 channel "active" lights rather than a meter
if (!mLeftTrack) if (!GetWave())
return; return;
#else
wxASSERT(mLeftTrack && (mLeftTrack->GetKind() == Track::Wave));
#endif
//vvv Vaughan, 2010-11-27:
// NOTE TO ROGER DANNENBERG:
// I undid the mTrack hack in this conditional, as the rest of the method still assumed it's a wavetrack
// so dereferencing mLeftTrack would have gotten a NULL pointer fault.
// I really think MixerTrackCluster should be factored for NoteTracks.
// REPLY: I think bSuccess prevents dereferencing mLeftTrack, but I will
// check. We should talk about whether it's better to factor
// MixerTrackCluster or more fully hide track types from MixerTrackCluster.
// For now, out change plan produced the following:
// Vaughan, 2011=10-15: There's no bSuccess here, so I don't know what you mean.
// But this change is consistent with the others for EXPERIMENTAL_MIDI_OUT, so I accept it.
if ((t0 < 0.0) || (t1 < 0.0) || (t0 >= t1) || // bad time value or nothing to show if ((t0 < 0.0) || (t1 < 0.0) || (t0 >= t1) || // bad time value or nothing to show
#ifdef EXPERIMENTAL_MIDI_OUT
((mMixerBoard->HasSolo() || mTrack->GetMute()) && !mTrack->GetSolo()) ((mMixerBoard->HasSolo() || mTrack->GetMute()) && !mTrack->GetSolo())
#else
((mMixerBoard->HasSolo() || mLeftTrack->GetMute()) && !mLeftTrack->GetSolo())
#endif
) )
{ {
//v Vaughan, 2011-02-25: Moved the update back to TrackPanel::OnTimer() as it helps with //v Vaughan, 2011-02-25: Moved the update back to TrackPanel::OnTimer() as it helps with
@ -577,7 +518,7 @@ void MixerTrackCluster::UpdateMeter(const double t0, const double t1)
//Floats rmsRight{kFramesPerBuffer}; //Floats rmsRight{kFramesPerBuffer};
// //
//#ifdef EXPERIMENTAL_MIDI_OUT //#ifdef EXPERIMENTAL_MIDI_OUT
// bool bSuccess = (mLeftTrack != NULL); // bool bSuccess = (GetWave() != nullptr);
//#else //#else
// bool bSuccess = true; // bool bSuccess = true;
//#endif //#endif
@ -589,8 +530,8 @@ void MixerTrackCluster::UpdateMeter(const double t0, const double t1)
//while (bSuccess && (i < kFramesPerBuffer)) //while (bSuccess && (i < kFramesPerBuffer))
//{ //{
// bSuccess &= // bSuccess &=
// mLeftTrack->GetMinMax(&min, &(maxLeft[i]), dFrameT0, dFrameT1) && // mTrack->GetMinMax(&min, &(maxLeft[i]), dFrameT0, dFrameT1) &&
// mLeftTrack->GetRMS(&(rmsLeft[i]), dFrameT0, dFrameT1); // mTrack->GetRMS(&(rmsLeft[i]), dFrameT0, dFrameT1);
// if (bSuccess && mRightTrack) // if (bSuccess && mRightTrack)
// bSuccess &= // bSuccess &=
// mRightTrack->GetMinMax(&min, &(maxRight[i]), dFrameT0, dFrameT1) && // mRightTrack->GetMinMax(&min, &(maxRight[i]), dFrameT0, dFrameT1) &&
@ -613,7 +554,7 @@ void MixerTrackCluster::UpdateMeter(const double t0, const double t1)
//{ //{
// for (i = 0; i < kFramesPerBuffer; i++) // for (i = 0; i < kFramesPerBuffer; i++)
// { // {
// float gain = mLeftTrack->GetChannelGain(0); // float gain = mTrack->GetChannelGain(0);
// maxLeft[i] *= gain; // maxLeft[i] *= gain;
// rmsLeft[i] *= gain; // rmsLeft[i] *= gain;
// if (mRightTrack) // if (mRightTrack)
@ -621,17 +562,18 @@ void MixerTrackCluster::UpdateMeter(const double t0, const double t1)
// maxRight[i] *= gain; // maxRight[i] *= gain;
// rmsRight[i] *= gain; // rmsRight[i] *= gain;
// } // }
// mMeter->UpdateDisplay( // if ( mMeter ) mMeter->UpdateDisplay(
// 2, // If mono, show left track values in both meters, as in MeterToolBar, rather than kNumChannels. // 2, // If mono, show left track values in both meters, as in MeterToolBar, rather than kNumChannels.
// kFramesPerBuffer, // kFramesPerBuffer,
// maxLeft, rmsLeft, // maxLeft, rmsLeft,
// maxRight, rmsRight, // maxRight, rmsRight,
// mLeftTrack->TimeToLongSamples(t1 - t0)); // mTrack->TimeToLongSamples(t1 - t0));
//} //}
// //
auto startSample = (sampleCount)((mLeftTrack->GetRate() * t0) + 0.5); const auto pTrack = GetWave();
auto scnFrames = (sampleCount)((mLeftTrack->GetRate() * (t1 - t0)) + 0.5); auto startSample = (sampleCount)((pTrack->GetRate() * t0) + 0.5);
auto scnFrames = (sampleCount)((pTrack->GetRate() * (t1 - t0)) + 0.5);
// Expect that the difference of t1 and t0 is the part of a track played // Expect that the difference of t1 and t0 is the part of a track played
// in about 1/20 second (ticks of TrackPanel timer), so this won't overflow // in about 1/20 second (ticks of TrackPanel timer), so this won't overflow
@ -640,7 +582,7 @@ void MixerTrackCluster::UpdateMeter(const double t0, const double t1)
Floats tempFloatsArray{ nFrames }; Floats tempFloatsArray{ nFrames };
decltype(tempFloatsArray) meterFloatsArray; decltype(tempFloatsArray) meterFloatsArray;
// Don't throw on read error in this drawing update routine // Don't throw on read error in this drawing update routine
bool bSuccess = mLeftTrack->Get((samplePtr)tempFloatsArray.get(), bool bSuccess = pTrack->Get((samplePtr)tempFloatsArray.get(),
floatSample, startSample, nFrames, fillZero, false); floatSample, startSample, nFrames, fillZero, false);
if (bSuccess) if (bSuccess)
{ {
@ -653,9 +595,9 @@ void MixerTrackCluster::UpdateMeter(const double t0, const double t1)
for (int index = 0; index < nFrames; index++) for (int index = 0; index < nFrames; index++)
meterFloatsArray[2 * index] = tempFloatsArray[index]; meterFloatsArray[2 * index] = tempFloatsArray[index];
if (mRightTrack) if (GetRight())
// Again, don't throw // Again, don't throw
bSuccess = mRightTrack->Get((samplePtr)tempFloatsArray.get(), bSuccess = GetRight()->Get((samplePtr)tempFloatsArray.get(),
floatSample, startSample, nFrames, fillZero, false); floatSample, startSample, nFrames, fillZero, false);
if (bSuccess) if (bSuccess)
@ -669,14 +611,14 @@ void MixerTrackCluster::UpdateMeter(const double t0, const double t1)
if (bSuccess) if (bSuccess)
{ {
//vvv Need to apply envelope, too? See Mixer::MixSameRate. //vvv Need to apply envelope, too? See Mixer::MixSameRate.
float gain = mLeftTrack->GetChannelGain(0); float gain = pTrack->GetChannelGain(0);
if (gain < 1.0) if (gain < 1.0)
for (int index = 0; index < nFrames; index++) for (int index = 0; index < nFrames; index++)
meterFloatsArray[2 * index] *= gain; meterFloatsArray[2 * index] *= gain;
if (mRightTrack) if (GetRight())
gain = mRightTrack->GetChannelGain(1); gain = GetRight()->GetChannelGain(1);
else else
gain = mLeftTrack->GetChannelGain(1); gain = pTrack->GetChannelGain(1);
if (gain < 1.0) if (gain < 1.0)
for (int index = 0; index < nFrames; index++) for (int index = 0; index < nFrames; index++)
meterFloatsArray[(2 * index) + 1] *= gain; meterFloatsArray[(2 * index) + 1] *= gain;
@ -705,13 +647,7 @@ wxColour MixerTrackCluster::GetTrackColor()
void MixerTrackCluster::HandleSelect(bool bShiftDown, bool bControlDown) void MixerTrackCluster::HandleSelect(bool bShiftDown, bool bControlDown)
{ {
#ifdef EXPERIMENTAL_MIDI_OUT mProject->GetTrackPanel()->HandleListSelection(mTrack, bShiftDown, bControlDown);
Track *pTrack = mTrack;
#else
Track *pTrack = mLeftTrack;
#endif
mProject->GetTrackPanel()->HandleListSelection(pTrack, bShiftDown, bControlDown);
} }
void MixerTrackCluster::OnMouseEvent(wxMouseEvent& event) void MixerTrackCluster::OnMouseEvent(wxMouseEvent& event)
@ -735,11 +671,7 @@ void MixerTrackCluster::OnPaint(wxPaintEvent & WXUNUSED(event))
wxSize clusterSize = this->GetSize(); wxSize clusterSize = this->GetSize();
wxRect bev(0, 0, clusterSize.GetWidth() - 1, clusterSize.GetHeight() - 1); wxRect bev(0, 0, clusterSize.GetWidth() - 1, clusterSize.GetHeight() - 1);
#ifdef EXPERIMENTAL_MIDI_OUT
auto selected = mTrack->GetSelected(); auto selected = mTrack->GetSelected();
#else
auto selected = mLeftTrack->GetSelected();
#endif
for (unsigned int i = 0; i < 4; i++) // 4 gives a big bevel, but there were complaints about visibility otherwise. for (unsigned int i = 0; i < 4; i++) // 4 gives a big bevel, but there were complaints about visibility otherwise.
{ {
@ -782,13 +714,8 @@ void MixerTrackCluster::OnSlider_Pan(wxCommandEvent& WXUNUSED(event))
void MixerTrackCluster::OnButton_Mute(wxCommandEvent& WXUNUSED(event)) void MixerTrackCluster::OnButton_Mute(wxCommandEvent& WXUNUSED(event))
{ {
#ifdef EXPERIMENTAL_MIDI_OUT
mProject->HandleTrackMute(mTrack, mToggleButton_Mute->WasShiftDown()); mProject->HandleTrackMute(mTrack, mToggleButton_Mute->WasShiftDown());
mToggleButton_Mute->SetAlternateIdx(mTrack->GetSolo() ? 1 : 0); mToggleButton_Mute->SetAlternateIdx(mTrack->GetSolo() ? 1 : 0);
#else
mProject->HandleTrackMute(mLeftTrack, mToggleButton_Mute->WasShiftDown());
mToggleButton_Mute->SetAlternateIdx(mLeftTrack->GetSolo() ? 1 : 0);
#endif
// Update the TrackPanel correspondingly. // Update the TrackPanel correspondingly.
if (mProject->IsSoloSimple()) if (mProject->IsSoloSimple())
@ -799,22 +726,13 @@ void MixerTrackCluster::OnButton_Mute(wxCommandEvent& WXUNUSED(event))
} }
else else
// Update only the changed track. // Update only the changed track.
#ifdef EXPERIMENTAL_MIDI_OUT
mProject->RefreshTPTrack(mTrack); mProject->RefreshTPTrack(mTrack);
#else
mProject->RefreshTPTrack(mLeftTrack);
#endif
} }
void MixerTrackCluster::OnButton_Solo(wxCommandEvent& WXUNUSED(event)) void MixerTrackCluster::OnButton_Solo(wxCommandEvent& WXUNUSED(event))
{ {
#ifdef EXPERIMENTAL_MIDI_OUT
mProject->HandleTrackSolo(mTrack, mToggleButton_Solo->WasShiftDown()); mProject->HandleTrackSolo(mTrack, mToggleButton_Solo->WasShiftDown());
bool bIsSolo = mTrack->GetSolo(); bool bIsSolo = mTrack->GetSolo();
#else
mProject->HandleTrackSolo(mLeftTrack, mToggleButton_Solo->WasShiftDown());
bool bIsSolo = mLeftTrack->GetSolo();
#endif
mToggleButton_Mute->SetAlternateIdx(bIsSolo ? 1 : 0); mToggleButton_Mute->SetAlternateIdx(bIsSolo ? 1 : 0);
// Update the TrackPanel correspondingly. // Update the TrackPanel correspondingly.
@ -827,11 +745,7 @@ void MixerTrackCluster::OnButton_Solo(wxCommandEvent& WXUNUSED(event))
} }
else else
// Update only the changed track. // Update only the changed track.
#ifdef EXPERIMENTAL_MIDI_OUT
mProject->RefreshTPTrack(mTrack); mProject->RefreshTPTrack(mTrack);
#else
mProject->RefreshTPTrack(mLeftTrack);
#endif
} }
@ -1010,18 +924,14 @@ void MixerBoard::UpdateTrackClusters()
unsigned int nClusterIndex = 0; unsigned int nClusterIndex = 0;
TrackListIterator iterTracks(mTracks); TrackListIterator iterTracks(mTracks);
MixerTrackCluster* pMixerTrackCluster = NULL; MixerTrackCluster* pMixerTrackCluster = NULL;
Track* pLeftTrack; Track* pTrack;
Track* pRightTrack; Track* pRightTrack;
pLeftTrack = iterTracks.First(); pTrack = iterTracks.First();
while (pLeftTrack) { while (pTrack) {
pRightTrack = pLeftTrack->GetLinked() ? iterTracks.Next() : NULL; pRightTrack = pTrack->GetLinked() ? iterTracks.Next() : NULL;
if (pLeftTrack->GetKind() == Track::Wave if (auto pPlayableTrack = dynamic_cast<PlayableTrack*>(pTrack))
#ifdef EXPERIMENTAL_MIDI_OUT
|| pLeftTrack->GetKind() == Track::Note
#endif
)
{ {
if (nClusterIndex < nClusterCount) if (nClusterIndex < nClusterCount)
{ {
@ -1029,20 +939,8 @@ void MixerBoard::UpdateTrackClusters()
// Track clusters are maintained in the same order as the WaveTracks. // Track clusters are maintained in the same order as the WaveTracks.
// Track pointers can change for the "same" track for different states // Track pointers can change for the "same" track for different states
// on the undo stack, so update the pointers and display name. // on the undo stack, so update the pointers and display name.
#ifdef EXPERIMENTAL_MIDI_OUT mMixerTrackClusters[nClusterIndex]->mTrack = pPlayableTrack;
if (pLeftTrack->GetKind() == Track::Note) {
mMixerTrackClusters[nClusterIndex]->mNoteTrack = (NoteTrack*)pLeftTrack;
mMixerTrackClusters[nClusterIndex]->mLeftTrack = NULL;
} else {
mMixerTrackClusters[nClusterIndex]->mNoteTrack = NULL;
mMixerTrackClusters[nClusterIndex]->mLeftTrack = (WaveTrack*)pLeftTrack;
}
#else
mMixerTrackClusters[nClusterIndex]->mLeftTrack = (WaveTrack*)pLeftTrack;
#endif
// Assume linked track is wave or null // Assume linked track is wave or null
mMixerTrackClusters[nClusterIndex]->mRightTrack =
static_cast<WaveTrack*>(pRightTrack);
mMixerTrackClusters[nClusterIndex]->UpdateForStateChange(); mMixerTrackClusters[nClusterIndex]->UpdateForStateChange();
} }
else else
@ -1057,16 +955,14 @@ void MixerBoard::UpdateTrackClusters()
wxSize clusterSize(kMixerTrackClusterWidth, nClusterHeight); wxSize clusterSize(kMixerTrackClusterWidth, nClusterHeight);
pMixerTrackCluster = pMixerTrackCluster =
safenew MixerTrackCluster(mScrolledWindow, this, mProject, safenew MixerTrackCluster(mScrolledWindow, this, mProject,
static_cast<WaveTrack*>(pLeftTrack), pPlayableTrack,
// Assume linked track is wave or null
static_cast<WaveTrack*>(pRightTrack),
clusterPos, clusterSize); clusterPos, clusterSize);
if (pMixerTrackCluster) if (pMixerTrackCluster)
mMixerTrackClusters.Add(pMixerTrackCluster); mMixerTrackClusters.Add(pMixerTrackCluster);
} }
nClusterIndex++; nClusterIndex++;
} }
pLeftTrack = iterTracks.Next(); pTrack = iterTracks.Next();
} }
if (pMixerTrackCluster) if (pMixerTrackCluster)
@ -1083,11 +979,7 @@ void MixerBoard::UpdateTrackClusters()
// We've already updated the track pointers for the clusters to the left, so just remove all the rest. // We've already updated the track pointers for the clusters to the left, so just remove all the rest.
// Keep nClusterIndex constant and successively DELETE from left to right. // Keep nClusterIndex constant and successively DELETE from left to right.
for (unsigned int nCounter = nClusterIndex; nCounter < nClusterCount; nCounter++) for (unsigned int nCounter = nClusterIndex; nCounter < nClusterCount; nCounter++)
#ifdef EXPERIMENTAL_MIDI_OUT
this->RemoveTrackCluster(mMixerTrackClusters[nClusterIndex]->mTrack); this->RemoveTrackCluster(mMixerTrackClusters[nClusterIndex]->mTrack);
#else
this->RemoveTrackCluster(mMixerTrackClusters[nClusterIndex]->mLeftTrack);
#endif
} }
} }
@ -1100,13 +992,8 @@ int MixerBoard::GetTrackClustersWidth()
kDoubleInset; // plus final right margin kDoubleInset; // plus final right margin
} }
#ifdef EXPERIMENTAL_MIDI_OUT void MixerBoard::MoveTrackCluster(const PlayableTrack* pTrack,
void MixerBoard::MoveTrackCluster(const Track* pTrack,
bool bUp) // Up in TrackPanel is left in MixerBoard. bool bUp) // Up in TrackPanel is left in MixerBoard.
#else
void MixerBoard::MoveTrackCluster(const WaveTrack* pTrack,
bool bUp) // Up in TrackPanel is left in MixerBoard.
#endif
{ {
MixerTrackCluster* pMixerTrackCluster; MixerTrackCluster* pMixerTrackCluster;
int nIndex = FindMixerTrackCluster(pTrack, &pMixerTrackCluster); int nIndex = FindMixerTrackCluster(pTrack, &pMixerTrackCluster);
@ -1140,11 +1027,7 @@ void MixerBoard::MoveTrackCluster(const WaveTrack* pTrack,
} }
} }
#ifdef EXPERIMENTAL_MIDI_OUT void MixerBoard::RemoveTrackCluster(const PlayableTrack* pTrack)
void MixerBoard::RemoveTrackCluster(const Track* pTrack)
#else
void MixerBoard::RemoveTrackCluster(const WaveTrack* pTrack)
#endif
{ {
// Find and destroy. // Find and destroy.
MixerTrackCluster* pMixerTrackCluster; MixerTrackCluster* pMixerTrackCluster;
@ -1180,22 +1063,14 @@ void MixerBoard::RemoveTrackCluster(const WaveTrack* pTrack)
} }
#ifdef EXPERIMENTAL_MIDI_OUT wxBitmap* MixerBoard::GetMusicalInstrumentBitmap(const Track* pTrack)
wxBitmap* MixerBoard::GetMusicalInstrumentBitmap(const wxString & name)
#else
wxBitmap* MixerBoard::GetMusicalInstrumentBitmap(const WaveTrack* pLeftTrack)
#endif
{ {
if (mMusicalInstruments.empty()) if (mMusicalInstruments.empty())
return NULL; return NULL;
// random choice: return mMusicalInstruments[(int)pLeftTrack % mMusicalInstruments.GetCount()].mBitmap; // random choice: return mMusicalInstruments[(int)pTrack % mMusicalInstruments.GetCount()].mBitmap;
#ifdef EXPERIMENTAL_MIDI_OUT const wxString strTrackName(pTrack->GetName().MakeLower());
const wxString strTrackName(wxString{ name }.MakeLower());
#else
const wxString strTrackName(pLeftTrack->GetName().MakeLower());
#endif
size_t nBestItemIndex = 0; size_t nBestItemIndex = 0;
unsigned int nBestScore = 0; unsigned int nBestScore = 0;
unsigned int nInstrIndex = 0; unsigned int nInstrIndex = 0;
@ -1242,11 +1117,7 @@ bool MixerBoard::HasSolo()
return false; return false;
} }
#ifdef EXPERIMENTAL_MIDI_OUT void MixerBoard::RefreshTrackCluster(const PlayableTrack* pTrack, bool bEraseBackground /*= true*/)
void MixerBoard::RefreshTrackCluster(const Track* pTrack, bool bEraseBackground /*= true*/)
#else
void MixerBoard::RefreshTrackCluster(const WaveTrack* pTrack, bool bEraseBackground )
#endif
{ {
MixerTrackCluster* pMixerTrackCluster; MixerTrackCluster* pMixerTrackCluster;
this->FindMixerTrackCluster(pTrack, &pMixerTrackCluster); this->FindMixerTrackCluster(pTrack, &pMixerTrackCluster);
@ -1277,11 +1148,7 @@ void MixerBoard::ResetMeters(const bool bResetClipping)
mMixerTrackClusters[i]->ResetMeter(bResetClipping); mMixerTrackClusters[i]->ResetMeter(bResetClipping);
} }
#ifdef EXPERIMENTAL_MIDI_OUT void MixerBoard::UpdateName(const PlayableTrack* pTrack)
void MixerBoard::UpdateName(const Track* pTrack)
#else
void MixerBoard::UpdateName(const WaveTrack* pTrack)
#endif
{ {
MixerTrackCluster* pMixerTrackCluster; MixerTrackCluster* pMixerTrackCluster;
this->FindMixerTrackCluster(pTrack, &pMixerTrackCluster); this->FindMixerTrackCluster(pTrack, &pMixerTrackCluster);
@ -1289,11 +1156,7 @@ void MixerBoard::UpdateName(const WaveTrack* pTrack)
pMixerTrackCluster->UpdateName(); pMixerTrackCluster->UpdateName();
} }
#ifdef EXPERIMENTAL_MIDI_OUT void MixerBoard::UpdateMute(const PlayableTrack* pTrack /*= NULL*/) // NULL means update for all tracks.
void MixerBoard::UpdateMute(const Track* pTrack /*= NULL*/) // NULL means update for all tracks.
#else
void MixerBoard::UpdateMute(const WaveTrack* pTrack /*= NULL*/) // NULL means update for all tracks.
#endif
{ {
if (pTrack == NULL) if (pTrack == NULL)
{ {
@ -1309,11 +1172,7 @@ void MixerBoard::UpdateMute(const WaveTrack* pTrack /*= NULL*/) // NULL means up
} }
} }
#ifdef EXPERIMENTAL_MIDI_OUT void MixerBoard::UpdateSolo(const PlayableTrack* pTrack /*= NULL*/) // NULL means update for all tracks.
void MixerBoard::UpdateSolo(const Track* pTrack /*= NULL*/) // NULL means update for all tracks.
#else
void MixerBoard::UpdateSolo(const WaveTrack* pTrack /*= NULL*/) // NULL means update for all tracks.
#endif
{ {
if (pTrack == NULL) if (pTrack == NULL)
{ {
@ -1329,11 +1188,7 @@ void MixerBoard::UpdateSolo(const WaveTrack* pTrack /*= NULL*/) // NULL means up
} }
} }
#ifdef EXPERIMENTAL_MIDI_OUT void MixerBoard::UpdatePan(const PlayableTrack* pTrack)
void MixerBoard::UpdatePan(const Track* pTrack)
#else
void MixerBoard::UpdatePan(const WaveTrack* pTrack)
#endif
{ {
MixerTrackCluster* pMixerTrackCluster; MixerTrackCluster* pMixerTrackCluster;
FindMixerTrackCluster(pTrack, &pMixerTrackCluster); FindMixerTrackCluster(pTrack, &pMixerTrackCluster);
@ -1341,11 +1196,7 @@ void MixerBoard::UpdatePan(const WaveTrack* pTrack)
pMixerTrackCluster->UpdatePan(); pMixerTrackCluster->UpdatePan();
} }
#ifdef EXPERIMENTAL_MIDI_OUT void MixerBoard::UpdateGain(const PlayableTrack* pTrack)
void MixerBoard::UpdateGain(const Track* pTrack)
#else
void MixerBoard::UpdateGain(const WaveTrack* pTrack)
#endif
{ {
MixerTrackCluster* pMixerTrackCluster; MixerTrackCluster* pMixerTrackCluster;
FindMixerTrackCluster(pTrack, &pMixerTrackCluster); FindMixerTrackCluster(pTrack, &pMixerTrackCluster);
@ -1471,22 +1322,13 @@ void MixerBoard::CreateMuteSoloImages()
mImageSoloDisabled = std::make_unique<wxImage>(mMuteSoloWidth, MUTE_SOLO_HEIGHT); // Leave empty because unused. mImageSoloDisabled = std::make_unique<wxImage>(mMuteSoloWidth, MUTE_SOLO_HEIGHT); // Leave empty because unused.
} }
#ifdef EXPERIMENTAL_MIDI_OUT int MixerBoard::FindMixerTrackCluster(const PlayableTrack* pTrack,
int MixerBoard::FindMixerTrackCluster(const Track* pTrack,
MixerTrackCluster** hMixerTrackCluster) const MixerTrackCluster** hMixerTrackCluster) const
#else
int MixerBoard::FindMixerTrackCluster(const WaveTrack* pLeftTrack,
MixerTrackCluster** hMixerTrackCluster) const
#endif
{ {
*hMixerTrackCluster = NULL; *hMixerTrackCluster = NULL;
for (unsigned int i = 0; i < mMixerTrackClusters.GetCount(); i++) for (unsigned int i = 0; i < mMixerTrackClusters.GetCount(); i++)
{ {
#ifdef EXPERIMENTAL_MIDI_OUT
if (mMixerTrackClusters[i]->mTrack == pTrack) if (mMixerTrackClusters[i]->mTrack == pTrack)
#else
if (mMixerTrackClusters[i]->mLeftTrack == pLeftTrack)
#endif
{ {
*hMixerTrackCluster = mMixerTrackClusters[i]; *hMixerTrackCluster = mMixerTrackClusters[i];
return i; return i;

View File

@ -62,10 +62,11 @@ public:
class AudacityProject; class AudacityProject;
class Meter; class Meter;
class MixerBoard; class MixerBoard;
#ifdef EXPERIMENTAL_MIDI_OUT
class Track; class Track;
class NoteTrack; class NoteTrack;
#endif class PlayableTrack;
class WaveTrack; class WaveTrack;
class MixerTrackCluster final : public wxPanelWrapper class MixerTrackCluster final : public wxPanelWrapper
@ -73,11 +74,15 @@ class MixerTrackCluster final : public wxPanelWrapper
public: public:
MixerTrackCluster(wxWindow* parent, MixerTrackCluster(wxWindow* parent,
MixerBoard* grandParent, AudacityProject* project, MixerBoard* grandParent, AudacityProject* project,
WaveTrack* pLeftTrack, WaveTrack* pRightTrack = NULL, PlayableTrack* pTrack,
const wxPoint& pos = wxDefaultPosition, const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize); const wxSize& size = wxDefaultSize);
virtual ~MixerTrackCluster() {} virtual ~MixerTrackCluster() {}
WaveTrack *GetWave() const;
WaveTrack *GetRight() const;
NoteTrack *GetNote() const;
void UpdatePrefs(); void UpdatePrefs();
void HandleResize(); // For wxSizeEvents, update gain slider and meter. void HandleResize(); // For wxSizeEvents, update gain slider and meter.
@ -115,23 +120,7 @@ private:
public: public:
#ifdef EXPERIMENTAL_MIDI_OUT PlayableTrack * mTrack;
// mTrack is redundant, but simplifies code that operates on either
// mLeftTrack or mNoteTrack.
Track* mTrack; // either mLeftTrack or mNoteTrack, whichever is not NULL
#endif
WaveTrack* mLeftTrack; // NULL if Note Track
WaveTrack* mRightTrack; // NULL if mono
//vvv Vaughan, 2010-11-05:
// I suggest that when this is no longer experimental, rather than all these #ifdef's,
// this be done by factoring, i.e., add two subclasses to MixerTrackCluster,
// MixerNoteTrackCluster and MixerWaveTrackCluster, such that all the common
// code is in the parent, and these #ifdef's are only around
// MixerNoteTrackCluster rather than sprinkled throughout MixerTrackCluster.
#ifdef EXPERIMENTAL_MIDI_OUT
NoteTrack* mNoteTrack; // NULL if Wave Track
#endif
private: private:
MixerBoard* mMixerBoard; MixerBoard* mMixerBoard;
@ -213,45 +202,25 @@ public:
void UpdateTrackClusters(); void UpdateTrackClusters();
int GetTrackClustersWidth(); int GetTrackClustersWidth();
#ifdef EXPERIMENTAL_MIDI_OUT void MoveTrackCluster(const PlayableTrack* pTrack, bool bUp); // Up in TrackPanel is left in MixerBoard.
void MoveTrackCluster(const Track* pTrack, bool bUp); // Up in TrackPanel is left in MixerBoard. void RemoveTrackCluster(const PlayableTrack* pTrack);
void RemoveTrackCluster(const Track* pTrack);
wxBitmap* GetMusicalInstrumentBitmap(const wxString & name); wxBitmap* GetMusicalInstrumentBitmap(const Track *pTrack);
#else
void MoveTrackCluster(const WaveTrack* pTrack, bool bUp); // Up in TrackPanel is left in MixerBoard.
void RemoveTrackCluster(const WaveTrack* pTrack);
wxBitmap* GetMusicalInstrumentBitmap(const WaveTrack* pLeftTrack);
#endif
bool HasSolo(); bool HasSolo();
#ifdef EXPERIMENTAL_MIDI_OUT void RefreshTrackCluster(const PlayableTrack* pTrack, bool bEraseBackground = true);
void RefreshTrackCluster(const Track* pTrack, bool bEraseBackground = true);
#else
void RefreshTrackCluster(const WaveTrack* pTrack, bool bEraseBackground = true);
#endif
void RefreshTrackClusters(bool bEraseBackground = true); void RefreshTrackClusters(bool bEraseBackground = true);
void ResizeTrackClusters(); void ResizeTrackClusters();
void ResetMeters(const bool bResetClipping); void ResetMeters(const bool bResetClipping);
#ifdef EXPERIMENTAL_MIDI_OUT void UpdateName(const PlayableTrack* pTrack);
void UpdateName(const Track* pTrack); void UpdateMute(const PlayableTrack* pTrack = NULL); // NULL means update for all tracks.
void UpdateMute(const Track* pTrack = NULL); // NULL means update for all tracks. void UpdateSolo(const PlayableTrack* pTrack = NULL); // NULL means update for all tracks.
void UpdateSolo(const Track* pTrack = NULL); // NULL means update for all tracks. void UpdatePan(const PlayableTrack* pTrack);
void UpdatePan(const Track* pTrack); void UpdateGain(const PlayableTrack* pTrack);
void UpdateGain(const Track* pTrack);
#else
void UpdateName(const WaveTrack* pTrack);
void UpdateMute(const WaveTrack* pTrack = NULL); // NULL means update for all tracks.
void UpdateSolo(const WaveTrack* pTrack = NULL); // NULL means update for all tracks.
void UpdatePan(const WaveTrack* pTrack);
void UpdateGain(const WaveTrack* pTrack);
#endif
void UpdateMeters(const double t1, const bool bLoopedPlay); void UpdateMeters(const double t1, const bool bLoopedPlay);
@ -259,13 +228,8 @@ public:
private: private:
void CreateMuteSoloImages(); void CreateMuteSoloImages();
#ifdef EXPERIMENTAL_MIDI_OUT int FindMixerTrackCluster(const PlayableTrack* pTrack,
int FindMixerTrackCluster(const Track* pTrack,
MixerTrackCluster** hMixerTrackCluster) const; MixerTrackCluster** hMixerTrackCluster) const;
#else
int FindMixerTrackCluster(const WaveTrack* pLeftTrack,
MixerTrackCluster** hMixerTrackCluster) const;
#endif
void LoadMusicalInstruments(); void LoadMusicalInstruments();
// event handlers // event handlers

View File

@ -5396,12 +5396,13 @@ void AudacityProject::RemoveTrack(Track * toRemove)
wxString name = toRemove->GetName(); wxString name = toRemove->GetName();
Track *partner = toRemove->GetLink(); Track *partner = toRemove->GetLink();
if (toRemove->GetKind() == Track::Wave) auto playable = dynamic_cast<PlayableTrack*>(toRemove);
if (playable)
{ {
// Update mixer board displayed tracks. // Update mixer board displayed tracks.
MixerBoard* pMixerBoard = this->GetMixerBoard(); MixerBoard* pMixerBoard = this->GetMixerBoard();
if (pMixerBoard) if (pMixerBoard)
pMixerBoard->RemoveTrackCluster((WaveTrack*)toRemove); // Will remove partner shown in same cluster. pMixerBoard->RemoveTrackCluster(playable); // Will remove partner shown in same cluster.
} }
mTracks->Remove(toRemove); mTracks->Remove(toRemove);

View File

@ -5212,27 +5212,17 @@ void TrackPanel::HandleRearrange(wxMouseEvent & event)
if (event.m_y < mMoveUpThreshold || event.m_y < 0) { if (event.m_y < mMoveUpThreshold || event.m_y < 0) {
mTracks->MoveUp(mCapturedTrack); mTracks->MoveUp(mCapturedTrack);
--mRearrangeCount; --mRearrangeCount;
#ifdef EXPERIMENTAL_MIDI_OUT if (pMixerBoard)
if (pMixerBoard && (mCapturedTrack->GetKind() == Track::Wave || if(auto pPlayable = dynamic_cast< const PlayableTrack* >( mCapturedTrack ))
mCapturedTrack->GetKind() == Track::Note)) pMixerBoard->MoveTrackCluster(pPlayable, true /* up */);
pMixerBoard->MoveTrackCluster(mCapturedTrack, true /* up */);
#else
if (pMixerBoard && (mCapturedTrack->GetKind() == Track::Wave))
pMixerBoard->MoveTrackCluster((WaveTrack*)mCapturedTrack, true /* up */);
#endif
} }
else if (event.m_y > mMoveDownThreshold || event.m_y > GetRect().GetHeight()) { else if (event.m_y > mMoveDownThreshold || event.m_y > GetRect().GetHeight()) {
mTracks->MoveDown(mCapturedTrack); mTracks->MoveDown(mCapturedTrack);
++mRearrangeCount; ++mRearrangeCount;
/* i18n-hint: a direction as in up or down.*/ /* i18n-hint: a direction as in up or down.*/
#ifdef EXPERIMENTAL_MIDI_OUT if (pMixerBoard)
if (pMixerBoard && (mCapturedTrack->GetKind() == Track::Wave || if(auto pPlayable = dynamic_cast< const PlayableTrack* >( mCapturedTrack ))
mCapturedTrack->GetKind() == Track::Note)) pMixerBoard->MoveTrackCluster(pPlayable, false /* down */);
pMixerBoard->MoveTrackCluster(mCapturedTrack, false /* down */);
#else
if (pMixerBoard && (mCapturedTrack->GetKind() == Track::Wave))
pMixerBoard->MoveTrackCluster((WaveTrack*)mCapturedTrack, false /* down */);
#endif
} }
else else
{ {

View File

@ -44,9 +44,8 @@ class TipPanel;
#define DB_SLIDER 2 // -36...36 dB #define DB_SLIDER 2 // -36...36 dB
#define PAN_SLIDER 3 // -1.0...1.0 #define PAN_SLIDER 3 // -1.0...1.0
#define SPEED_SLIDER 4 // 0.01 ..3.0 #define SPEED_SLIDER 4 // 0.01 ..3.0
#ifdef EXPERIMENTAL_MIDI_OUT
#define VEL_SLIDER 5 // -50..50 #define VEL_SLIDER 5 // -50..50
#endif
#define DB_MIN -36.0f #define DB_MIN -36.0f
#define DB_MAX 36.0f #define DB_MAX 36.0f