diff --git a/src/AudioIO.cpp b/src/AudioIO.cpp index 8724dfb89..1ed9b34f9 100644 --- a/src/AudioIO.cpp +++ b/src/AudioIO.cpp @@ -1124,14 +1124,9 @@ int AudioIO::StartStream(WaveTrackArray playbackTracks, mCutPreviewGapLen = cutPreviewGapLen; double factor = 1.0; - if (mTimeTrack) { - factor = mTimeTrack->GetEnvelope()->Average(mT0, mT1); - factor = (mTimeTrack->GetRangeLower() * - (1 - factor) + - factor * - mTimeTrack->GetRangeUpper()) / - 100.0; - } + if (mTimeTrack) + factor = mTimeTrack->ComputeWarpFactor(mT0, mT1); + mWarpedT1 = factor >= 1 ? mT1 : mT0 + ((mT1 - mT0) / factor); // diff --git a/src/TimeTrack.cpp b/src/TimeTrack.cpp index b5545f28b..8ced0649c 100644 --- a/src/TimeTrack.cpp +++ b/src/TimeTrack.cpp @@ -109,6 +109,19 @@ double TimeTrack::warp( double t ) return result; } +//Compute the integral warp factor between two non-warped time points +double TimeTrack::ComputeWarpFactor(double t0, double t1) +{ + double factor; + factor = GetEnvelope()->Average(t0, t1); + factor = (GetRangeLower() * + (1 - factor) + + factor * + GetRangeUpper()) / + 100.0; + return factor; +} + bool TimeTrack::HandleXMLTag(const wxChar *tag, const wxChar **attrs) { if (!wxStrcmp(tag, wxT("timetrack"))) { @@ -208,7 +221,7 @@ void TimeTrack::Draw(wxDC & dc, const wxRect & r, double h, double pps) // LL: It's because the ruler only Invalidate()s when the new value is different // than the current value. mRuler->SetFlip(GetHeight() > 75 ? true : true); - mRuler->Draw(dc, GetEnvelope(), GetRangeLower(), GetRangeUpper()); + mRuler->Draw(dc, this); int *heights = new int[mid.width]; double *envValues = new double[mid.width]; diff --git a/src/TimeTrack.h b/src/TimeTrack.h index 068865d71..ffa8127b3 100644 --- a/src/TimeTrack.h +++ b/src/TimeTrack.h @@ -57,6 +57,9 @@ class TimeTrack: public Track { // Access the track's speed envelope Envelope *GetEnvelope() { return mEnvelope; } + + //Compute the integral warp factor between two non-warped time points + double ComputeWarpFactor(double t0, double t1); // Get/Set the speed-warping range, as percentage of original speed (e.g. 90%-110%) diff --git a/src/export/Export.cpp b/src/export/Export.cpp index 02a62f228..065edb046 100644 --- a/src/export/Export.cpp +++ b/src/export/Export.cpp @@ -72,6 +72,7 @@ #include "../WaveTrack.h" #include "../widgets/Warning.h" #include "../AColor.h" +#include "../TimeTrack.h" // Callback to display format options static void ExportCallback(void *cbdata, int index) @@ -264,6 +265,28 @@ int ExportPlugin::DoExport(AudacityProject *project, return false; } +//Create a mixer by computing the time warp factor +Mixer* ExportPlugin::CreateMixer(int numInputTracks, WaveTrack **inputTracks, + TimeTrack *timeTrack, + double startTime, double stopTime, + int numOutChannels, int outBufferSize, bool outInterleaved, + double outRate, sampleFormat outFormat, + bool highQuality, MixerSpec *mixerSpec) +{ + double warpedStopTime; + double warpFactor = 1.0; + if(timeTrack) + warpFactor = timeTrack->ComputeWarpFactor(startTime, stopTime); + + warpedStopTime = warpFactor >= 1.0 ? stopTime : (startTime + ((stopTime - startTime) / warpFactor)); + printf("warpfactor %f, stoptime %f, warpstoptime %f\n",warpFactor, stopTime, warpedStopTime); + return new Mixer(numInputTracks, inputTracks, + timeTrack, + startTime, warpedStopTime, + numOutChannels, outBufferSize, outInterleaved, + outRate, outFormat, + highQuality, mixerSpec); +} //---------------------------------------------------------------------------- // Export //---------------------------------------------------------------------------- diff --git a/src/export/Export.h b/src/export/Export.h index 0394509bc..58ee496e3 100644 --- a/src/export/Export.h +++ b/src/export/Export.h @@ -16,6 +16,7 @@ #include #include #include "../Tags.h" +#include "../SampleFormat.h" class wxMemoryDC; class wxStaticText; @@ -25,6 +26,8 @@ class WaveTrack; class TrackList; class MixerSpec; class FileDialog; +class TimeTrack; +class Mixer; class FormatInfo { @@ -114,8 +117,15 @@ public: MixerSpec *mixerSpec, int subformat); -private: +protected: + Mixer* CreateMixer(int numInputTracks, WaveTrack **inputTracks, + TimeTrack *timeTrack, + double startTime, double stopTime, + int numOutChannels, int outBufferSize, bool outInterleaved, + double outRate, sampleFormat outFormat, + bool highQuality = true, MixerSpec *mixerSpec = NULL); +private: FormatInfoArray mFormatInfos; }; diff --git a/src/export/ExportCL.cpp b/src/export/ExportCL.cpp index faf30b60d..c5d7028a5 100644 --- a/src/export/ExportCL.cpp +++ b/src/export/ExportCL.cpp @@ -338,7 +338,7 @@ int ExportCL::Export(AudacityProject *project, WaveTrack **waveTracks; TrackList *tracks = project->GetTracks(); tracks->GetWaveTracks(selectionOnly, &numWaveTracks, &waveTracks); - Mixer *mixer = new Mixer(numWaveTracks, + Mixer *mixer = CreateMixer(numWaveTracks, waveTracks, tracks->GetTimeTrack(), t0, diff --git a/src/export/ExportFFmpeg.cpp b/src/export/ExportFFmpeg.cpp index 3fba7d598..547854559 100644 --- a/src/export/ExportFFmpeg.cpp +++ b/src/export/ExportFFmpeg.cpp @@ -729,7 +729,7 @@ int ExportFFmpeg::Export(AudacityProject *project, int numWaveTracks; WaveTrack **waveTracks; tracks->GetWaveTracks(selectionOnly, &numWaveTracks, &waveTracks); - Mixer *mixer = new Mixer(numWaveTracks, waveTracks, + Mixer *mixer = CreateMixer(numWaveTracks, waveTracks, tracks->GetTimeTrack(), t0, t1, channels, pcmBufferSize, true, diff --git a/src/export/ExportFLAC.cpp b/src/export/ExportFLAC.cpp index 33dfb5bf9..f2b98217d 100644 --- a/src/export/ExportFLAC.cpp +++ b/src/export/ExportFLAC.cpp @@ -306,7 +306,7 @@ int ExportFLAC::Export(AudacityProject *project, int numWaveTracks; WaveTrack **waveTracks; tracks->GetWaveTracks(selectionOnly, &numWaveTracks, &waveTracks); - Mixer *mixer = new Mixer(numWaveTracks, waveTracks, + Mixer *mixer = CreateMixer(numWaveTracks, waveTracks, tracks->GetTimeTrack(), t0, t1, numChannels, SAMPLES_PER_RUN, false, diff --git a/src/export/ExportMP2.cpp b/src/export/ExportMP2.cpp index 9a3d4257c..d19a1c852 100644 --- a/src/export/ExportMP2.cpp +++ b/src/export/ExportMP2.cpp @@ -261,7 +261,7 @@ int ExportMP2::Export(AudacityProject *project, int numWaveTracks; WaveTrack **waveTracks; tracks->GetWaveTracks(selectionOnly, &numWaveTracks, &waveTracks); - Mixer *mixer = new Mixer(numWaveTracks, waveTracks, + Mixer *mixer = CreateMixer(numWaveTracks, waveTracks, tracks->GetTimeTrack(), t0, t1, stereo? 2: 1, pcmBufferSize, true, diff --git a/src/export/ExportMP3.cpp b/src/export/ExportMP3.cpp index ec8c2175e..1c502150f 100644 --- a/src/export/ExportMP3.cpp +++ b/src/export/ExportMP3.cpp @@ -1639,7 +1639,7 @@ int ExportMP3::Export(AudacityProject *project, int numWaveTracks; WaveTrack **waveTracks; tracks->GetWaveTracks(selectionOnly, &numWaveTracks, &waveTracks); - Mixer *mixer = new Mixer(numWaveTracks, waveTracks, + Mixer *mixer = CreateMixer(numWaveTracks, waveTracks, tracks->GetTimeTrack(), t0, t1, channels, inSamples, true, diff --git a/src/export/ExportOGG.cpp b/src/export/ExportOGG.cpp index 80100ec52..71d5115c9 100644 --- a/src/export/ExportOGG.cpp +++ b/src/export/ExportOGG.cpp @@ -244,7 +244,7 @@ int ExportOGG::Export(AudacityProject *project, int numWaveTracks; WaveTrack **waveTracks; tracks->GetWaveTracks(selectionOnly, &numWaveTracks, &waveTracks); - Mixer *mixer = new Mixer(numWaveTracks, waveTracks, + Mixer *mixer = CreateMixer(numWaveTracks, waveTracks, tracks->GetTimeTrack(), t0, t1, numChannels, SAMPLES_PER_RUN, false, diff --git a/src/export/ExportPCM.cpp b/src/export/ExportPCM.cpp index 0a877c7b8..54fa73862 100644 --- a/src/export/ExportPCM.cpp +++ b/src/export/ExportPCM.cpp @@ -517,7 +517,7 @@ int ExportPCM::Export(AudacityProject *project, int numWaveTracks; WaveTrack **waveTracks; tracks->GetWaveTracks(selectionOnly, &numWaveTracks, &waveTracks); - Mixer *mixer = new Mixer(numWaveTracks, waveTracks, + Mixer *mixer = CreateMixer(numWaveTracks, waveTracks, tracks->GetTimeTrack(), t0, t1, info.channels, maxBlockLen, true, diff --git a/src/widgets/Ruler.cpp b/src/widgets/Ruler.cpp index 37d2a5717..96e2e1a80 100644 --- a/src/widgets/Ruler.cpp +++ b/src/widgets/Ruler.cpp @@ -69,6 +69,7 @@ array of Ruler::Label. #include "../Theme.h" #include "../AllThemeResources.h" #include "../Experimental.h" +#include "../TimeTrack.h" #define max(a,b) ( (a0 && speedEnv != NULL ) { - warpfactor = speedEnv->Average( lastD, d ); - // Now we re-scale so that 0.5 is normal speed and - // 0 and 1.0 are min% and max% of normal speed - warpfactor = (maxSpeed * (1 - warpfactor) + - warpfactor * minSpeed) / 100.0; - } + if( d>0 && timetrack != NULL ) + warpfactor = timetrack->ComputeWarpFactor( lastD, d ); else warpfactor = 1.0; i++; lastD = d; - d += UPP*warpfactor; + d += UPP/warpfactor; if ((int)floor(sg * d / mMajor) > majorInt) { majorInt = (int)floor(sg * d / mMajor); @@ -1077,19 +1073,14 @@ void Ruler::Update( Envelope *speedEnv, long minSpeed, long maxSpeed ) i = -1; while(i <= mLength) { double warpfactor; - if( d>0 && speedEnv != NULL ) { - warpfactor = speedEnv->Average( lastD, d ); - // Now we re-scale so that 0.5 is normal speed and - // 0 and 1.0 are min% and max% of normal speed - warpfactor = (maxSpeed * (1 - warpfactor) + - warpfactor * minSpeed) / 100.0; - } + if( d>0 && timetrack != NULL ) + warpfactor = timetrack->ComputeWarpFactor( lastD, d ); else warpfactor = 1.0; i++; lastD = d; - d += UPP*warpfactor; + d += UPP/warpfactor; if ((int)floor(sg * d / mMinor) > minorInt) { minorInt = (int)floor(sg * d / mMinor); @@ -1217,17 +1208,17 @@ void Ruler::Update( Envelope *speedEnv, long minSpeed, long maxSpeed ) void Ruler::Draw(wxDC& dc) { - Draw( dc, NULL, 0, 0); + Draw( dc, NULL); } -void Ruler::Draw(wxDC& dc, Envelope *speedEnv, long minSpeed, long maxSpeed) +void Ruler::Draw(wxDC& dc, TimeTrack* timetrack) { mDC = &dc; if( mLength <=0 ) return; if (!mValid) - Update( speedEnv, minSpeed, maxSpeed ); + Update(timetrack); #ifdef EXPERIMENTAL_THEMING mDC->SetPen(mPen); @@ -1462,7 +1453,7 @@ void Ruler::GetMaxSize(wxCoord *width, wxCoord *height) wxBitmap tmpBM(1, 1); tmpDC.SelectObject(tmpBM); mDC = &tmpDC; - Update( NULL, 0, 0 ); + Update( NULL); } if (width) diff --git a/src/widgets/Ruler.h b/src/widgets/Ruler.h index b50740b22..5d2317a7f 100644 --- a/src/widgets/Ruler.h +++ b/src/widgets/Ruler.h @@ -21,6 +21,7 @@ struct ViewInfo; class AudacityProject; +class TimeTrack; class AUDACITY_DLL_API Ruler { public: @@ -115,7 +116,7 @@ class AUDACITY_DLL_API Ruler { // Note that it will not erase for you... void Draw(wxDC& dc); - void Draw(wxDC& dc, Envelope *speedEnv, long minSpeed, long maxSpeed); + void Draw(wxDC& dc, TimeTrack* timetrack); // If length <> 0, draws lines perpendiculars to ruler corresponding // to selected ticks (major, minor, or both), in an adjacent window. // You may need to use the offsets if you are using part of the dc for rulers, borders etc. @@ -128,7 +129,7 @@ class AUDACITY_DLL_API Ruler { private: void Invalidate(); void Update(); - void Update(Envelope *speedEnv, long minSpeed, long maxSpeed); + void Update(TimeTrack* timetrack); void FindTickSizes(); void FindLinearTickSizes(double UPP); wxString LabelString(double d, bool major);