Index: src/Audacity.h =================================================================== --- src/Audacity.h (revision 10825) +++ src/Audacity.h (working copy) @@ -17,6 +17,9 @@ *//********************************************************************/ +#ifndef _AUDACITY_AUDACITY_ +#define _AUDACITY_AUDACITY_ + // Set to 0 for a release version and 1 for a beta version #define IS_BETA 1 @@ -154,3 +157,5 @@ // This macro is used widely, so declared here. #define QUANTIZED_TIME(time, rate) ((double)((sampleCount)floor(((double)(time) * (rate)) + 0.5))) / (rate) + +#endif Index: src/AudioIO.cpp =================================================================== --- src/AudioIO.cpp (revision 10825) +++ src/AudioIO.cpp (working copy) @@ -393,7 +393,10 @@ public: typedef int ExitCode; AudioThread() { mDestroy = false; mThread = NULL; } - virtual ExitCode Entry(); +#ifdef EXPERIMENTAL_MIDI_OUT + virtual +#endif + ExitCode Entry(); void Create() {} void Delete() { mDestroy = true; @@ -426,7 +429,10 @@ class AudioThread : public wxThread { public: AudioThread():wxThread(wxTHREAD_JOINABLE) {} - virtual ExitCode Entry(); +#ifdef EXPERIMENTAL_MIDI_OUT + virtual +#endif + ExitCode Entry(); }; #endif @@ -3267,6 +3273,20 @@ 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. @@ -3282,6 +3302,7 @@ 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. @@ -3291,9 +3312,10 @@ { 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) Index: src/NoteTrack.cpp =================================================================== --- src/NoteTrack.cpp (revision 10825) +++ src/NoteTrack.cpp (working copy) @@ -21,9 +21,9 @@ #include "Audacity.h" +#if defined(USE_MIDI) #include -#if defined(USE_MIDI) #define ROUND(x) ((int) ((x) + 0.5)) #include "AColor.h" @@ -112,9 +112,9 @@ mSerializationLength = 0; mDirManager = projDirManager; - +#ifdef EXPERIMENTAL_MIDI_OUT mGain = 0; - +#endif mBottomNote = 24; mPitchHeight = 5; @@ -164,8 +164,9 @@ duplicate->mLastMidiPosition = mLastMidiPosition; duplicate->mVisibleChannels = mVisibleChannels; duplicate->SetOffset(GetOffset()); +#ifdef EXPERIMENTAL_MIDI_OUT duplicate->SetGain(GetGain()); - +#endif return duplicate; } @@ -769,10 +770,12 @@ 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 @@ 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")); Index: src/widgets/ASlider.h =================================================================== --- src/widgets/ASlider.h (revision 10825) +++ src/widgets/ASlider.h (working copy) @@ -123,7 +123,9 @@ 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); Index: src/widgets/ASlider.cpp =================================================================== --- src/widgets/ASlider.cpp (revision 10825) +++ src/widgets/ASlider.cpp (working copy) @@ -330,7 +330,7 @@ stepValue, canUseShift, style, heavyweight, popup, 1.0, orientation); } - +#ifdef EXPERIMENTAL_MIDI_OUT void LWSlider::SetStyle(int style) { mStyle = style; @@ -380,8 +380,8 @@ wxASSERT(false); // undefined style } } +#endif - // Construct predefined slider LWSlider::LWSlider(wxWindow *parent, wxString name, @@ -393,6 +393,7 @@ 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 @@ 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, Index: src/NoteTrack.h =================================================================== --- src/NoteTrack.h (revision 10825) +++ src/NoteTrack.h (working copy) @@ -18,6 +18,7 @@ #include "effects/TimeWarper.h" #if defined(USE_MIDI) +#include "allegro.h" #include "allegro.h" @@ -95,8 +96,10 @@ 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 +164,10 @@ 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 +202,9 @@ DirManager *mDirManager; +#ifdef EXPERIMENTAL_MIDI_OUT float mGain; // velocity offset +#endif // mBottom is the Y offset of pitch 0 (normally off screen) int mBottom; Index: src/MixerBoard.h =================================================================== --- src/MixerBoard.h (revision 10825) +++ src/MixerBoard.h (working copy) @@ -59,11 +59,11 @@ class AudacityProject; class MixerBoard; +#ifdef EXPERIMENTAL_MIDI_OUT class Track; +class NoteTrack; +#endif class WaveTrack; -#ifdef EXPERIMENTAL_MIDI_OUT - class NoteTrack; -#endif class MixerTrackCluster : public wxPanel { @@ -109,9 +109,11 @@ //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 @@ 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* pLeftTrack, bool bUp); // Up in TrackPanel is left in MixerBoard. + void RemoveTrackCluster(const WaveTrack* pLeftTrack); + + 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* pLeftTrack, 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* pLeftTrack); + void UpdateMute(const WaveTrack* pLeftTrack = NULL); // NULL means update for all tracks. + void UpdateSolo(const WaveTrack* pLeftTrack = NULL); // NULL means update for all tracks. + void UpdatePan(const WaveTrack* pLeftTrack); + void UpdateGain(const WaveTrack* pLeftTrack); +#endif void UpdateMeters(const double t1, const bool bLoopedPlay); @@ -228,8 +250,13 @@ 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 Index: src/TrackPanel.h =================================================================== --- src/TrackPanel.h (revision 10825) +++ src/TrackPanel.h (working copy) @@ -533,10 +533,6 @@ // us to undo the slide and then slide it by another amount double mHSlideAmount; -#ifdef USE_MIDI - NoteTrack *mCapturedNoteClip; -#endif - bool mDidSlideVertically; bool mRedrawAfterStop; Index: src/effects/ScoreAlignDialog.cpp =================================================================== --- src/effects/ScoreAlignDialog.cpp (revision 10825) +++ src/effects/ScoreAlignDialog.cpp (working copy) @@ -1,5 +1,9 @@ + #include "../Audacity.h" +#include "Experimental.h" +#ifdef EXPERIMENTAL_SCOREALIGN + // For compilers that support precompilation, includes "wx/wx.h". #include @@ -262,3 +266,5 @@ EVT_SLIDER(ID_LINETIME, ScoreAlignDialog::OnSlider) EVT_SLIDER(ID_SMOOTHTIME, ScoreAlignDialog::OnSlider) END_EVENT_TABLE() + +#endif Index: src/AudioIO.h =================================================================== --- src/AudioIO.h (revision 10825) +++ src/AudioIO.h (working copy) @@ -21,8 +21,8 @@ #ifdef EXPERIMENTAL_MIDI_OUT #include "portmidi.h" #include "porttime.h" +#include "allegro.h" #endif // EXPERIMENTAL_MIDI_OUT -#include "allegro.h" #endif // USE_MIDI #if USE_PORTMIXER @@ -532,7 +532,9 @@ AudioIOListener* mListener; friend class AudioThread; +#ifdef EXPERIMENTAL_MIDI_OUT friend class MidiThread; +#endif friend void InitAudioIO(); friend void DeinitAudioIO(); Index: src/MixerBoard.cpp =================================================================== --- src/MixerBoard.cpp (revision 10825) +++ src/MixerBoard.cpp (working copy) @@ -25,8 +25,11 @@ #include "NoteTrack.h" #endif #include "Project.h" -#include "Track.h" +// Note: WaveTrack.h is included by Project.h +#ifdef EXPERIMENTAL_MIDI_OUT +#include "NoteTrack.h" +#endif #include "../images/MusicalInstruments.h" #ifdef __WXMSW__ @@ -131,7 +134,7 @@ } #else wxASSERT(pLeftTrack->GetKind() == Track::Wave); - mTrack = mLeftTrack = pLeftTrack; + mLeftTrack = pLeftTrack; #endif mRightTrack = pRightTrack; @@ -145,10 +148,16 @@ // track name wxPoint ctrlPos(kDoubleInset, kDoubleInset); wxSize ctrlSize(size.GetWidth() - kQuadrupleInset, TRACK_NAME_HEIGHT); +#ifdef EXPERIMENTAL_MIDI_OUT wxString name = mTrack->GetName(); mStaticText_TrackName = new wxStaticText(this, -1, name, ctrlPos, ctrlSize, wxALIGN_CENTRE | wxST_NO_AUTORESIZE | wxSUNKEN_BORDER); +#else + mStaticText_TrackName = + 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()); @@ -185,7 +194,11 @@ // 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(name); +#else + wxBitmap* bitmap = mMixerBoard->GetMusicalInstrumentBitmap(mLeftTrack); +#endif wxASSERT(bitmap); mBitmapButton_MusicalInstrument = new wxBitmapButton(this, ID_BITMAPBUTTON_MUSICAL_INSTRUMENT, *bitmap, @@ -246,17 +259,32 @@ (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 + #ifdef EXPERIMENTAL_MIDI_OUT mStaticText_TrackName->SetToolTip(name); + #else + mStaticText_TrackName->SetToolTip(mLeftTrack->GetName()); + #endif mToggleButton_Mute->SetToolTip(_("Mute")); mToggleButton_Solo->SetToolTip(_("Solo")); - mMeter->SetToolTip(_("Signal Level Meter")); + #ifdef EXPERIMENTAL_MIDI_OUT + if (mLeftTrack) + #endif + mMeter->SetToolTip(_("Signal Level Meter")); #endif // wxUSE_TOOLTIPS #ifdef __WXMAC__ @@ -298,24 +326,32 @@ TRACK_NAME_HEIGHT + kDoubleInset + nRequiredHeightAboveMeter; const int nMeterHeight = nGainSliderHeight - nRequiredHeightAboveMeter; + #ifdef EXPERIMENTAL_MIDI_OUT + if (mMeter) + #endif mMeter->SetSize(-1, nMeterY, -1, nMeterHeight); } void MixerTrackCluster::HandleSliderGain(const bool bWantPushState /*= false*/) { float fValue = mSlider_Gain->Get(); +#ifdef EXPERIMENTAL_MIDI_OUT if (mLeftTrack) mLeftTrack->SetGain(fValue); -#ifdef EXPERIMENTAL_MIDI_OUT else mNoteTrack->SetGain(fValue); +#else + mLeftTrack->SetGain(fValue); #endif if (mRightTrack) 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"), true /* consolidate */); } @@ -323,13 +359,19 @@ void MixerTrackCluster::HandleSliderPan(const bool bWantPushState /*= false*/) { float fValue = mSlider_Pan->Get(); +#ifdef EXPERIMENTAL_MIDI_OUT if (mLeftTrack) // test in case track is a NoteTrack +#endif mLeftTrack->SetPan(fValue); if (mRightTrack) 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"), true /* consolidate */); @@ -337,7 +379,9 @@ void MixerTrackCluster::ResetMeter(const bool bResetClipping) { - if (mLeftTrack) +#ifdef EXPERIMENTAL_MIDI_OUT + if (mMeter) +#endif mMeter->Reset(mLeftTrack->GetRate(), bResetClipping); } @@ -354,19 +398,32 @@ void MixerTrackCluster::UpdateName() { - wxString newName = mTrack->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(); @@ -374,7 +431,11 @@ void MixerTrackCluster::UpdateSolo() { +#ifdef EXPERIMENTAL_MIDI_OUT bool bIsSolo = mTrack->GetSolo(); +#else + bool bIsSolo = mLeftTrack->GetSolo(); +#endif if (bIsSolo) mToggleButton_Solo->PushDown(); else @@ -408,15 +469,28 @@ void MixerTrackCluster::UpdateMeter(const double t0, const double t1) { +#ifndef EXPERIMENTAL_MIDI_OUT wxASSERT(mLeftTrack && (mLeftTrack->GetKind() == Track::Wave)); - +#else + // 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; +#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: 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 { this->ResetMeter(false); return; @@ -438,6 +512,12 @@ //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; @@ -558,28 +638,46 @@ 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); + 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. @@ -616,7 +714,11 @@ 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. { @@ -662,8 +764,13 @@ 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()) @@ -674,14 +781,22 @@ } 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. @@ -694,7 +809,11 @@ } else // Update only the changed track. +#ifdef EXPERIMENTAL_MIDI_OUT mProject->RefreshTPTrack(mTrack); +#else + mProject->RefreshTPTrack(mLeftTrack); +#endif } @@ -937,7 +1056,11 @@ // 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 } } @@ -950,11 +1073,20 @@ 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* pLeftTrack, + bool bUp) +#endif { MixerTrackCluster* pMixerTrackCluster; +#ifdef EXPERIMENTAL_MIDI_OUT int nIndex = FindMixerTrackCluster(pTrack, &pMixerTrackCluster); +#else + int nIndex = this->FindMixerTrackCluster(pLeftTrack, &pMixerTrackCluster); +#endif if (pMixerTrackCluster == NULL) return; // Couldn't find it. @@ -965,6 +1097,7 @@ return; // It's already first (0), or not found (-1). pos = pMixerTrackCluster->GetPosition(); + // assume mMixerTrackClusters[nIndex] = mMixerTrackClusters[nIndex - 1]; mMixerTrackClusters[nIndex]->Move(pos); @@ -985,11 +1118,19 @@ } } +#ifdef EXPERIMENTAL_MIDI_OUT void MixerBoard::RemoveTrackCluster(const Track* pTrack) +#else +void MixerBoard::RemoveTrackCluster(const WaveTrack* pLeftTrack) +#endif { // Find and destroy. MixerTrackCluster* pMixerTrackCluster; +#ifdef EXPERIMENTAL_MIDI_OUT int nIndex = FindMixerTrackCluster(pTrack, &pMixerTrackCluster); +#else + int nIndex = this->FindMixerTrackCluster(pLeftTrack, &pMixerTrackCluster); +#endif if (pMixerTrackCluster == NULL) return; // Couldn't find it. @@ -1012,21 +1153,31 @@ 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 } +#ifdef EXPERIMENTAL_MIDI_OUT wxBitmap* MixerBoard::GetMusicalInstrumentBitmap(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; @@ -1073,10 +1224,18 @@ return false; } +#ifdef EXPERIMENTAL_MIDI_OUT void MixerBoard::RefreshTrackCluster(const Track* pTrack, bool bEraseBackground /*= true*/) +#else +void MixerBoard::RefreshTrackCluster(const WaveTrack* pLeftTrack, bool bEraseBackground ) +#endif { MixerTrackCluster* pMixerTrackCluster; +#ifdef EXPERIMENTAL_MIDI_OUT FindMixerTrackCluster(pTrack, &pMixerTrackCluster); +#else + this->FindMixerTrackCluster(pLeftTrack, &pMixerTrackCluster); +#endif if (pMixerTrackCluster) pMixerTrackCluster->Refresh(bEraseBackground); } @@ -1104,17 +1263,33 @@ mMixerTrackClusters[i]->ResetMeter(bResetClipping); } +#ifdef EXPERIMENTAL_MIDI_OUT void MixerBoard::UpdateName(const Track* pTrack) +#else +void MixerBoard::UpdateName(const WaveTrack* pLeftTrack) +#endif { MixerTrackCluster* pMixerTrackCluster; +#ifdef EXPERIMENTAL_MIDI_OUT FindMixerTrackCluster(pTrack, &pMixerTrackCluster); +#else + this->FindMixerTrackCluster(pLeftTrack, &pMixerTrackCluster); +#endif 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* pLeftTrack ) +#endif { +#ifdef EXPERIMENTAL_MIDI_OUT if (pTrack == NULL) +#else + if (pLeftTrack == NULL) +#endif { for (unsigned int i = 0; i < mMixerTrackClusters.GetCount(); i++) mMixerTrackClusters[i]->UpdateMute(); @@ -1122,15 +1297,27 @@ else { MixerTrackCluster* pMixerTrackCluster; +#ifdef EXPERIMENTAL_MIDI_OUT FindMixerTrackCluster(pTrack, &pMixerTrackCluster); +#else + this->FindMixerTrackCluster(pLeftTrack, &pMixerTrackCluster); +#endif if (pMixerTrackCluster) pMixerTrackCluster->UpdateMute(); } } +#ifdef EXPERIMENTAL_MIDI_OUT void MixerBoard::UpdateSolo(const Track* pTrack /*= NULL*/) // NULL means update for all tracks. +#else +void MixerBoard::UpdateSolo(const WaveTrack* pLeftTrack ) +#endif { +#ifdef EXPERIMENTAL_MIDI_OUT if (pTrack == NULL) +#else + if (pLeftTrack == NULL) +#endif { for (unsigned int i = 0; i < mMixerTrackClusters.GetCount(); i++) mMixerTrackClusters[i]->UpdateSolo(); @@ -1138,24 +1325,44 @@ else { MixerTrackCluster* pMixerTrackCluster; +#ifdef EXPERIMENTAL_MIDI_OUT FindMixerTrackCluster(pTrack, &pMixerTrackCluster); +#else + this->FindMixerTrackCluster(pLeftTrack, &pMixerTrackCluster); +#endif if (pMixerTrackCluster) pMixerTrackCluster->UpdateSolo(); } } +#ifdef EXPERIMENTAL_MIDI_OUT void MixerBoard::UpdatePan(const Track* pTrack) +#else +void MixerBoard::UpdatePan(const WaveTrack* pLeftTrack) +#endif { MixerTrackCluster* pMixerTrackCluster; +#ifdef EXPERIMENTAL_MIDI_OUT FindMixerTrackCluster(pTrack, &pMixerTrackCluster); +#else + this->FindMixerTrackCluster(pLeftTrack, &pMixerTrackCluster); +#endif if (pMixerTrackCluster) pMixerTrackCluster->UpdatePan(); } +#ifdef EXPERIMENTAL_MIDI_OUT void MixerBoard::UpdateGain(const Track* pTrack) +#else +void MixerBoard::UpdateGain(const WaveTrack* pLeftTrack) +#endif { MixerTrackCluster* pMixerTrackCluster; +#ifdef EXPERIMENTAL_MIDI_OUT FindMixerTrackCluster(pTrack, &pMixerTrackCluster); +#else + this->FindMixerTrackCluster(pLeftTrack, &pMixerTrackCluster); +#endif if (pMixerTrackCluster) pMixerTrackCluster->UpdateGain(); } @@ -1272,13 +1479,22 @@ 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; Index: src/TrackArtist.cpp =================================================================== --- src/TrackArtist.cpp (revision 10825) +++ src/TrackArtist.cpp (working copy) @@ -52,7 +52,7 @@ 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 @@ -2179,7 +2179,6 @@ 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) Index: src/TrackPanel.cpp =================================================================== --- src/TrackPanel.cpp (revision 10825) +++ src/TrackPanel.cpp (working copy) @@ -1157,6 +1157,7 @@ DoDrawCursor( dc ); } + /// Second level DrawCursor() void TrackPanel::DoDrawCursor(wxDC & dc) { @@ -2586,7 +2587,11 @@ double clickTime = PositionToTime(event.m_x, GetLeftOffset()); bool clickedInSelection = +#ifdef USE_MIDI (vt->GetSelected() && +#else + (wt->GetSelected() && +#endif clickTime > mViewInfo->sel0 && clickTime < mViewInfo->sel1); @@ -2604,10 +2609,17 @@ } else { mCapturedClipIsSelection = false; +#ifdef USE_MIDI mCapturedClipArray.Add(TrackClip(vt, mCapturedClip)); - +#else + mCapturedClipArray.Add(TrackClip(wt, mCapturedClip)); +#endif // Check for stereo partner +#ifdef USE_MIDI Track *partner = mTracks->GetLink(vt); +#else + Track *partner = mTracks->GetLink(wt); +#endif if (partner && partner->GetKind() == Track::Wave) { WaveClip *clip = ((WaveTrack *)partner)->GetClipAtX(event.m_x); if (clip) { @@ -2824,8 +2836,7 @@ clipRight = mCapturedTrack->GetEndTime() + desiredSlideAmount; } #else - desiredSlideAmount = rint(mouseTrack->GetRate() * desiredSlideAmount) / - mouseTrack->GetRate(); // set it to a sample point + desiredSlideAmount = rint(mouseTrack->GetRate() * desiredSlideAmount) / mouseTrack->GetRate(); // set it to a sample point if (mSnapManager && mCapturedClip) { double clipLeft = mCapturedClip->GetStartTime() + desiredSlideAmount; double clipRight = mCapturedClip->GetEndTime() + desiredSlideAmount; @@ -2889,7 +2900,10 @@ // See if it can be moved if (MoveClipToTrack(mCapturedClip, (WaveTrack*)mCapturedTrack, - (WaveTrack*)mouseTrack)) { +#ifdef USE_MIDI + (WaveTrack*) +#endif + mouseTrack)) { mCapturedTrack = mouseTrack; mDidSlideVertically = true; @@ -3150,13 +3164,12 @@ if (!mCapturedTrack) return; +#ifdef USE_MIDI // 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 - || mCapturedTrack->GetKind() == Track::Note -#endif - ) { + && ((WaveTrack *) mCapturedTrack)->GetDisplay() <= + WaveTrack::SpectrumLogDisplay) + || mCapturedTrack->GetKind() == Track::Note) { mMouseCapture = IsVZooming; mZoomStart = event.m_y; mZoomEnd = event.m_y; @@ -3167,6 +3180,16 @@ // } //#endif } +#else + // don't do anything if track is not wave or Spectrum/log Spectrum + if (mCapturedTrack->GetKind() != Track::Wave + || ((WaveTrack *) mCapturedTrack)->GetDisplay() > WaveTrack::SpectrumLogDisplay) + return; + mMouseCapture = IsVZooming; + mZoomStart = event.m_y; + mZoomEnd = event.m_y; +#endif + } /// VZoom drag @@ -3240,7 +3263,9 @@ int fftSkipPoints=0; #endif //EXPERIMENTAL_FFT_SKIP_POINTS double rate = ((WaveTrack *)track)->GetRate(); - spectrum = ((WaveTrack *) track)->GetDisplay() == WaveTrack::SpectrumDisplay; + ((WaveTrack *) track)->GetDisplay() == WaveTrack::SpectrumDisplay ? spectrum = true : spectrum = false; + // The previous line could be rewritten as follows: + // spectrum = ((WaveTrack *) track)->GetDisplay() == WaveTrack::SpectrumDisplay; spectrumLog=(((WaveTrack *) track)->GetDisplay() == WaveTrack::SpectrumLogDisplay); if(spectrum) { min = mTrackArtist->GetSpectrumMinFreq(0); @@ -3999,7 +4024,7 @@ 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 @@ -4220,14 +4245,26 @@ 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); +#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); +#endif } else { @@ -5364,7 +5401,8 @@ mRefreshBacking = true; } - Refresh( false, &r ); + // force full redraw in order to update indicator during play + Refresh(false); } @@ -5519,10 +5557,13 @@ 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); } Index: src/xml/XMLTagHandler.h =================================================================== --- src/xml/XMLTagHandler.h (revision 10825) +++ src/xml/XMLTagHandler.h (working copy) @@ -42,7 +42,9 @@ 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 }; Index: src/Menus.cpp =================================================================== --- src/Menus.cpp (revision 10825) +++ src/Menus.cpp (working copy) @@ -3674,14 +3674,13 @@ Track *n = iter.First(); while (n) { +#if defined(USE_MIDI) if (n->GetSelected()) { switch (n->GetKind()) { -#if defined(USE_MIDI) case Track::Note: ((NoteTrack*)n)->Trim(mViewInfo.sel0, mViewInfo.sel1); break; -#endif case Track::Wave: //Delete the section before the left selector @@ -3692,5 +3691,11 @@ break; } } +#else + if ((n->GetKind() == Track::Wave) && n->GetSelected()) { + //Delete the section before the left selector + ((WaveTrack*)n)->Trim(mViewInfo.sel0, mViewInfo.sel1); + } +#endif n = iter.Next(); }