オーディオプラグインの作成、パート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から、初期化とゲッターを含むmLastVelocitymLastNoteNumbermLastFrequencyを削除します。 getLastNoteNumbergetLastFrequencyおよび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.cppadvance機能を変更します

 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.hprivateセクションに追加します。

 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とその値でOnParamChangeOnParamChangeれます。 0.3値でmFilterCutoffと言います。 次にVoiceManager次のVoiceManager「各Voice0.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 . .

!

, ! , , , . .

.

, .

.

Source: https://habr.com/ru/post/J231923/


All Articles