オーディオプラグインの作成、パート15

シリーズのすべての投稿:

パート1.紹介とセットアップ

パート2.コードの学習

パート3. VSTおよびAU

パート4.デジタル歪み

パート5.プリセットとGUI

パート6.信号合成

パート7. MIDIメッセージの受信

パート8.仮想キーボード

パート9.封筒

パート10. GUIの改善

パート11.フィルター

パート12.低周波発振器

パート13.再設計

パート14.ポリフォニー1

パート15.ポリフォニー2

パート16.アンチエイリアス




この投稿では、ポリフォニーの作業を終了します。コードをとかし、GUIを動作状態にします。







土曜日





MIDIReceiver



から始めましょう。 構造はポリフォニックになっているため、 mLast



変数は必要ありません。 MIDIReceiver.hから、初期化とゲッターを含むmLastVelocity



、 mLastNoteNumber



、 mLastFrequency



を削除します。 getLastNoteNumber



、 getLastFrequency



およびgetLastVelocity



noteNumberToFrequency



も削除しnoteNumberToFrequency



。 念のため、クラスは次のようになります。



 class MIDIReceiver { private: IMidiQueue mMidiQueue; static const int keyCount = 128; int mNumKeys; // how many keys are being played at the moment (via midi) bool mKeyStatus[keyCount]; // array of on/off for each key (index is note number) int mOffset; public: MIDIReceiver() : mNumKeys(0), mOffset(0) { for (int i = 0; i < keyCount; i++) { mKeyStatus[i] = false; } }; // Returns true if the key with a given index is currently pressed inline bool getKeyStatus(int keyIndex) const { return mKeyStatus[keyIndex]; } // Returns the number of keys currently pressed inline int getNumKeys() const { return mNumKeys; } void advance(); void onMessageReceived(IMidiMsg* midiMessage); inline void Flush(int nFrames) { mMidiQueue.Flush(nFrames); mOffset = 0; } inline void Resize(int blockSize) { mMidiQueue.Resize(blockSize); } Signal2< int, int > noteOn; Signal2< int, int > noteOff; };
      
      







MIDIReceiver.cppのadvance



機能を変更します 。



 void MIDIReceiver::advance() { while (!mMidiQueue.Empty()) { IMidiMsg* midiMessage = mMidiQueue.Peek(); if (midiMessage->mOffset > mOffset) break; IMidiMsg::EStatusMsg status = midiMessage->StatusMsg(); int noteNumber = midiMessage->NoteNumber(); int velocity = midiMessage->Velocity(); // There are only note on/off messages in the queue, see ::OnMessageReceived if (status == IMidiMsg::kNoteOn && velocity) { if(mKeyStatus[noteNumber] == false) { mKeyStatus[noteNumber] = true; mNumKeys += 1; noteOn(noteNumber, velocity); } } else { if(mKeyStatus[noteNumber] == true) { mKeyStatus[noteNumber] = false; mNumKeys -= 1; noteOff(noteNumber, velocity); } } mMidiQueue.Remove(); } mOffset++; }
      
      







ここでは3つのことが変更されました。







SpaceBass.hに渡します。 ここでは、次のものを削除する必要があります。





コードは見た目が良いですね。 プラグインクラスは、 VoiceManager



とのVoiceManager



相互作用しなくなりVoiceManager



。

private



セクションに追加します。



 VoiceManager voiceManager;
      
      







SpaceBass.cppのクラスコンストラクターを変更します 。



 SpaceBass::SpaceBass(IPlugInstanceInfo instanceInfo) : IPLUG_CTOR(kNumParams, kNumPrograms, instanceInfo), lastVirtualKeyboardNoteNumber(virtualKeyboardMinimumNoteNumber - 1) { TRACE; CreateParams(); CreateGraphics(); CreatePresets(); mMIDIReceiver.noteOn.Connect(&voiceManager, &VoiceManager::onNoteOn); mMIDIReceiver.noteOff.Connect(&voiceManager, &VoiceManager::onNoteOff); }
      
      







mMIDIReceiver



、プラグインクラスではなくVoiceManager



に接続されました。 EnvelopeGenerator



VoiceManager



クラスとVoice



クラスによって管理されるようになったため、それらをConnect()



フックしなくなりました。

今、コンパイラは誓います ProcessDoubleReplacing



は、削除したばかりのものを指します。 新しい実装は非常に簡単です。これはVoiceManager::nextSample



へのVoiceManager::nextSample



:



 void SpaceBass::ProcessDoubleReplacing( double** inputs, double** outputs, int nFrames) { // Mutex is already locked for us. double *leftOutput = outputs[0]; double *rightOutput = outputs[1]; processVirtualKeyboard(); for (int i = 0; i < nFrames; ++i) { mMIDIReceiver.advance(); leftOutput[i] = rightOutput[i] = voiceManager.nextSample(); } mMIDIReceiver.Flush(nFrames); }
      
      







オシレーター、エンベロープジェネレーター、フィルターとの相互作用がすべて消えていることに注意してください。

Reset()



本体では、これらのコンポーネントにアクセスできなくなったため、 VoiceManager



ですべてのコンポーネントのサンプリングレートを変更する必要があります。



 void SpaceBass::Reset() { TRACE; IMutexLock lock(this); double sampleRate = GetSampleRate(); voiceManager.setSampleRate(sampleRate); }
      
      







setSampleRate



はまだ実装されていません。VoiceManager.hヘッダーの public



セクションに追加します。



 void setSampleRate(double sampleRate) { EnvelopeGenerator::setSampleRate(sampleRate); for (int i = 0; i < NumberOfVoices; i++) { Voice& voice = voices[i]; voice.mOscillatorOne.setSampleRate(sampleRate); voice.mOscillatorTwo.setSampleRate(sampleRate); } mLFO.setSampleRate(sampleRate); }
      
      







基本的に、この関数は、各音声および各コンポーネントに対してsetSampleRate



を呼び出すだけです。 Oscillator::mSampleRate



静的に呼び出すことができますが、それでも各音声の両方のオシレーターに対してupdateIncrement



を呼び出すupdateIncrement



があります。 しかし、私の意見では、最初のオプションはより透明です。



インターフェイスハンドルが機能しないことを除いて、すべてが正常になりました。 しかし、それらを完成する前に、オシレーターのトーン変調を追加しましょう。



トーン変調





これまで、リファクタリングはほとんど構造的でした。コードの一部をプラグイン構造の別の部分に移動し、不要な部分をすべて削除しました。 私はこの時点までトーンの変調を延期しました、なぜなら それはポリフォニーとは何の関係もありません;私はすべてを1つの山に入れたくありませんでした。



関数Voice::nextSample



return



直前に以下return



追加します。



 mOscillatorOne.setPitchMod(mLFOValue * mOscillatorOnePitchAmount); mOscillatorTwo.setPitchMod(mLFOValue * mOscillatorTwoPitchAmount);
      
      







ご覧のとおり、トーンのモジュレーション値は、GUIノブに関連付けられたパラメーターの値を掛けたLFO値によって決まります。

Oscillator.hのprivate



セクションに追加します。



 double mPitchMod;
      
      







そして、コンストラクターの初期化リストに:



 mPitchMod(0.0),
      
      







public



セクションでは、セッターが必要です。



 void setPitchMod(double amount);
      
      







Oscillator.cppに関数自体を記述します。



 void Oscillator::setPitchMod(double amount) { mPitchMod = amount; updateIncrement(); }
      
      







トーンの変調値を設定することにより、再生周波数自体を変更するため、 updateIncrement



を呼び出す必要があります。 そして、この関数内では、何らかの形でmPitchMod



を考慮する必要があります。 updateIncrement



書き換えましょう:



 void Oscillator::updateIncrement() { double pitchModAsFrequency = pow(2.0, fabs(mPitchMod) * 14.0) - 1; if (mPitchMod < 0) { pitchModAsFrequency = -pitchModAsFrequency; }
      
      







ここで何が起こっていますか? mPitchMode



は-1



から1



まで変化しますが、491.3 Hzの表現をプラスする方が便利です。 pow



はヘルツへの変換に役立ちますが、 fabs



呼び出すと負の値が失われfabs



(絶対値)。 次のif



は負の値を返します。 最後に1を引く必要がありますmPitchMod



がゼロのとき、式pow(2.0, 0)



mPitchMod



pow(2.0, 0)



は1



を与え、1 Hzのトーン変調を得るためです。これは間違っています。

次に、基本周波数mFrequency



と取得したヘルツ単位の値からCalculatedFrequencyを計算しcalculatedFrequency



。



  double calculatedFrequency = fmin(fmax(mFrequency + pitchModAsFrequency, 0), mSampleRate/2.0);
      
      







まず、これらの2つの周波数を追加します。 fmin



は、サンプリングレートの半分を超えないようにします。 ナイキスト周波数を超えてはなりません。そうしないと、エイリアシングが発生します。 fmax



は、周波数がゼロを下回らないようにします。

さて、位相増分を追加します。



  mPhaseIncrement = calculatedFrequency * 2 * mPI / mSampleRate; }
      
      







もちろん、今はcalculatedFrequency



を使用しているcalculatedFrequency



を除いて、すべてが以前と同じです。



インターフェイスハンドル





パズルの最後のピース! その後、シンセの準備が整います!



LFOノブから始めましょう。 それらは音声に影響を与えないので、それらに関してはすべてが他のパラメーターと多少異なります。 OnParamChange



関数OnParamChange



新しい関数に置き換えます。



 void SpaceBass::OnParamChange(int paramIdx) { IMutexLock lock(this); IParam* param = GetParam(paramIdx); if(paramIdx == mLFOWaveform) { voiceManager.setLFOMode(static_cast<Oscillator::OscillatorMode>(param->Int())); } else if(paramIdx == mLFOFrequency) { voiceManager.setLFOFrequency(param->Value()); } }
      
      







どのパラメーターが変化しているかを確認し、 setLFOMode



またはsetLFOFrequency



を呼び出します。 これらの2つの関数はまだ作成されていません。VoiceManager.hの public



セクションで実行してみましょう。



 inline void setLFOMode(Oscillator::OscillatorMode mode) { mLFO.setMode(mode); }; inline void setLFOFrequency(double frequency) { mLFO.setFrequency(frequency); };
      
      







ご覧のとおり、どちらもmLFO



セッターを呼び出すだけです。



他のパラメーターには、C ++の機能メカニズムを使用します 。 これらは非常に強力で便利なものですが、言語ガイドではあまり話されていません。 それらについて知る価値があることに同意すると思います。 では、これはどのような問題ですか?



ノブを回すと、パラメーターIDとその値でOnParamChange



がOnParamChange



れます。 0.3



値でmFilterCutoff



と言います。 次にVoiceManager



次のVoiceManager



。 「各Voice



に0.3



フィルタースライスを設定します
。 」 さらに、おそらく、次のようなsetFilterCutoffForEachVoice



関数を呼び出します(デモのためだけに示します)。



 VoiceManager::setFilterCutoffForEachVoice(double newCutoff) { for (int i = 0; i < NumberOfVoices; i++) { voice[i].mFilter.setCutoff(newCutoff); } }
      
      







すべてがうまくいくように思えますが、異なるパラメーターに対して約10個のそのような関数が必要になります。 それぞれがわずかに異なりますがfor



すべて同じです。 「これは変更です。 すべての投票に適用する必要があります 。 」と言うことができればうれしいです。 C ++では、そのような機会は自然に存在します。 関数を取得し、最初にいくつかの入力値を入力し、それを呼び出してさまざまなものを処理できます。 これはJavaScriptのFunction.prototype.bindに似ていますが、データ型の互換性チェックのみがあります。

このアプローチを試してみましょう! VoiceManager.hに追加します 。



 #include <tr1/functional> // #include <functional> if that doesn't work
      
      







public



追加:



 typedef std::tr1::function<void (Voice&)> VoiceChangerFunction;
      
      







VoiceChangerFunction



は、 Voice&



を最初のパラメーターとして取り、 void



を返す関数です。 実際、これが関数である必要はまったくありません。 ()



で呼び出すことができるものはすべて()



。

その後、関数を追加します。



 inline void changeAllVoices(VoiceChangerFunction changer) { for (int i = 0; i < NumberOfVoices; i++) { changer(voices[i]); } }
      
      







VoiceChangerFunction



、すべてのボイスをVoiceChangerFunction



し、すべてのボイスに適用します。

この下に、関数自体を追加します。 それらはすべてほぼ同じように見えます。それぞれが音声と音声およびその他のパラメーターへのリンクを取り、その音声を変更します。



 // Functions to change a single voice: static void setVolumeEnvelopeStageValue(Voice& voice, EnvelopeGenerator::EnvelopeStage stage, double value) { voice.mVolumeEnvelope.setStageValue(stage, value); } static void setFilterEnvelopeStageValue(Voice& voice, EnvelopeGenerator::EnvelopeStage stage, double value) { voice.mFilterEnvelope.setStageValue(stage, value); } static void setOscillatorMode(Voice& voice, int oscillatorNumber, Oscillator::OscillatorMode mode) { switch (oscillatorNumber) { case 1: voice.mOscillatorOne.setMode(mode); break; case 2: voice.mOscillatorTwo.setMode(mode); break; } } static void setOscillatorPitchMod(Voice& voice, int oscillatorNumber, double amount) { switch (oscillatorNumber) { case 1: voice.setOscillatorOnePitchAmount(amount); break; case 2: voice.setOscillatorTwoPitchAmount(amount); break; } } static void setOscillatorMix(Voice& voice, double value) { voice.setOscillatorMix(value); } static void setFilterCutoff(Voice& voice, double cutoff) { voice.mFilter.setCutoff(cutoff); } static void setFilterResonance(Voice& voice, double resonance) { voice.mFilter.setResonance(resonance); } static void setFilterMode(Voice& voice, Filter::FilterMode mode) { voice.mFilter.setFilterMode(mode); } static void setFilterEnvAmount(Voice& voice, double amount) { voice.setFilterEnvelopeAmount(amount); } static void setFilterLFOAmount(Voice& voice, double amount) { voice.setFilterLFOAmount(amount); }
      
      







ただし、それらをchangeAllVoices



関数に渡すことはできません。 誰もが複数の引数を取るため、 VoiceChangerFunction



関数ではありません。 最初の( Voice&



)を除くすべての引数を事前に入力します。 そして、これはそれらをVoiceChangerFunction



関数にVoiceChangerFunction



ます。

SpaceBass.cppで 、 #include <tr1/functional>



(または#include ). OnParamChange else



, :



// ... } else { using std::tr1::placeholders::_1; using std::tr1::bind; VoiceManager::VoiceChangerFunction changer; switch(paramIdx) { // We'll add this part in a moment } voiceManager.changeAllVoices(changer); } }







, std::tr1::



. _1



bind



( ). VoiceChangerFunction



. switch



changer



ID . changeAllVoices



, changer



.



changer



?



, std::tr1::bind



, Voice&







VoiceChangerFunction



. , , . case



switch(paramIdx)



:



case mOsc1Waveform: changer = bind(&VoiceManager::setOscillatorMode, _1, 1, static_cast<Oscillator::OscillatorMode>(param->Int())); break;







(. bind) , . setOscillatorMode



. - . _1



, . changer



. changer



Voice&



. : 1



. OscillatorMode enum



.



changer



. . , , :



case mOsc1PitchMod: changer = bind(&VoiceManager::setOscillatorPitchMod, _1, 1, param->Value()); break; case mOsc2Waveform: changer = bind(&VoiceManager::setOscillatorMode, _1, 2, static_cast<Oscillator::OscillatorMode>(param->Int())); break; case mOsc2PitchMod: changer = bind(&VoiceManager::setOscillatorPitchMod, _1, 2, param->Value()); break; case mOscMix: changer = bind(&VoiceManager::setOscillatorMix, _1, param->Value()); break; // Filter Section: case mFilterMode: changer = bind(&VoiceManager::setFilterMode, _1, static_cast<Filter::FilterMode>(param->Int())); break; case mFilterCutoff: changer = bind(&VoiceManager::setFilterCutoff, _1, param->Value()); break; case mFilterResonance: changer = bind(&VoiceManager::setFilterResonance, _1, param->Value()); break; case mFilterLfoAmount: changer = bind(&VoiceManager::setFilterLFOAmount, _1, param->Value()); break; case mFilterEnvAmount: changer = bind(&VoiceManager::setFilterEnvAmount, _1, param->Value()); break; // Volume Envelope: case mVolumeEnvAttack: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_ATTACK, param->Value()); break; case mVolumeEnvDecay: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_DECAY, param->Value()); break; case mVolumeEnvSustain: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_SUSTAIN, param->Value()); break; case mVolumeEnvRelease: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_RELEASE, param->Value()); break; // Filter Envelope: case mFilterEnvAttack: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_ATTACK, param->Value()); break; case mFilterEnvDecay: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_DECAY, param->Value()); break; case mFilterEnvSustain: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_SUSTAIN, param->Value()); break; case mFilterEnvRelease: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_RELEASE, param->Value()); break;







: changer



- enum



.

- VoiceManager



, changeAllVoices



. .



!



, ! , , , . .



.



, .



.








追加し#include ). OnParamChange else



, :



// ... } else { using std::tr1::placeholders::_1; using std::tr1::bind; VoiceManager::VoiceChangerFunction changer; switch(paramIdx) { // We'll add this part in a moment } voiceManager.changeAllVoices(changer); } }







, std::tr1::



. _1



bind



( ). VoiceChangerFunction



. switch



changer



ID . changeAllVoices



, changer



.



changer



?



, std::tr1::bind



, Voice&







VoiceChangerFunction



. , , . case



switch(paramIdx)



:



case mOsc1Waveform: changer = bind(&VoiceManager::setOscillatorMode, _1, 1, static_cast<Oscillator::OscillatorMode>(param->Int())); break;







(. bind) , . setOscillatorMode



. - . _1



, . changer



. changer



Voice&



. : 1



. OscillatorMode enum



.



changer



. . , , :



case mOsc1PitchMod: changer = bind(&VoiceManager::setOscillatorPitchMod, _1, 1, param->Value()); break; case mOsc2Waveform: changer = bind(&VoiceManager::setOscillatorMode, _1, 2, static_cast<Oscillator::OscillatorMode>(param->Int())); break; case mOsc2PitchMod: changer = bind(&VoiceManager::setOscillatorPitchMod, _1, 2, param->Value()); break; case mOscMix: changer = bind(&VoiceManager::setOscillatorMix, _1, param->Value()); break; // Filter Section: case mFilterMode: changer = bind(&VoiceManager::setFilterMode, _1, static_cast<Filter::FilterMode>(param->Int())); break; case mFilterCutoff: changer = bind(&VoiceManager::setFilterCutoff, _1, param->Value()); break; case mFilterResonance: changer = bind(&VoiceManager::setFilterResonance, _1, param->Value()); break; case mFilterLfoAmount: changer = bind(&VoiceManager::setFilterLFOAmount, _1, param->Value()); break; case mFilterEnvAmount: changer = bind(&VoiceManager::setFilterEnvAmount, _1, param->Value()); break; // Volume Envelope: case mVolumeEnvAttack: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_ATTACK, param->Value()); break; case mVolumeEnvDecay: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_DECAY, param->Value()); break; case mVolumeEnvSustain: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_SUSTAIN, param->Value()); break; case mVolumeEnvRelease: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_RELEASE, param->Value()); break; // Filter Envelope: case mFilterEnvAttack: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_ATTACK, param->Value()); break; case mFilterEnvDecay: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_DECAY, param->Value()); break; case mFilterEnvSustain: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_SUSTAIN, param->Value()); break; case mFilterEnvRelease: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_RELEASE, param->Value()); break;







: changer



- enum



.

- VoiceManager



, changeAllVoices



. .



!



, ! , , , . .



.



, .



.








#include ). OnParamChange



else



, :



// ... } else { using std::tr1::placeholders::_1; using std::tr1::bind; VoiceManager::VoiceChangerFunction changer; switch(paramIdx) { // We'll add this part in a moment } voiceManager.changeAllVoices(changer); } }







, std::tr1::



. _1



bind



( ). VoiceChangerFunction



. switch



changer



ID . changeAllVoices



, changer



.



changer



?



, std::tr1::bind



, Voice&







VoiceChangerFunction



. , , . case



switch(paramIdx)



:



case mOsc1Waveform: changer = bind(&VoiceManager::setOscillatorMode, _1, 1, static_cast<Oscillator::OscillatorMode>(param->Int())); break;







(. bind) , . setOscillatorMode



. - . _1



, . changer



. changer



Voice&



. : 1



. OscillatorMode enum



.



changer



. . , , :



case mOsc1PitchMod: changer = bind(&VoiceManager::setOscillatorPitchMod, _1, 1, param->Value()); break; case mOsc2Waveform: changer = bind(&VoiceManager::setOscillatorMode, _1, 2, static_cast<Oscillator::OscillatorMode>(param->Int())); break; case mOsc2PitchMod: changer = bind(&VoiceManager::setOscillatorPitchMod, _1, 2, param->Value()); break; case mOscMix: changer = bind(&VoiceManager::setOscillatorMix, _1, param->Value()); break; // Filter Section: case mFilterMode: changer = bind(&VoiceManager::setFilterMode, _1, static_cast<Filter::FilterMode>(param->Int())); break; case mFilterCutoff: changer = bind(&VoiceManager::setFilterCutoff, _1, param->Value()); break; case mFilterResonance: changer = bind(&VoiceManager::setFilterResonance, _1, param->Value()); break; case mFilterLfoAmount: changer = bind(&VoiceManager::setFilterLFOAmount, _1, param->Value()); break; case mFilterEnvAmount: changer = bind(&VoiceManager::setFilterEnvAmount, _1, param->Value()); break; // Volume Envelope: case mVolumeEnvAttack: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_ATTACK, param->Value()); break; case mVolumeEnvDecay: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_DECAY, param->Value()); break; case mVolumeEnvSustain: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_SUSTAIN, param->Value()); break; case mVolumeEnvRelease: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_RELEASE, param->Value()); break; // Filter Envelope: case mFilterEnvAttack: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_ATTACK, param->Value()); break; case mFilterEnvDecay: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_DECAY, param->Value()); break; case mFilterEnvSustain: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_SUSTAIN, param->Value()); break; case mFilterEnvRelease: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_RELEASE, param->Value()); break;







: changer



- enum



.

- VoiceManager



, changeAllVoices



. .



!



, ! , , , . .



.



, .



.




 #include ).   OnParamChange
      
      



else



, :



// ... } else { using std::tr1::placeholders::_1; using std::tr1::bind; VoiceManager::VoiceChangerFunction changer; switch(paramIdx) { // We'll add this part in a moment } voiceManager.changeAllVoices(changer); } }







, std::tr1::



. _1



bind



( ). VoiceChangerFunction



. switch



changer



ID . changeAllVoices



, changer



.



changer



?



, std::tr1::bind



, Voice&







VoiceChangerFunction



. , , . case



switch(paramIdx)



:



case mOsc1Waveform: changer = bind(&VoiceManager::setOscillatorMode, _1, 1, static_cast<Oscillator::OscillatorMode>(param->Int())); break;







(. bind) , . setOscillatorMode



. - . _1



, . changer



. changer



Voice&



. : 1



. OscillatorMode enum



.



changer



. . , , :



case mOsc1PitchMod: changer = bind(&VoiceManager::setOscillatorPitchMod, _1, 1, param->Value()); break; case mOsc2Waveform: changer = bind(&VoiceManager::setOscillatorMode, _1, 2, static_cast<Oscillator::OscillatorMode>(param->Int())); break; case mOsc2PitchMod: changer = bind(&VoiceManager::setOscillatorPitchMod, _1, 2, param->Value()); break; case mOscMix: changer = bind(&VoiceManager::setOscillatorMix, _1, param->Value()); break; // Filter Section: case mFilterMode: changer = bind(&VoiceManager::setFilterMode, _1, static_cast<Filter::FilterMode>(param->Int())); break; case mFilterCutoff: changer = bind(&VoiceManager::setFilterCutoff, _1, param->Value()); break; case mFilterResonance: changer = bind(&VoiceManager::setFilterResonance, _1, param->Value()); break; case mFilterLfoAmount: changer = bind(&VoiceManager::setFilterLFOAmount, _1, param->Value()); break; case mFilterEnvAmount: changer = bind(&VoiceManager::setFilterEnvAmount, _1, param->Value()); break; // Volume Envelope: case mVolumeEnvAttack: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_ATTACK, param->Value()); break; case mVolumeEnvDecay: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_DECAY, param->Value()); break; case mVolumeEnvSustain: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_SUSTAIN, param->Value()); break; case mVolumeEnvRelease: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_RELEASE, param->Value()); break; // Filter Envelope: case mFilterEnvAttack: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_ATTACK, param->Value()); break; case mFilterEnvDecay: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_DECAY, param->Value()); break; case mFilterEnvSustain: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_SUSTAIN, param->Value()); break; case mFilterEnvRelease: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_RELEASE, param->Value()); break;







: changer



- enum



.

- VoiceManager



, changeAllVoices



. .



!



, ! , , , . .



.



, .



.




#include ). OnParamChange



else



, :



// ... } else { using std::tr1::placeholders::_1; using std::tr1::bind; VoiceManager::VoiceChangerFunction changer; switch(paramIdx) { // We'll add this part in a moment } voiceManager.changeAllVoices(changer); } }







, std::tr1::



. _1



bind



( ). VoiceChangerFunction



. switch



changer



ID . changeAllVoices



, changer



.



changer



?



, std::tr1::bind



, Voice&







VoiceChangerFunction



. , , . case



switch(paramIdx)



:



case mOsc1Waveform: changer = bind(&VoiceManager::setOscillatorMode, _1, 1, static_cast<Oscillator::OscillatorMode>(param->Int())); break;







(. bind) , . setOscillatorMode



. - . _1



, . changer



. changer



Voice&



. : 1



. OscillatorMode enum



.



changer



. . , , :



case mOsc1PitchMod: changer = bind(&VoiceManager::setOscillatorPitchMod, _1, 1, param->Value()); break; case mOsc2Waveform: changer = bind(&VoiceManager::setOscillatorMode, _1, 2, static_cast<Oscillator::OscillatorMode>(param->Int())); break; case mOsc2PitchMod: changer = bind(&VoiceManager::setOscillatorPitchMod, _1, 2, param->Value()); break; case mOscMix: changer = bind(&VoiceManager::setOscillatorMix, _1, param->Value()); break; // Filter Section: case mFilterMode: changer = bind(&VoiceManager::setFilterMode, _1, static_cast<Filter::FilterMode>(param->Int())); break; case mFilterCutoff: changer = bind(&VoiceManager::setFilterCutoff, _1, param->Value()); break; case mFilterResonance: changer = bind(&VoiceManager::setFilterResonance, _1, param->Value()); break; case mFilterLfoAmount: changer = bind(&VoiceManager::setFilterLFOAmount, _1, param->Value()); break; case mFilterEnvAmount: changer = bind(&VoiceManager::setFilterEnvAmount, _1, param->Value()); break; // Volume Envelope: case mVolumeEnvAttack: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_ATTACK, param->Value()); break; case mVolumeEnvDecay: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_DECAY, param->Value()); break; case mVolumeEnvSustain: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_SUSTAIN, param->Value()); break; case mVolumeEnvRelease: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_RELEASE, param->Value()); break; // Filter Envelope: case mFilterEnvAttack: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_ATTACK, param->Value()); break; case mFilterEnvDecay: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_DECAY, param->Value()); break; case mFilterEnvSustain: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_SUSTAIN, param->Value()); break; case mFilterEnvRelease: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_RELEASE, param->Value()); break;







: changer



- enum



.

- VoiceManager



, changeAllVoices



. .



!



, ! , , , . .



.



, .



.




#include ). OnParamChange



else



, :



// ... } else { using std::tr1::placeholders::_1; using std::tr1::bind; VoiceManager::VoiceChangerFunction changer; switch(paramIdx) { // We'll add this part in a moment } voiceManager.changeAllVoices(changer); } }







, std::tr1::



. _1



bind



( ). VoiceChangerFunction



. switch



changer



ID . changeAllVoices



, changer



.



changer



?



, std::tr1::bind



, Voice&







VoiceChangerFunction



. , , . case



switch(paramIdx)



:



case mOsc1Waveform: changer = bind(&VoiceManager::setOscillatorMode, _1, 1, static_cast<Oscillator::OscillatorMode>(param->Int())); break;







(. bind) , . setOscillatorMode



. - . _1



, . changer



. changer



Voice&



. : 1



. OscillatorMode enum



.



changer



. . , , :



case mOsc1PitchMod: changer = bind(&VoiceManager::setOscillatorPitchMod, _1, 1, param->Value()); break; case mOsc2Waveform: changer = bind(&VoiceManager::setOscillatorMode, _1, 2, static_cast<Oscillator::OscillatorMode>(param->Int())); break; case mOsc2PitchMod: changer = bind(&VoiceManager::setOscillatorPitchMod, _1, 2, param->Value()); break; case mOscMix: changer = bind(&VoiceManager::setOscillatorMix, _1, param->Value()); break; // Filter Section: case mFilterMode: changer = bind(&VoiceManager::setFilterMode, _1, static_cast<Filter::FilterMode>(param->Int())); break; case mFilterCutoff: changer = bind(&VoiceManager::setFilterCutoff, _1, param->Value()); break; case mFilterResonance: changer = bind(&VoiceManager::setFilterResonance, _1, param->Value()); break; case mFilterLfoAmount: changer = bind(&VoiceManager::setFilterLFOAmount, _1, param->Value()); break; case mFilterEnvAmount: changer = bind(&VoiceManager::setFilterEnvAmount, _1, param->Value()); break; // Volume Envelope: case mVolumeEnvAttack: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_ATTACK, param->Value()); break; case mVolumeEnvDecay: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_DECAY, param->Value()); break; case mVolumeEnvSustain: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_SUSTAIN, param->Value()); break; case mVolumeEnvRelease: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_RELEASE, param->Value()); break; // Filter Envelope: case mFilterEnvAttack: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_ATTACK, param->Value()); break; case mFilterEnvDecay: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_DECAY, param->Value()); break; case mFilterEnvSustain: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_SUSTAIN, param->Value()); break; case mFilterEnvRelease: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_RELEASE, param->Value()); break;







: changer



- enum



.

- VoiceManager



, changeAllVoices



. .



!



, ! , , , . .



.



, .



.




 #include ).   OnParamChange
      
      



else



, :



// ... } else { using std::tr1::placeholders::_1; using std::tr1::bind; VoiceManager::VoiceChangerFunction changer; switch(paramIdx) { // We'll add this part in a moment } voiceManager.changeAllVoices(changer); } }







, std::tr1::



. _1



bind



( ). VoiceChangerFunction



. switch



changer



ID . changeAllVoices



, changer



.



changer



?



, std::tr1::bind



, Voice&







VoiceChangerFunction



. , , . case



switch(paramIdx)



:



case mOsc1Waveform: changer = bind(&VoiceManager::setOscillatorMode, _1, 1, static_cast<Oscillator::OscillatorMode>(param->Int())); break;







(. bind) , . setOscillatorMode



. - . _1



, . changer



. changer



Voice&



. : 1



. OscillatorMode enum



.



changer



. . , , :



case mOsc1PitchMod: changer = bind(&VoiceManager::setOscillatorPitchMod, _1, 1, param->Value()); break; case mOsc2Waveform: changer = bind(&VoiceManager::setOscillatorMode, _1, 2, static_cast<Oscillator::OscillatorMode>(param->Int())); break; case mOsc2PitchMod: changer = bind(&VoiceManager::setOscillatorPitchMod, _1, 2, param->Value()); break; case mOscMix: changer = bind(&VoiceManager::setOscillatorMix, _1, param->Value()); break; // Filter Section: case mFilterMode: changer = bind(&VoiceManager::setFilterMode, _1, static_cast<Filter::FilterMode>(param->Int())); break; case mFilterCutoff: changer = bind(&VoiceManager::setFilterCutoff, _1, param->Value()); break; case mFilterResonance: changer = bind(&VoiceManager::setFilterResonance, _1, param->Value()); break; case mFilterLfoAmount: changer = bind(&VoiceManager::setFilterLFOAmount, _1, param->Value()); break; case mFilterEnvAmount: changer = bind(&VoiceManager::setFilterEnvAmount, _1, param->Value()); break; // Volume Envelope: case mVolumeEnvAttack: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_ATTACK, param->Value()); break; case mVolumeEnvDecay: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_DECAY, param->Value()); break; case mVolumeEnvSustain: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_SUSTAIN, param->Value()); break; case mVolumeEnvRelease: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_RELEASE, param->Value()); break; // Filter Envelope: case mFilterEnvAttack: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_ATTACK, param->Value()); break; case mFilterEnvDecay: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_DECAY, param->Value()); break; case mFilterEnvSustain: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_SUSTAIN, param->Value()); break; case mFilterEnvRelease: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_RELEASE, param->Value()); break;







: changer



- enum



.

- VoiceManager



, changeAllVoices



. .



!



, ! , , , . .



.



, .



.




#include ). OnParamChange



else



, :



// ... } else { using std::tr1::placeholders::_1; using std::tr1::bind; VoiceManager::VoiceChangerFunction changer; switch(paramIdx) { // We'll add this part in a moment } voiceManager.changeAllVoices(changer); } }







, std::tr1::



. _1



bind



( ). VoiceChangerFunction



. switch



changer



ID . changeAllVoices



, changer



.



changer



?



, std::tr1::bind



, Voice&







VoiceChangerFunction



. , , . case



switch(paramIdx)



:



case mOsc1Waveform: changer = bind(&VoiceManager::setOscillatorMode, _1, 1, static_cast<Oscillator::OscillatorMode>(param->Int())); break;







(. bind) , . setOscillatorMode



. - . _1



, . changer



. changer



Voice&



. : 1



. OscillatorMode enum



.



changer



. . , , :



case mOsc1PitchMod: changer = bind(&VoiceManager::setOscillatorPitchMod, _1, 1, param->Value()); break; case mOsc2Waveform: changer = bind(&VoiceManager::setOscillatorMode, _1, 2, static_cast<Oscillator::OscillatorMode>(param->Int())); break; case mOsc2PitchMod: changer = bind(&VoiceManager::setOscillatorPitchMod, _1, 2, param->Value()); break; case mOscMix: changer = bind(&VoiceManager::setOscillatorMix, _1, param->Value()); break; // Filter Section: case mFilterMode: changer = bind(&VoiceManager::setFilterMode, _1, static_cast<Filter::FilterMode>(param->Int())); break; case mFilterCutoff: changer = bind(&VoiceManager::setFilterCutoff, _1, param->Value()); break; case mFilterResonance: changer = bind(&VoiceManager::setFilterResonance, _1, param->Value()); break; case mFilterLfoAmount: changer = bind(&VoiceManager::setFilterLFOAmount, _1, param->Value()); break; case mFilterEnvAmount: changer = bind(&VoiceManager::setFilterEnvAmount, _1, param->Value()); break; // Volume Envelope: case mVolumeEnvAttack: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_ATTACK, param->Value()); break; case mVolumeEnvDecay: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_DECAY, param->Value()); break; case mVolumeEnvSustain: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_SUSTAIN, param->Value()); break; case mVolumeEnvRelease: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_RELEASE, param->Value()); break; // Filter Envelope: case mFilterEnvAttack: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_ATTACK, param->Value()); break; case mFilterEnvDecay: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_DECAY, param->Value()); break; case mFilterEnvSustain: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_SUSTAIN, param->Value()); break; case mFilterEnvRelease: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_RELEASE, param->Value()); break;







: changer



- enum



.

- VoiceManager



, changeAllVoices



. .



!



, ! , , , . .



.



, .



.




 #include ).   OnParamChange
      
      



else



, :



// ... } else { using std::tr1::placeholders::_1; using std::tr1::bind; VoiceManager::VoiceChangerFunction changer; switch(paramIdx) { // We'll add this part in a moment } voiceManager.changeAllVoices(changer); } }







, std::tr1::



. _1



bind



( ). VoiceChangerFunction



. switch



changer



ID . changeAllVoices



, changer



.



changer



?



, std::tr1::bind



, Voice&







VoiceChangerFunction



. , , . case



switch(paramIdx)



:



case mOsc1Waveform: changer = bind(&VoiceManager::setOscillatorMode, _1, 1, static_cast<Oscillator::OscillatorMode>(param->Int())); break;







(. bind) , . setOscillatorMode



. - . _1



, . changer



. changer



Voice&



. : 1



. OscillatorMode enum



.



changer



. . , , :



case mOsc1PitchMod: changer = bind(&VoiceManager::setOscillatorPitchMod, _1, 1, param->Value()); break; case mOsc2Waveform: changer = bind(&VoiceManager::setOscillatorMode, _1, 2, static_cast<Oscillator::OscillatorMode>(param->Int())); break; case mOsc2PitchMod: changer = bind(&VoiceManager::setOscillatorPitchMod, _1, 2, param->Value()); break; case mOscMix: changer = bind(&VoiceManager::setOscillatorMix, _1, param->Value()); break; // Filter Section: case mFilterMode: changer = bind(&VoiceManager::setFilterMode, _1, static_cast<Filter::FilterMode>(param->Int())); break; case mFilterCutoff: changer = bind(&VoiceManager::setFilterCutoff, _1, param->Value()); break; case mFilterResonance: changer = bind(&VoiceManager::setFilterResonance, _1, param->Value()); break; case mFilterLfoAmount: changer = bind(&VoiceManager::setFilterLFOAmount, _1, param->Value()); break; case mFilterEnvAmount: changer = bind(&VoiceManager::setFilterEnvAmount, _1, param->Value()); break; // Volume Envelope: case mVolumeEnvAttack: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_ATTACK, param->Value()); break; case mVolumeEnvDecay: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_DECAY, param->Value()); break; case mVolumeEnvSustain: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_SUSTAIN, param->Value()); break; case mVolumeEnvRelease: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_RELEASE, param->Value()); break; // Filter Envelope: case mFilterEnvAttack: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_ATTACK, param->Value()); break; case mFilterEnvDecay: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_DECAY, param->Value()); break; case mFilterEnvSustain: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_SUSTAIN, param->Value()); break; case mFilterEnvRelease: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_RELEASE, param->Value()); break;







: changer



- enum



.

- VoiceManager



, changeAllVoices



. .



!



, ! , , , . .



.



, .



.




#include ). OnParamChange



else



, :



// ... } else { using std::tr1::placeholders::_1; using std::tr1::bind; VoiceManager::VoiceChangerFunction changer; switch(paramIdx) { // We'll add this part in a moment } voiceManager.changeAllVoices(changer); } }







, std::tr1::



. _1



bind



( ). VoiceChangerFunction



. switch



changer



ID . changeAllVoices



, changer



.



changer



?



, std::tr1::bind



, Voice&







VoiceChangerFunction



. , , . case



switch(paramIdx)



:



case mOsc1Waveform: changer = bind(&VoiceManager::setOscillatorMode, _1, 1, static_cast<Oscillator::OscillatorMode>(param->Int())); break;







(. bind) , . setOscillatorMode



. - . _1



, . changer



. changer



Voice&



. : 1



. OscillatorMode enum



.



changer



. . , , :



case mOsc1PitchMod: changer = bind(&VoiceManager::setOscillatorPitchMod, _1, 1, param->Value()); break; case mOsc2Waveform: changer = bind(&VoiceManager::setOscillatorMode, _1, 2, static_cast<Oscillator::OscillatorMode>(param->Int())); break; case mOsc2PitchMod: changer = bind(&VoiceManager::setOscillatorPitchMod, _1, 2, param->Value()); break; case mOscMix: changer = bind(&VoiceManager::setOscillatorMix, _1, param->Value()); break; // Filter Section: case mFilterMode: changer = bind(&VoiceManager::setFilterMode, _1, static_cast<Filter::FilterMode>(param->Int())); break; case mFilterCutoff: changer = bind(&VoiceManager::setFilterCutoff, _1, param->Value()); break; case mFilterResonance: changer = bind(&VoiceManager::setFilterResonance, _1, param->Value()); break; case mFilterLfoAmount: changer = bind(&VoiceManager::setFilterLFOAmount, _1, param->Value()); break; case mFilterEnvAmount: changer = bind(&VoiceManager::setFilterEnvAmount, _1, param->Value()); break; // Volume Envelope: case mVolumeEnvAttack: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_ATTACK, param->Value()); break; case mVolumeEnvDecay: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_DECAY, param->Value()); break; case mVolumeEnvSustain: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_SUSTAIN, param->Value()); break; case mVolumeEnvRelease: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_RELEASE, param->Value()); break; // Filter Envelope: case mFilterEnvAttack: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_ATTACK, param->Value()); break; case mFilterEnvDecay: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_DECAY, param->Value()); break; case mFilterEnvSustain: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_SUSTAIN, param->Value()); break; case mFilterEnvRelease: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_RELEASE, param->Value()); break;







: changer



- enum



.

- VoiceManager



, changeAllVoices



. .



!



, ! , , , . .



.



, .



.




#include ). OnParamChange



else



, :



// ... } else { using std::tr1::placeholders::_1; using std::tr1::bind; VoiceManager::VoiceChangerFunction changer; switch(paramIdx) { // We'll add this part in a moment } voiceManager.changeAllVoices(changer); } }







, std::tr1::



. _1



bind



( ). VoiceChangerFunction



. switch



changer



ID . changeAllVoices



, changer



.



changer



?



, std::tr1::bind



, Voice&







VoiceChangerFunction



. , , . case



switch(paramIdx)



:



case mOsc1Waveform: changer = bind(&VoiceManager::setOscillatorMode, _1, 1, static_cast<Oscillator::OscillatorMode>(param->Int())); break;







(. bind) , . setOscillatorMode



. - . _1



, . changer



. changer



Voice&



. : 1



. OscillatorMode enum



.



changer



. . , , :



case mOsc1PitchMod: changer = bind(&VoiceManager::setOscillatorPitchMod, _1, 1, param->Value()); break; case mOsc2Waveform: changer = bind(&VoiceManager::setOscillatorMode, _1, 2, static_cast<Oscillator::OscillatorMode>(param->Int())); break; case mOsc2PitchMod: changer = bind(&VoiceManager::setOscillatorPitchMod, _1, 2, param->Value()); break; case mOscMix: changer = bind(&VoiceManager::setOscillatorMix, _1, param->Value()); break; // Filter Section: case mFilterMode: changer = bind(&VoiceManager::setFilterMode, _1, static_cast<Filter::FilterMode>(param->Int())); break; case mFilterCutoff: changer = bind(&VoiceManager::setFilterCutoff, _1, param->Value()); break; case mFilterResonance: changer = bind(&VoiceManager::setFilterResonance, _1, param->Value()); break; case mFilterLfoAmount: changer = bind(&VoiceManager::setFilterLFOAmount, _1, param->Value()); break; case mFilterEnvAmount: changer = bind(&VoiceManager::setFilterEnvAmount, _1, param->Value()); break; // Volume Envelope: case mVolumeEnvAttack: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_ATTACK, param->Value()); break; case mVolumeEnvDecay: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_DECAY, param->Value()); break; case mVolumeEnvSustain: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_SUSTAIN, param->Value()); break; case mVolumeEnvRelease: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_RELEASE, param->Value()); break; // Filter Envelope: case mFilterEnvAttack: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_ATTACK, param->Value()); break; case mFilterEnvDecay: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_DECAY, param->Value()); break; case mFilterEnvSustain: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_SUSTAIN, param->Value()); break; case mFilterEnvRelease: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_RELEASE, param->Value()); break;







: changer



- enum



.

- VoiceManager



, changeAllVoices



. .



!



, ! , , , . .



.



, .



.




#include ). OnParamChange



else



, :



// ... } else { using std::tr1::placeholders::_1; using std::tr1::bind; VoiceManager::VoiceChangerFunction changer; switch(paramIdx) { // We'll add this part in a moment } voiceManager.changeAllVoices(changer); } }







, std::tr1::



. _1



bind



( ). VoiceChangerFunction



. switch



changer



ID . changeAllVoices



, changer



.



changer



?



, std::tr1::bind



, Voice&







VoiceChangerFunction



. , , . case



switch(paramIdx)



:



case mOsc1Waveform: changer = bind(&VoiceManager::setOscillatorMode, _1, 1, static_cast<Oscillator::OscillatorMode>(param->Int())); break;







(. bind) , . setOscillatorMode



. - . _1



, . changer



. changer



Voice&



. : 1



. OscillatorMode enum



.



changer



. . , , :



case mOsc1PitchMod: changer = bind(&VoiceManager::setOscillatorPitchMod, _1, 1, param->Value()); break; case mOsc2Waveform: changer = bind(&VoiceManager::setOscillatorMode, _1, 2, static_cast<Oscillator::OscillatorMode>(param->Int())); break; case mOsc2PitchMod: changer = bind(&VoiceManager::setOscillatorPitchMod, _1, 2, param->Value()); break; case mOscMix: changer = bind(&VoiceManager::setOscillatorMix, _1, param->Value()); break; // Filter Section: case mFilterMode: changer = bind(&VoiceManager::setFilterMode, _1, static_cast<Filter::FilterMode>(param->Int())); break; case mFilterCutoff: changer = bind(&VoiceManager::setFilterCutoff, _1, param->Value()); break; case mFilterResonance: changer = bind(&VoiceManager::setFilterResonance, _1, param->Value()); break; case mFilterLfoAmount: changer = bind(&VoiceManager::setFilterLFOAmount, _1, param->Value()); break; case mFilterEnvAmount: changer = bind(&VoiceManager::setFilterEnvAmount, _1, param->Value()); break; // Volume Envelope: case mVolumeEnvAttack: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_ATTACK, param->Value()); break; case mVolumeEnvDecay: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_DECAY, param->Value()); break; case mVolumeEnvSustain: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_SUSTAIN, param->Value()); break; case mVolumeEnvRelease: changer = bind(&VoiceManager::setVolumeEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_RELEASE, param->Value()); break; // Filter Envelope: case mFilterEnvAttack: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_ATTACK, param->Value()); break; case mFilterEnvDecay: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_DECAY, param->Value()); break; case mFilterEnvSustain: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_SUSTAIN, param->Value()); break; case mFilterEnvRelease: changer = bind(&VoiceManager::setFilterEnvelopeStageValue, _1, EnvelopeGenerator::ENVELOPE_STAGE_RELEASE, param->Value()); break;







: changer



- enum



.

- VoiceManager



, changeAllVoices



. .



!



, ! , , , . .



.



, .



.







All Articles