diff -Nru audacity-2.0.6+svn20150801+r3549+31~ubuntu14.04.1/debian/bzr-builder.manifest audacity-2.0.6+svn20150802+r3559+31~ubuntu14.04.1/debian/bzr-builder.manifest --- audacity-2.0.6+svn20150801+r3549+31~ubuntu14.04.1/debian/bzr-builder.manifest 2015-08-01 10:16:55.000000000 +0000 +++ audacity-2.0.6+svn20150802+r3559+31~ubuntu14.04.1/debian/bzr-builder.manifest 2015-08-02 10:16:42.000000000 +0000 @@ -1,3 +1,3 @@ -# bzr-builder format 0.3 deb-version {debupstream}+svn20150801+r3549+31 -lp:audacity revid:git-v1:7414b000c264becd7a47279c123a6f7308eff8f0 +# bzr-builder format 0.3 deb-version {debupstream}+svn20150802+r3559+31 +lp:audacity revid:git-v1:e151980c5505d3a15304816002d2af5e624bce99 merge packaging lp:~audacity-team/audacity/daily-packaging revid:bdrung@ubuntu.com-20150124215604-m9u7zg4az3umfz4x diff -Nru audacity-2.0.6+svn20150801+r3549+31~ubuntu14.04.1/debian/changelog audacity-2.0.6+svn20150802+r3559+31~ubuntu14.04.1/debian/changelog --- audacity-2.0.6+svn20150801+r3549+31~ubuntu14.04.1/debian/changelog 2015-08-01 10:16:55.000000000 +0000 +++ audacity-2.0.6+svn20150802+r3559+31~ubuntu14.04.1/debian/changelog 2015-08-02 10:16:42.000000000 +0000 @@ -1,8 +1,8 @@ -audacity (2.0.6+svn20150801+r3549+31~ubuntu14.04.1) trusty; urgency=low +audacity (2.0.6+svn20150802+r3559+31~ubuntu14.04.1) trusty; urgency=low * Auto build. - -- Launchpad Package Builder Sat, 01 Aug 2015 10:16:55 +0000 + -- Launchpad Package Builder Sun, 02 Aug 2015 10:16:42 +0000 audacity (2.0.6-2) unstable; urgency=medium diff -Nru audacity-2.0.6+svn20150801+r3549+31~ubuntu14.04.1/README.txt audacity-2.0.6+svn20150802+r3559+31~ubuntu14.04.1/README.txt --- audacity-2.0.6+svn20150801+r3549+31~ubuntu14.04.1/README.txt 2015-08-01 10:16:43.000000000 +0000 +++ audacity-2.0.6+svn20150802+r3559+31~ubuntu14.04.1/README.txt 2015-08-02 10:16:33.000000000 +0000 @@ -140,7 +140,7 @@ Source code to this program is always available; for more information visit our web site at: - http://audacity.sourceforge.net/download/ + http://audacityteam.org/download/source Audacity is built upon other free libraries; some of these libraries may have come with Audacity in the lib-src directory. Others you are expected to install diff -Nru audacity-2.0.6+svn20150801+r3549+31~ubuntu14.04.1/src/effects/Effect.cpp audacity-2.0.6+svn20150802+r3559+31~ubuntu14.04.1/src/effects/Effect.cpp --- audacity-2.0.6+svn20150801+r3549+31~ubuntu14.04.1/src/effects/Effect.cpp 2015-08-01 10:16:43.000000000 +0000 +++ audacity-2.0.6+svn20150802+r3559+31~ubuntu14.04.1/src/effects/Effect.cpp 2015-08-02 10:16:33.000000000 +0000 @@ -421,6 +421,8 @@ return mClient->RealtimeInitialize(); } + mBlockSize = 512; + return false; } @@ -455,9 +457,15 @@ mRealtimeSuspendLock.Leave(); return true; } + + return false; } - return false; + mRealtimeSuspendLock.Enter(); + mRealtimeSuspendCount++; + mRealtimeSuspendLock.Leave(); + + return true; } bool Effect::RealtimeResume() @@ -471,9 +479,15 @@ mRealtimeSuspendLock.Leave(); return true; } + + return false; } - return false; + mRealtimeSuspendLock.Enter(); + mRealtimeSuspendCount--; + mRealtimeSuspendLock.Leave(); + + return true; } bool Effect::RealtimeProcessStart() @@ -677,6 +691,7 @@ mUIParent->RemoveEventHandler(this); mUIParent = NULL; + mUIDialog = NULL; return true; } @@ -2270,7 +2285,7 @@ } // Add a new processor - mClient->RealtimeAddProcessor(gchans, rate); + RealtimeAddProcessor(gchans, rate); // Bump to next processor mCurrentProcessor++; @@ -2377,7 +2392,7 @@ for (sampleCount block = 0; block < numSamples; block += mBlockSize) { sampleCount cnt = (block + mBlockSize > numSamples ? numSamples - block : mBlockSize); - len += mClient->RealtimeProcess(processor, clientIn, clientOut, cnt); + len += RealtimeProcess(processor, clientIn, clientOut, cnt); for (int i = 0 ; i < mNumAudioIn; i++) { diff -Nru audacity-2.0.6+svn20150801+r3549+31~ubuntu14.04.1/src/effects/ladspa/LadspaEffect.cpp audacity-2.0.6+svn20150802+r3559+31~ubuntu14.04.1/src/effects/ladspa/LadspaEffect.cpp --- audacity-2.0.6+svn20150801+r3549+31~ubuntu14.04.1/src/effects/ladspa/LadspaEffect.cpp 2015-08-01 10:16:43.000000000 +0000 +++ audacity-2.0.6+svn20150802+r3559+31~ubuntu14.04.1/src/effects/ladspa/LadspaEffect.cpp 2015-08-02 10:16:33.000000000 +0000 @@ -896,7 +896,7 @@ if (mUseLatency && mLatencyPort >= 0 && !mLatencyDone) { mLatencyDone = true; - return mOutputControls[mLatencyPort] * 2; + return mOutputControls[mLatencyPort]; } return 0; diff -Nru audacity-2.0.6+svn20150801+r3549+31~ubuntu14.04.1/src/effects/Phaser.cpp audacity-2.0.6+svn20150802+r3559+31~ubuntu14.04.1/src/effects/Phaser.cpp --- audacity-2.0.6+svn20150801+r3549+31~ubuntu14.04.1/src/effects/Phaser.cpp 2015-08-01 10:16:43.000000000 +0000 +++ audacity-2.0.6+svn20150802+r3559+31~ubuntu14.04.1/src/effects/Phaser.cpp 2015-08-02 10:16:33.000000000 +0000 @@ -56,6 +56,9 @@ // How many samples are processed before recomputing the lfo value again #define lfoskipsamples 20 +#include +WX_DEFINE_OBJARRAY(EffectPhaserStateArray); + // // EffectPhaser // @@ -110,6 +113,15 @@ return EffectTypeProcess; } +bool EffectPhaser::SupportsRealtime() +{ +#if defined(EXPERIMENTAL_REALTIME_AUDACITY_EFFECTS) + return true; +#else + return false; +#endif +} + // EffectClientInterface implementation int EffectPhaser::GetAudioInCount() @@ -124,20 +136,10 @@ bool EffectPhaser::ProcessInitialize(sampleCount WXUNUSED(totalLen), ChannelNames chanMap) { - for (int j = 0; j < mStages; j++) - { - old[j] = 0; - } - - skipcount = 0; - gain = 0; - fbout = 0; - lfoskip = mFreq * 2 * M_PI / mSampleRate; - - phase = mPhase * M_PI / 180; + InstanceInit(mMaster, mSampleRate); if (chanMap[0] == ChannelNameFrontRight) { - phase += M_PI; + mMaster.phase += M_PI; } return true; @@ -145,40 +147,43 @@ sampleCount EffectPhaser::ProcessBlock(float **inBlock, float **outBlock, sampleCount blockLen) { - float *ibuf = inBlock[0]; - float *obuf = outBlock[0]; + return InstanceProcess(mMaster, inBlock, outBlock, blockLen); +} - for (sampleCount i = 0; i < blockLen; i++) - { - double in = ibuf[i]; +bool EffectPhaser::RealtimeInitialize() +{ + SetBlockSize(512); - double m = in + fbout * mFeedback / 101; // Feedback must be less than 100% to avoid infinite gain. + mSlaves.Clear(); - if (((skipcount++) % lfoskipsamples) == 0) - { - //compute sine between 0 and 1 - gain = (1.0 + cos(skipcount * lfoskip + phase)) / 2.0; + return true; +} - // change lfo shape - gain = expm1(gain * phaserlfoshape) / expm1(phaserlfoshape); +bool EffectPhaser::RealtimeAddProcessor(int WXUNUSED(numChannels), float sampleRate) +{ + EffectPhaserState slave; - // attenuate the lfo - gain = 1.0 - gain / 255.0 * mDepth; - } + InstanceInit(slave, sampleRate); - // phasing routine - for (int j = 0; j < mStages; j++) - { - double tmp = old[j]; - old[j] = gain * tmp + m; - m = tmp - gain * old[j]; - } - fbout = m; + mSlaves.Add(slave); - obuf[i] = (float) ((m * mDryWet + in * (255 - mDryWet)) / 255); - } + return true; +} - return blockLen; +bool EffectPhaser::RealtimeFinalize() +{ + mSlaves.Clear(); + + return true; +} + +sampleCount EffectPhaser::RealtimeProcess(int group, + float **inbuf, + float **outbuf, + sampleCount numSamples) +{ + + return InstanceProcess(mSlaves[group], inbuf, outbuf, numSamples); } bool EffectPhaser::GetAutomationParameters(EffectAutomationParameters & parms) @@ -329,6 +334,70 @@ // EffectPhaser implementation +void EffectPhaser::InstanceInit(EffectPhaserState & data, float sampleRate) +{ + data.samplerate = sampleRate; + + for (int j = 0; j < mStages; j++) + { + data.old[j] = 0; + } + + data.skipcount = 0; + data.gain = 0; + data.fbout = 0; + data.laststages = 0; + + return; +} + +sampleCount EffectPhaser::InstanceProcess(EffectPhaserState & data, float **inBlock, float **outBlock, sampleCount blockLen) +{ + float *ibuf = inBlock[0]; + float *obuf = outBlock[0]; + + for (int j = data.laststages; j < mStages; j++) + { + data.old[j] = 0; + } + data.laststages = mStages; + + data.lfoskip = mFreq * 2 * M_PI / data.samplerate; + data.phase = mPhase * M_PI / 180; + + for (sampleCount i = 0; i < blockLen; i++) + { + double in = ibuf[i]; + + double m = in + data.fbout * mFeedback / 101; // Feedback must be less than 100% to avoid infinite gain. + + if (((data.skipcount++) % lfoskipsamples) == 0) + { + //compute sine between 0 and 1 + data.gain = (1.0 + cos(data.skipcount * data.lfoskip + data.phase)) / 2.0; + + // change lfo shape + data.gain = expm1(data.gain * phaserlfoshape) / expm1(phaserlfoshape); + + // attenuate the lfo + data.gain = 1.0 - data.gain / 255.0 * mDepth; + } + + // phasing routine + for (int j = 0; j < mStages; j++) + { + double tmp = data.old[j]; + data.old[j] = data.gain * tmp + m; + m = tmp - data.gain * data.old[j]; + } + data.fbout = m; + + obuf[i] = (float) ((m * mDryWet + in * (255 - mDryWet)) / 255); + } + + return blockLen; +} + void EffectPhaser::OnStagesSlider(wxCommandEvent & evt) { mStages = (evt.GetInt() / SCL_Stages) & ~1; // must be even; diff -Nru audacity-2.0.6+svn20150801+r3549+31~ubuntu14.04.1/src/effects/Phaser.h audacity-2.0.6+svn20150802+r3559+31~ubuntu14.04.1/src/effects/Phaser.h --- audacity-2.0.6+svn20150801+r3549+31~ubuntu14.04.1/src/effects/Phaser.h 2015-08-01 10:16:43.000000000 +0000 +++ audacity-2.0.6+svn20150802+r3559+31~ubuntu14.04.1/src/effects/Phaser.h 2015-08-02 10:16:33.000000000 +0000 @@ -29,6 +29,22 @@ #define PHASER_PLUGIN_SYMBOL XO("Phaser") +class EffectPhaserState +{ +public: + // state variables + float samplerate; + sampleCount skipcount; + double old[NUM_STAGES]; // must be as large as MAX_STAGES + double gain; + double fbout; + double lfoskip; + double phase; + int laststages; +}; + +WX_DECLARE_OBJARRAY(EffectPhaserState, EffectPhaserStateArray); + class EffectPhaser : public Effect { public: @@ -43,6 +59,7 @@ // EffectIdentInterface implementation virtual EffectType GetType(); + virtual bool SupportsRealtime(); // EffectClientInterface implementation @@ -50,6 +67,13 @@ virtual int GetAudioOutCount(); virtual bool ProcessInitialize(sampleCount totalLen, ChannelNames chanMap = NULL); virtual sampleCount ProcessBlock(float **inBlock, float **outBlock, sampleCount blockLen); + virtual bool RealtimeInitialize(); + virtual bool RealtimeAddProcessor(int numChannels, float sampleRate); + virtual bool RealtimeFinalize(); + virtual sampleCount RealtimeProcess(int group, + float **inbuf, + float **outbuf, + sampleCount numSamples); virtual bool GetAutomationParameters(EffectAutomationParameters & parms); virtual bool SetAutomationParameters(EffectAutomationParameters & parms); @@ -62,6 +86,9 @@ protected: // EffectPhaser implementation + void InstanceInit(EffectPhaserState & data, float sampleRate); + sampleCount InstanceProcess(EffectPhaserState & data, float **inBlock, float **outBlock, sampleCount blockLen); + void OnStagesSlider(wxCommandEvent & evt); void OnDryWetSlider(wxCommandEvent & evt); void OnFeedbackSlider(wxCommandEvent & evt); @@ -87,13 +114,8 @@ */ private: - // state variables - sampleCount skipcount; - double old[NUM_STAGES]; // must be as large as MAX_STAGES - double gain; - double fbout; - double lfoskip; - double phase; + EffectPhaserState mMaster; + EffectPhaserStateArray mSlaves; // parameters int mStages; diff -Nru audacity-2.0.6+svn20150801+r3549+31~ubuntu14.04.1/src/effects/Wahwah.cpp audacity-2.0.6+svn20150802+r3559+31~ubuntu14.04.1/src/effects/Wahwah.cpp --- audacity-2.0.6+svn20150801+r3549+31~ubuntu14.04.1/src/effects/Wahwah.cpp 2015-08-01 10:16:43.000000000 +0000 +++ audacity-2.0.6+svn20150802+r3559+31~ubuntu14.04.1/src/effects/Wahwah.cpp 2015-08-02 10:16:33.000000000 +0000 @@ -49,6 +49,9 @@ // How many samples are processed before recomputing the lfo value again #define lfoskipsamples 30 +#include +WX_DEFINE_OBJARRAY(EffectWahwahStateArray); + // // EffectWahwah // @@ -100,6 +103,15 @@ return EffectTypeProcess; } +bool EffectWahwah::SupportsRealtime() +{ +#if defined(EXPERIMENTAL_REALTIME_AUDACITY_EFFECTS) + return true; +#else + return false; +#endif +} + // EffectClientInterface implementation int EffectWahwah::GetAudioInCount() @@ -114,26 +126,11 @@ bool EffectWahwah::ProcessInitialize(sampleCount WXUNUSED(totalLen), ChannelNames chanMap) { - lfoskip = mFreq * 2 * M_PI / mSampleRate; - skipcount = 0; - xn1 = 0; - xn2 = 0; - yn1 = 0; - yn2 = 0; - b0 = 0; - b1 = 0; - b2 = 0; - a0 = 0; - a1 = 0; - a2 = 0; + InstanceInit(mMaster, mSampleRate); - depth = mDepth / 100.0; - freqofs = mFreqOfs / 100.0; - - phase = mPhase * M_PI / 180.0; if (chanMap[0] == ChannelNameFrontRight) { - phase += M_PI; + mMaster.phase += M_PI; } return true; @@ -141,41 +138,43 @@ sampleCount EffectWahwah::ProcessBlock(float **inBlock, float **outBlock, sampleCount blockLen) { - float *ibuf = inBlock[0]; - float *obuf = outBlock[0]; - double frequency, omega, sn, cs, alpha; - double in, out; + return InstanceProcess(mMaster, inBlock, outBlock, blockLen); +} - for (int i = 0; i < blockLen; i++) - { - in = (double) ibuf[i]; +bool EffectWahwah::RealtimeInitialize() +{ + SetBlockSize(512); - if ((skipcount++) % lfoskipsamples == 0) - { - frequency = (1 + cos(skipcount * lfoskip + phase)) / 2; - frequency = frequency * depth * (1 - freqofs) + freqofs; - frequency = exp((frequency - 1) * 6); - omega = M_PI * frequency; - sn = sin(omega); - cs = cos(omega); - alpha = sn / (2 * mRes); - b0 = (1 - cs) / 2; - b1 = 1 - cs; - b2 = (1 - cs) / 2; - a0 = 1 + alpha; - a1 = -2 * cs; - a2 = 1 - alpha; - }; - out = (b0 * in + b1 * xn1 + b2 * xn2 - a1 * yn1 - a2 * yn2) / a0; - xn2 = xn1; - xn1 = in; - yn2 = yn1; - yn1 = out; + mSlaves.Clear(); - obuf[i] = (float) out; - } + return true; +} - return blockLen; +bool EffectWahwah::RealtimeAddProcessor(int WXUNUSED(numChannels), float sampleRate) +{ + EffectWahwahState slave; + + InstanceInit(slave, sampleRate); + + mSlaves.Add(slave); + + return true; +} + +bool EffectWahwah::RealtimeFinalize() +{ + mSlaves.Clear(); + + return true; +} + +sampleCount EffectWahwah::RealtimeProcess(int group, + float **inbuf, + float **outbuf, + sampleCount numSamples) +{ + + return InstanceProcess(mSlaves[group], inbuf, outbuf, numSamples); } bool EffectWahwah::GetAutomationParameters(EffectAutomationParameters & parms) @@ -299,6 +298,73 @@ // EffectWahwah implementation +void EffectWahwah::InstanceInit(EffectWahwahState & data, float sampleRate) +{ + data.samplerate = sampleRate; + data.lfoskip = mFreq * 2 * M_PI / sampleRate; + data.skipcount = 0; + data.xn1 = 0; + data.xn2 = 0; + data.yn1 = 0; + data.yn2 = 0; + data.b0 = 0; + data.b1 = 0; + data.b2 = 0; + data.a0 = 0; + data.a1 = 0; + data.a2 = 0; + + data.depth = mDepth / 100.0; + data.freqofs = mFreqOfs / 100.0; + + data.phase = mPhase * M_PI / 180.0; +} + +sampleCount EffectWahwah::InstanceProcess(EffectWahwahState & data, float **inBlock, float **outBlock, sampleCount blockLen) +{ + float *ibuf = inBlock[0]; + float *obuf = outBlock[0]; + double frequency, omega, sn, cs, alpha; + double in, out; + + data.lfoskip = mFreq * 2 * M_PI / data.samplerate; + data.depth = mDepth / 100.0; + data.freqofs = mFreqOfs / 100.0; + + data.phase = mPhase * M_PI / 180.0; + + for (int i = 0; i < blockLen; i++) + { + in = (double) ibuf[i]; + + if ((data.skipcount++) % lfoskipsamples == 0) + { + frequency = (1 + cos(data.skipcount * data.lfoskip + data.phase)) / 2; + frequency = frequency * data.depth * (1 - data.freqofs) + data.freqofs; + frequency = exp((frequency - 1) * 6); + omega = M_PI * frequency; + sn = sin(omega); + cs = cos(omega); + alpha = sn / (2 * mRes); + data.b0 = (1 - cs) / 2; + data.b1 = 1 - cs; + data.b2 = (1 - cs) / 2; + data.a0 = 1 + alpha; + data.a1 = -2 * cs; + data.a2 = 1 - alpha; + }; + out = (data.b0 * in + data.b1 * data.xn1 + data.b2 * data.xn2 - data.a1 * data.yn1 - data.a2 * data.yn2) / data.a0; + data.xn2 = data.xn1; + data.xn1 = in; + data.yn2 = data.yn1; + data.yn1 = out; + + obuf[i] = (float) out; + } + + return blockLen; +} + void EffectWahwah::OnFreqSlider(wxCommandEvent & evt) { mFreq = (double) evt.GetInt() / SCL_Freq; diff -Nru audacity-2.0.6+svn20150801+r3549+31~ubuntu14.04.1/src/effects/Wahwah.h audacity-2.0.6+svn20150802+r3559+31~ubuntu14.04.1/src/effects/Wahwah.h --- audacity-2.0.6+svn20150801+r3549+31~ubuntu14.04.1/src/effects/Wahwah.h 2015-08-01 10:16:43.000000000 +0000 +++ audacity-2.0.6+svn20150802+r3559+31~ubuntu14.04.1/src/effects/Wahwah.h 2015-08-02 10:16:33.000000000 +0000 @@ -27,6 +27,21 @@ #define WAHWAH_PLUGIN_SYMBOL XO("Wahwah") +class EffectWahwahState +{ +public: + float samplerate; + double depth; + double freqofs; + double phase; + double lfoskip; + unsigned long skipcount; + double xn1, xn2, yn1, yn2; + double b0, b1, b2, a0, a1, a2; +}; + +WX_DECLARE_OBJARRAY(EffectWahwahState, EffectWahwahStateArray); + class EffectWahwah : public Effect { public: @@ -41,6 +56,7 @@ // EffectIdentInterface implementation virtual EffectType GetType(); + virtual bool SupportsRealtime(); // EffectClientInterface implementation @@ -48,6 +64,13 @@ virtual int GetAudioOutCount(); virtual bool ProcessInitialize(sampleCount totalLen, ChannelNames chanMap = NULL); virtual sampleCount ProcessBlock(float **inBlock, float **outBlock, sampleCount blockLen); + virtual bool RealtimeInitialize(); + virtual bool RealtimeAddProcessor(int numChannels, float sampleRate); + virtual bool RealtimeFinalize(); + virtual sampleCount RealtimeProcess(int group, + float **inbuf, + float **outbuf, + sampleCount numSamples); virtual bool GetAutomationParameters(EffectAutomationParameters & parms); virtual bool SetAutomationParameters(EffectAutomationParameters & parms); @@ -60,6 +83,9 @@ private: // EffectWahwah implementation + void InstanceInit(EffectWahwahState & data, float sampleRate); + sampleCount InstanceProcess(EffectWahwahState & data, float **inBlock, float **outBlock, sampleCount blockLen); + void OnFreqSlider(wxCommandEvent & evt); void OnPhaseSlider(wxCommandEvent & evt); void OnDepthSlider(wxCommandEvent & evt); @@ -73,15 +99,10 @@ void OnFreqOffText(wxCommandEvent & evt); private: - double depth; - double freqofs; - double phase; - double lfoskip; - unsigned long skipcount; - double xn1, xn2, yn1, yn2; - double b0, b1, b2, a0, a1, a2; + EffectWahwahState mMaster; + EffectWahwahStateArray mSlaves; -/* Parameters: + /* Parameters: mFreq - LFO frequency mPhase - LFO startphase in RADIANS - useful for stereo WahWah mDepth - Wah depth diff -Nru audacity-2.0.6+svn20150801+r3549+31~ubuntu14.04.1/src/Experimental.h audacity-2.0.6+svn20150802+r3559+31~ubuntu14.04.1/src/Experimental.h --- audacity-2.0.6+svn20150801+r3549+31~ubuntu14.04.1/src/Experimental.h 2015-08-01 10:16:43.000000000 +0000 +++ audacity-2.0.6+svn20150802+r3559+31~ubuntu14.04.1/src/Experimental.h 2015-08-02 10:16:33.000000000 +0000 @@ -150,6 +150,9 @@ // to enable. #define EXPERIMENTAL_MODULE_PREFS +// Define to allow realtime processing in Audacity effects that have been converted. +#define EXPERIMENTAL_REALTIME_AUDACITY_EFFECTS + // Define to include the effects rack (such as it is). //#define EXPERIMENTAL_EFFECTS_RACK diff -Nru audacity-2.0.6+svn20150801+r3549+31~ubuntu14.04.1/src/FreqWindow.cpp audacity-2.0.6+svn20150802+r3559+31~ubuntu14.04.1/src/FreqWindow.cpp --- audacity-2.0.6+svn20150801+r3549+31~ubuntu14.04.1/src/FreqWindow.cpp 2015-08-01 10:16:43.000000000 +0000 +++ audacity-2.0.6+svn20150802+r3559+31~ubuntu14.04.1/src/FreqWindow.cpp 2015-08-02 10:16:33.000000000 +0000 @@ -641,7 +641,7 @@ void FreqWindow::DrawPlot() { - if (!mData || mDataLen < mWindowSize) { + if (!mData || mDataLen < mWindowSize || mAnalyst->GetProcessedSize() == 0) { wxMemoryDC memDC; vRuler->ruler.SetLog(false); diff -Nru audacity-2.0.6+svn20150801+r3549+31~ubuntu14.04.1/src/prefs/SpectrogramSettings.cpp audacity-2.0.6+svn20150802+r3559+31~ubuntu14.04.1/src/prefs/SpectrogramSettings.cpp --- audacity-2.0.6+svn20150801+r3549+31~ubuntu14.04.1/src/prefs/SpectrogramSettings.cpp 2015-08-01 10:16:43.000000000 +0000 +++ audacity-2.0.6+svn20150802+r3559+31~ubuntu14.04.1/src/prefs/SpectrogramSettings.cpp 2015-08-02 10:16:33.000000000 +0000 @@ -170,10 +170,14 @@ // Keep in correspondence with enum SpectrogramSettings::ScaleType: theArray.Add(_("Linear")); theArray.Add(_("Logarithmic")); + /* i18n-hint: The name of a frequency scale in psychoacoustics */ theArray.Add(_("Mel")); + /* i18n-hint: The name of a frequency scale in psychoacoustics, named for Heinrich Barkhausen */ theArray.Add(_("Bark")); - theArray.Add(_("Erb")); - theArray.Add(_("Undertone")); + /* i18n-hint: The name of a frequency scale in psychoacoustics, abbreviates Equivalent Rectangular Bandwidth */ + theArray.Add(_("ERB")); + /* i18n-hint: A mathematical formula where f stands for frequency */ + theArray.Add(_("1 / f")); } return theArray; diff -Nru audacity-2.0.6+svn20150801+r3549+31~ubuntu14.04.1/src/prefs/SpectrumPrefs.cpp audacity-2.0.6+svn20150802+r3559+31~ubuntu14.04.1/src/prefs/SpectrumPrefs.cpp --- audacity-2.0.6+svn20150801+r3549+31~ubuntu14.04.1/src/prefs/SpectrumPrefs.cpp 2015-08-01 10:16:43.000000000 +0000 +++ audacity-2.0.6+svn20150802+r3559+31~ubuntu14.04.1/src/prefs/SpectrumPrefs.cpp 2015-08-02 10:16:33.000000000 +0000 @@ -157,7 +157,8 @@ { mDefaultsCheckbox = 0; if (mWt) { - mDefaultsCheckbox = S.Id(ID_DEFAULTS).TieCheckBox(_("Defaults"), mDefaulted); + /* i18n-hint: use is a verb */ + mDefaultsCheckbox = S.Id(ID_DEFAULTS).TieCheckBox(_("Use Preferences"), mDefaulted); } S.StartStatic(_("FFT Window")); { diff -Nru audacity-2.0.6+svn20150801+r3549+31~ubuntu14.04.1/src/prefs/WaveformPrefs.cpp audacity-2.0.6+svn20150802+r3559+31~ubuntu14.04.1/src/prefs/WaveformPrefs.cpp --- audacity-2.0.6+svn20150801+r3549+31~ubuntu14.04.1/src/prefs/WaveformPrefs.cpp 2015-08-01 10:16:43.000000000 +0000 +++ audacity-2.0.6+svn20150802+r3559+31~ubuntu14.04.1/src/prefs/WaveformPrefs.cpp 2015-08-02 10:16:33.000000000 +0000 @@ -73,7 +73,8 @@ { mDefaultsCheckbox = 0; if (mWt) { - mDefaultsCheckbox = S.Id(ID_DEFAULTS).TieCheckBox(_("Defaults"), mDefaulted); + /* i18n-hint: use is a verb */ + mDefaultsCheckbox = S.Id(ID_DEFAULTS).TieCheckBox(_("Use Preferences"), mDefaulted); } S.StartStatic(_("Display")); diff -Nru audacity-2.0.6+svn20150801+r3549+31~ubuntu14.04.1/src/TrackPanel.cpp audacity-2.0.6+svn20150802+r3559+31~ubuntu14.04.1/src/TrackPanel.cpp --- audacity-2.0.6+svn20150801+r3549+31~ubuntu14.04.1/src/TrackPanel.cpp 2015-08-01 10:16:43.000000000 +0000 +++ audacity-2.0.6+svn20150802+r3559+31~ubuntu14.04.1/src/TrackPanel.cpp 2015-08-02 10:16:33.000000000 +0000 @@ -156,6 +156,10 @@ *//*****************************************************************/ +// This conditional compilation switch does not need to be seen +// in any other file, so I define it here, not in Experimental.h -- PRL +#undef EXPERIMENTAL_CASCADE_MOVE_MENU +#define EXPERIMENTAL_CASCADE_TCP_MENU #include "Audacity.h" #include "Experimental.h" @@ -336,6 +340,8 @@ OnTimeTrackLogID, OnTimeTrackLogIntID, + ChannelMenuID, + // Reserve an ample block of ids for waveform scale types OnFirstWaveformScaleID, OnLastWaveformScaleID = OnFirstWaveformScaleID + 9, @@ -556,6 +562,7 @@ mNoteTrackMenu = NULL; mLabelTrackMenu = NULL; mTimeTrackMenu = NULL; + mHiddenChannelMenu = mChannelMenuMono = mChannelMenuStereo = NULL; mRulerWaveformMenu = mRulerSpectrumMenu = NULL; @@ -734,17 +741,62 @@ mWaveTrackMenu->Append(OnViewSettingsID, _("&View Settings...")); mWaveTrackMenu->AppendSeparator(); - mWaveTrackMenu->AppendRadioItem(OnChannelMonoID, _("&Mono")); - mWaveTrackMenu->AppendRadioItem(OnChannelLeftID, _("&Left Channel")); - mWaveTrackMenu->AppendRadioItem(OnChannelRightID, _("&Right Channel")); - mWaveTrackMenu->Append(OnMergeStereoID, _("Ma&ke Stereo Track")); - mWaveTrackMenu->Append(OnSwapChannelsID, _("Swap Stereo &Channels")); - mWaveTrackMenu->Append(OnSplitStereoID, _("Spl&it Stereo Track")); - mWaveTrackMenu->Append(OnSplitStereoMonoID, _("Split Stereo to Mo&no")); + // Handle the channels items + { +#ifdef EXPERIMENTAL_CASCADE_TCP_MENU + mChannelMenuMono = new wxMenu(); + mChannelMenuStereo = new wxMenu(); + mHiddenChannelMenu = mChannelMenuMono; + mWaveTrackMenu->Append(ChannelMenuID, _("&Channels"), mChannelMenuStereo); + wxString names[] = { + _("&Mono"), + _("&Left"), + _("&Right"), + _("Make &Stereo"), + + _("S&wap"), + _("S&plit"), + _("Split to &Mono"), + }; +#else + mChannelMenuMono = mChannelMenuStereo = mWaveTrackMenu; + mHiddenChannelMenu = NULL; + wxString names[] = { + _("&Mono"), + _("&Left Channel"), + _("&Right Channel"), + _("Ma&ke Stereo Track"), + + _("Swap Stereo &Channels"), + _("Spl&it Stereo Track"), + _("Split Stereo to Mo&no"), + }; +#endif + + mChannelMenuMono->AppendRadioItem(OnChannelMonoID, names[0]); + mChannelMenuMono->AppendRadioItem(OnChannelLeftID, names[1]); + mChannelMenuMono->AppendRadioItem(OnChannelRightID, names[2]); + mChannelMenuMono->Append(OnMergeStereoID, names[3]); + + mChannelMenuStereo->Append(OnSwapChannelsID, names[4]); + mChannelMenuStereo->Append(OnSplitStereoID, names[5]); + mChannelMenuStereo->Append(OnSplitStereoMonoID, names[6]); + } mWaveTrackMenu->AppendSeparator(); + +#ifdef EXPERIMENTAL_CASCADE_TCP_MENU + mWaveTrackMenu->Append(0, _("&Format"), mFormatMenu); +#else mWaveTrackMenu->Append(0, _("Set Sample &Format"), mFormatMenu); +#endif + mWaveTrackMenu->AppendSeparator(); + +#ifdef EXPERIMENTAL_CASCADE_TCP_MENU + mWaveTrackMenu->Append(0, _("&Rate"), mRateMenu); +#else mWaveTrackMenu->Append(0, _("Set Rat&e"), mRateMenu); +#endif /* build the pop-down menu used on note (MIDI) tracks */ mNoteTrackMenu = new wxMenu(); @@ -763,7 +815,11 @@ mTimeTrackMenu->Append(OnTimeTrackLinID, _("&Linear")); mTimeTrackMenu->Append(OnTimeTrackLogID, _("L&ogarithmic")); mTimeTrackMenu->AppendSeparator(); +#ifdef EXPERIMENTAL_CASCADE_TCP_MENU + mTimeTrackMenu->Append(OnSetTimeTrackRangeID, _("Set &Range...")); +#else mTimeTrackMenu->Append(OnSetTimeTrackRangeID, _("Set Ra&nge...")); +#endif mTimeTrackMenu->AppendCheckItem(OnTimeTrackLogIntID, _("Logarithmic &Interpolation")); mRulerWaveformMenu = new wxMenu(); @@ -779,14 +835,40 @@ void TrackPanel::BuildCommonDropMenuItems(wxMenu * menu) { +#ifdef EXPERIMENTAL_CASCADE_TCP_MENU + menu->Append(OnSetNameID, _("&Name...")); +#else menu->Append(OnSetNameID, _("N&ame...")); - menu->AppendSeparator(); - menu->Append(OnMoveUpID, _("Move Track &Up")); - menu->Append(OnMoveDownID, _("Move Track &Down")); - menu->Append(OnMoveTopID, _("Move Track to &Top")); - menu->Append(OnMoveBottomID, _("Move Track to &Bottom")); +#endif menu->AppendSeparator(); + wxMenu *theMenu; +#ifdef EXPERIMENTAL_CASCADE_MOVE_MENU + wxMenu *const moveMenu = new wxMenu(); + menu->Append(0, _("&Move"), moveMenu); + theMenu = moveMenu; + wxString names[] = { + _("&Up"), + _("&Down"), + _("To &Top"), + _("To &Bottom"), + }; +#else + theMenu = menu; + wxString names[] = { + _("Move Track &Up"), + _("Move Track &Down"), + _("Move Track to &Top"), + _("Move Track to &Bottom"), + }; +#endif + + theMenu->Append(OnMoveUpID, names[0]); + theMenu->Append(OnMoveDownID, names[1]); + theMenu->Append(OnMoveTopID, names[2]); + theMenu->Append(OnMoveBottomID, names[3]); + + menu->AppendSeparator(); } // static @@ -806,6 +888,13 @@ { // Note that the submenus (mRateMenu, ...) // are deleted by their parent + + // ... except for this special swapping of the Channel sub-menus. + // One of them is not managed by the main popup menu. + if (mHiddenChannelMenu) + delete mHiddenChannelMenu; + mHiddenChannelMenu = mChannelMenuMono = mChannelMenuStereo = NULL; + if (mWaveTrackMenu) { delete mWaveTrackMenu; mWaveTrackMenu = NULL; @@ -8324,7 +8413,6 @@ mPopupMenuTarget = t; - bool canMakeStereo = false; Track *next = mTracks->GetNext(t); wxMenu *theMenu = NULL; @@ -8340,31 +8428,55 @@ if (t->GetKind() == Track::Wave) { theMenu = mWaveTrackMenu; - if (next && !t->GetLinked() && !next->GetLinked() - && t->GetKind() == Track::Wave - && next->GetKind() == Track::Wave) - canMakeStereo = true; - - theMenu->Enable(OnSwapChannelsID, t->GetLinked()); - theMenu->Enable(OnMergeStereoID, canMakeStereo); - theMenu->Enable(OnSplitStereoID, t->GetLinked()); - theMenu->Enable(OnSplitStereoMonoID, t->GetLinked()); + + const bool isMono = !t->GetLinked(); + wxMenu *const correctSubMenu = + isMono ? mChannelMenuMono : mChannelMenuStereo; + + const bool canMakeStereo = isMono && + (next && !next->GetLinked() + && t->GetKind() == Track::Wave + && next->GetKind() == Track::Wave); + mChannelMenuMono->Enable(OnMergeStereoID, canMakeStereo); // We only need to set check marks. Clearing checks causes problems on Linux (bug 851) switch (t->GetChannel()) { case Track::LeftChannel: - theMenu->Check(OnChannelLeftID, true); + mChannelMenuMono->Check(OnChannelLeftID, true); break; case Track::RightChannel: - theMenu->Check(OnChannelRightID, true); + mChannelMenuMono->Check(OnChannelRightID, true); break; default: - theMenu->Check(OnChannelMonoID, true); + mChannelMenuMono->Check(OnChannelMonoID, true); } - theMenu->Enable(OnChannelMonoID, !t->GetLinked()); - theMenu->Enable(OnChannelLeftID, !t->GetLinked()); - theMenu->Enable(OnChannelRightID, !t->GetLinked()); +#ifdef EXPERIMENTAL_CASCADE_TCP_MENU + // Swap in appropriate Channels sub-menu. + if (correctSubMenu == mHiddenChannelMenu) { + wxMenu *const otherSubMenu = + isMono ? mChannelMenuStereo : mChannelMenuMono; + size_t position; + wxMenuItem *const pItem = + theMenu->FindChildItem(ChannelMenuID, &position); + wxASSERT(pItem->GetSubMenu() == otherSubMenu); + theMenu->Remove(pItem); + pItem->SetSubMenu(0); + delete pItem; + theMenu->Insert(position, ChannelMenuID, + isMono ? _("&Channel") : _("&Channels"), + correctSubMenu); + mHiddenChannelMenu = otherSubMenu; + } +#else + mChannelMenuStereo->Enable(OnSwapChannelsID, !isMono); + mChannelMenuStereo->Enable(OnSplitStereoID, !isMono); + mChannelMenuStereo->Enable(OnSplitStereoMonoID, !isMono); + + mChannelMenuMono->Enable(OnChannelMonoID, isMono); + mChannelMenuMono->Enable(OnChannelLeftID, isMono); + mChannelMenuMono->Enable(OnChannelRightID, isMono); +#endif const int display = static_cast(t)->GetDisplay(); theMenu->Check( @@ -8745,6 +8857,10 @@ void TrackPanel::OnSwapChannels(wxCommandEvent & WXUNUSED(event)) { Track *partner = mPopupMenuTarget->GetLink(); + Track *const focused = GetFocusedTrack(); + const bool hasFocus = + (focused == mPopupMenuTarget || focused == partner); + SplitStereo(true); mPopupMenuTarget->SetChannel(Track::RightChannel); partner->SetChannel(Track::LeftChannel); @@ -8757,6 +8873,9 @@ pMixerBoard->UpdateTrackClusters(); } + if (hasFocus) + SetFocusedTrack(partner); + MakeParentPushState(wxString::Format(_("Swapped Channels in '%s'"), mPopupMenuTarget->GetName().c_str()), _("Swap Channels")); @@ -9249,6 +9368,7 @@ void TrackPanel::OnWaveformScaleType(wxCommandEvent &evt) { WaveTrack *const wt = static_cast(mPopupMenuTarget); + WaveTrack *const partner = static_cast(wt->GetLink()); const WaveformSettings::ScaleType newScaleType = WaveformSettings::ScaleType( std::max(0, @@ -9257,6 +9377,8 @@ ))); if (wt->GetWaveformSettings().scaleType != newScaleType) { wt->GetIndependentWaveformSettings().scaleType = newScaleType; + if (partner) + partner->GetIndependentWaveformSettings().scaleType = newScaleType; UpdateVRuler(wt); // Is this really needed? MakeParentModifyState(true); Refresh(false); @@ -9266,6 +9388,7 @@ void TrackPanel::OnSpectrumScaleType(wxCommandEvent &evt) { WaveTrack *const wt = static_cast(mPopupMenuTarget); + WaveTrack *const partner = static_cast(wt->GetLink()); const SpectrogramSettings::ScaleType newScaleType = SpectrogramSettings::ScaleType( std::max(0, @@ -9274,6 +9397,8 @@ ))); if (wt->GetSpectrogramSettings().scaleType != newScaleType) { wt->GetIndependentSpectrogramSettings().scaleType = newScaleType; + if (partner) + partner->GetIndependentSpectrogramSettings().scaleType = newScaleType; UpdateVRuler(wt); // Is this really needed? MakeParentModifyState(true); Refresh(false); diff -Nru audacity-2.0.6+svn20150801+r3549+31~ubuntu14.04.1/src/TrackPanel.h audacity-2.0.6+svn20150802+r3559+31~ubuntu14.04.1/src/TrackPanel.h --- audacity-2.0.6+svn20150801+r3549+31~ubuntu14.04.1/src/TrackPanel.h 2015-08-01 10:16:43.000000000 +0000 +++ audacity-2.0.6+svn20150802+r3559+31~ubuntu14.04.1/src/TrackPanel.h 2015-08-02 10:16:33.000000000 +0000 @@ -830,6 +830,10 @@ wxMenu *mRulerWaveformMenu; wxMenu *mRulerSpectrumMenu; + wxMenu *mChannelMenuMono; + wxMenu *mChannelMenuStereo; + wxMenu *mHiddenChannelMenu; + Track *mPopupMenuTarget; friend class TrackPanelAx;