1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-09-17 16:50:26 +02:00

Apply modified version Roger Dannenberg's patch to remedy some problems from commit r10680 and fix some bugs.

This commit is contained in:
v.audacity 2011-10-19 23:06:53 +00:00
parent 939eab26ae
commit 1ceb0ef660
13 changed files with 363 additions and 54 deletions

View File

@ -3387,6 +3387,20 @@ int audacityAudioCallback(const void *inputBuffer, void *outputBuffer,
linkFlag = vt->GetLinked();
}
#define ORIGINAL_DO_NOT_PLAY_ALL_MUTED_TRACKS_TO_END
#ifdef ORIGINAL_DO_NOT_PLAY_ALL_MUTED_TRACKS_TO_END
// this is original code prior to r10680 -RBD
if (cut)
{
gAudioIO->mPlaybackBuffers[t]->Discard(framesPerBuffer);
continue;
}
unsigned int len = (unsigned int)
gAudioIO->mPlaybackBuffers[t]->Get((samplePtr)tempFloats,
floatSample,
(int)framesPerBuffer);
#else
// This code was reorganized so that if all audio tracks
// are muted, we still return paComplete when the end of
// a selection is reached.
@ -3402,6 +3416,7 @@ int audacityAudioCallback(const void *inputBuffer, void *outputBuffer,
floatSample,
(int)framesPerBuffer);
}
#endif
// If our buffer is empty and the time indicator is past
// the end, then we've actually finished playing the entire
// selection.
@ -3411,9 +3426,10 @@ int audacityAudioCallback(const void *inputBuffer, void *outputBuffer,
{
callbackReturn = paComplete;
}
#ifndef ORIGINAL_DO_NOT_PLAY_ALL_MUTED_TRACKS_TO_END
if (cut) // no samples to process, they've been discarded
continue;
#endif
if (vt->GetChannel() == Track::LeftChannel ||
vt->GetChannel() == Track::MonoChannel)

View File

@ -21,8 +21,8 @@
#ifdef EXPERIMENTAL_MIDI_OUT
#include "portmidi.h"
#include "porttime.h"
#endif // EXPERIMENTAL_MIDI_OUT
#include "allegro.h"
#endif // EXPERIMENTAL_MIDI_OUT
#endif // USE_MIDI
#if USE_PORTMIXER
@ -549,7 +549,9 @@ private:
AudioIOListener* mListener;
friend class AudioThread;
#ifdef EXPERIMENTAL_MIDI_OUT
friend class MidiThread;
#endif
friend void InitAudioIO();
friend void DeinitAudioIO();

View File

@ -132,7 +132,7 @@ MixerTrackCluster::MixerTrackCluster(wxWindow* parent,
}
#else
wxASSERT(pLeftTrack->GetKind() == Track::Wave);
mTrack = mLeftTrack = pLeftTrack;
mLeftTrack = pLeftTrack;
#endif
mRightTrack = pRightTrack;
@ -146,10 +146,14 @@ MixerTrackCluster::MixerTrackCluster(wxWindow* parent,
// track name
wxPoint ctrlPos(kDoubleInset, kDoubleInset);
wxSize ctrlSize(size.GetWidth() - kQuadrupleInset, TRACK_NAME_HEIGHT);
wxString name = mTrack->GetName();
mStaticText_TrackName =
new wxStaticText(this, -1, name, ctrlPos, ctrlSize,
#ifdef EXPERIMENTAL_MIDI_OUT
new wxStaticText(this, -1, mTrack->GetName(), ctrlPos, ctrlSize,
wxALIGN_CENTRE | wxST_NO_AUTORESIZE | wxSUNKEN_BORDER);
#else
new 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());
@ -186,7 +190,11 @@ 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);
wxBitmap* bitmap = mMixerBoard->GetMusicalInstrumentBitmap(name);
#ifdef EXPERIMENTAL_MIDI_OUT
wxBitmap* bitmap = mMixerBoard->GetMusicalInstrumentBitmap(mTrack->GetName());
#else
wxBitmap* bitmap = mMixerBoard->GetMusicalInstrumentBitmap(mLeftTrack);
#endif
wxASSERT(bitmap);
mBitmapButton_MusicalInstrument =
new wxBitmapButton(this, ID_BITMAPBUTTON_MUSICAL_INSTRUMENT, *bitmap,
@ -247,16 +255,31 @@ 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 =
new Meter(this, -1, // wxWindow* parent, wxWindowID id,
false, // bool isInput
ctrlPos, ctrlSize, // const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
Meter::MixerTrackCluster); // Style style = HorizontalStereo,
#ifdef EXPERIMENTAL_MIDI_OUT
} else {
mMeter = NULL;
}
#endif
#if wxUSE_TOOLTIPS
mStaticText_TrackName->SetToolTip(name);
#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"));
#endif // wxUSE_TOOLTIPS
@ -299,6 +322,9 @@ 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);
}
@ -315,8 +341,11 @@ void MixerTrackCluster::HandleSliderGain(const bool bWantPushState /*= false*/)
mRightTrack->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"), PUSH_CONSOLIDATE );
}
@ -330,7 +359,11 @@ void MixerTrackCluster::HandleSliderPan(const bool bWantPushState /*= false*/)
mRightTrack->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"), PUSH_CONSOLIDATE );
@ -338,7 +371,9 @@ void MixerTrackCluster::HandleSliderPan(const bool bWantPushState /*= false*/)
void MixerTrackCluster::ResetMeter(const bool bResetClipping)
{
if (mLeftTrack)
#ifdef EXPERIMENTAL_MIDI_OUT
if (mMeter)
#endif
mMeter->Reset(mLeftTrack->GetRate(), bResetClipping);
}
@ -355,19 +390,32 @@ void MixerTrackCluster::UpdateForStateChange()
void MixerTrackCluster::UpdateName()
{
wxString newName = mLeftTrack->GetName();
#ifdef EXPERIMENTAL_MIDI_OUT
const wxString newName = mTrack->GetName();
#else
const wxString newName = mLeftTrack->GetName();
#endif
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
}
void MixerTrackCluster::UpdateMute()
{
#ifdef EXPERIMENTAL_MIDI_OUT
mToggleButton_Mute->SetAlternate(mTrack->GetSolo());
if (mTrack->GetMute())
#else
mToggleButton_Mute->SetAlternate(mLeftTrack->GetSolo());
if (mLeftTrack->GetMute())
#endif
mToggleButton_Mute->PushDown();
else
mToggleButton_Mute->PopUp();
@ -375,7 +423,11 @@ 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
@ -409,15 +461,32 @@ void MixerTrackCluster::UpdateGain()
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)
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
// playback issues reported by Bill and noted on Bug 258, so no assert.
@ -445,6 +514,12 @@ void MixerTrackCluster::UpdateMeter(const double t0, const double t1)
//float* maxRight = new float[kFramesPerBuffer];
//float* rmsRight = new float[kFramesPerBuffer];
//
//#ifdef EXPERIMENTAL_MIDI_OUT
// bool bSuccess = (mLeftTrack != NULL);
//#else
// bool bSuccess = true;
//#endif
//const double dFrameInterval = (t1 - t0) / (double)kFramesPerBuffer;
//double dFrameT0 = t0;
//double dFrameT1 = t0 + dFrameInterval;
@ -573,28 +648,46 @@ void MixerTrackCluster::HandleSelect(const bool bShiftDown)
if (bShiftDown)
{
// ShiftDown => Just toggle selection on this track.
#ifdef EXPERIMENTAL_MIDI_OUT
bool bSelect = !mTrack->GetSelected();
mTrack->SetSelected(bSelect);
#else
bool bSelect = !mLeftTrack->GetSelected();
mLeftTrack->SetSelected(bSelect);
#endif
if (mRightTrack)
mRightTrack->SetSelected(bSelect);
// Refresh only this MixerTrackCluster and WaveTrack in TrackPanel.
this->Refresh(true);
#ifdef EXPERIMENTAL_MIDI_OUT
mProject->RefreshTPTrack(mTrack);
#else
mProject->RefreshTPTrack(mLeftTrack);
#endif
}
else
{
// exclusive select
mProject->SelectNone();
#ifdef EXPERIMENTAL_MIDI_OUT
mTrack->SetSelected(true);
#else
mLeftTrack->SetSelected(true);
#endif
if (mRightTrack)
mRightTrack->SetSelected(true);
if (mProject->GetSel0() >= mProject->GetSel1())
{
// No range previously selected, so use the range of this track.
#ifdef EXPERIMENTAL_MIDI_OUT
mProject->mViewInfo.sel0 = mTrack->GetOffset();
mProject->mViewInfo.sel1 = mTrack->GetEndTime();
#else
mProject->mViewInfo.sel0 = mLeftTrack->GetOffset();
mProject->mViewInfo.sel1 = mLeftTrack->GetEndTime();
#endif
}
// Exclusive select, so refresh all MixerTrackClusters.
@ -631,7 +724,11 @@ void MixerTrackCluster::OnPaint(wxPaintEvent &evt)
wxSize clusterSize = this->GetSize();
wxRect bev(0, 0, clusterSize.GetWidth() - 1, clusterSize.GetHeight() - 1);
#ifdef EXPERIMENTAL_MIDI_OUT
if (mTrack->GetSelected())
#else
if (mLeftTrack->GetSelected())
#endif
{
for (unsigned int i = 0; i < 4; i++) // 4 gives a big bevel, but there were complaints about visibility otherwise.
{
@ -677,8 +774,13 @@ void MixerTrackCluster::OnSlider_Pan(wxCommandEvent& event)
void MixerTrackCluster::OnButton_Mute(wxCommandEvent& event)
{
#ifdef EXPERIMENTAL_MIDI_OUT
mProject->HandleTrackMute(mTrack, mToggleButton_Mute->WasShiftDown());
mToggleButton_Mute->SetAlternate(mTrack->GetSolo());
#else
mProject->HandleTrackMute(mLeftTrack, mToggleButton_Mute->WasShiftDown());
mToggleButton_Mute->SetAlternate(mLeftTrack->GetSolo());
#endif
// Update the TrackPanel correspondingly.
if (mProject->IsSoloSimple())
@ -689,14 +791,22 @@ void MixerTrackCluster::OnButton_Mute(wxCommandEvent& event)
}
else
// Update only the changed track.
#ifdef EXPERIMENTAL_MIDI_OUT
mProject->RefreshTPTrack(mTrack);
#else
mProject->RefreshTPTrack(mLeftTrack);
#endif
}
void MixerTrackCluster::OnButton_Solo(wxCommandEvent& 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->SetAlternate(bIsSolo);
// Update the TrackPanel correspondingly.
@ -709,7 +819,11 @@ void MixerTrackCluster::OnButton_Solo(wxCommandEvent& event)
}
else
// Update only the changed track.
#ifdef EXPERIMENTAL_MIDI_OUT
mProject->RefreshTPTrack(mTrack);
#else
mProject->RefreshTPTrack(mLeftTrack);
#endif
}
@ -952,7 +1066,11 @@ void MixerBoard::UpdateTrackClusters()
// that don't call RemoveTrackCluster explicitly.
// We've already updated the track pointers for the clusters to the left, so just remove these.
for (; nClusterIndex < nClusterCount; nClusterIndex++)
#ifdef EXPERIMENTAL_MIDI_OUT
this->RemoveTrackCluster(mMixerTrackClusters[nClusterIndex]->mTrack);
#else
this->RemoveTrackCluster(mMixerTrackClusters[nClusterIndex]->mLeftTrack);
#endif
}
}
@ -965,8 +1083,13 @@ int MixerBoard::GetTrackClustersWidth()
kDoubleInset; // plus final right margin
}
#ifdef EXPERIMENTAL_MIDI_OUT
void MixerBoard::MoveTrackCluster(const Track* 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);
@ -1000,11 +1123,15 @@ void MixerBoard::MoveTrackCluster(const Track* pTrack,
}
}
#ifdef EXPERIMENTAL_MIDI_OUT
void MixerBoard::RemoveTrackCluster(const Track* pTrack)
#else
void MixerBoard::RemoveTrackCluster(const WaveTrack* pTrack)
#endif
{
// Find and destroy.
MixerTrackCluster* pMixerTrackCluster;
int nIndex = FindMixerTrackCluster(pTrack, &pMixerTrackCluster);
int nIndex = this->FindMixerTrackCluster(pTrack, &pMixerTrackCluster);
if (pMixerTrackCluster == NULL)
return; // Couldn't find it.
@ -1027,21 +1154,31 @@ void MixerBoard::RemoveTrackCluster(const Track* pTrack)
this->UpdateWidth();
#ifdef EXPERIMENTAL_MIDI_OUT
// Sanity check: if there is still a MixerTrackCluster with pTrack, then
// we deleted the first but should have deleted the last:
FindMixerTrackCluster(pTrack, &pMixerTrackCluster);
assert(pMixerTrackCluster == NULL);
#endif
}
wxBitmap* MixerBoard::GetMusicalInstrumentBitmap(wxString name)
#ifdef EXPERIMENTAL_MIDI_OUT
wxBitmap* MixerBoard::GetMusicalInstrumentBitmap(const wxString name)
#else
wxBitmap* MixerBoard::GetMusicalInstrumentBitmap(const WaveTrack* pLeftTrack)
#endif
{
if (mMusicalInstruments.IsEmpty())
return NULL;
// random choice: return mMusicalInstruments[(int)pLeftTrack % mMusicalInstruments.GetCount()].mBitmap;
#ifdef EXPERIMENTAL_MIDI_OUT
const wxString strTrackName(name.MakeLower());
#else
const wxString strTrackName(pLeftTrack->GetName().MakeLower());
#endif
size_t nBestItemIndex = 0;
unsigned int nBestScore = 0;
unsigned int nInstrIndex = 0;
@ -1088,10 +1225,14 @@ 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
{
MixerTrackCluster* pMixerTrackCluster;
FindMixerTrackCluster(pTrack, &pMixerTrackCluster);
this->FindMixerTrackCluster(pTrack, &pMixerTrackCluster);
if (pMixerTrackCluster)
pMixerTrackCluster->Refresh(bEraseBackground);
}
@ -1119,15 +1260,23 @@ 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
{
MixerTrackCluster* pMixerTrackCluster;
FindMixerTrackCluster(pTrack, &pMixerTrackCluster);
this->FindMixerTrackCluster(pTrack, &pMixerTrackCluster);
if (pMixerTrackCluster)
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
{
if (pTrack == NULL)
{
@ -1143,7 +1292,11 @@ void MixerBoard::UpdateMute(const Track* pTrack /*= NULL*/) // NULL means update
}
}
#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
{
if (pTrack == NULL)
{
@ -1159,7 +1312,11 @@ void MixerBoard::UpdateSolo(const Track* pTrack /*= NULL*/) // NULL means update
}
}
#ifdef EXPERIMENTAL_MIDI_OUT
void MixerBoard::UpdatePan(const Track* pTrack)
#else
void MixerBoard::UpdatePan(const WaveTrack* pTrack)
#endif
{
MixerTrackCluster* pMixerTrackCluster;
FindMixerTrackCluster(pTrack, &pMixerTrackCluster);
@ -1167,7 +1324,11 @@ void MixerBoard::UpdatePan(const Track* pTrack)
pMixerTrackCluster->UpdatePan();
}
#ifdef EXPERIMENTAL_MIDI_OUT
void MixerBoard::UpdateGain(const Track* pTrack)
#else
void MixerBoard::UpdateGain(const WaveTrack* pTrack)
#endif
{
MixerTrackCluster* pMixerTrackCluster;
FindMixerTrackCluster(pTrack, &pMixerTrackCluster);
@ -1293,13 +1454,22 @@ void MixerBoard::CreateMuteSoloImages()
mImageSoloDisabled = new 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,
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

@ -59,11 +59,11 @@ public:
class AudacityProject;
class MixerBoard;
class Track;
class WaveTrack;
#ifdef EXPERIMENTAL_MIDI_OUT
class NoteTrack;
class Track;
class NoteTrack;
#endif
class WaveTrack;
class MixerTrackCluster : public wxPanel
{
@ -109,9 +109,11 @@ private:
//v void OnSliderScroll_Gain(wxScrollEvent& event);
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
@ -202,25 +204,45 @@ 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);
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
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 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 UpdateMeters(const double t1, const bool bLoopedPlay);
@ -228,8 +250,13 @@ public:
private:
void CreateMuteSoloImages();
#ifdef EXPERIMENTAL_MIDI_OUT
int FindMixerTrackCluster(const Track* pTrack,
MixerTrackCluster** hMixerTrackCluster) const;
#else
int FindMixerTrackCluster(const WaveTrack* pLeftTrack,
MixerTrackCluster** hMixerTrackCluster) const;
#endif
void LoadMusicalInstruments();
// event handlers

View File

@ -21,9 +21,9 @@
#include "Audacity.h"
#if defined(USE_MIDI)
#include <sstream>
#if defined(USE_MIDI)
#define ROUND(x) ((int) ((x) + 0.5))
#include "AColor.h"
@ -112,9 +112,9 @@ Track(projDirManager)
mSerializationLength = 0;
mDirManager = projDirManager;
#ifdef EXPERIMENTAL_MIDI_OUT
mGain = 0;
#endif
mBottomNote = 24;
mPitchHeight = 5;
@ -164,8 +164,9 @@ Track *NoteTrack::Duplicate()
duplicate->mLastMidiPosition = mLastMidiPosition;
duplicate->mVisibleChannels = mVisibleChannels;
duplicate->SetOffset(GetOffset());
#ifdef EXPERIMENTAL_MIDI_OUT
duplicate->SetGain(GetGain());
#endif
return duplicate;
}
@ -769,10 +770,12 @@ bool NoteTrack::HandleXMLTag(const wxChar *tag, const wxChar **attrs)
else if (!wxStrcmp(attr, wxT("minimized")) &&
XMLValueChecker::IsGoodInt(strValue) && strValue.ToLong(&nValue))
mMinimized = (nValue != 0);
#ifdef EXPERIMENTAL_MIDI_OUT
else if (!wxStrcmp(attr, wxT("velocity")) &&
XMLValueChecker::IsGoodString(strValue) &&
Internat::CompatibleToDouble(strValue, &dblValue))
mGain = (float) dblValue;
#endif
else if (!wxStrcmp(attr, wxT("bottomnote")) &&
XMLValueChecker::IsGoodInt(strValue) && strValue.ToLong(&nValue))
SetBottomNote(nValue);
@ -821,7 +824,9 @@ void NoteTrack::WriteXML(XMLWriter &xmlFile)
xmlFile.WriteAttr(wxT("visiblechannels"), saveme->mVisibleChannels);
xmlFile.WriteAttr(wxT("height"), saveme->GetActualHeight());
xmlFile.WriteAttr(wxT("minimized"), saveme->GetMinimized());
#ifdef EXPERIMENTAL_MIDI_OUT
xmlFile.WriteAttr(wxT("velocity"), (double) saveme->mGain);
#endif
xmlFile.WriteAttr(wxT("bottomnote"), saveme->mBottomNote);
xmlFile.WriteAttr(wxT("data"), wxString(data.str().c_str(), wxConvUTF8));
xmlFile.EndTag(wxT("notetrack"));

View File

@ -95,8 +95,10 @@ class AUDACITY_DLL_API NoteTrack:public Track {
virtual bool Paste(double t, Track *src);
virtual bool Shift(double t);
#ifdef EXPERIMENTAL_MIDI_OUT
float GetGain() const { return mGain; }
void SetGain(float gain) { mGain = gain; }
#endif
double NearestBeatTime(double time, double *beat);
bool StretchRegion(double b0, double b1, double dur);
@ -161,8 +163,10 @@ class AUDACITY_DLL_API NoteTrack:public Track {
void StartVScroll();
void VScroll(int start, int end);
#ifdef EXPERIMENTAL_MIDI_OUT
wxRect GetGainPlacementRect() const { return mGainPlacementRect; }
void SetGainPlacementRect(const wxRect &r) { mGainPlacementRect = r; }
#endif
virtual bool HandleXMLTag(const wxChar *tag, const wxChar **attrs);
virtual XMLTagHandler *HandleXMLChild(const wxChar *tag);
@ -197,7 +201,9 @@ class AUDACITY_DLL_API NoteTrack:public Track {
DirManager *mDirManager;
#ifdef EXPERIMENTAL_MIDI_OUT
float mGain; // velocity offset
#endif
// mBottom is the Y offset of pitch 0 (normally off screen)
int mBottom;

View File

@ -52,7 +52,7 @@ Audacity, the "2-level" invalidation works like this: Anything
that invalidates the bitmap calls TrackPanel::Refresh(), which
has an eraseBackground parameter. This flag says to redraw the
bitmap when OnPaint() is called. If eraseBackground is false, the
existing bitmap can be used for waveform imges. Audacity also
existing bitmap can be used for waveform images. Audacity also
draws directly to the screen to update the time indicator during
playback. To move the indicator, one column of pixels is drawn to
the screen to remove the indicator. Then the indicator is drawn at
@ -2183,7 +2183,6 @@ static const char *LookupStringAttribute(Alg_note_ptr note, Alg_attribute attr,
static const char *LookupAtomAttribute(Alg_note_ptr note, Alg_attribute attr, char *def);
//static int PITCH_TO_Y(double p, int bottom);
// returns NULL if note is not a shape,
// returns atom (string) value of note if note is a shape
const char *IsShape(Alg_note_ptr note)

View File

@ -590,6 +590,11 @@ TrackPanel::~TrackPanel()
delete mRearrangeCursor;
delete mAdjustLeftSelectionCursor;
delete mAdjustRightSelectionCursor;
#if USE_MIDI
delete mStretchCursor;
delete mStretchLeftCursor;
delete mStretchRightCursor;
#endif
delete mSnapManager;
@ -2911,11 +2916,7 @@ void TrackPanel::DoSlide(wxMouseEvent & event)
{
// Make sure we always have the first linked track of a stereo track
if (!mouseTrack->GetLinked() && mTracks->GetLink(mouseTrack))
mouseTrack =
#ifndef USE_MIDI
(WaveTrack*)
#endif
mTracks->GetLink(mouseTrack);
mouseTrack = mTracks->GetLink(mouseTrack);
// Temporary apply the offset because we want to see if the
// track fits with the desired offset
@ -3186,21 +3187,22 @@ void TrackPanel::HandleVZoomClick( wxMouseEvent & event )
return;
// don't do anything if track is not wave or Spectrum/log Spectrum
if ((mCapturedTrack->GetKind() == Track::Wave
&& ((WaveTrack *) mCapturedTrack)->GetDisplay() <= WaveTrack::SpectrumLogDisplay)
#ifdef USE_MIDI
if (((mCapturedTrack->GetKind() == Track::Wave) &&
(((WaveTrack*)mCapturedTrack)->GetDisplay() <= WaveTrack::SpectrumLogDisplay))
#ifdef USE_MIDI
|| mCapturedTrack->GetKind() == Track::Note
#endif
) {
#endif
)
{
mMouseCapture = IsVZooming;
mZoomStart = event.m_y;
mZoomEnd = event.m_y;
// change note track to zoom like audio track
//#ifdef USE_MIDI
// if (mCapturedTrack->GetKind() == Track::Note) {
// ((NoteTrack *) mCapturedTrack)->StartVScroll();
// }
//#endif
//#ifdef USE_MIDI
// if (mCapturedTrack->GetKind() == Track::Note) {
// ((NoteTrack *) mCapturedTrack)->StartVScroll();
// }
//#endif
}
}
@ -4037,7 +4039,7 @@ void TrackPanel::HandleSliders(wxMouseEvent &event, bool pan)
pMixerBoard->UpdateGain((WaveTrack*)mCapturedTrack);
}
#ifdef EXPERIMENTAL_MIDI_OUT
} else {
} else { // Note: funny indentation to match "if" about 20 lines back
if (!pan) {
((NoteTrack *) mCapturedTrack)->SetGain(newValue);
#ifdef EXPERIMENTAL_MIXER_BOARD
@ -4258,14 +4260,26 @@ void TrackPanel::HandleRearrange(wxMouseEvent & event)
if (event.m_y < mMoveUpThreshold || event.m_y < 0) {
mTracks->MoveUp(mCapturedTrack);
dir = _("up");
#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);
pMixerBoard->MoveTrackCluster((WaveTrack*)mCapturedTrack, true /* up */);
#endif
}
else if (event.m_y > mMoveDownThreshold || event.m_y > GetRect().GetHeight()) {
mTracks->MoveDown(mCapturedTrack);
dir = _("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);
pMixerBoard->MoveTrackCluster((WaveTrack*)mCapturedTrack, false /* down */);
#endif
}
else
{
@ -5562,10 +5576,13 @@ void TrackPanel::DrawEverythingElse(wxDC * dc,
clip.height - trackRect.y);
}
// Previous code that caused highlight NOT to be drawn on backing
// bitmap due to wxWindow::FindFocus() not returning "this" on Mac:
// if (GetFocusedTrack() != NULL) && wxWindow::FindFocus() == this) {
if (GetFocusedTrack() != NULL) {
// Sometimes highlight is not drawn on backing bitmap. I thought
// it was because FindFocus did not return "this" on Mac, but
// when I removed that test, yielding this condition:
// if (GetFocusedTrack() != NULL) {
// the highlight was reportedly drawn even when something else
// was the focus and no highlight should be drawn. -RBD
if (GetFocusedTrack() != NULL && wxWindow::FindFocus() == this) {
HighlightFocusedTrack(dc, focusRect);
}

View File

@ -535,10 +535,6 @@ private:
// us to undo the slide and then slide it by another amount
double mHSlideAmount;
#ifdef USE_MIDI
NoteTrack *mCapturedNoteClip;
#endif
bool mDidSlideVertically;
bool mRedrawAfterStop;

View File

@ -1,4 +1,25 @@
/**********************************************************************
Audacity: A Digital Audio Editor
Audacity(R) is copyright (c) 1999-2008 Audacity Team.
License: GPL v2. See License.txt.
ScoreAlignDialog.cpp
<TODO: authors>
******************************************************************//**
\class ScoreAlignDialog
\brief ScoreAlignDialog is <TODO>.
It <TODO: description>
*//*******************************************************************/
#include "../Audacity.h"
#include "../Experimental.h"
#ifdef EXPERIMENTAL_SCOREALIGN
// For compilers that support precompilation, includes "wx/wx.h".
#include <wx/wxprec.h>
@ -262,3 +283,5 @@ BEGIN_EVENT_TABLE(ScoreAlignDialog, wxDialog)
EVT_SLIDER(ID_LINETIME, ScoreAlignDialog::OnSlider)
EVT_SLIDER(ID_SMOOTHTIME, ScoreAlignDialog::OnSlider)
END_EVENT_TABLE()
#endif

View File

@ -330,7 +330,7 @@ LWSlider::LWSlider(wxWindow * parent,
stepValue, canUseShift, style, heavyweight, popup, 1.0, orientation);
}
#ifdef EXPERIMENTAL_MIDI_OUT
void LWSlider::SetStyle(int style)
{
mStyle = style;
@ -380,7 +380,7 @@ void LWSlider::SetStyle(int style)
wxASSERT(false); // undefined style
}
}
#endif
// Construct predefined slider
LWSlider::LWSlider(wxWindow *parent,
@ -393,6 +393,7 @@ LWSlider::LWSlider(wxWindow *parent,
int orientation /* = wxHORIZONTAL */) // wxHORIZONTAL or wxVERTICAL. wxVERTICAL is currently only for DB_SLIDER.
{
wxString leftLabel, rightLabel;
#ifdef EXPERIMENTAL_MIDI_OUT
mOrientation = orientation;
mName = name;
@ -400,6 +401,49 @@ LWSlider::LWSlider(wxWindow *parent,
Init(parent, mName, pos, size, mMinValue, mMaxValue, mStepValue,
true, style, heavyweight, popup, mSpeed, mOrientation);
#else
float minValue, maxValue, stepValue;
float speed = 1.0;
switch(style)
{
case PAN_SLIDER:
minValue = -1.0f;
maxValue = +1.0f;
stepValue = 0.1f;
orientation = wxHORIZONTAL; //v Vertical PAN_SLIDER currently not handled, forced to horizontal.
break;
case DB_SLIDER:
minValue = -36.0f;
if (orientation == wxHORIZONTAL)
maxValue = 36.0f;
else
maxValue = 36.0f; // for MixerBoard //vvv Previously was 6dB for MixerBoard, but identical for now.
stepValue = 1.0f;
speed = 0.5;
break;
case FRAC_SLIDER:
minValue = 0.0f;
maxValue = 1.0f;
stepValue = STEP_CONTINUOUS;
break;
case SPEED_SLIDER:
minValue = 0.01f;
maxValue = 3.0f;
stepValue = STEP_CONTINUOUS;
break;
default:
minValue = 0.0f;
maxValue = 1.0f;
stepValue = 0.0f;
wxASSERT(false); // undefined style
}
Init(parent, name, pos, size, minValue, maxValue, stepValue,
true, style, heavyweight, popup, speed, orientation);
#endif
}
void LWSlider::Init(wxWindow * parent,

View File

@ -123,7 +123,9 @@ class LWSlider
float Get(bool convert = true);
void Set(float value);
#ifdef EXPERIMENTAL_MIDI_OUT
void SetStyle(int style);
#endif
void Increase(float steps);
void Decrease(float steps);

View File

@ -42,7 +42,9 @@ public:
static bool IsGoodInt(const wxString strInt);
static bool IsValidChannel(const int nValue);
#ifdef USE_MIDI
static bool IsValidVisibleChannels(const int nValue);
#endif
static bool IsValidSampleFormat(const int nValue); // true if nValue is one sampleFormat enum values
};