From 90e400b0a7e2b1dbab471d9df9463d4ea1bddd7e Mon Sep 17 00:00:00 2001 From: Steve Daulton Date: Sat, 13 Aug 2016 17:27:55 +0100 Subject: [PATCH] Add SBSMS option to Change Pitch effect --- src/effects/ChangePitch.cpp | 76 +++++++++++++++++++++++++++++-------- src/effects/ChangePitch.h | 10 +++++ src/effects/SBSMSEffect.cpp | 6 +++ src/effects/SBSMSEffect.h | 1 + 4 files changed, 78 insertions(+), 15 deletions(-) diff --git a/src/effects/ChangePitch.cpp b/src/effects/ChangePitch.cpp index f29272001..bc8da84ee 100644 --- a/src/effects/ChangePitch.cpp +++ b/src/effects/ChangePitch.cpp @@ -18,9 +18,13 @@ the pitch without changing the tempo. #include "../Audacity.h" // for USE_SOUNDTOUCH #if USE_SOUNDTOUCH - #include "ChangePitch.h" +#if USE_SBSMS +#include "sbsms.h" +#include +#endif + #include #include @@ -51,6 +55,7 @@ enum { // // Name Type Key Def Min Max Scale Param( Percentage, double, XO("Percentage"), 0.0, -99.0, 3000.0, 1 ); +Param( UseSBSMS, bool, XO("SBSMS"), false, false, true, 1 ); // We warp the slider to go up to 400%, but user can enter up to 3000% static const double kSliderMax = 100.0; // warped above zero to actually go up to 400% @@ -80,6 +85,12 @@ EffectChangePitch::EffectChangePitch() m_dStartFrequency = 0.0; // 0.0 => uninitialized m_bLoopDetect = false; +#if USE_SBSMS + mUseSBSMS = DEF_UseSBSMS; +#else + mUseSBSMS = false; +#endif + // NULL out these control members because there are some cases where the // event table handlers get called during this method, and those handlers that // can cause trouble check for NULL. @@ -127,6 +138,7 @@ EffectType EffectChangePitch::GetType() bool EffectChangePitch::GetAutomationParameters(EffectAutomationParameters & parms) { parms.Write(KEY_Percentage, m_dPercentChange); + parms.Write(KEY_UseSBSMS, mUseSBSMS); return true; } @@ -140,6 +152,13 @@ bool EffectChangePitch::SetAutomationParameters(EffectAutomationParameters & par m_dPercentChange = Percentage; Calc_SemitonesChange_fromPercentChange(); +#if USE_SBSMS + ReadAndVerifyBool(UseSBSMS); + mUseSBSMS = UseSBSMS; +#else + mUseSBSMS = false; +#endif + return true; } @@ -160,20 +179,37 @@ bool EffectChangePitch::Init() bool EffectChangePitch::Process() { - mSoundTouch = std::make_unique(); - SetTimeWarper(std::make_unique()); - mSoundTouch->setPitchSemiTones((float)(m_dSemitonesChange)); -#ifdef USE_MIDI - // Note: m_dSemitonesChange is private to ChangePitch because it only - // needs to pass it along to mSoundTouch (above). I added mSemitones - // to SoundTouchEffect (the super class) to convey this value - // to process Note tracks. This approach minimizes changes to existing - // code, but it would be cleaner to change all m_dSemitonesChange to - // mSemitones, make mSemitones exist with or without USE_MIDI, and - // eliminate the next line: - mSemitones = m_dSemitonesChange; +#if USE_SBSMS + if (mUseSBSMS) + { + double pitchRatio = 1.0 + m_dPercentChange / 100.0; + SelectedRegion region(mT0, mT1); + EffectSBSMS proxy; + proxy.setParameters(1.0, pitchRatio); + + return proxy.DoEffect(mUIParent, mProjectRate, mTracks, mFactory, ®ion, false); + } + else #endif - return EffectSoundTouch::Process(); + { + mSoundTouch = std::make_unique(); + SetTimeWarper(std::make_unique()); + mSoundTouch->setPitchSemiTones((float)(m_dSemitonesChange)); +#ifdef USE_MIDI + // Pitch shifting note tracks is currently only supported by SoundTouchEffect + // and non-real-time-preview effects require an audio track selection. + // + // Note: m_dSemitonesChange is private to ChangePitch because it only + // needs to pass it along to mSoundTouch (above). I added mSemitones + // to SoundTouchEffect (the super class) to convey this value + // to process Note tracks. This approach minimizes changes to existing + // code, but it would be cleaner to change all m_dSemitonesChange to + // mSemitones, make mSemitones exist with or without USE_MIDI, and + // eliminate the next line: + mSemitones = m_dSemitonesChange; +#endif + return EffectSoundTouch::Process(); + } } bool EffectChangePitch::CheckWhetherSkipEffect() @@ -287,6 +323,17 @@ void EffectChangePitch::PopulateOrExchange(ShuttleGui & S) S.EndHorizontalLay(); } S.EndStatic(); + +#if USE_SBSMS + S.StartMultiColumn(2); + { + mUseSBSMSCheckBox = S.AddCheckBox(_("Use high quality stretching (slow)"), + mUseSBSMS? wxT("true") : wxT("false")); + mUseSBSMSCheckBox->SetValidator(wxGenericValidator(&mUseSBSMS)); + } + S.EndMultiColumn(); +#endif + } S.EndVerticalLay(); @@ -460,7 +507,6 @@ void EffectChangePitch::Calc_PercentChange() // handlers - void EffectChangePitch::OnChoice_FromPitch(wxCommandEvent & WXUNUSED(evt)) { if (m_bLoopDetect) diff --git a/src/effects/ChangePitch.h b/src/effects/ChangePitch.h index 5828f4db0..6de394d86 100644 --- a/src/effects/ChangePitch.h +++ b/src/effects/ChangePitch.h @@ -20,6 +20,11 @@ the pitch without changing the tempo. #ifndef __AUDACITY_EFFECT_CHANGEPITCH__ #define __AUDACITY_EFFECT_CHANGEPITCH__ +#if USE_SBSMS +#include "SBSMSEffect.h" +#include +#endif + #include #include #include @@ -108,6 +113,7 @@ private: void Update_Slider_PercentChange(); // Update control per current m_dPercentChange. private: + bool mUseSBSMS; // effect parameters int m_nFromPitch; // per PitchIndex() int m_nFromOctave; // per PitchOctave() @@ -136,6 +142,10 @@ private: wxTextCtrl * m_pTextCtrl_PercentChange; wxSlider * m_pSlider_PercentChange; +#if USE_SBSMS + wxCheckBox * mUseSBSMSCheckBox; +#endif + DECLARE_EVENT_TABLE(); }; diff --git a/src/effects/SBSMSEffect.cpp b/src/effects/SBSMSEffect.cpp index 27279dbb2..596a4b678 100644 --- a/src/effects/SBSMSEffect.cpp +++ b/src/effects/SBSMSEffect.cpp @@ -156,6 +156,12 @@ void EffectSBSMS :: setParameters(double rateStart, double rateEnd, double pitch this->bPitchReferenceInput = bPitchReferenceInput; } +void EffectSBSMS::setParameters(double tempoRatio, double pitchRatio) +{ + setParameters(tempoRatio, tempoRatio, pitchRatio, pitchRatio, + SlideConstant, SlideConstant, false, false, false); +} + std::unique_ptr createTimeWarper(double t0, double t1, double duration, double rateStart, double rateEnd, SlideType rateSlideType) { diff --git a/src/effects/SBSMSEffect.h b/src/effects/SBSMSEffect.h index ddbb6caef..fd5da4648 100644 --- a/src/effects/SBSMSEffect.h +++ b/src/effects/SBSMSEffect.h @@ -28,6 +28,7 @@ public: void setParameters(double rateStart, double rateEnd, double pitchStart, double pitchEnd, SlideType rateSlideType, SlideType pitchSlideType, bool bLinkRatePitch, bool bRateReferenceInput, bool bPitchReferenceInput); + void setParameters(double tempoRatio, double pitchRatio); // Constant ratio (tempoRatio, pitchRatio) static double getInvertedStretchedTime(double rateStart, double rateEnd, SlideType slideType, double outputTime); static double getRate(double rateStart, double rateEnd, SlideType slideType, double t); private: