From 43790cfa568ad367020afdd199678449f398db4a Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Fri, 26 Feb 2016 18:10:45 -0500 Subject: [PATCH] std::vector for wave track pointers; remove deprecated TrackList function; ... ... and some more uses of const --- src/AudioIO.cpp | 76 ++++++++++++++++----------------- src/AutoRecovery.cpp | 12 +++--- src/Mix.cpp | 27 +++++------- src/Mix.h | 15 ++++--- src/Project.cpp | 6 +-- src/Track.cpp | 65 ++++++++++++---------------- src/Track.h | 19 ++++++--- src/effects/Effect.cpp | 2 +- src/export/Export.cpp | 18 ++++---- src/export/Export.h | 7 +-- src/export/ExportCL.cpp | 10 ++--- src/export/ExportFFmpeg.cpp | 10 ++--- src/export/ExportFLAC.cpp | 10 ++--- src/export/ExportMP2.cpp | 10 ++--- src/export/ExportMP3.cpp | 10 ++--- src/export/ExportMultiple.cpp | 26 +++++------ src/export/ExportMultiple.h | 3 -- src/export/ExportOGG.cpp | 10 ++--- src/export/ExportPCM.cpp | 11 ++--- src/toolbars/ControlToolBar.cpp | 16 ++++--- 20 files changed, 173 insertions(+), 190 deletions(-) diff --git a/src/AudioIO.cpp b/src/AudioIO.cpp index 7cc7fac73..a2ad3705e 100644 --- a/src/AudioIO.cpp +++ b/src/AudioIO.cpp @@ -1562,7 +1562,7 @@ int AudioIO::StartStream(WaveTrackArray playbackTracks, double minScrubStutter = options.minScrubStutter; if (scrubbing) { - if (mCaptureTracks->GetCount() > 0 || + if (mCaptureTracks->size() > 0 || mPlayMode == PLAY_LOOPED || mTimeTrack != NULL || options.maxScrubSpeed < GetMinScrubSpeed()) @@ -1624,23 +1624,23 @@ int AudioIO::StartStream(WaveTrackArray playbackTracks, // Capacity of the playback buffer. mPlaybackRingBufferSecs = 10.0; - mCaptureRingBufferSecs = 4.5 + 0.5 * std::min(size_t(16), mCaptureTracks->GetCount()); - mMinCaptureSecsToCopy = 0.2 + 0.2 * std::min(size_t(16), mCaptureTracks->GetCount()); + mCaptureRingBufferSecs = 4.5 + 0.5 * std::min(size_t(16), mCaptureTracks->size()); + mMinCaptureSecsToCopy = 0.2 + 0.2 * std::min(size_t(16), mCaptureTracks->size()); unsigned int playbackChannels = 0; unsigned int captureChannels = 0; sampleFormat captureFormat = floatSample; - if( playbackTracks.GetCount() > 0 ) + if( playbackTracks.size() > 0 ) playbackChannels = 2; if (mSoftwarePlaythrough) playbackChannels = 2; - if( captureTracks.GetCount() > 0 ) + if( captureTracks.size() > 0 ) { // For capture, every input channel gets its own track - captureChannels = mCaptureTracks->GetCount(); + captureChannels = mCaptureTracks->size(); // I don't deal with the possibility of the capture tracks // having different sample formats, since it will never happen // with the current code. This code wouldn't *break* if this @@ -1710,12 +1710,12 @@ int AudioIO::StartStream(WaveTrackArray playbackTracks, return 0; } - mPlaybackBuffers = new RingBuffer* [mPlaybackTracks->GetCount()]; - mPlaybackMixers = new Mixer* [mPlaybackTracks->GetCount()]; + mPlaybackBuffers = new RingBuffer* [mPlaybackTracks->size()]; + mPlaybackMixers = new Mixer* [mPlaybackTracks->size()]; // Set everything to zero in case we have to DELETE these due to a memory exception. - memset(mPlaybackBuffers, 0, sizeof(RingBuffer*)*mPlaybackTracks->GetCount()); - memset(mPlaybackMixers, 0, sizeof(Mixer*)*mPlaybackTracks->GetCount()); + memset(mPlaybackBuffers, 0, sizeof(RingBuffer*)*mPlaybackTracks->size()); + memset(mPlaybackMixers, 0, sizeof(Mixer*)*mPlaybackTracks->size()); const Mixer::WarpOptions &warpOptions = #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT @@ -1723,12 +1723,12 @@ int AudioIO::StartStream(WaveTrackArray playbackTracks, #endif Mixer::WarpOptions(mTimeTrack); - for (unsigned int i = 0; i < mPlaybackTracks->GetCount(); i++) + for (unsigned int i = 0; i < mPlaybackTracks->size(); i++) { mPlaybackBuffers[i] = new RingBuffer(floatSample, playbackBufferSize); // MB: use normal time for the end time, not warped time! - mPlaybackMixers[i] = new Mixer(1, &(*mPlaybackTracks)[i], + mPlaybackMixers[i] = new Mixer(WaveTrackConstArray{ (*mPlaybackTracks)[i] }, warpOptions, mT0, mT1, 1, playbackMixBufferSize, false, @@ -1752,15 +1752,15 @@ int AudioIO::StartStream(WaveTrackArray playbackTracks, return 0; } - mCaptureBuffers = new RingBuffer* [mCaptureTracks->GetCount()]; - mResample = new Resample* [mCaptureTracks->GetCount()]; + mCaptureBuffers = new RingBuffer* [mCaptureTracks->size()]; + mResample = new Resample* [mCaptureTracks->size()]; mFactor = sampleRate / mRate; // Set everything to zero in case we have to DELETE these due to a memory exception. - memset(mCaptureBuffers, 0, sizeof(RingBuffer*)*mCaptureTracks->GetCount()); - memset(mResample, 0, sizeof(Resample*)*mCaptureTracks->GetCount()); + memset(mCaptureBuffers, 0, sizeof(RingBuffer*)*mCaptureTracks->size()); + memset(mResample, 0, sizeof(Resample*)*mCaptureTracks->size()); - for( unsigned int i = 0; i < mCaptureTracks->GetCount(); i++ ) + for( unsigned int i = 0; i < mCaptureTracks->size(); i++ ) { mCaptureBuffers[i] = new RingBuffer( (*mCaptureTracks)[i]->GetSampleFormat(), captureBufferSize ); @@ -1790,7 +1790,7 @@ int AudioIO::StartStream(WaveTrackArray playbackTracks, // group determination should mimic what is done in audacityAudioCallback() // when calling RealtimeProcess(). int group = 0; - for (size_t i = 0, cnt = mPlaybackTracks->GetCount(); i < cnt; i++) + for (size_t i = 0, cnt = mPlaybackTracks->size(); i < cnt; i++) { WaveTrack *vt = (*gAudioIO->mPlaybackTracks)[i]; @@ -1814,7 +1814,7 @@ int AudioIO::StartStream(WaveTrackArray playbackTracks, // Calculate the NEW time position mTime = std::max(mT0, std::min(mT1, *options.pStartTime)); // Reset mixer positions for all playback tracks - unsigned numMixers = mPlaybackTracks->GetCount(); + unsigned numMixers = mPlaybackTracks->size(); for (unsigned ii = 0; ii < numMixers; ++ii) mPlaybackMixers[ii]->Reposition(mTime); if(mTimeTrack) @@ -1918,7 +1918,7 @@ void AudioIO::StartStreamCleanup(bool bOnlyBuffers) if(mPlaybackBuffers) { - for( unsigned int i = 0; i < mPlaybackTracks->GetCount(); i++ ) + for (unsigned int i = 0; i < mPlaybackTracks->size(); i++) delete mPlaybackBuffers[i]; delete [] mPlaybackBuffers; mPlaybackBuffers = NULL; @@ -1926,7 +1926,7 @@ void AudioIO::StartStreamCleanup(bool bOnlyBuffers) if(mPlaybackMixers) { - for( unsigned int i = 0; i < mPlaybackTracks->GetCount(); i++ ) + for (unsigned int i = 0; i < mPlaybackTracks->size(); i++) delete mPlaybackMixers[i]; delete [] mPlaybackMixers; mPlaybackMixers = NULL; @@ -1934,7 +1934,7 @@ void AudioIO::StartStreamCleanup(bool bOnlyBuffers) if(mCaptureBuffers) { - for( unsigned int i = 0; i < mCaptureTracks->GetCount(); i++ ) + for (unsigned int i = 0; i < mCaptureTracks->size(); i++) delete mCaptureBuffers[i]; delete [] mCaptureBuffers; mCaptureBuffers = NULL; @@ -1942,7 +1942,7 @@ void AudioIO::StartStreamCleanup(bool bOnlyBuffers) if(mResample) { - for( unsigned int i = 0; i < mCaptureTracks->GetCount(); i++ ) + for (unsigned int i = 0; i < mCaptureTracks->size(); i++) delete mResample[i]; delete [] mResample; mResample = NULL; @@ -2267,9 +2267,9 @@ void AudioIO::StopStream() // we allocated in StartStream() // - if( mPlaybackTracks->GetCount() > 0 ) + if (mPlaybackTracks->size() > 0) { - for( unsigned int i = 0; i < mPlaybackTracks->GetCount(); i++ ) + for (unsigned int i = 0; i < mPlaybackTracks->size(); i++) { delete mPlaybackBuffers[i]; delete mPlaybackMixers[i]; @@ -2282,7 +2282,7 @@ void AudioIO::StopStream() // // Offset all recorded tracks to account for latency // - if( mCaptureTracks->GetCount() > 0 ) + if (mCaptureTracks->size() > 0) { // // We only apply latency correction when we actually played back @@ -2297,7 +2297,7 @@ void AudioIO::StopStream() double recordingOffset = mLastRecordingOffset + latencyCorrection / 1000.0; - for( unsigned int i = 0; i < mCaptureTracks->GetCount(); i++ ) + for (unsigned int i = 0; i < mCaptureTracks->size(); i++) { delete mCaptureBuffers[i]; delete mResample[i]; @@ -2305,14 +2305,14 @@ void AudioIO::StopStream() WaveTrack* track = (*mCaptureTracks)[i]; track->Flush(); - if (mPlaybackTracks->GetCount() > 0) + if (mPlaybackTracks->size() > 0) { // only do latency correction if some tracks are being played back WaveTrackArray playbackTracks; AudacityProject *p = GetActiveProject(); // we need to get this as mPlaybackTracks does not contain tracks being recorded into playbackTracks = p->GetTracks()->GetWaveTrackArray(false); bool appendRecord = false; - for( unsigned int j = 0; j < playbackTracks.GetCount(); j++) + for (unsigned int j = 0; j < playbackTracks.size(); j++) { // find if we are recording into an existing track (append-record) WaveTrack* trackP = playbackTracks[j]; if( track == trackP ) @@ -2873,7 +2873,7 @@ int AudioIO::GetCommonlyAvailPlayback() int commonlyAvail = mPlaybackBuffers[0]->AvailForPut(); unsigned int i; - for( i = 1; i < mPlaybackTracks->GetCount(); i++ ) + for (i = 1; i < mPlaybackTracks->size(); i++) { int thisBlockAvail = mPlaybackBuffers[i]->AvailForPut(); @@ -2889,7 +2889,7 @@ int AudioIO::GetCommonlyAvailCapture() int commonlyAvail = mCaptureBuffers[0]->AvailForGet(); unsigned int i; - for( i = 1; i < mCaptureTracks->GetCount(); i++ ) + for (i = 1; i < mCaptureTracks->size(); i++) { int avail = mCaptureBuffers[i]->AvailForGet(); if( avail < commonlyAvail ) @@ -3268,7 +3268,7 @@ void AudioIO::FillBuffers() { unsigned int i; - if( mPlaybackTracks->GetCount() > 0 ) + if (mPlaybackTracks->size() > 0) { // Though extremely unlikely, it is possible that some buffers // will have more samples available than others. This could happen @@ -3325,7 +3325,7 @@ void AudioIO::FillBuffers() mWarpedTime += deltat; } - for( i = 0; i < mPlaybackTracks->GetCount(); i++ ) + for (i = 0; i < mPlaybackTracks->size(); i++) { // The mixer here isn't actually mixing: it's just doing // resampling, format conversion, and possibly time track @@ -3395,7 +3395,7 @@ void AudioIO::FillBuffers() startTime = startSample / mRate; endTime = endSample / mRate; speed = double(abs(endSample - startSample)) / mScrubDuration; - for (i = 0; i < mPlaybackTracks->GetCount(); i++) + for (i = 0; i < mPlaybackTracks->size(); i++) mPlaybackMixers[i]->SetTimesAndSpeed(startTime, endTime, speed); } } @@ -3410,7 +3410,7 @@ void AudioIO::FillBuffers() // and if yes, restart from the beginning. if (mWarpedTime >= mWarpedLength) { - for (i = 0; i < mPlaybackTracks->GetCount(); i++) + for (i = 0; i < mPlaybackTracks->size(); i++) mPlaybackMixers[i]->Restart(); mWarpedTime = 0.0; } @@ -3424,7 +3424,7 @@ void AudioIO::FillBuffers() } } // end of playback buffering - if( mCaptureTracks->GetCount() > 0 ) // start record buffering + if (mCaptureTracks->size() > 0) // start record buffering { int commonlyAvail = GetCommonlyAvailCapture(); @@ -3439,7 +3439,7 @@ void AudioIO::FillBuffers() // Append captured samples to the end of the WaveTracks. // The WaveTracks have their own buffering for efficiency. AutoSaveFile blockFileLog; - int numChannels = mCaptureTracks->GetCount(); + int numChannels = mCaptureTracks->size(); for( i = 0; (int)i < numChannels; i++ ) { @@ -3948,7 +3948,7 @@ int audacityAudioCallback(const void *inputBuffer, void *outputBuffer, const PaStreamCallbackFlags WXUNUSED(statusFlags), void * WXUNUSED(userData) ) { int numPlaybackChannels = gAudioIO->mNumPlaybackChannels; - int numPlaybackTracks = gAudioIO->mPlaybackTracks->GetCount(); + int numPlaybackTracks = gAudioIO->mPlaybackTracks->size(); int numCaptureChannels = gAudioIO->mNumCaptureChannels; int callbackReturn = paContinue; void *tempBuffer = alloca(framesPerBuffer*sizeof(float)* diff --git a/src/AutoRecovery.cpp b/src/AutoRecovery.cpp index a1da1ac61..0af767d4e 100644 --- a/src/AutoRecovery.cpp +++ b/src/AutoRecovery.cpp @@ -287,7 +287,7 @@ int RecordingRecoveryHandler::FindTrack() const int index; if (mAutoSaveIdent) { - for (index = 0; index < (int)tracks.GetCount(); index++) + for (index = 0; index < (int)tracks.size(); index++) { if (tracks[index]->GetAutoSaveIdent() == mAutoSaveIdent) { @@ -297,7 +297,7 @@ int RecordingRecoveryHandler::FindTrack() const } else { - index = tracks.GetCount() - mNumChannels + mChannel; + index = tracks.size() - mNumChannels + mChannel; } return index; @@ -320,14 +320,14 @@ bool RecordingRecoveryHandler::HandleXMLTag(const wxChar *tag, int index = FindTrack(); // We need to find the track and sequence where the blockfile belongs - if (index < 0 || index >= (int) tracks.GetCount()) + if (index < 0 || index >= (int)tracks.size()) { // This should only happen if there is a bug wxASSERT(false); return false; } - WaveTrack* track = tracks.Item(index); + WaveTrack* track = tracks[index]; WaveClip* clip = track->NewestOrNewClip(); Sequence* seq = clip->GetSequence(); @@ -407,12 +407,12 @@ void RecordingRecoveryHandler::HandleXMLEndTag(const wxChar *tag) int index = FindTrack(); // We need to find the track and sequence where the blockfile belongs - if (index < 0 || index >= (int)tracks.GetCount()) { + if (index < 0 || index >= (int)tracks.size()) { // This should only happen if there is a bug wxASSERT(false); } else { - WaveTrack* track = tracks.Item(index); + WaveTrack* track = tracks[index]; WaveClip* clip = track->NewestOrNewClip(); Sequence* seq = clip->GetSequence(); diff --git a/src/Mix.cpp b/src/Mix.cpp index 4ce0cef02..24b0295f5 100644 --- a/src/Mix.cpp +++ b/src/Mix.cpp @@ -49,14 +49,10 @@ bool MixAndRender(TrackList *tracks, TrackFactory *trackFactory, WaveTrack **newLeft, WaveTrack **newRight) { // This function was formerly known as "Quick Mix". - WaveTrack **waveArray; Track *t; - int numWaves = 0; /* number of wave tracks in the selection */ - int numMono = 0; /* number of mono, centre-panned wave tracks in selection*/ bool mono = false; /* flag if output can be mono without loosing anything*/ bool oneinput = false; /* flag set to true if there is only one input track (mono or stereo) */ - int w; TrackListIterator iter(tracks); SelectedTrackListOfKindIterator usefulIter(Track::Wave, tracks); @@ -64,6 +60,8 @@ bool MixAndRender(TrackList *tracks, TrackFactory *trackFactory, // selected WaveTracks. The tracklist is (confusingly) the list of all // tracks in the project + int numWaves = 0; /* number of wave tracks in the selection */ + int numMono = 0; /* number of mono, centre-panned wave tracks in selection*/ t = iter.First(); while (t) { if (t->GetSelected() && t->GetKind() == Track::Wave) { @@ -89,13 +87,12 @@ bool MixAndRender(TrackList *tracks, TrackFactory *trackFactory, double mixEndTime = 0.0; /* end time of last track to end */ double tstart, tend; // start and end times for one track. - waveArray = new WaveTrack *[numWaves]; - w = 0; + WaveTrackConstArray waveArray; t = iter.First(); while (t) { if (t->GetSelected() && t->GetKind() == Track::Wave) { - waveArray[w++] = (WaveTrack *) t; + waveArray.push_back(static_cast(t)); tstart = t->GetStartTime(); tend = t->GetEndTime(); if (tend > mixEndTime) @@ -161,7 +158,7 @@ bool MixAndRender(TrackList *tracks, TrackFactory *trackFactory, endTime = mixEndTime; } - Mixer mixer(numWaves, waveArray, + Mixer mixer(waveArray, Mixer::WarpOptions(tracks->GetTimeTrack()), startTime, endTime, mono ? 1 : 2, maxBlockLen, false, rate, format); @@ -221,9 +218,6 @@ bool MixAndRender(TrackList *tracks, TrackFactory *trackFactory, printf("Max number of tracks to mix in real time: %f\n", maxTracks); #endif } - - delete[] waveArray; - return (updateResult == eProgressSuccess || updateResult == eProgressStopped); } @@ -247,7 +241,7 @@ Mixer::WarpOptions::WarpOptions(double min, double max) } } -Mixer::Mixer(int numInputTracks, WaveTrack **inputTracks, +Mixer::Mixer(const WaveTrackConstArray &inputTracks, const WarpOptions &warpOptions, double startTime, double stopTime, int numOutChannels, int outBufferSize, bool outInterleaved, @@ -256,9 +250,10 @@ Mixer::Mixer(int numInputTracks, WaveTrack **inputTracks, { int i; + const auto numInputTracks = inputTracks.size(); mHighQuality = highQuality; mNumInputTracks = numInputTracks; - mInputTrack = new WaveTrack*[mNumInputTracks]; + mInputTrack = new const WaveTrack*[mNumInputTracks]; // mSamplePos holds for each track the next sample position not // yet processed. @@ -415,7 +410,7 @@ void MixBuffers(int numChannels, int *channelFlags, float *gains, } } -sampleCount Mixer::MixVariableRates(int *channelFlags, WaveTrack *track, +sampleCount Mixer::MixVariableRates(int *channelFlags, const WaveTrack *track, sampleCount *pos, float *queue, int *queueStart, int *queueLen, Resample * pResample) @@ -565,7 +560,7 @@ sampleCount Mixer::MixVariableRates(int *channelFlags, WaveTrack *track, return out; } -sampleCount Mixer::MixSameRate(int *channelFlags, WaveTrack *track, +sampleCount Mixer::MixSameRate(int *channelFlags, const WaveTrack *track, sampleCount *pos) { int slen = mMaxOut; @@ -639,7 +634,7 @@ sampleCount Mixer::Process(sampleCount maxToProcess) Clear(); for(i=0; iImport(strAttr, &trackArray); - if (trackArray.IsEmpty()) + if (trackArray.empty()) return false; // Handle other attributes, now that we have the tracks. @@ -461,7 +461,7 @@ bool ImportXMLTagHandler::HandleXMLTag(const wxChar *tag, const wxChar **attrs) const wxChar** pAttr; bool bSuccess = true; - for (size_t i = 0; i < trackArray.GetCount(); i++) + for (size_t i = 0; i < trackArray.size(); i++) { // Most of the "import" tag attributes are the same as for "wavetrack" tags, // so apply them via WaveTrack::HandleXMLTag(). @@ -3822,7 +3822,7 @@ bool AudacityProject::Import(const wxString &fileName, WaveTrackArray* pTrackArr if (pTrackArray) { for (int i = 0; i < numTracks; i++) { if (newTracks[i]->GetKind() == Track::Wave) { - pTrackArray->Add((WaveTrack *)newTracks[i]); + pTrackArray->push_back(static_cast(newTracks[i])); } } } diff --git a/src/Track.cpp b/src/Track.cpp index fa35a8d87..f536e0981 100644 --- a/src/Track.cpp +++ b/src/Track.cpp @@ -1153,15 +1153,20 @@ TimeTrack *TrackList::GetTimeTrack() return NULL; } -int TrackList::GetNumExportChannels(bool selectionOnly) +const TimeTrack *TrackList::GetTimeTrack() const +{ + return const_cast(this)->GetTimeTrack(); +} + +int TrackList::GetNumExportChannels(bool selectionOnly) const { /* counters for tracks panned different places */ int numLeft = 0; int numRight = 0; int numMono = 0; /* track iteration kit */ - Track *tr; - TrackListIterator iter; + const Track *tr; + TrackListConstIterator iter; for (tr = iter.First(this); tr != NULL; tr = iter.Next()) { @@ -1214,48 +1219,34 @@ int TrackList::GetNumExportChannels(bool selectionOnly) return 1; } -void TrackList::GetWaveTracks(bool selectionOnly, - int *num, WaveTrack ***tracks) -{ - int i; - *num = 0; +namespace { + template + Array GetWaveTracks(TrackListNode *p, bool selectionOnly, bool includeMuted) + { + Array waveTrackArray; - TrackListNode *p = head; - while (p) { - if (p->t->GetKind() == Track::Wave && !(p->t->GetMute()) && - (p->t->GetSelected() || !selectionOnly)) { - (*num)++; - } - p = p->next; - } + while (p) { + if (p->t->GetKind() == Track::Wave && + (includeMuted || !p->t->GetMute()) && + (p->t->GetSelected() || !selectionOnly)) { + waveTrackArray.push_back(static_cast(p->t)); + } - *tracks = new WaveTrack*[*num]; - p = head; - i = 0; - while (p) { - if (p->t->GetKind() == Track::Wave && !(p->t->GetMute()) && - (p->t->GetSelected() || !selectionOnly)) { - (*tracks)[i++] = (WaveTrack *)p->t; + p = p->next; } - p = p->next; + + return waveTrackArray; } } -WaveTrackArray TrackList::GetWaveTrackArray(bool selectionOnly) +WaveTrackArray TrackList::GetWaveTrackArray(bool selectionOnly, bool includeMuted) { - WaveTrackArray waveTrackArray; + return GetWaveTracks(head, selectionOnly, includeMuted); +} - TrackListNode *p = head; - while (p) { - if (p->t->GetKind() == Track::Wave && - (p->t->GetSelected() || !selectionOnly)) { - waveTrackArray.Add((WaveTrack*)p->t); - } - - p = p->next; - } - - return waveTrackArray; +WaveTrackConstArray TrackList::GetWaveTrackConstArray(bool selectionOnly, bool includeMuted) const +{ + return GetWaveTracks(head, selectionOnly, includeMuted); } #if defined(USE_MIDI) diff --git a/src/Track.h b/src/Track.h index 56c3b5a37..f19515d29 100644 --- a/src/Track.h +++ b/src/Track.h @@ -13,6 +13,7 @@ #include "Audacity.h" +#include #include #include #include @@ -37,7 +38,15 @@ class AudacityProject; class ZoomInfo; WX_DEFINE_USER_EXPORTED_ARRAY(Track*, TrackArray, class AUDACITY_DLL_API); -WX_DEFINE_USER_EXPORTED_ARRAY(WaveTrack*, WaveTrackArray, class AUDACITY_DLL_API); +class WaveTrackArray : public std::vector < WaveTrack* > { +}; +class WaveTrackConstArray : public std::vector < const WaveTrack* > { +public: + WaveTrackConstArray() {} + // I'd like to use an inherited constructor, but that's not here yet in MSVC compiler... + WaveTrackConstArray + (std::initializer_list tracks) : std::vector(tracks) {} +}; #if defined(USE_MIDI) class NoteTrack; @@ -417,6 +426,7 @@ class AUDACITY_DLL_API TrackList final : public wxEvtHandler bool Move(Track * t, bool up) { return up ? MoveUp(t) : MoveDown(t); } TimeTrack *GetTimeTrack(); + const TimeTrack *GetTimeTrack() const; /** \brief Find out how many channels this track list mixes to * @@ -424,11 +434,10 @@ class AUDACITY_DLL_API TrackList final : public wxEvtHandler * Mono, Stereo etc. @param selectionOnly Whether to consider the entire track * list or only the selected members of it */ - int GetNumExportChannels(bool selectionOnly); + int GetNumExportChannels(bool selectionOnly) const; - WaveTrackArray GetWaveTrackArray(bool selectionOnly); - /** Consider this function depricated in favor of GetWaveTrackArray */ - void GetWaveTracks(bool selectionOnly, int *num, WaveTrack ***tracks); + WaveTrackArray GetWaveTrackArray(bool selectionOnly, bool includeMuted = true); + WaveTrackConstArray GetWaveTrackConstArray(bool selectionOnly, bool includeMuted = true) const; #if defined(USE_MIDI) NoteTrackArray GetNoteTrackArray(bool selectionOnly); diff --git a/src/effects/Effect.cpp b/src/effects/Effect.cpp index 989aa9be5..86eb6920f 100644 --- a/src/effects/Effect.cpp +++ b/src/effects/Effect.cpp @@ -2641,7 +2641,7 @@ void Effect::Preview(bool dryOnly) SelectedTrackListOfKindIterator iter(Track::Wave, mTracks); WaveTrack *src = (WaveTrack *) iter.First(); while (src) { - playbackTracks.Add(src); + playbackTracks.push_back(src); src = (WaveTrack *) iter.Next(); } // Some effects (Paulstretch) may need to generate more diff --git a/src/export/Export.cpp b/src/export/Export.cpp index e5e6ac06a..7c4860de9 100644 --- a/src/export/Export.cpp +++ b/src/export/Export.cpp @@ -243,15 +243,15 @@ wxWindow *ExportPlugin::OptionsCreate(wxWindow *parent, int WXUNUSED(format)) } //Create a mixer by computing the time warp factor -Mixer* ExportPlugin::CreateMixer(int numInputTracks, WaveTrack **inputTracks, - TimeTrack *timeTrack, +Mixer* ExportPlugin::CreateMixer(const WaveTrackConstArray &inputTracks, + const TimeTrack *timeTrack, double startTime, double stopTime, int numOutChannels, int outBufferSize, bool outInterleaved, double outRate, sampleFormat outFormat, bool highQuality, MixerSpec *mixerSpec) { // MB: the stop time should not be warped, this was a bug. - return new Mixer(numInputTracks, inputTracks, + return new Mixer(inputTracks, Mixer::WarpOptions(timeTrack), startTime, stopTime, numOutChannels, outBufferSize, outInterleaved, @@ -431,9 +431,9 @@ bool Exporter::ExamineTracks() double earliestBegin = mT1; double latestEnd = mT0; - TrackList *tracks = mProject->GetTracks(); - TrackListIterator iter1(tracks); - Track *tr = iter1.First(); + const TrackList *tracks = mProject->GetTracks(); + TrackListConstIterator iter1(tracks); + const Track *tr = iter1.First(); while (tr) { if (tr->GetKind() == Track::Wave) { @@ -1148,7 +1148,7 @@ BEGIN_EVENT_TABLE( ExportMixerDialog,wxDialog ) EVT_SLIDER( ID_SLIDER_CHANNEL, ExportMixerDialog::OnSlider ) END_EVENT_TABLE() -ExportMixerDialog::ExportMixerDialog( TrackList *tracks, bool selectedOnly, +ExportMixerDialog::ExportMixerDialog( const TrackList *tracks, bool selectedOnly, int maxNumChannels, wxWindow *parent, wxWindowID id, const wxString &title, const wxPoint &position, const wxSize& size, long style ) : wxDialog( parent, id, title, position, size, style | wxRESIZE_BORDER ) @@ -1156,9 +1156,9 @@ ExportMixerDialog::ExportMixerDialog( TrackList *tracks, bool selectedOnly, SetName(GetTitle()); int numTracks = 0; - TrackListIterator iter( tracks ); + TrackListConstIterator iter( tracks ); - for( Track *t = iter.First(); t; t = iter.Next() ) + for( const Track *t = iter.First(); t; t = iter.Next() ) { if( t->GetKind() == Track::Wave && ( t->GetSelected() || !selectedOnly ) && !t->GetMute() ) { diff --git a/src/export/Export.h b/src/export/Export.h index b8611e2c0..9bd50b1be 100644 --- a/src/export/Export.h +++ b/src/export/Export.h @@ -30,6 +30,7 @@ class TrackList; class MixerSpec; class TimeTrack; class Mixer; +class WaveTrackConstArray; class AUDACITY_DLL_API FormatInfo { @@ -114,8 +115,8 @@ public: int subformat = 0) = 0; protected: - Mixer* CreateMixer(int numInputTracks, WaveTrack **inputTracks, - TimeTrack *timeTrack, + Mixer* CreateMixer(const WaveTrackConstArray &inputTracks, + const TimeTrack *timeTrack, double startTime, double stopTime, int numOutChannels, int outBufferSize, bool outInterleaved, double outRate, sampleFormat outFormat, @@ -232,7 +233,7 @@ class ExportMixerDialog final : public wxDialog { public: // constructors and destructors - ExportMixerDialog( TrackList * tracks, bool selectedOnly, int maxNumChannels, + ExportMixerDialog( const TrackList * tracks, bool selectedOnly, int maxNumChannels, wxWindow *parent, wxWindowID id, const wxString &title, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, diff --git a/src/export/ExportCL.cpp b/src/export/ExportCL.cpp index c60685deb..ba29ae165 100644 --- a/src/export/ExportCL.cpp +++ b/src/export/ExportCL.cpp @@ -419,11 +419,10 @@ int ExportCL::Export(AudacityProject *project, os->Write(&header, sizeof(wav_header)); // Mix 'em up - int numWaveTracks; - WaveTrack **waveTracks; - TrackList *tracks = project->GetTracks(); - tracks->GetWaveTracks(selectionOnly, &numWaveTracks, &waveTracks); - Mixer *mixer = CreateMixer(numWaveTracks, + const TrackList *tracks = project->GetTracks(); + const WaveTrackConstArray waveTracks = + tracks->GetWaveTrackConstArray(selectionOnly, false); + Mixer *mixer = CreateMixer( waveTracks, tracks->GetTimeTrack(), t0, @@ -529,7 +528,6 @@ int ExportCL::Export(AudacityProject *project, // Clean up delete mixer; - delete[] waveTracks; return updateResult; } diff --git a/src/export/ExportFFmpeg.cpp b/src/export/ExportFFmpeg.cpp index c1f577f36..19839a4a7 100644 --- a/src/export/ExportFFmpeg.cpp +++ b/src/export/ExportFFmpeg.cpp @@ -817,7 +817,7 @@ int ExportFFmpeg::Export(AudacityProject *project, return false; } mName = fName; - TrackList *tracks = project->GetTracks(); + const TrackList *tracks = project->GetTracks(); bool ret = true; if (mSubFormat >= FMT_LAST) return false; @@ -830,15 +830,13 @@ int ExportFFmpeg::Export(AudacityProject *project, if (!ret) return false; int pcmBufferSize = 1024; - int numWaveTracks; - WaveTrack **waveTracks; - tracks->GetWaveTracks(selectionOnly, &numWaveTracks, &waveTracks); - Mixer *mixer = CreateMixer(numWaveTracks, waveTracks, + const WaveTrackConstArray waveTracks = + tracks->GetWaveTrackConstArray(selectionOnly, false); + Mixer *mixer = CreateMixer(waveTracks, tracks->GetTimeTrack(), t0, t1, channels, pcmBufferSize, true, mSampleRate, int16Sample, true, mixerSpec); - delete[] waveTracks; int updateResult = eProgressSuccess; { diff --git a/src/export/ExportFLAC.cpp b/src/export/ExportFLAC.cpp index 0741d39db..e169a7bd0 100644 --- a/src/export/ExportFLAC.cpp +++ b/src/export/ExportFLAC.cpp @@ -229,7 +229,7 @@ int ExportFLAC::Export(AudacityProject *project, int WXUNUSED(subformat)) { double rate = project->GetRate(); - TrackList *tracks = project->GetTracks(); + const TrackList *tracks = project->GetTracks(); wxLogNull logNo; // temporarily disable wxWidgets error messages int updateResult = eProgressSuccess; @@ -309,15 +309,13 @@ int ExportFLAC::Export(AudacityProject *project, ::FLAC__metadata_object_delete(mMetadata); } - int numWaveTracks; - WaveTrack **waveTracks; - tracks->GetWaveTracks(selectionOnly, &numWaveTracks, &waveTracks); - Mixer *mixer = CreateMixer(numWaveTracks, waveTracks, + const WaveTrackConstArray waveTracks = + tracks->GetWaveTrackConstArray(selectionOnly, false); + Mixer *mixer = CreateMixer(waveTracks, tracks->GetTimeTrack(), t0, t1, numChannels, SAMPLES_PER_RUN, false, rate, format, true, mixerSpec); - delete [] waveTracks; int i, j; FLAC__int32 **tmpsmplbuf = new FLAC__int32*[numChannels]; diff --git a/src/export/ExportMP2.cpp b/src/export/ExportMP2.cpp index 75d33a891..2e82dedb3 100644 --- a/src/export/ExportMP2.cpp +++ b/src/export/ExportMP2.cpp @@ -217,7 +217,7 @@ int ExportMP2::Export(AudacityProject *project, bool stereo = (channels == 2); long bitrate = gPrefs->Read(wxT("/FileFormats/MP2Bitrate"), 160); double rate = project->GetRate(); - TrackList *tracks = project->GetTracks(); + const TrackList *tracks = project->GetTracks(); wxLogNull logNo; /* temporarily disable wxWidgets error messages */ @@ -264,15 +264,13 @@ int ExportMP2::Export(AudacityProject *project, // We have to multiply by 4 because one sample is 2 bytes wide! unsigned char* mp2Buffer = new unsigned char[mp2BufferSize]; - int numWaveTracks; - WaveTrack **waveTracks; - tracks->GetWaveTracks(selectionOnly, &numWaveTracks, &waveTracks); - Mixer *mixer = CreateMixer(numWaveTracks, waveTracks, + const WaveTrackConstArray waveTracks = + tracks->GetWaveTrackConstArray(selectionOnly, false); + Mixer *mixer = CreateMixer(waveTracks, tracks->GetTimeTrack(), t0, t1, stereo? 2: 1, pcmBufferSize, true, rate, int16Sample, true, mixerSpec); - delete[] waveTracks; int updateResult = eProgressSuccess; { diff --git a/src/export/ExportMP3.cpp b/src/export/ExportMP3.cpp index edf82496e..e519f7e2f 100644 --- a/src/export/ExportMP3.cpp +++ b/src/export/ExportMP3.cpp @@ -1631,7 +1631,7 @@ int ExportMP3::Export(AudacityProject *project, #ifndef DISABLE_DYNAMIC_LOADING_LAME wxWindow *parent = project; #endif // DISABLE_DYNAMIC_LOADING_LAME - TrackList *tracks = project->GetTracks(); + const TrackList *tracks = project->GetTracks(); MP3Exporter exporter; #ifdef DISABLE_DYNAMIC_LOADING_LAME @@ -1762,15 +1762,13 @@ int ExportMP3::Export(AudacityProject *project, unsigned char *buffer = new unsigned char[bufferSize]; wxASSERT(buffer); - int numWaveTracks; - WaveTrack **waveTracks; - tracks->GetWaveTracks(selectionOnly, &numWaveTracks, &waveTracks); - Mixer *mixer = CreateMixer(numWaveTracks, waveTracks, + const WaveTrackConstArray waveTracks = + tracks->GetWaveTrackConstArray(selectionOnly, false); + Mixer *mixer = CreateMixer(waveTracks, tracks->GetTimeTrack(), t0, t1, channels, inSamples, true, rate, int16Sample, true, mixerSpec); - delete [] waveTracks; wxString title; if (rmode == MODE_SET) { diff --git a/src/export/ExportMultiple.cpp b/src/export/ExportMultiple.cpp index 7bf7897d2..5202eef7e 100644 --- a/src/export/ExportMultiple.cpp +++ b/src/export/ExportMultiple.cpp @@ -105,7 +105,6 @@ END_EVENT_TABLE() ExportMultiple::ExportMultiple(AudacityProject *project) : wxDialog(project, wxID_ANY, wxString(_("Export Multiple"))) -, mIterator(new TrackListIterator) { SetName(GetTitle()); @@ -141,7 +140,6 @@ ExportMultiple::ExportMultiple(AudacityProject *project) ExportMultiple::~ExportMultiple() { - delete mIterator; } void ExportMultiple::CountTracksAndLabels() @@ -150,8 +148,9 @@ void ExportMultiple::CountTracksAndLabels() mNumLabels = 0; mNumWaveTracks = 0; - Track* pTrack; - for (pTrack = mIterator->First(mTracks); pTrack != NULL; pTrack = mIterator->Next()) + const Track* pTrack; + TrackListConstIterator iter; + for (pTrack = iter.First(mTracks); pTrack != NULL; pTrack = iter.Next()) { switch (pTrack->GetKind()) { @@ -746,7 +745,7 @@ int ExportMultiple::ExportMultipleByTrack(bool byName, int numTracks = 0; int ok = eProgressSuccess; wxArrayString otherNames; - wxArrayPtrVoid selected; /**< Array of pointers to the tracks which were + std::vector selected; /**< Array of pointers to the tracks which were selected when we started */ ExportKitArray exportSettings; // dynamic array we will use to store the // settings needed to do the exports with in @@ -759,13 +758,14 @@ int ExportMultiple::ExportMultipleByTrack(bool byName, wxString title; // un-messed-with title of file for tagging with /* Remember which tracks were selected, and set them to unselected */ - for (tr = mIterator->First(mTracks); tr != NULL; tr = mIterator->Next()) { + TrackListIterator iter; + for (tr = iter.First(mTracks); tr != NULL; tr = iter.Next()) { if (tr->GetKind() != Track::Wave) { continue; } if (tr->GetSelected()) { - selected.Add(tr); + selected.push_back(tr); tr->SetSelected(false); } @@ -775,7 +775,7 @@ int ExportMultiple::ExportMultipleByTrack(bool byName, } /* Examine all tracks in turn, collecting export information */ - for (tr = mIterator->First(mTracks); tr != NULL; tr = mIterator->Next()) { + for (tr = iter.First(mTracks); tr != NULL; tr = iter.Next()) { // Want only non-muted wave tracks. if ((tr->GetKind() != Track::Wave) || tr->GetMute()) @@ -788,7 +788,7 @@ int ExportMultiple::ExportMultipleByTrack(bool byName, // Check for a linked track tr2 = NULL; if (tr->GetLinked()) { - tr2 = mIterator->Next(); + tr2 = iter.Next(); if (tr2) { // Make sure it gets included @@ -819,7 +819,7 @@ int ExportMultiple::ExportMultipleByTrack(bool byName, name = title; if (addNumber) { name.Prepend( - wxString::Format(wxT("%02d-"), l+1)); + wxString::Format(wxT("%02d-"), l+1)); } } else { @@ -858,7 +858,7 @@ int ExportMultiple::ExportMultipleByTrack(bool byName, // loop int count = 0; // count the number of sucessful runs ExportKit activeSetting; // pointer to the settings in use for this export - for (tr = mIterator->First(mTracks); tr != NULL; tr = mIterator->Next()) { + for (tr = iter.First(mTracks); tr != NULL; tr = iter.Next()) { // Want only non-muted wave tracks. if ((tr->GetKind() != Track::Wave) || (tr->GetMute() == true)) { @@ -871,7 +871,7 @@ int ExportMultiple::ExportMultipleByTrack(bool byName, // Check for a linked track tr2 = NULL; if (tr->GetLinked()) { - tr2 = mIterator->Next(); + tr2 = iter.Next(); if (tr2) { // Select it also tr2->SetSelected(true); @@ -900,7 +900,7 @@ int ExportMultiple::ExportMultipleByTrack(bool byName, // Restore the selection states for (size_t i = 0; i < mSelected.GetCount(); i++) { - ((Track *) selected[i])->SetSelected(true); + selected[i]->SetSelected(true); } return ok; diff --git a/src/export/ExportMultiple.h b/src/export/ExportMultiple.h index 3733ed1ec..3c156274c 100644 --- a/src/export/ExportMultiple.h +++ b/src/export/ExportMultiple.h @@ -29,7 +29,6 @@ class wxTextCtrl; class AudacityProject; class LabelTrack; class ShuttleGui; -class TrackListIterator; class ExportMultiple final : public wxDialog { @@ -109,8 +108,6 @@ private: AudacityProject *mProject; TrackList *mTracks; /**< The list of tracks in the project that is being exported */ - TrackListIterator *mIterator; /**< Iterator used to work through all the - tracks in the project */ LabelTrack *mLabels; int mNumLabels; int mNumWaveTracks; diff --git a/src/export/ExportOGG.cpp b/src/export/ExportOGG.cpp index 8d0fd8ab0..f4846144a 100644 --- a/src/export/ExportOGG.cpp +++ b/src/export/ExportOGG.cpp @@ -175,7 +175,7 @@ int ExportOGG::Export(AudacityProject *project, int WXUNUSED(subformat)) { double rate = project->GetRate(); - TrackList *tracks = project->GetTracks(); + const TrackList *tracks = project->GetTracks(); double quality = (gPrefs->Read(wxT("/FileFormats/OggExportQuality"), 50)/(float)100.0); wxLogNull logNo; // temporarily disable wxWidgets error messages @@ -245,15 +245,13 @@ int ExportOGG::Export(AudacityProject *project, outFile.Write(page.body, page.body_len); } - int numWaveTracks; - WaveTrack **waveTracks; - tracks->GetWaveTracks(selectionOnly, &numWaveTracks, &waveTracks); - Mixer *mixer = CreateMixer(numWaveTracks, waveTracks, + const WaveTrackConstArray waveTracks = + tracks->GetWaveTrackConstArray(selectionOnly, false); + Mixer *mixer = CreateMixer(waveTracks, tracks->GetTimeTrack(), t0, t1, numChannels, SAMPLES_PER_RUN, false, rate, floatSample, true, mixerSpec); - delete[] waveTracks; { ProgressDialog progress(wxFileName(fName).GetName(), diff --git a/src/export/ExportPCM.cpp b/src/export/ExportPCM.cpp index 37b4313d3..44781b21c 100644 --- a/src/export/ExportPCM.cpp +++ b/src/export/ExportPCM.cpp @@ -399,7 +399,7 @@ int ExportPCM::Export(AudacityProject *project, int subformat) { double rate = project->GetRate(); - TrackList *tracks = project->GetTracks(); + const TrackList *tracks = project->GetTracks(); int sf_format; if (subformat < 0 || subformat >= WXSIZEOF(kFormats)) @@ -484,10 +484,9 @@ int ExportPCM::Export(AudacityProject *project, int updateResult = eProgressSuccess; - int numWaveTracks; - WaveTrack **waveTracks; - tracks->GetWaveTracks(selectionOnly, &numWaveTracks, &waveTracks); - Mixer *mixer = CreateMixer(numWaveTracks, waveTracks, + const WaveTrackConstArray waveTracks = + tracks->GetWaveTrackConstArray(selectionOnly, false); + Mixer *mixer = CreateMixer(waveTracks, tracks->GetTimeTrack(), t0, t1, info.channels, maxBlockLen, true, @@ -536,8 +535,6 @@ int ExportPCM::Export(AudacityProject *project, delete mixer; - delete[] waveTracks; - // Install the WAV metata in a "LIST" chunk at the end of the file if ((sf_format & SF_FORMAT_TYPEMASK) == SF_FORMAT_WAV || (sf_format & SF_FORMAT_TYPEMASK) == SF_FORMAT_WAVEX) { diff --git a/src/toolbars/ControlToolBar.cpp b/src/toolbars/ControlToolBar.cpp index ebec43aaa..a662662cb 100644 --- a/src/toolbars/ControlToolBar.cpp +++ b/src/toolbars/ControlToolBar.cpp @@ -869,8 +869,12 @@ void ControlToolBar::OnRecord(wxCommandEvent &evt) for (Track *tt = it.First(); tt; tt = it.Next()) { if (tt->GetKind() == Track::Wave && (tt->GetSelected() || !sel)) { WaveTrack *wt = static_cast(tt); - if (duplex) - playbackTracks.Remove(wt); + if (duplex) { + auto end = playbackTracks.end(); + auto it = std::find(playbackTracks.begin(), end, wt); + if (it != end) + playbackTracks.erase(it); + } t1 = wt->GetEndTime(); if (t1 < t0) { if (!tracksCopied) { @@ -892,7 +896,7 @@ void ControlToolBar::OnRecord(wxCommandEvent &evt) wxUnusedVar(bResult); delete newTrack; } - newRecordingTracks.Add(wt); + newRecordingTracks.push_back(wt); } } @@ -974,13 +978,13 @@ void ControlToolBar::OnRecord(wxCommandEvent &evt) newTrack->SetChannel( Track::MonoChannel ); } - newRecordingTracks.Add(newTrack); + newRecordingTracks.push_back(newTrack); } // msmeyer: StartStream calls a callback which triggers auto-save, so // we add the tracks where recording is done into now. We remove them // later if starting the stream fails - for (unsigned int i = 0; i < newRecordingTracks.GetCount(); i++) + for (unsigned int i = 0; i < newRecordingTracks.size(); i++) t->Add(newRecordingTracks[i]); } @@ -1020,7 +1024,7 @@ void ControlToolBar::OnRecord(wxCommandEvent &evt) } else { // msmeyer: Delete recently added tracks if opening stream fails - for (unsigned int i = 0; i < newRecordingTracks.GetCount(); i++) { + for (unsigned int i = 0; i < newRecordingTracks.size(); i++) { t->Remove(newRecordingTracks[i]); delete newRecordingTracks[i]; }