Skip to content

Instrument Reference

odashi edited this page Nov 15, 2026 · 1 revision

Integralの音源仕様・操作

Integral Wiki · README

音色設定134個とProgram・Pitch Bendの計136パラメーターを公開します。操作と音源の仕様をまとめ、実装・検証の入口を技術資料に整理しています。

Windows x86_64/Linux x86_64(GNU)では、AVX2・FMA3対応CPUとOSによるXMM/YMM状態の保存・復元を必要とします。起動時にCPU・OSを確認し、非対応環境ではVST3のロードを拒否します。

ノート操作

Amp列の最上段のNoteグループにPhase・Poly・Porta・Pitchを配置します。

コントロール 機能・範囲 初期値 ParamID
Phase Note On時の位相(Keep / Zero / Random) Keep 0x50484153
Poly 同時発音枠数(1〜32) 1 0x504f4c59
Porta ポルタメント(0 ms、1 ms〜10 sの指数軸) 0 ms 0x504f5254
Pitch ホストのピッチベンドに対する適用幅(0〜1200 cent) 200 cent 0x50495443

PortamentoはPoly=1のときだけ有効です。発音中(release中を含む)に次のNote Onが来ると、その時点の音高から新しい音高へ指定時間で移行します。cent上で線形なので、同じ時間間隔で同じ音程幅ずつ変わります。無音からの発音は直ちに目標音高になります。移行中のNote Onでも現在の音高を出発点として、指定時間全体を使います。時間変更は次のNote Onから反映し、0 msまたはPoly>1にすると進行中の移行も直ちに目標へ到達します。

Portaは音量AHDSRと同じ401tickの整数ノブです。0が0 ms、1が1 ms、以降100tickで10倍、401が10000 msです。1tickに必要な移動量は3物理pxです。Pitchは10 cent刻み・1tickにつき4物理pxで操作します。

Pitchノブ単独では音程を変えません。ホストからのベンド正規化値をb(中央0.5)として、(2b−1)×Pitch centを全Voiceの3発振器へ共通に加えます。Pitch=1200 centでは最大で上下1オクターブ、0ではベンドの影響がなくなります。各OscillatorのTune・Detuneはこの後に加算します。ノート基準のフィルタもポルタメント・ベンド後の音高へ追従します。

VST3のIMidiMappingを通じ、イベント入力バス0のチャンネル0〜15のkPitchBendを共通のPitch Bendパラメーター(0x42454e44)へ割り当てます。ホストはinputParameterChangesで受信値を配送します。ベンドは変更点間を正規化空間で線形補間し、最後の値を保持します。Portamento・Pitchは音色の保存対象、受信したベンド位置は演奏状態です。

発音と位相

  • 有効なNote Onを次のVoiceへ循環順に割り当て、周波数と目標振幅を更新します。枠の再使用時には古いノートを置き換え、古いノートには戻りません。
  • 音程は12平均律(ノート番号69 = 440 Hz)とイベントのtuning(セント)で決めます。 基準実効値を BASE_RMS_AMPLITUDE = 0.5 と定義し、全波形で目標実効値を BASE_RMS_AMPLITUDE × (1 − Amp Sensitivity / 100 × (1 − velocity)) とします。velocityが0のNote Onも受理し、感度に応じた目標振幅へattack時間をかけて移行します。
  • Note Offは、両イベントにnoteIdがあればIDで照合します。どちらかが -1 の場合はチャンネルと音高で照合します。 同じID、またはIDがない同チャンネル・同音高が複数枠にあれば、全一致をreleaseします。上書き済みの旧IDへのNote Offは新しいノートを消しません。
  • OscillatorInput は発振器回路の定常入力で、波形・位相モード・ユニゾン数・Detune・周波数・位相変調・発音期間・ノート世代番号を持ちます。 OscillatorState は位相と乱数の状態を保持し、Voiceが3発振器と共通の音量用Envelopeを所有します。現在値・attack開始値・経過サンプル数・ノートオフ位置はEnvelopeStateが保持します。Voiceはノート境界をEnvelopeへ通知し、Envelopeが次のサンプル生成時に反映します。
  • 各サンプルで「現在の入力と状態からサンプル生成 → 入力を用いて状態更新」を繰り返します。 エンベロープの計算はサンプル数をミリ秒へ変換して行い、位相と時間の更新はサンプル生成後です。 初期位相は0。Note On時の位相はPhaseの選択に従います。音程変更・ブロック境界では位相を保持します。
  • ノートと設定が一定の区間は32サンプルずつ系列生成します。発振器の準備は、ノートや該当する設定が変わった場合に行います。位相変調はOsc3→Osc2→Osc1の順に系列を作り、同じ時刻の変調値・音量・フィルタ処理を対応させます。Voiceの加算順は維持します。
  • Note Offではreleaseへ移行し、終了後に位相を止めます。release=0msなら即時に消音します。 再Note Onではreleaseを挟まず、その時点の実効振幅から新しい目標へattack時間全体を使って移行します。 位相はPhaseの選択に従います。周波数・波形の即時変更や0ms設定ではクリックが発生し得ます。
  • sampleOffset の位置でイベントを反映します。同位置ではリスト順です。取得失敗、未対応の種類・バス、 不正な値、範囲外または処理済み位置より前のイベントは無視します。
  • イベントがないブロックでも発音を継続します。処理中は出力バッファがなくてもイベントを処理し、 発音中の位相を進めます。0サンプルの場合はoffset 0のイベントだけを処理します。
  • イベント入力バスは、有効化通知を省略するホストへの互換性対応として初期化時から有効にします。 これは全バスを初期状態で無効とするVST3仕様からの意図的な逸脱です。 明示的な無効化には従い、処理を再開しても無効のままです。再初期化時は初期状態へ戻ります。 音声出力バスはホストによる有効化を必要とします。
  • 処理停止・無効化では消音しますが位相は保持します。処理停止中の0サンプルフラッシュではノートを受け付けません。 ホストのトランスポート再生状態は参照しないため、停止中でもホストが処理とノートを送れば演奏できます。

PhaseはVoice内の3発振器に共通するNote On時の位相を選ぶ3択パラメーターです(ParamID 0x50484153、初期値Keep)。

選択 Note On時の動作
Keep(維持) 割り当て先オシレータの直前の位相を引き継ぐ
Zero(ゼロ) 割り当て先オシレータの全ユニゾン位相を0にする
Random(ランダム) 全ユニゾン位相をそれぞれ独立に0以上1周期未満へ設定する

選択の変更は次のNote Onから適用し、同じサンプル位置ではパラメーターを先に反映します。 位相とNoiseの疑似乱数には共通のxoshiro256+コンポーネントを使用し、用途ごとに独立した状態を持ちます。 シードはオシレータ作成時に標準ライブラリのRandomStateから取得します。 同じ乱数状態とノート入力からは同じ位相列を生成し、新しく作成したインスタンスでは異なる位相列になります。

内部では OscillatorInput.waveform の Waveform で波形を指定します。既定は Sine です。 波形を変更しても位相を引き継ぎ、次のNote Onでも選択した波形を維持します。

波形 理想波形に掛ける振幅倍率(Vol=0 dB、最大ベロシティ・エンベロープ最大) 帯域制限前の形状
サイン波(Sine) 0.5 × √2 ≈ 0.707107 0から上昇
三角波(Triangle) 0.5 × √3 ≈ 0.866025 0から上昇、1/4周期で正のピーク
矩形波(Square) 0.5 前半は正、後半は負(デューティ比50%)
ノコギリ波(Sawtooth) 0.5 × √3 ≈ 0.866025 負のピークから直線的に上昇
ホワイトノイズ(Noise) 0.5 × √3 ≈ 0.866025 毎サンプル別の一様乱数

Triangle・Square・Sawtoothは帯域別テーブルで生成します。Detuneを反映した各ユニゾンの周波数と サンプルレートから、最高倍音がNyquist未満のテーブルを選びます。境界直前で倍音の少ないテーブルへ 連続的に混合し、基音がNyquistへ達する場合も直前で0へ下げます。保持位相は音程や帯域を変えても継承します。

残る倍音の振幅を維持し、除いた高次倍音を音量の増加で補いません。 表の倍率は帯域制限前の理想実効値を 0.5とするものです。帯域制限後の実効値は高音域ほど低下し、Square・Sawtoothの不連続点は滑らかになり、 その近傍にはリンギングが生じます。残る倍音の振幅とオーバーシュートを、音声・位相変調の両方にそのまま使用します。 音量処理では表の倍率・Vol・定位を適用します。

テーブルは最大16,384倍音・27帯域で共有し、Sawは半周期、Square・Triangleは四半周期だけを保存します。 1周期あたり最低4,096区間、最高倍音あたり8区間以上とし、4点Lagrange補間の係数も事前計算します。 係数はf32へ丸めた値をlittle-endian f64で保持し、サンプル読出し時の型変換を省きます。共有係数データの容量は16,103,200バイトで、32バイト境界に配置します。音声処理中の生成・メモリ確保は行いません。 生成し直す場合は性能検証用Python環境のNumPyを使い、 python scripts/generate-wavetables.pyを実行します。通常のビルドは格納済みデータを読み込みます。

帯域選択の基準は発振周波数です。位相変調で生じる側波帯は別に発生するため、強い変調では折り返しが残ります。

ホワイトノイズ

Noiseはxoshiro256+ 1.0の上位53bitから一様乱数u ∈ [0,1)を生成し、 2u−1の生波形を出力し、独立した音量処理で√3 × amplitudeを掛けます。ベロシティ・エンベロープ最大時の理論実効値は0.5です。 乱数コンポーネントはOscillatorStateが所有し、乱数の状態更新は固定長の整数演算で行います。 位相用とは別の状態を進めるため、PhaseのKeep・Zero・Randomでノイズ列はリセットされません。 同じ初期乱数状態・入力・サンプル数なら同じ列を生成し、初期シードはインスタンスごとに取得します。

Detune=0ではノイズ源1個にまとめ、Widthは無効です。Detune>0ではUnison数の別々の乱数値を生成し、 既存のequal-power定位と1/√Nの倍率で合成します。Detuneの正の値やノート音程はノイズ列の生成速度に影響しません。 ノート音程はフィルタの基準周波数に使います。Pan、音量・カットオフ用AHDSR、フィルタは他の波形と共通です。 ノートオンでは乱数列を継続し、リリース完了・処理停止後は更新を止めます。

Voiceごとのフィルタ

音源は Synthesizer → Voice → Oscillator の階層です。各コンポーネントは専用のStateを所有します。各VoiceはOsc1・Osc2・Osc3とそれぞれの定常入力を保持します。Osc1はユニゾンを生成し、Osc2/3は各1発振器です。各発振器のVolumeを適用して加算し、共通の音量AHDSR、フィルタの順に通した後、全Voiceのフィルタ出力を左右別に加算します。合成音はSynthesizerが所有する3スロットのエフェクタ系列、EQ、Limiter、Master Volumeの順に通します。フィルタの係数は左右で共用し、積分器の履歴は独立させます。 Stateはデータ保持専用とし、所有コンポーネントのメソッドが処理とStateの更新を担当します。 音声関数は1サンプルを*_sample、サンプル系列を*_samplesで区別します。

パラメーター 範囲 初期値 ParamID
Filter Off / LowPass1 / LowPass2 / HighPass1 / HighPass2 / BandPass1 / BandPass2 LowPass1 0x46545950
Cutoff ノート周波数から−2400〜9600 cent(−2〜+8 oct) +4800 cent(+4 oct) 0x46435554
Resonance Q=0.5〜10 1 0x46524553

GUIではFilterを横並びのドロップダウン、CutoffとResonanceを整数ノブで操作します。 Cutoffは0〜1200 tickを10 cent刻みへ換算し、Resonanceは0〜950 tickをQ=0.5〜10(0.01刻み)へ換算します。 FilterはstepCount=6のリスト、CutoffはstepCount=0の連続値として公開し、どちらも変更点で切り替えます。 Resonanceは連続値で、ホストの変更点間を正規化値で線形補間します。

Voiceはノートの音程とtuningを含む周波数に 2^(cent/1200) を乗じ、具体的なHzをフィルタへ渡します。 カットオフはユニゾンのデチューン前のノート周波数に追従し、Note Off後も最後のノート周波数を使用します。

  • FilterParametersはそのサンプルのHzとQを持ち、既定値はUI/VST3設定側で定義します。
  • SvfStateはTPT SVF1段の状態を保持します。単体入口のSvf::process_sampleはlow / band / highを返し、音源用のFilter::process_sampleは準備済み係数と左右独立の積分器を使って出力選択・直列接続を行います。同じHz・Q・サンプルレートの係数を左右・両段で共用します。
  • LPF・HPFは1段で12 dB/oct、2段で24 dB/oct。BPFの両側はそれぞれ6/12 dB/oct、中心利得はQ/Q²です。
  • 周波数は有限値を受け取り、内部の係数計算時だけ20〜20,000 Hzにクランプします。対応サンプルレートは44.1 kHz以上なので、この範囲は常にNyquist未満です。
  • 設定変更やVoiceの再使用でも有効な段の履歴を保持します。未使用の2段目とOff時の両段は消去します。Offでは入力値を検証せずそのまま返します。
  • Note Off後のフィルタ残響も処理します。処理停止・Voice数の減少による停止ではフィルタの履歴も消去します。音量補正・クリッピングは追加しません。

Voiceはカットオフ用エンベロープを毎サンプル計算し、変調後のHzをフィルタへ渡します。

台形積分したSVFの連立方程式をRustで実装しています。数式の参考は Andrew SimperによるSVFの解説です。

カットオフエンベロープ

各Voiceは、音量用と独立したカットオフ用AHDSRを持ちます。 両者は同じEnvelopeコンポーネントを使い、EnvelopeStateで時間と現在値を管理します。 エンベロープが扱う値は単位のない0〜1の正規化量で、適用先が実単位へ換算します。

パラメーター 範囲 初期値 ParamID
Cutoff Attack 0〜10000 ms 10 ms 0x43415454
Cutoff Hold 0〜10000 ms 0 ms 0x43484c44
Cutoff Decay 0〜10000 ms 100 ms 0x43444543
Cutoff Sustain 0〜1 0.7 0x43535553
Cutoff Release 0〜10000 ms 100 ms 0x4352454c
Cutoff Amount −4800〜+4800 cent 0 cent 0x43414d54

変調後のcent = Cutoff + Cutoff Amount × (1 − Filter Amount Sensitivity / 100 × (1 − velocity)) × エンベロープ値 とし、 カットオフHz = ノート周波数 × 2^(変調後のcent / 1200) をフィルタへ渡します。 Amountはattackの目標値1に対応する変化量で、負なら下方向へ変化します。 sustainではAmount×感度による倍率×Sustainの変化量を保ち、releaseで基本のCutoffへ戻ります。 再ノートオンでは現在のエンベロープ値を開始点として、attack時間全体を使って1へ移行します。 音量のreleaseが先に終わっても、カットオフ用のreleaseはフィルタの残響に適用されます。

時間ノブは音量用と同じ対数軸、Sustainは線形です。 Amountは10 cent刻みの整数ノブで操作します。 6パラメーターは連続値として公開し、VST3の変更点間を正規化値で線形補間します。

リミッタ

EQ → Limiter → Master Volumeの順に処理します。上部バーの Limiter ボタンでOff/Onを切り替えます。Onでは緑色の光バーを点灯します。初期値はOffです。 左右のサンプルピークを共通検出し、同じ倍率を両チャンネルへ適用します。プリゲインは0 dB、シーリングは0 dBFS、Releaseの時定数は100 ms、先読みは5 msに固定します。 Master VolumeはLimiterの後に作用するため、正のMaster設定では最終出力が0 dBFSを超えます。

先読み窓の最大振幅へ即時追従し、下降時には指数減衰させます。その包絡を先読み長の矩形窓で平均し、1を超える場合にその逆数をゲインとします。 Releaseはミリ秒から係数を計算し、サンプル区間内の指数減衰を積分して平均することで、サンプルレートによるゲイン推移の差を抑えます。 音声の遅延長は ceil(ホストサンプルレート × 0.005) です。44.1 kHzでは221サンプル(約5.011 ms)、48/96/192 kHzでは240/480/960サンプル(5 ms)になります。

Offでも同じ純遅延と検出履歴を維持します。切替時刻に音量制御だけを切り替え、ホスト申告遅延は変わりません。 エフェクタ系列の3サンプルを加えた総遅延をホストへ申告します。 VST3 ParamIDは0x4c490000、正規化値0がOff、1がOnです。オートメーションは変更点で切り替え、保存・復元にも対応します。

信号経路と遅延

全段をホストのサンプルレートで処理します。

Integralのモジュール構成と信号経路

SVGを開く

上段はSynthesizer全体、下段は各Voiceの内部です。緑の実線は音声、紫の実線は音量処理前の生波形による位相変調、橙の破線は制御信号を示します。

DistortionのADAA2が持つ1サンプル遅延を含め、3スロットの系列を常に3サンプルへ揃えます。 LimiterはOffでも5 ms分の純遅延を維持します。ホスト申告遅延は 3 + ceil(ホストサンプルレート × 0.005) サンプルです。 エフェクト種類・LimiterのOn/Offによってこの値は変わりません。

ホストレート エフェクタ系列 Limiter 合計
44.1 kHz 3 221 224
48 kHz 3 240 243
96 kHz 3 480 483
192 kHz 3 960 963

Delayの音価で指定する反復間隔やReverbの残響時間は、上記の処理遅延には加算しません。 残響を維持するため、VST3のテール長はkInfiniteTailです。

マスターボリューム

Volumeは全Voiceのフィルタ出力を加算し、エフェクタ系列・EQ・Limiterを通した後の音量です(ParamID 0x4d564f4c)。 全Volumeの範囲は−60〜+12 dBで、下限の−60 dB位置を−∞(完全消音)として扱います。MasterとOsc1の初期値は0 dB、Osc2/3は−∞です。 整数ノブのtick=0は−∞、1〜720はdB = tick / 10 − 60で換算し、0.1 dB刻みで設定します。 振幅倍率は10^(dB / 20)(−∞では0)で、値の変更時だけ計算して保持します。 VST3では連続値として公開し、正規化値0は−∞、正の値はnormalized × 72 − 60 dBです。 変更点間は正規化空間で補間し、−∞自体の加減算は行いません。

3つのオシレータ

設定 範囲・初期値 ParamID
Osc1 Volume −60〜+12 dB(最小値は−∞)・初期値0 dB 0x4f31564c
Osc2 Waveform 5波形・Sine 0x4f325746
Osc2 Tune −2400〜+2400 cent・0 cent 0x4f32544e
Osc2 Volume −60〜+12 dB(最小値は−∞)・初期値−∞ 0x4f32564c
Osc3 Waveform 5波形・Sine 0x4f335746
Osc3 Tune −2400〜+2400 cent・0 cent 0x4f33544e
Osc3 Volume −60〜+12 dB(最小値は−∞)・初期値−∞ 0x4f33564c

TuneはGUIで10 cent刻み、VST3では連続値です。ノート周波数へ2^(Tune / 1200)を乗じます。 Osc1のUnison・Detune・WidthはOsc1へ適用し、Osc2/3は共通Panのみで定位させます。 Phaseは3発振器共通で、Randomの乱数と位相はそれぞれ独立しています。 各発振器のVolumeが−∞の間も発音期間中は位相・ノイズ列を進め、音量を戻しても位相を再初期化しません。 3発振器の加算には音数による音量補正を行いません。カットオフはTune適用前のノート周波数を基準とします。

位相変調

Osc2/3のModノブは位相変調の深さを指定します。0〜200%(初期値0%、GUIは1%刻み)で、 生波形の値が1のとき、100%は1回転、200%は2回転(4π rad)です。 帯域制限によるオーバーシュートも、その大きさに比例して位相偏移へ反映します。 Osc2 Mod(ParamID 0x4f32464d)はOsc1、Osc3 Mod(0x4f33464d)はOsc2を変調します。 各サンプル時刻でOsc3→Osc2→Osc1の順に生成し、受け側の波形を読む位相を次の式で決めます。

読出し位相 = (保持位相 + Mod / 100 × 生波形) mod 1(周期単位)

保持位相はTune・Detune適用後の周波数で進め、変調量は累積しません。 Mod=200%でモジュレータが±1なら、±2回転なので周期波形は無変調時と同じ位相になります。 途中の値では位相がずれるため、変調音が生じます。 Osc1のユニゾン各音には同じ位相変調量を適用します。Modの変更点間は正規化空間で線形補間します。

位相変調を受ける周期波には2階ADAAを適用します。Osc2→Osc1、Osc3→Osc2の各経路で、対応するModが0なら通常の波形読出しを使います。 ADAAは直前2サンプルの変調後位相と、波形ごとの2階原始関数テーブルで計算します。1階原始関数と生波形は同じ多項式の微分から求めます。全ユニゾンに適用し、Note On・波形・発音数の変更時に履歴を初期化します。 原始関数テーブルはscripts/generate-pm-primitives.py(NumPy)で生成します。小さい帯域テーブルは参照速度を優先して全周期を保持し、大きい帯域テーブルは波形の対称性で1/2周期へ縮小します。共有データは約39.5 MiBです。

発振器は各ユニゾンについて理想波形のピーク振幅1を基準とした生波形を出力し、帯域制限のオーバーシュートを保持します。 実効値補正・ユニゾン合成・Vol・Panは独立したvolumeモジュールで適用し、3発振器の加算後にAHDSRを掛けます。 生波形を変調に使うため、Volが−∞でも変調は継続します。 Noiseは音声と変調で同じ乱数サンプルを共用し、Noise自体への位相変調では乱数列を変更しません。

ポリフォニー

Polyphony は1〜32(初期値1)、ParamIDは 0x504F4C59、stepCount=31 / kCanAutomate です。 GUIでは1刻みの整数ノブで設定します。変更点では補間せず、ノートより先に適用します。

SynthesizerState.next_oscillator_id は初期値0です。有効なNote OnをそのIDへ割り当てた後、 (ID + 1) % Polyphony へ進めます。空き枠の探索はせず、発音中・release中の枠もこの順に再使用します。 Note Offと不正なNote OnではIDを進めません。処理停止でも次のIDは保持します。 再使用時は現在振幅を引き継ぎ、新しいノートのattackを開始します。位相はPhaseの選択に従います。

各枠に独立した入力・位相・エンベロープ状態・ノートの対応を持ち、各枠で既存のユニゾンを生成します。 波形、AHDSR、Unison、Detune、フィルタ設定は全枠共通です。フィルタ状態と実際のカットオフ周波数はVoiceごとに独立しています。 出力は使用する全枠の単純加算で、音数による音量補正やクリッピングは行いません。 最大ベロシティ・エンベロープ最大、Vol=0 dB、定位中央では、各オシレータの帯域制限前の理想実効値を0.5とします。3発振器と複数Voiceを加算するため、合成ピークは1を超える場合があります。

Polyphonyを減らすと、IDが新しい枠数以上のノートを即時停止し、次のIDを新しい枠数の剰余へ変更します。 増やしても停止したノートは復活しません。未使用枠の位相は停止して保持します。 最大32枠の領域は初期化時に確保し、音声処理中の確保・解放は行いません。

ユニゾン

各VoiceのOsc1内で、同じノート・波形を1〜7声で生成します。音量エンベロープはVoiceで共有し、Osc2/3は各1声です。

パラメーター 範囲 初期値 ParamID
Unison 1〜7ボイス 1 0x554E4953
Detune 0〜100 cent 0 cent 0x4454554E

Nが2以上のとき、ボイスk(0〜N−1)の音程差は detune × (2k/(N−1) − 1) cent、 周波数は 基準周波数 × 2^(音程差/1200) です。1ボイスではDetuneを適用しません。 Detuneが正なら合成音を 1/√N 倍にし、最大ベロシティ・エンベロープ最大時の 長時間平均の理想実効値を0.5に合わせます。うなりにより短時間の実効値は変動します。 Detune=0では保持した先頭ボイスの位相だけで1ボイス相当の音を生成し、実効値0.5を保ちます。

各ボイスの初期位相は0で、Note On時にはPhaseの選択を全7位相へ適用します。 音程・設定変更では位相を保持します。未使用ボイスの位相は停止し、ユニゾン数を増やすと保持した位置から再開します。 設定の即時切り替えではクリックが発生する場合があります。ピーク制限は行いません。

Unisonは stepCount=6、Detuneは stepCount=0、ともに kCanAutomate で公開します。 Unisonは変更点で切り替え、DetuneはAHDSRと同様に正規化空間で線形補間します。 GUIではUnisonを1ボイス刻み、Detuneを1 cent刻みの整数ノブで操作します。 ホストからはDetuneの端数も受け付けます。

WidthとPan

パラメーター 範囲 初期値 ParamID
Width 0〜100% 0% 0x57494454
Pan −100〜+100%(左〜右) 0%(中央) 0x4D50414E

Widthはユニゾンの左右への広がり、Panは全オシレータ共通の定位です。 W = Width / 100、P = Pan / 100、s = 2k/(N−1) − 1として、 各ユニゾン音の定位を p = P + (1−|P|) × W × s とします。 1ボイスではs=0です。Width=0では全音が同じ位置になり、Panを端へ近づけると広がりが縮まり、端では全音が片側へ移ります。 Detune=0では先頭位相による1ボイス相当の生成を維持するため、Widthは音に影響しません。

最終的な左右の倍率はequal-power panningを使い、θ = (p+1) × π/4、 L = √2 cos(θ)、R = √2 sin(θ)とします。中央の倍率を左右とも1に保つため√2を掛けています。 理想式での左右の二乗和は2です。実装では既存の四半周期正弦波表(1024区間)を線形補間し、左右倍率の最大絶対誤差を4.17×10⁻⁷、二乗和の最大絶対偏差を1.18×10⁻⁶以内とします。中央の左右倍率1と、端点の無音側0は厳密に維持します。 Width=0・Pan=0では従来と同じ左右出力になります。

GUIでは整数tickで1%刻みに操作し、VST3では連続値として公開します。 オートメーションはAHDSRと同様に正規化空間で線形補間します。 定位の倍率はSynthesizerStateがOsc1用PanningGainsとOsc2/3用の共通Pan倍率を保持し、各Voiceの音量処理へ参照で渡します。有効ユニゾン数・有効なWidth・Panが変わった場合だけ再計算し、1ボイス時のWidth変更や正のDetune間の変更では再計算しません。波形生成・位相更新は各ユニゾン音につき1回です。

ベロシティ感度

AmpとFilterのSensノブで、Note Onのベロシティが音量とカットオフAmountへ及ぼす強さを個別に指定します。

パラメーター 範囲 初期値 ParamID
Amp Sensitivity 0〜100% 100% 0x4153454e
Filter Amount Sensitivity 0〜100% 0% 0x4653454e

感度をS = Sensitivity / 100、ベロシティをV(0〜1)として、倍率は1 − S × (1 − V)です。 0%ではベロシティを無視し、100%ではベロシティをそのまま倍率にします。 たとえば感度50%・ベロシティ0なら倍率0.5、ベロシティ1なら感度によらず倍率1です。 Ampは音量AHDSRの目標実効振幅へ、Filterは符号を保ったCutoff Amountへ適用します。 Filter感度100%・ベロシティ0ではAmountが0となり、基準のCutoffで処理します。

GUIは1%刻みの整数tick、VST3は連続値です。発音中・release中にも感度変更を反映し、変更キューの点間を線形補間します。 再Note On時の音量は現在値から新しい目標へattack時間全体で移行します。ベロシティと計算済み倍率はVoiceごとに保持します。

音量エンベロープ

src/envelope.rs の value は、EnvelopeParameters、ノートオンからの経過ミリ秒、 ノートオフ時刻(同じ時刻基準、未到達は None)、開始値、目標ピーク値を受け取り、0〜1の正規化値を返します。 音量用EnvelopeはEnvelopeStateに現在値・開始値・経過サンプル数を保持し、カットオフ用と同じAHDSRを使います。

パラメーター 範囲 初期値 ParamID
Attack 0〜10000 ms 10 ms 0x4154544B
Hold 0〜10000 ms 0 ms 0x484F4C44
Decay 0〜10000 ms 100 ms 0x44454359
Sustain 0〜1(ピークに対する倍率) 0.7 0x53555354
Release 0〜10000 ms 100 ms 0x52454C53

すべて線形に変化します。attack終了後にholdの間ピークを維持し、decayでsustainまで下がります。 ノートオフでは、その時点の振幅からrelease時間で0へ下がります。各時間が0msならその段階は即時に完了します。 再ノートオンでは現在の実効振幅を開始値として保存し、経過時間を0に戻します。 開始振幅や新しいベロシティにかかわらず、attackの終了は再ノートオンからattack時間後です。 初期設定のsustain時、最大ベロシティでの理想実効値は 0.5 × 0.7 = 0.35 です。

時間ノブの設定値は整数tick(0〜401)です。tick=0が0ms、tick=1が1msで、 tick=1〜401は ms = 10^((tick−1)/100)、最大端点のtick=401は10000msに換算します。 正の対数領域では100 tick進むと10倍になります。 VST3の正規化値は実単位から連続値へ換算し、0〜1msの区間は線形に対応させます。 Sustainも整数tick(0〜100)を保持し、音量 = tick / 100 に換算します。 ノブ操作中は中央直上に現在値(時間はms)を表示します。

5パラメーターは stepCount=0 / kCanAutomate で公開します。 変更キューの連続値は、前ブロック末尾(offset=-1)から各点まで正規化空間で線形補間し、 最後の点以降は保持します。同位置のノートより先に設定を適用します。 計算は毎サンプルの設定を用いるため、発音中の時間・sustain変更は進行中の形にも反映します。 開始振幅は次のノートオンまで固定します。不正・非有限の入力は音声へ伝播させません。

パラメーターと状態保存

ホストのVST3パラメーター表示で Osc1 Waveform を操作します。画面上の表示形式はホストに依存します。 IEditController で列挙する離散パラメーターで、固定ParamIDは 0x57415645、 stepCount = 4、フラグは kCanAutomate | kIsList、既定値は0です。

表示名 実単位の番号 正規化値
Sine 0 0
Triangle 1 1/4
Square 2 1/2
Sawtooth 3 3/4
Noise 4 1

正規化値は5つの等幅区間へ量子化し、上端の1はNoiseに含めます。

全パラメーターの変更は ProcessData.inputParameterChanges から受け取り、sampleOffset に従って反映します。

パラメーター 変更点の間の処理
Osc1/2/3 Waveform・Unison・Polyphony・Filter・Cutoff・Phase・Clipper type・Effect種類・Delay Time・Stereo・Reverb Size・EQ Enable・Limiter 直前の値を保持し、変更点で切り替える
音量/カットオフ用AHDSR・Amount・Detune・Resonance・全Volume・Osc2/3 Tune・Mod・Width・Pan・Gain・Mix・EQのFrequency/Gain/Mid Q・Reverb Decay/Damping・Chorus全6設定・Phaser全5設定・Compressor全7設定・Amp Sensitivity・Filter Amount Sensitivity・Portamento・Pitch・Pitch Bend 前ブロック末尾(offset=-1)から各点まで正規化空間で線形補間する

最後の点以降は値を保持します。同位置ではパラメーターをキュー順に適用した後、ノートをイベントリスト順に処理します。

音声バッファがない場合や処理停止中の0サンプルフラッシュでも、offset 0のパラメーター変更を受け付けます。 未知のParamID、不正な値、範囲外・後戻りする位置、取得に失敗した変更点は無視します。 Controllerの setParamNormalized は表示値を更新し、DSPの更新はホストが渡す変更キューを通じて行います。

保存・復元には標準の IComponent::getState/setState と IBStream を使用します。 保存形式v37は1076バイトです。すべてlittle endianで、先頭4バイトがSVST、次のu32がバージョン37、次のu32がOsc1の波形番号です。残る133設定を、src/parameters.rsのIDSと同じ順序で実単位のf64として保持します。Program番号は保存せず、編集済みの実際の134設定を保存します。 読み込みは現行形式v37のみです。異なるバージョン・空データ・不正値・途中切れは拒否し、現在の設定を保持します。 setState はProcessorと同一インスタンスのControllerの値を復元し、DSPには次の音声処理ブロックから適用します。 標準の setComponentState によるControllerの同期にも対応します。 位相・乱数状態・発音中のノート・受信したベンド位置は保存・復元の対象にせず、Controller固有の保存状態は空です。 状態の受け渡しはatomicで行い、音声スレッドをロックしません。

内蔵プリセット

DAWのVST3プログラム一覧で「Factory → Sine」を選択できます。IUnitInfoでルートユニット0、 プログラム一覧0、音色番号0の「Sine」を公開します。音色設定134個に加え、 Program(ParamID 0x50524f47、kIsList | kIsProgramChange)をホストへ公開します。 一覧は1音色なので選択番号・正規化値は0です。表示方法はDAWのプログラム選択画面に従います。

Sineの設定 値
Waveform / Phase Sine / Keep
Unison / Detune / Polyphony 1 / 0 cent / 1
音量AHDSR A/H/D/R=0 ms、S=1
Filter / Cutoff / Resonance Off / +4800 cent / Q=1
カットオフAHDSR / Amount A/H/D/R=0 ms、S=1 / 0 cent
Amp Sensitivity / Filter Amount Sensitivity 100% / 0%
Width / Pan / Master Volume / Osc1 Volume 0% / 中央 / 0 dB / 0 dB
Effect 1/2/3 / EQ / Limiter すべてOff
Osc2/3 Waveform / Tune / Volume / Mod Sine / 0 cent / −∞ dB / 0%
Clipper / Gain / Mix Soft / 0 dB / 100%

ノートオン・オフで即時に発音・消音し、最大ベロシティ時の実効値は片チャンネル当たり0.5です。 選択すると全設定を読み直し、同じ「Sine」の再選択でも編集した値を元に戻します。 ControllerはGUI表示を更新し、kParamValuesChangedでホストへ値の再取得を通知します。 音声側はProgramの変更キューの時刻で切り替えます。同位置ではProgram、個別パラメーター、ノートの順に適用します。 連続パラメーターに後続の変更点がある場合、切替時のプリセット値からその点まで補間します。 編集内容は実際の134設定として保存し、復元時にも編集後の値を保持します。

仕様: VST3 Presets & Program Lists

エフェクタ系列

全Voiceのフィルタ出力を合成した後、Effector 1 → Effector 2 → Effector 3 → EQ → Limiter → Master Volumeの順に処理します。 各スロットでOff/Chorus/Compressor/Delay/Distortion/Phaser/Reverbを選択し、Offはそのスロットを素通しにします。初期値はすべてOffです。 同じエフェクトを複数のスロットで使えます。設定と左右の処理履歴はスロットごとに独立します。

各スロットの↑/↓ボタンで、隣のスロットと種類とDistortion/Delay/Reverb/Chorus/Phaser/Compressorの全設定をまとめて交換します。 パラメーターIDとオートメーションはスロット位置に対応します。交換はVST3の編集通知を通してホストへ伝えます。 種類の変更時は対象スロットの履歴を初期化します。全設定を音色として保存・復元します。

設定 Effect 1 ParamID Effect 2 ParamID Effect 3 ParamID
種類(Off/Chorus/Compressor/Delay/Distortion/Phaser/Reverb) 0x45463154 0x45463254 0x45463354
Clipper 0x43545950 0x45463243 0x45463343
Gain 0x43474149 0x45463247 0x45463347
Distortion Mix 0x434d4958 0x4546324d 0x4546334d
Delay Time 0x45463142 0x45463242 0x45463342
Delay Feedback 0x45463146 0x45463246 0x45463346
Delay Mix 0x45463144 0x45463244 0x45463344
Delay Stereo 0x45463153 0x45463253 0x45463353
Reverb Decay 0x52314443 0x52324443 0x52334443
Reverb Damping 0x5231444d 0x5232444d 0x5233444d
Reverb Size 0x5231535a 0x5232535a 0x5233535a
Reverb Mix 0x52314d58 0x52324d58 0x52334d58
Chorus Time 0x4331544d 0x4332544d 0x4333544d
Chorus Depth 0x43314450 0x43324450 0x43334450
Chorus Rate 0x43315254 0x43325254 0x43335254
Chorus Detune 0x43314454 0x43324454 0x43334454
Chorus Feedback 0x43314642 0x43324642 0x43334642
Chorus Mix 0x43314d58 0x43324d58 0x43334d58
Phaser Center 0x50314346 0x50324346 0x50334346
Phaser Depth 0x50314450 0x50324450 0x50334450
Phaser Rate 0x50315254 0x50325254 0x50335254
Phaser Feedback 0x50314642 0x50324642 0x50334642
Phaser Mix 0x50314d58 0x50324d58 0x50334d58
Compressor Threshold 0x43500100 0x43500200 0x43500300
Compressor Ratio 0x43500101 0x43500201 0x43500301
Compressor Attack 0x43500102 0x43500202 0x43500302
Compressor Release 0x43500103 0x43500203 0x43500303
Compressor Knee 0x43500104 0x43500204 0x43500304
Compressor Makeup 0x43500105 0x43500205 0x43500305
Compressor Mix 0x43500106 0x43500206 0x43500306

Distortionは1段につきホストレートの1サンプル遅延します。系列の末尾で不足分の純遅延を補い、エフェクタ系列の遅延をホストレートの3サンプルに揃えます。ホストへはLimiterの先読みを加えた遅延を申告します。 全スロットがOffの場合も、エフェクタ系列自体はホストレートの3サンプルの純遅延になります。

テンポ同期ディレイ

Delayはステレオ方式を選択できるフィードバックディレイです。操作項目は次のとおりです。

設定 範囲 初期値
Time 1/32、1/16 T、1/16、1/8 T、1/16 D、1/8、1/4 T、1/8 D、1/4、1/2 T、1/4 D、1/2、1/2 D、1/1 1/8
Feedback 0〜100%、GUIは1%刻み 35%
Mix 0〜100%、GUIは1%刻み 25%
Stereo Dual/Cross/PP-L/PP-R Dual

Tは三連、Dは付点です。ホストのBPMと音価から遅延時間を求め、1サンプル〜8秒へクランプします。 IProcessContextRequirements::kNeedTempoを申告し、ProcessContext::kTempoValidが設定された有限の正のBPMを使用します。 初回取得前は120 BPM、情報が欠ける場合は直前の有効値を保持します。 分数サンプルは線形補間し、テンポ・音価変更は旧・新読出し位置を50msでクロスフェードします。 切替中の変更は最新値を保持し、現在のフェード完了後に次の切替を始めます。 Feedback・Mixは変更点間で線形補間し、Time・Stereoは変更点で切り替えます。 Mixは0%で原音、100%で遅延音。Feedback 100%は減衰なしの反復になります。

Dualは左右独立に帰還します。Crossは左右を交差して帰還し、最初の反復は入力と同じ配置、以後は左右交互になります。 PP-L/PP-RはWetへの入力を(L + R) / 2でモノラル化し、指定側だけへ入れて交差帰還します。PP-Lの反復は左→右→左、PP-Rは右→左→右です。 どの方式もDryの左右配置を保持します。Stereo方式の変更では履歴を保持し、変更点以降の入力と帰還先を切り替えます。

リングバッファは停止中のsetupProcessingでホストレートに応じて3スロット分を準備し、音声処理中には確保しません。 各スロットの上限は64 MiBで、8秒分を確保できないレートや確保失敗は設定時に拒否します。 1スロットのフレーム数はnext_power_of_two(ceil(Fs × 8) + 2)、各フレームは左右のf64(16バイト)です。 44.1/48 kHzでは524,288フレーム×16バイト=8 MiB、全3スロットで24 MiBです。96 kHzでは合計48 MiB、192 kHzでは合計96 MiBになります。 再生停止・シーク・ループで履歴を消さず、処理停止・再設定・スロット種類変更で初期化します。 音価による遅延はエフェクトの動作であり、固定の処理遅延に加算しません。

コーラス/フランジャー

Chorusは左右1本ずつの可変遅延で、短いTimeとFeedbackによるフランジャーも同じ処理で扱います。

設定 範囲・GUI刻み 初期値
Time 0.1〜40 ms・0.1 ms 20 ms
Depth 0〜10 ms・0.01 ms 2 ms
Rate 0.05〜5 Hz・0.01 Hz 0.7 Hz
Detune −0.1〜+0.1・0.001 0
Feedback −95〜+95%・1% 0%
Mix 0〜100%・1% 50%

左右LFOの周波数は左Rate × (1 + Detune)、右Rate × (1 − Detune)です。 開始位相は左0°・右180°とし、Rate・Detune変更では位相を継続します。 正弦波LFOでTimeを中心にDepth分だけ遅延を動かし、2点の線形補間で読み出します。 帰還を常に過去の音声へ限定するため、実効Depthをmin(Depth, Time − 1サンプル)に制限します。 設定値は保持し、Timeが広がると指定したDepthまで使います。 各チャンネルで入力 + Feedback × 遅延音を履歴へ書き込み、出力は原音と遅延音の線形混合です。 すべての設定はホストの変更点間で補間します。

履歴は最大Time+Depthの50 ms分を収める2の累乗長で、setup時に各スロットへ確保します。 1スロットの上限は16 MiBとし、処理中の設定変更では確保・解放しません。 スロット種類変更・処理停止・再設定で履歴とLFOを初期化し、再生停止・シークでは継続します。 Chorus自体の追加レイテンシーは0、エフェクタ系列は3サンプルです。 UIは上段にTime・Depth・Fdbk、下段にRate・Detを行ごとに均等割りし、Mixを右端中央に置きます。

Compressor

各スロットでCompressorを選択すると、左右の最大絶対振幅を共通検出し、左右に同じゲインを掛けます。

設定 範囲・GUI刻み 初期値
Threshold −60〜0 dBFS、0.1 dB −18 dBFS
Ratio 1〜20、0.1 4
Attack 0〜10,000 ms、エンベロープと同じ対数軸 10 ms
Release 0〜10,000 ms、エンベロープと同じ対数軸 100 ms
Knee 0〜24 dB、0.1 dB 6 dB
Makeup 0〜24 dB、0.1 dB 0 dB
Mix 0〜100%、1% 100%

Thresholdを中心とする二次soft kneeで目標減衰dBを求め、Attack/Releaseの1極応答で平滑化します。 時間設定は目標差の63.2%へ到達する時定数で、0 msなら即時に追従します。 Makeupは処理音だけに適用し、Mixは原音0%・処理音100%の線形混合です。 UIは上段にThrs・Ratio・Knee、下段にA・R・Gainを同じ列へ配置し、Mixを右端中央に置きます。Makeupは6 dBごとに吸着します。 7設定はオートメーションの変更点間で補間し、保存・復元と隣接スロット交換に含めます。 各スロットの減衰履歴は独立し、種類変更・処理停止・再設定で初期化します。 音声処理中のメモリ確保はなく、Compressorによる追加レイテンシーは0です。

Phaser

各スロットでPhaserを選択すると、左右独立の6段正規化ラティスallpassを原音と混合します。

設定 範囲・GUI刻み 初期値
Center 100〜4000 Hz、対数400 tick 1000 Hz
Depth 0〜2400 cent、10 cent 1200 cent
Rate 0.05〜5 Hz、0.01 Hz 0.5 Hz
Feedback −95〜95%、1% 50%
Mix 0〜100%、1% 50%

左右共通の正弦LFOで周波数を Center × 2^(Depth × LFO / 1200) として動かし、 1サンプル前のWetをFeedbackで入力へ戻します。Mixは原音0%・処理音100%の線形混合です。 係数を64サンプルごとに計算して間を線形補間し、Rate変更でもLFOの位相を保持します。 5設定はホストの変更点間で補間し、保存・復元と隣接スロット交換に含めます。 種類変更・処理停止・再設定で履歴を初期化し、ホストの再生停止・シークでは継続します。 処理状態は固定長で、音声処理中のメモリ確保はありません。追加レイテンシーは0、系列全体は3サンプルです。

PhaserのUIは上段にCenter・Depth、下段にRate・Fdbkを2×2で均等配置し、Mixを右端中央に置きます。

リバーブ

Reverbは8本の遅延線をHouseholder行列で結合するステレオFDNです。各帰還へ遅延長に応じた減衰と1極LPFを適用します。

設定 範囲・GUI刻み 初期値
Decay 0.1〜10秒、対数200tick 2秒
Damping 500〜20,000Hz、対数300tick 6,000Hz
Size 50〜200%、1%刻み 100%
Mix 0〜100%、1%刻み 25%

Decayは低域の設計残響時間(T60)、Dampingは帰還LPFの設計周波数、Sizeは遅延長の倍率です。 Decay・Damping・Mixは変更点間を線形補間し、Sizeは変更点で切り替えて残響をリセットします。 Mix=0%は原音、100%は残響です。操作ノブは各スロットにSize・Dec・Dampを等間隔で横一列に並べ、縦ディバイダの右側にMixを配置します。

8本の履歴は最大Sizeを収める領域を停止中のsetupProcessingで全3スロット分確保し、処理中に確保・解放しません。 上限は1スロット合計16 MiBです。資源上限を超えるサンプルレートや確保失敗は再構成時に拒否します。 再生停止・シークでは残響を継続し、処理停止・再設定・スロット種類変更でリセットします。 追加の処理遅延は0サンプルで、エフェクタ系列はホストレートの固定3サンプルです。

ディストーション

ClipperはSoft/Hard(初期値Soft)、Gainは0〜+48 dB・0.1 dB刻み(初期値0 dB)、Mixは0〜100%・1%刻み(初期値100%)です。 Softはtanh(x × gain)、Hardはclamp(x × gain, −1, 1)をホストレートの2階ADAAで左右独立に処理します。 Gainの線形倍率は10^(dB/20)です。Dryはそのスロットへの入力を1サンプルだけ遅延し、Gainや平均化を掛けません。 Mixは0%でDry、100%でWetになり、その間を線形混合して次の段へ渡します。Mixは各スロットの出力時点の値を使います。 バイパスはスロットの種類でOffを選択します。Gain・Mixはオートメーションの変更点間を線形補間し、種類・Clipperは変更点で切り替えます。

ADAA2による平均化はWetの高域特性に影響します。Dryは平均化を通しません。 Softの原始関数は1025点の共有テーブルから整合した多項式で求め、近接入力では差分の桁落ちを避ける式を使います。 Hardは区分的な関数の積分を直接計算します。ADAAの履歴は各スロットのDistortionが左右チャンネルごとに保持します。

処理中のClipper typeの変更は、Wetの32サンプルのフェードアウト、2サンプルの履歴充填、32サンプルのフェードインで切り替えます。 切替中もDryとノート・位相・AHDSRの時間は継続します。停止中の設定は次の処理開始時に即時適用します。 Gain・Mixはホストから届いた変更点間をホストレートで補間し、最後の変更点以降は値を保持します。

GUI

Integralの操作画面

画面は1076×768物理ピクセルの固定サイズです。左列にOsc1〜3、中央列にNote・Amp・Filter、右列に3つのエフェクト、左2列の下にEQを配置します。

  • ノブ:左ボタンで押し、上へドラッグすると増加、下へ動かすと減少します。操作中は正式名称と現在値を表示します。音程・音量・Panなどの基準値に吸着します。
  • 調整の終了:ボタン解放、Esc、フォーカス喪失、画面終了で調整を終えます。Escでも調整済みの値を保持します。操作終了時にはカーソルを復帰します。
  • 選択リスト:項目を押し、その項目の内側で離すと確定します。外側のクリックやEscでは選択を変えずに閉じます。
  • Off:Filter・EQは無効中でもノブを編集できます。Offのエフェクトスロットに薄く表示するMixは表示専用です。
  • エフェクト順序:各スロットの↑/↓で、種類と設定を隣のスロットと交換します。
  • Limiter:上部ボタンで切り替えます。Onでは緑色に点灯します。
  • Reset:音色・サンプルレート・テンポを保ったまま、発音とエフェクトの履歴を初期化します。
  • メーター:出力ピークはMaster音量適用後の左右最大値を表示します。0 dBFSを超える部分は赤です。発音数はリリース中を含むVoice数で、ユニゾン数や発振器数を加算しません。

ロゴ右のバージョン表示はリリース時のタグ名、未指定時はdevです。この表示はPR #109で追加します。ビルド時の指定を参照してください。

LinuxはX11へ埋め込み、ホストのLinux::IRunLoopを使用します。Waylandへの直接埋め込みと自由な画面サイズ変更には対応していません。GUIを閉じても音声処理は継続します。

全ノブの範囲・初期値・目盛 · 配置・入力・ホスト連携の詳細 · 描画と素材

EQ

3帯域EQをエフェクタ系列後・Limiter前で処理します。Low shelf → Peak → High shelfをTPT SVFで処理します。各帯域のFrequencyは20〜20,000 Hz、Gainは−18〜+18 dB、Mid Qは0.1〜10です。棚型の傾斜は固定。既定はOff、250/1,000/4,000 Hz、全Gain=0 dB、Q=1です。Off/On切替では履歴をリセットします。

EQの8設定はVST3の変更キューと状態保存へ接続し、内蔵SineではOffに戻ります。Enableは変更点で切り替え、他の7設定はVST3の正規化空間で線形補間します。GUIはFrequencyを300tickの対数軸、Gainを0.1 dB、Qを200tickの対数軸で操作します。Gainは−12・−6・0・+6・+12 dBで、共通の80物理pxの吸着区間を使います。端点の±18 dBは通常操作です。Mid帯域のQは「Mid Q」と表示します。ParamIDは0x45510000〜0x45510007です。

実装の参照先

Clone this wiki locally