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) {
if (t->GetSelected()) {
if (mMixerBoard && (t->GetKind() == Track::Wave))
mMixerBoard->RemoveTrackCluster((WaveTrack*)t);
auto playable = dynamic_cast<PlayableTrack*>(t);
if (mMixerBoard && playable)
mMixerBoard->RemoveTrackCluster(playable);
if (!f)
f = l; // Capture the track preceeding the first removed track
t = iter.RemoveCurrent();

View File

@ -23,9 +23,9 @@
#include "AColor.h"
#include "AudioIO.h"
#ifdef EXPERIMENTAL_MIDI_OUT
#include "NoteTrack.h"
#endif
#include "NoteTrack.h"
#include "Project.h"
#include "TrackPanel.h" // for EVT_TRACK_PANEL_TIMER
#include "UndoManager.h"
@ -155,30 +155,17 @@ END_EVENT_TABLE()
MixerTrackCluster::MixerTrackCluster(wxWindow* parent,
MixerBoard* grandParent, AudacityProject* project,
WaveTrack* pLeftTrack, WaveTrack* pRightTrack /*= NULL*/,
PlayableTrack* pTrack,
const wxPoint& pos /*= wxDefaultPosition*/,
const wxSize& size /*= wxDefaultSize*/)
: wxPanelWrapper(parent, -1, pos, size)
, mTrack{ pTrack }
{
mMixerBoard = grandParent;
mProject = project;
#ifdef EXPERIMENTAL_MIDI_OUT
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;
wxASSERT( pTrack );
SetName(mLeftTrack->GetName());
SetName(mTrack->GetName());
this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
@ -191,13 +178,8 @@ MixerTrackCluster::MixerTrackCluster(wxWindow* parent,
wxPoint ctrlPos(kDoubleInset, kDoubleInset);
wxSize ctrlSize(size.GetWidth() - kQuadrupleInset, TRACK_NAME_HEIGHT);
mStaticText_TrackName =
#ifdef EXPERIMENTAL_MIDI_OUT
safenew wxStaticText(this, -1, mTrack->GetName(), ctrlPos, ctrlSize,
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.
// mStaticText_TrackName->SetBackgroundColour(this->GetTrackColor());
@ -208,8 +190,8 @@ MixerTrackCluster::MixerTrackCluster(wxWindow* parent,
const int nGainSliderHeight =
size.GetHeight() - ctrlPos.y - kQuadrupleInset;
ctrlSize.Set(kLeftSideStackWidth - kQuadrupleInset, nGainSliderHeight);
#ifdef EXPERIMENTAL_MIDI_OUT
if (mNoteTrack) {
if (GetNote()) {
mSlider_Gain =
safenew MixerTrackSlider(
this, ID_SLIDER_GAIN,
@ -217,15 +199,16 @@ MixerTrackCluster::MixerTrackCluster(wxWindow* parent,
_("Velocity"),
ctrlPos, ctrlSize, VEL_SLIDER, true,
true, 0.0, wxVERTICAL);
} else
#endif
mSlider_Gain =
safenew MixerTrackSlider(
this, ID_SLIDER_GAIN,
/* i18n-hint: title of the Gain slider, used to adjust the volume */
_("Gain"),
ctrlPos, ctrlSize, DB_SLIDER, true,
true, 0.0, wxVERTICAL);
}
else
mSlider_Gain =
safenew MixerTrackSlider(
this, ID_SLIDER_GAIN,
/* i18n-hint: title of the Gain slider, used to adjust the volume */
_("Gain"),
ctrlPos, ctrlSize, DB_SLIDER, true,
true, 0.0, wxVERTICAL);
mSlider_Gain->SetName(_("Gain"));
this->UpdateGain();
@ -236,11 +219,7 @@ MixerTrackCluster::MixerTrackCluster(wxWindow* parent,
// musical instrument image
ctrlPos.x += kLeftSideStackWidth + kInset; // + kInset to center it in right side stack
ctrlSize.Set(MUSICAL_INSTRUMENT_HEIGHT_AND_WIDTH, MUSICAL_INSTRUMENT_HEIGHT_AND_WIDTH);
#ifdef EXPERIMENTAL_MIDI_OUT
wxBitmap* bitmap = mMixerBoard->GetMusicalInstrumentBitmap(mTrack->GetName());
#else
wxBitmap* bitmap = mMixerBoard->GetMusicalInstrumentBitmap(mLeftTrack);
#endif
wxBitmap* bitmap = mMixerBoard->GetMusicalInstrumentBitmap(mTrack);
wxASSERT(bitmap);
mBitmapButton_MusicalInstrument =
safenew wxBitmapButton(this, ID_BITMAPBUTTON_MUSICAL_INSTRUMENT, *bitmap,
@ -306,34 +285,24 @@ MixerTrackCluster::MixerTrackCluster(wxWindow* parent,
(PAN_HEIGHT + kDoubleInset) -
(MUTE_SOLO_HEIGHT + (bSoloNone ? 0 : MUTE_SOLO_HEIGHT) + kDoubleInset);
ctrlSize.Set(kRightSideStackWidth, nMeterHeight);
#ifdef EXPERIMENTAL_MIDI_OUT
if (mLeftTrack) {
#endif
mMeter =
safenew Meter(GetActiveProject(), // AudacityProject* project,
this, -1, // wxWindow* parent, wxWindowID id,
false, // bool isInput
ctrlPos, ctrlSize, // const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
Meter::MixerTrackCluster); // Style style = HorizontalStereo,
mMeter->SetName(_("Signal Level Meter"));
#ifdef EXPERIMENTAL_MIDI_OUT
} else {
mMeter = NULL;
mMeter = NULL;
if (GetWave()) {
mMeter =
safenew Meter(GetActiveProject(), // AudacityProject* project,
this, -1, // wxWindow* parent, wxWindowID id,
false, // bool isInput
ctrlPos, ctrlSize, // const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
Meter::MixerTrackCluster); // Style style = HorizontalStereo,
mMeter->SetName(_("Signal Level Meter"));
}
#endif
#if wxUSE_TOOLTIPS
#ifdef EXPERIMENTAL_MIDI_OUT
mStaticText_TrackName->SetToolTip(mTrack->GetName());
#else
mStaticText_TrackName->SetToolTip(mLeftTrack->GetName());
#endif
mToggleButton_Mute->SetToolTip(_("Mute"));
mToggleButton_Solo->SetToolTip(_("Solo"));
#ifdef EXPERIMENTAL_MIDI_OUT
if (mLeftTrack)
#endif
mMeter->SetToolTip(_("Signal Level Meter"));
if (GetWave())
mMeter->SetToolTip(_("Signal Level Meter"));
#endif // wxUSE_TOOLTIPS
#ifdef __WXMAC__
@ -344,9 +313,29 @@ MixerTrackCluster::MixerTrackCluster(wxWindow* parent,
#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()
{
mMeter->UpdatePrefs(); // in case meter range has changed
if (mMeter)
mMeter->UpdatePrefs(); // in case meter range has 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 +
nRequiredHeightAboveMeter;
const int nMeterHeight = nGainSliderHeight - nRequiredHeightAboveMeter;
#ifdef EXPERIMENTAL_MIDI_OUT
if (mMeter)
#endif
mMeter->SetSize(-1, nMeterY, -1, nMeterHeight);
mMeter->SetSize(-1, nMeterY, -1, nMeterHeight);
}
void MixerTrackCluster::HandleSliderGain(const bool bWantPushState /*= false*/)
{
float fValue = mSlider_Gain->Get();
if (mLeftTrack)
mLeftTrack->SetGain(fValue);
if (GetWave())
GetWave()->SetGain(fValue);
#ifdef EXPERIMENTAL_MIDI_OUT
else
mNoteTrack->SetVelocity(fValue);
GetNote()->SetVelocity(fValue);
#endif
if (mRightTrack)
mRightTrack->SetGain(fValue);
if (GetRight())
GetRight()->SetGain(fValue);
// Update the TrackPanel correspondingly.
#ifdef EXPERIMENTAL_MIDI_OUT
mProject->RefreshTPTrack(mTrack);
#else
mProject->RefreshTPTrack(mLeftTrack);
#endif
if (bWantPushState)
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*/)
{
float fValue = mSlider_Pan->Get();
if (mLeftTrack) // test in case track is a NoteTrack
mLeftTrack->SetPan(fValue);
if (mRightTrack)
mRightTrack->SetPan(fValue);
if (GetWave()) // test in case track is a NoteTrack
GetWave()->SetPan(fValue);
if (GetRight())
GetRight()->SetPan(fValue);
// Update the TrackPanel correspondingly.
#ifdef EXPERIMENTAL_MIDI_OUT
mProject->RefreshTPTrack(mTrack);
#else
mProject->RefreshTPTrack(mLeftTrack);
#endif
if (bWantPushState)
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)
{
#ifdef EXPERIMENTAL_MIDI_OUT
if (mMeter)
#endif
mMeter->Reset(mLeftTrack->GetRate(), bResetClipping);
mMeter->Reset(GetWave()->GetRate(), bResetClipping);
}
@ -450,33 +427,20 @@ void MixerTrackCluster::UpdateForStateChange()
void MixerTrackCluster::UpdateName()
{
#ifdef EXPERIMENTAL_MIDI_OUT
const wxString newName = mTrack->GetName();
#else
const wxString newName = mLeftTrack->GetName();
#endif
SetName(newName);
mStaticText_TrackName->SetLabel(newName);
#if wxUSE_TOOLTIPS
mStaticText_TrackName->SetToolTip(newName);
#endif
mBitmapButton_MusicalInstrument->SetBitmapLabel(
#ifdef EXPERIMENTAL_MIDI_OUT
*(mMixerBoard->GetMusicalInstrumentBitmap(newName)));
#else
*(mMixerBoard->GetMusicalInstrumentBitmap(mLeftTrack)));
#endif
*(mMixerBoard->GetMusicalInstrumentBitmap(mTrack)));
}
void MixerTrackCluster::UpdateMute()
{
#ifdef EXPERIMENTAL_MIDI_OUT
mToggleButton_Mute->SetAlternateIdx(mTrack->GetSolo() ? 1 : 0);
if (mTrack->GetMute())
#else
mToggleButton_Mute->SetAlternateIdx(mLeftTrack->GetSolo() ? 1 : 0);
if (mLeftTrack->GetMute())
#endif
mToggleButton_Mute->PushDown();
else
mToggleButton_Mute->PopUp();
@ -484,11 +448,7 @@ void MixerTrackCluster::UpdateMute()
void MixerTrackCluster::UpdateSolo()
{
#ifdef EXPERIMENTAL_MIDI_OUT
bool bIsSolo = mTrack->GetSolo();
#else
bool bIsSolo = mLeftTrack->GetSolo();
#endif
if (bIsSolo)
mToggleButton_Solo->PushDown();
else
@ -499,55 +459,36 @@ void MixerTrackCluster::UpdateSolo()
void MixerTrackCluster::UpdatePan()
{
#ifdef EXPERIMENTAL_MIDI_OUT
if (mNoteTrack) {
if (!GetWave()) {
mSlider_Pan->Hide();
return;
}
#endif
mSlider_Pan->Set(mLeftTrack->GetPan());
mSlider_Pan->Set(GetWave()->GetPan());
}
void MixerTrackCluster::UpdateGain()
{
#ifdef EXPERIMENTAL_MIDI_OUT
if (mNoteTrack) {
if (!GetWave()) {
mSlider_Gain->SetStyle(VEL_SLIDER);
mSlider_Gain->Set(mNoteTrack->GetVelocity());
mSlider_Gain->Set(GetNote()->GetVelocity());
return;
}
mSlider_Gain->SetStyle(DB_SLIDER);
#endif
mSlider_Gain->Set(mLeftTrack->GetGain());
mSlider_Gain->Set(GetWave()->GetGain());
}
void MixerTrackCluster::UpdateMeter(const double t0, const double t1)
{
#ifdef EXPERIMENTAL_MIDI_OUT
// NoteTracks do not (currently) register on meters. It would probably be
// a good idea to display 16 channel "active" lights rather than a meter
if (!mLeftTrack)
if (!GetWave())
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
#ifdef EXPERIMENTAL_MIDI_OUT
((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
@ -577,7 +518,7 @@ void MixerTrackCluster::UpdateMeter(const double t0, const double t1)
//Floats rmsRight{kFramesPerBuffer};
//
//#ifdef EXPERIMENTAL_MIDI_OUT
// bool bSuccess = (mLeftTrack != NULL);
// bool bSuccess = (GetWave() != nullptr);
//#else
// bool bSuccess = true;
//#endif
@ -589,8 +530,8 @@ void MixerTrackCluster::UpdateMeter(const double t0, const double t1)
//while (bSuccess && (i < kFramesPerBuffer))
//{
// bSuccess &=
// mLeftTrack->GetMinMax(&min, &(maxLeft[i]), dFrameT0, dFrameT1) &&
// mLeftTrack->GetRMS(&(rmsLeft[i]), dFrameT0, dFrameT1);
// mTrack->GetMinMax(&min, &(maxLeft[i]), dFrameT0, dFrameT1) &&
// mTrack->GetRMS(&(rmsLeft[i]), dFrameT0, dFrameT1);
// if (bSuccess && mRightTrack)
// bSuccess &=
// 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++)
// {
// float gain = mLeftTrack->GetChannelGain(0);
// float gain = mTrack->GetChannelGain(0);
// maxLeft[i] *= gain;
// rmsLeft[i] *= gain;
// if (mRightTrack)
@ -621,17 +562,18 @@ void MixerTrackCluster::UpdateMeter(const double t0, const double t1)
// maxRight[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.
// kFramesPerBuffer,
// maxLeft, rmsLeft,
// maxRight, rmsRight,
// mLeftTrack->TimeToLongSamples(t1 - t0));
// mTrack->TimeToLongSamples(t1 - t0));
//}
//
auto startSample = (sampleCount)((mLeftTrack->GetRate() * t0) + 0.5);
auto scnFrames = (sampleCount)((mLeftTrack->GetRate() * (t1 - t0)) + 0.5);
const auto pTrack = GetWave();
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
// 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 };
decltype(tempFloatsArray) meterFloatsArray;
// 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);
if (bSuccess)
{
@ -653,9 +595,9 @@ void MixerTrackCluster::UpdateMeter(const double t0, const double t1)
for (int index = 0; index < nFrames; index++)
meterFloatsArray[2 * index] = tempFloatsArray[index];
if (mRightTrack)
if (GetRight())
// Again, don't throw
bSuccess = mRightTrack->Get((samplePtr)tempFloatsArray.get(),
bSuccess = GetRight()->Get((samplePtr)tempFloatsArray.get(),
floatSample, startSample, nFrames, fillZero, false);
if (bSuccess)
@ -669,14 +611,14 @@ void MixerTrackCluster::UpdateMeter(const double t0, const double t1)
if (bSuccess)
{
//vvv Need to apply envelope, too? See Mixer::MixSameRate.
float gain = mLeftTrack->GetChannelGain(0);
float gain = pTrack->GetChannelGain(0);
if (gain < 1.0)
for (int index = 0; index < nFrames; index++)
meterFloatsArray[2 * index] *= gain;
if (mRightTrack)
gain = mRightTrack->GetChannelGain(1);
if (GetRight())
gain = GetRight()->GetChannelGain(1);
else
gain = mLeftTrack->GetChannelGain(1);
gain = pTrack->GetChannelGain(1);
if (gain < 1.0)
for (int index = 0; index < nFrames; index++)
meterFloatsArray[(2 * index) + 1] *= gain;
@ -705,13 +647,7 @@ wxColour MixerTrackCluster::GetTrackColor()
void MixerTrackCluster::HandleSelect(bool bShiftDown, bool bControlDown)
{
#ifdef EXPERIMENTAL_MIDI_OUT
Track *pTrack = mTrack;
#else
Track *pTrack = mLeftTrack;
#endif
mProject->GetTrackPanel()->HandleListSelection(pTrack, bShiftDown, bControlDown);
mProject->GetTrackPanel()->HandleListSelection(mTrack, bShiftDown, bControlDown);
}
void MixerTrackCluster::OnMouseEvent(wxMouseEvent& event)
@ -735,11 +671,7 @@ void MixerTrackCluster::OnPaint(wxPaintEvent & WXUNUSED(event))
wxSize clusterSize = this->GetSize();
wxRect bev(0, 0, clusterSize.GetWidth() - 1, clusterSize.GetHeight() - 1);
#ifdef EXPERIMENTAL_MIDI_OUT
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.
{
@ -782,13 +714,8 @@ void MixerTrackCluster::OnSlider_Pan(wxCommandEvent& WXUNUSED(event))
void MixerTrackCluster::OnButton_Mute(wxCommandEvent& WXUNUSED(event))
{
#ifdef EXPERIMENTAL_MIDI_OUT
mProject->HandleTrackMute(mTrack, mToggleButton_Mute->WasShiftDown());
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.
if (mProject->IsSoloSimple())
@ -799,22 +726,13 @@ void MixerTrackCluster::OnButton_Mute(wxCommandEvent& WXUNUSED(event))
}
else
// Update only the changed track.
#ifdef EXPERIMENTAL_MIDI_OUT
mProject->RefreshTPTrack(mTrack);
#else
mProject->RefreshTPTrack(mLeftTrack);
#endif
}
void MixerTrackCluster::OnButton_Solo(wxCommandEvent& WXUNUSED(event))
{
#ifdef EXPERIMENTAL_MIDI_OUT
mProject->HandleTrackSolo(mTrack, mToggleButton_Solo->WasShiftDown());
bool bIsSolo = mTrack->GetSolo();
#else
mProject->HandleTrackSolo(mLeftTrack, mToggleButton_Solo->WasShiftDown());
bool bIsSolo = mLeftTrack->GetSolo();
#endif
mToggleButton_Mute->SetAlternateIdx(bIsSolo ? 1 : 0);
// Update the TrackPanel correspondingly.
@ -827,11 +745,7 @@ void MixerTrackCluster::OnButton_Solo(wxCommandEvent& WXUNUSED(event))
}
else
// Update only the changed track.
#ifdef EXPERIMENTAL_MIDI_OUT
mProject->RefreshTPTrack(mTrack);
#else
mProject->RefreshTPTrack(mLeftTrack);
#endif
}
@ -1010,18 +924,14 @@ void MixerBoard::UpdateTrackClusters()
unsigned int nClusterIndex = 0;
TrackListIterator iterTracks(mTracks);
MixerTrackCluster* pMixerTrackCluster = NULL;
Track* pLeftTrack;
Track* pTrack;
Track* pRightTrack;
pLeftTrack = iterTracks.First();
while (pLeftTrack) {
pRightTrack = pLeftTrack->GetLinked() ? iterTracks.Next() : NULL;
pTrack = iterTracks.First();
while (pTrack) {
pRightTrack = pTrack->GetLinked() ? iterTracks.Next() : NULL;
if (pLeftTrack->GetKind() == Track::Wave
#ifdef EXPERIMENTAL_MIDI_OUT
|| pLeftTrack->GetKind() == Track::Note
#endif
)
if (auto pPlayableTrack = dynamic_cast<PlayableTrack*>(pTrack))
{
if (nClusterIndex < nClusterCount)
{
@ -1029,20 +939,8 @@ void MixerBoard::UpdateTrackClusters()
// Track clusters are maintained in the same order as the WaveTracks.
// Track pointers can change for the "same" track for different states
// on the undo stack, so update the pointers and display name.
#ifdef EXPERIMENTAL_MIDI_OUT
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
mMixerTrackClusters[nClusterIndex]->mTrack = pPlayableTrack;
// Assume linked track is wave or null
mMixerTrackClusters[nClusterIndex]->mRightTrack =
static_cast<WaveTrack*>(pRightTrack);
mMixerTrackClusters[nClusterIndex]->UpdateForStateChange();
}
else
@ -1057,16 +955,14 @@ void MixerBoard::UpdateTrackClusters()
wxSize clusterSize(kMixerTrackClusterWidth, nClusterHeight);
pMixerTrackCluster =
safenew MixerTrackCluster(mScrolledWindow, this, mProject,
static_cast<WaveTrack*>(pLeftTrack),
// Assume linked track is wave or null
static_cast<WaveTrack*>(pRightTrack),
pPlayableTrack,
clusterPos, clusterSize);
if (pMixerTrackCluster)
mMixerTrackClusters.Add(pMixerTrackCluster);
}
nClusterIndex++;
}
pLeftTrack = iterTracks.Next();
pTrack = iterTracks.Next();
}
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.
// Keep nClusterIndex constant and successively DELETE from left to right.
for (unsigned int nCounter = nClusterIndex; nCounter < nClusterCount; nCounter++)
#ifdef EXPERIMENTAL_MIDI_OUT
this->RemoveTrackCluster(mMixerTrackClusters[nClusterIndex]->mTrack);
#else
this->RemoveTrackCluster(mMixerTrackClusters[nClusterIndex]->mLeftTrack);
#endif
}
}
@ -1100,13 +992,8 @@ int MixerBoard::GetTrackClustersWidth()
kDoubleInset; // plus final right margin
}
#ifdef EXPERIMENTAL_MIDI_OUT
void MixerBoard::MoveTrackCluster(const Track* pTrack,
void MixerBoard::MoveTrackCluster(const PlayableTrack* pTrack,
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;
int nIndex = FindMixerTrackCluster(pTrack, &pMixerTrackCluster);
@ -1140,11 +1027,7 @@ void MixerBoard::MoveTrackCluster(const WaveTrack* pTrack,
}
}
#ifdef EXPERIMENTAL_MIDI_OUT
void MixerBoard::RemoveTrackCluster(const Track* pTrack)
#else
void MixerBoard::RemoveTrackCluster(const WaveTrack* pTrack)
#endif
void MixerBoard::RemoveTrackCluster(const PlayableTrack* pTrack)
{
// Find and destroy.
MixerTrackCluster* pMixerTrackCluster;
@ -1180,22 +1063,14 @@ void MixerBoard::RemoveTrackCluster(const WaveTrack* pTrack)
}
#ifdef EXPERIMENTAL_MIDI_OUT
wxBitmap* MixerBoard::GetMusicalInstrumentBitmap(const wxString & name)
#else
wxBitmap* MixerBoard::GetMusicalInstrumentBitmap(const WaveTrack* pLeftTrack)
#endif
wxBitmap* MixerBoard::GetMusicalInstrumentBitmap(const Track* pTrack)
{
if (mMusicalInstruments.empty())
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(wxString{ name }.MakeLower());
#else
const wxString strTrackName(pLeftTrack->GetName().MakeLower());
#endif
const wxString strTrackName(pTrack->GetName().MakeLower());
size_t nBestItemIndex = 0;
unsigned int nBestScore = 0;
unsigned int nInstrIndex = 0;
@ -1242,11 +1117,7 @@ bool MixerBoard::HasSolo()
return false;
}
#ifdef EXPERIMENTAL_MIDI_OUT
void MixerBoard::RefreshTrackCluster(const Track* pTrack, bool bEraseBackground /*= true*/)
#else
void MixerBoard::RefreshTrackCluster(const WaveTrack* pTrack, bool bEraseBackground )
#endif
void MixerBoard::RefreshTrackCluster(const PlayableTrack* pTrack, bool bEraseBackground /*= true*/)
{
MixerTrackCluster* pMixerTrackCluster;
this->FindMixerTrackCluster(pTrack, &pMixerTrackCluster);
@ -1277,11 +1148,7 @@ void MixerBoard::ResetMeters(const bool bResetClipping)
mMixerTrackClusters[i]->ResetMeter(bResetClipping);
}
#ifdef EXPERIMENTAL_MIDI_OUT
void MixerBoard::UpdateName(const Track* pTrack)
#else
void MixerBoard::UpdateName(const WaveTrack* pTrack)
#endif
void MixerBoard::UpdateName(const PlayableTrack* pTrack)
{
MixerTrackCluster* pMixerTrackCluster;
this->FindMixerTrackCluster(pTrack, &pMixerTrackCluster);
@ -1289,11 +1156,7 @@ void MixerBoard::UpdateName(const WaveTrack* pTrack)
pMixerTrackCluster->UpdateName();
}
#ifdef EXPERIMENTAL_MIDI_OUT
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
void MixerBoard::UpdateMute(const PlayableTrack* pTrack /*= NULL*/) // NULL means update for all tracks.
{
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 Track* pTrack /*= NULL*/) // NULL means update for all tracks.
#else
void MixerBoard::UpdateSolo(const WaveTrack* pTrack /*= NULL*/) // NULL means update for all tracks.
#endif
void MixerBoard::UpdateSolo(const PlayableTrack* pTrack /*= NULL*/) // NULL means update for all tracks.
{
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 Track* pTrack)
#else
void MixerBoard::UpdatePan(const WaveTrack* pTrack)
#endif
void MixerBoard::UpdatePan(const PlayableTrack* pTrack)
{
MixerTrackCluster* pMixerTrackCluster;
FindMixerTrackCluster(pTrack, &pMixerTrackCluster);
@ -1341,11 +1196,7 @@ void MixerBoard::UpdatePan(const WaveTrack* pTrack)
pMixerTrackCluster->UpdatePan();
}
#ifdef EXPERIMENTAL_MIDI_OUT
void MixerBoard::UpdateGain(const Track* pTrack)
#else
void MixerBoard::UpdateGain(const WaveTrack* pTrack)
#endif
void MixerBoard::UpdateGain(const PlayableTrack* pTrack)
{
MixerTrackCluster* pMixerTrackCluster;
FindMixerTrackCluster(pTrack, &pMixerTrackCluster);
@ -1471,22 +1322,13 @@ void MixerBoard::CreateMuteSoloImages()
mImageSoloDisabled = std::make_unique<wxImage>(mMuteSoloWidth, MUTE_SOLO_HEIGHT); // Leave empty because unused.
}
#ifdef EXPERIMENTAL_MIDI_OUT
int MixerBoard::FindMixerTrackCluster(const Track* pTrack,
MixerTrackCluster** hMixerTrackCluster) const
#else
int MixerBoard::FindMixerTrackCluster(const WaveTrack* pLeftTrack,
int MixerBoard::FindMixerTrackCluster(const PlayableTrack* pTrack,
MixerTrackCluster** hMixerTrackCluster) const
#endif
{
*hMixerTrackCluster = NULL;
for (unsigned int i = 0; i < mMixerTrackClusters.GetCount(); i++)
{
#ifdef EXPERIMENTAL_MIDI_OUT
if (mMixerTrackClusters[i]->mTrack == pTrack)
#else
if (mMixerTrackClusters[i]->mLeftTrack == pLeftTrack)
#endif
{
*hMixerTrackCluster = mMixerTrackClusters[i];
return i;

View File

@ -62,10 +62,11 @@ public:
class AudacityProject;
class Meter;
class MixerBoard;
#ifdef EXPERIMENTAL_MIDI_OUT
class Track;
class NoteTrack;
#endif
class PlayableTrack;
class WaveTrack;
class MixerTrackCluster final : public wxPanelWrapper
@ -73,11 +74,15 @@ class MixerTrackCluster final : public wxPanelWrapper
public:
MixerTrackCluster(wxWindow* parent,
MixerBoard* grandParent, AudacityProject* project,
WaveTrack* pLeftTrack, WaveTrack* pRightTrack = NULL,
PlayableTrack* pTrack,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize);
virtual ~MixerTrackCluster() {}
WaveTrack *GetWave() const;
WaveTrack *GetRight() const;
NoteTrack *GetNote() const;
void UpdatePrefs();
void HandleResize(); // For wxSizeEvents, update gain slider and meter.
@ -115,23 +120,7 @@ private:
public:
#ifdef EXPERIMENTAL_MIDI_OUT
// 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
PlayableTrack * mTrack;
private:
MixerBoard* mMixerBoard;
@ -213,45 +202,25 @@ public:
void UpdateTrackClusters();
int GetTrackClustersWidth();
#ifdef EXPERIMENTAL_MIDI_OUT
void MoveTrackCluster(const Track* pTrack, bool bUp); // Up in TrackPanel is left in MixerBoard.
void RemoveTrackCluster(const Track* pTrack);
void MoveTrackCluster(const PlayableTrack* pTrack, bool bUp); // Up in TrackPanel is left in MixerBoard.
void RemoveTrackCluster(const PlayableTrack* pTrack);
wxBitmap* GetMusicalInstrumentBitmap(const wxString & name);
#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
wxBitmap* GetMusicalInstrumentBitmap(const Track *pTrack);
bool HasSolo();
#ifdef EXPERIMENTAL_MIDI_OUT
void RefreshTrackCluster(const Track* pTrack, bool bEraseBackground = true);
#else
void RefreshTrackCluster(const WaveTrack* pTrack, bool bEraseBackground = true);
#endif
void RefreshTrackCluster(const PlayableTrack* pTrack, bool bEraseBackground = true);
void RefreshTrackClusters(bool bEraseBackground = true);
void ResizeTrackClusters();
void ResetMeters(const bool bResetClipping);
#ifdef EXPERIMENTAL_MIDI_OUT
void UpdateName(const Track* pTrack);
void UpdateMute(const Track* pTrack = NULL); // NULL means update for all tracks.
void UpdateSolo(const Track* pTrack = NULL); // NULL means update for all tracks.
void UpdatePan(const Track* 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 UpdateName(const PlayableTrack* pTrack);
void UpdateMute(const PlayableTrack* pTrack = NULL); // NULL means update for all tracks.
void UpdateSolo(const PlayableTrack* pTrack = NULL); // NULL means update for all tracks.
void UpdatePan(const PlayableTrack* pTrack);
void UpdateGain(const PlayableTrack* pTrack);
void UpdateMeters(const double t1, const bool bLoopedPlay);
@ -259,13 +228,8 @@ public:
private:
void CreateMuteSoloImages();
#ifdef EXPERIMENTAL_MIDI_OUT
int FindMixerTrackCluster(const Track* pTrack,
int FindMixerTrackCluster(const PlayableTrack* pTrack,
MixerTrackCluster** hMixerTrackCluster) const;
#else
int FindMixerTrackCluster(const WaveTrack* pLeftTrack,
MixerTrackCluster** hMixerTrackCluster) const;
#endif
void LoadMusicalInstruments();
// event handlers

View File

@ -5396,12 +5396,13 @@ void AudacityProject::RemoveTrack(Track * toRemove)
wxString name = toRemove->GetName();
Track *partner = toRemove->GetLink();
if (toRemove->GetKind() == Track::Wave)
auto playable = dynamic_cast<PlayableTrack*>(toRemove);
if (playable)
{
// Update mixer board displayed tracks.
MixerBoard* pMixerBoard = this->GetMixerBoard();
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);

View File

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

View File

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