KSPリファレンスマニュアル 25 - 応用概念(Advanced Concepts)

KSPリファレンスマニュアル 25 - 応用概念(Advanced Concepts)


KSPからのFXの変更

はじめに

Kontakt 5.5より前のバージョンでも、エフェクトスロットの内容に関する情報を取得するための仕組みは、$ENGINE_PAR_EFFECT_TYPEのようなエンジンパラメーター変数や$EFFECT_TYPE_FILTERのようなビルトイン定数を通じてすでに用意されていました(モジュールの種類とサブタイプを参照)。

Kontakt 5.5以降では、同じビルトイン定数のセットを使って、ロードされているエフェクトを変更することも可能になりました。

on init
    set_engine_par($ENGINE_PAR_EFFECT_TYPE, $EFFECT_TYPE_FILTER, 0, 0, -1)
    set_engine_par($ENGINE_PAR_EFFECT_SUBTYPE, $FILTER_TYPE_LDR_LP4, 0, 0, -1)
end on

Instrument内の最初のグループの、最初のGroup FXスロットに4ポールのローパスラダーフィルターを挿入します。

on async_completeコールバック

エフェクトスロットの内容の変更は非同期の処理です。つまり、インスタンス化した直後に、新しくインスタンス化されたエフェクトへ確実にアクセスすることはできません。これを解決するため、このコマンドは$NI_ASYNC_IDを返し、on async_completeコールバックをトリガーします。さらに、この処理を簡潔に書くためにwait_async()コマンドを使うこともできます(こちらが推奨されます)。

警告:on initコールバックからエフェクトスロットの内容を変更した場合、その処理は同期的に実行されるため、Instrumentの初期ロード時間に影響します。多数のエフェクトスロットに対してこれを行う場合はとくに顕著です。そのような処理はon persistence_changedコールバックへ移すことをおすすめします。

デフォルトのフィルタータイプ

フィルターはサブタイプを持つエフェクトタイプであるという点で、やや特殊です。KSPからサブタイプを明示的に選択せずに新しいフィルターをインスタンス化できるようになったため、あらかじめ定義されたデフォルトのフィルターサブタイプが必要になります。それがSV LP4です。

モジュレーションとオートメーションの割り当てへの影響

KSPを通じてエフェクトスロットの内容を変更するとき、割り当て済みのオートメーションとモジュレーションの扱いは、KontaktのGUIで同じ操作を行った場合と同一になることが期待されます。

  • スロットのエフェクトタイプを変更したり、エフェクトを完全に削除したりすると、モジュレーションとオートメーションの割り当てもすべて削除されます。とくにモジュレーターについては、削除される割り当てが、ある内部モジュレーターに属する唯一の割り当てであった場合(すなわち、そのモジュレーターが他のターゲットには割り当てられていない場合)、そのモジュレーター自体も削除されます。
  • スロットのエフェクトサブタイプを変更した場合(フィルターにのみ適用されます)、何も変更されません。現状と同じように、場合によっては「孤立した」モジュレーションの割り当てが残ってしまうことは許容されています。たとえば、ResonanceやGainのように、すでに利用できなくなったパラメーターにモジュレーションが割り当てられていた場合などです。

モジュレーターのサブタイプの変更

上で説明したのと同じコマンドを使って、内部モジュレーターのサブタイプを変更することもできます。具体的には、エンベロープのタイプ(AHDSR、Flex、DBD)や、LFOのタイプ(Rectangle、Triangle、Sawtooth、Random、Multi、Multi Digital)を切り替えられます。モジュレーターそのものを挿入したり削除したりはできません。また、そのタイプ(LFO、Envelope、Step Modulator、Envelope Follower、Glide)を変更することもできません。

特殊なケース

KSPから設定できないエフェクトタイプが2つあります。Surround PannerAET Filterです。


プリプロセッサーとシステムスクリプト

SET_CONDITION(<condition-symbol>)

条件として使用するシンボルを定義します。

RESET_CONDITION(<condition-symbol>)

条件の定義を削除します。

USE_CODE_IF(<condition-symbol>)

...

END_USE_CODE

<condition-symbol>が定義されているときにコードを解釈します。

USE_CODE_IF_NOT(<condition-symbol>)

...

END_USE_CODE

<condition-symbol>が定義されていないときにコードを解釈します。

NO_SYS_SCRIPT_GROUP_START

条件。SET_CONDITION()で定義すると、Group Start Optionsを処理するシステムスクリプトがバイパスされます。

NO_SYS_SCRIPT_PEDAL

条件。SET_CONDITION()で定義すると、CC# 64を受信したときにノートをサステインさせるシステムスクリプトがバイパスされます。

NO_SYS_SCRIPT_RLS_TRIG

条件。SET_CONDITION()で定義すると、キーリリース時にサンプルをトリガーするシステムスクリプトがバイパスされます。

reset_rls_trig_counter(<note>)

リリーストリガーのカウンターをリセットします(リリーストリガーのシステムスクリプトが使用します)。

will_never_terminate(<event-id>)

このイベントが決して終了しないことをスクリプトエンジンに伝えます(リリーストリガーのシステムスクリプトが使用します)。

プリプロセッサーは、解釈の対象からコード要素を除外するために使用します。<condition-symbol>は、英数字からなり先頭が文字であるシンボル名を指します。たとえば、次のように書くことができます:

on note
    { do something general }
    $var := 5

    {do some conditional code}
    USE_CODE_IF_NOT(dont_do_sequencer)
    while ($NOTE_HELD = 1)
        play_note($EVENT_NOTE, $EVENT_VELOCITY, 0, $DURATION_SIXTEENTH)
        wait($DURATION_EIGHTH)
    end while
    END_USE_CODE
end on

ここでは何が起きているのでしょうか。

シンボルdont_do_sequencerが定義されていない場合にかぎり、USE_END_USEの間のコードが処理されます。このシンボルが見つかった場合、コードはパーサーに渡されず、そのコードは最初から書かれていなかったのと同じ扱いになります。したがって、CPUリソースを一切消費しません。

すべてのコマンドは、スクリプトが実行されるに解釈されます。つまり、USE_CODE_を使うと、コードはスクリプトエンジンに渡される前に止められることがあります。これは、SET_CONDITIONRESET_CONDITIONが実際には本当のコマンドではないということを意味します。これらはif ... elseの制御構文の中では使用できず、また、これらのコマンドの前にwait()文を置いても意味がありません。SET_CONDITIONRESET_CONDITIONは、それぞれ他の処理よりも前に実行されます。

定義されたシンボルはすべて後続のスクリプトスロットに引き継がれます。つまり、スクリプトスロット3に条件付きのコードが含まれている場合、それをスクリプト1や2でオンにしたりオフにしたりできるということです。

条件付きのコードを使ってシステムスクリプトをバイパスできます。これらのシンボルのいずれかをSET_CONDITION()で定義すると、システムスクリプトの該当する部分がバイパスされます。分かりやすさのため、この定義は必ずon initコールバックの中で行うようにしてください。

on init
    { we want to do our own release triggering }
    SET_CONDITION(NO_SYS_SCRIPT_RLS_TRIG)
end on

on release
    { do something custom here }
end on

独自のリリーストリガーのロジックを実装したい場合、これがその第一歩となります。


PGS

Program Global Storage(PGS)コマンドを使うと、通常の左から右への処理順序を回避して、あるスクリプトから別のスクリプトへ値を送ったり受け取ったりできます。PGSは共有メモリで、どのスクリプトからも読み出しと書き込みができます。

PGSコマンド

pgs_create_key(<key-id>, <size>)

pgs_key_exists(<key-id>)

pgs_set_key_val(<key-id>, <index>, <value>)

pgs_get_key_val(<key-id>, <index>)

<key-id>は変数名に似ています。英数字のみを含むことができ、数字で始めることはできません。また、64文字を超えることもできません。固有の存在であることを強調するため、常に大文字で書くようにするとよいでしょう。

以下は例です。次のスクリプトを任意のスロットに挿入してください:

on init
    declare ui_button $Just_Do_It

    pgs_create_key(FIRST_KEY, 1)  { defines a key with 1 element }
    pgs_create_key(NEXT_KEY, 128) { defines a key with 128 elements }
end on

on ui_control($Just_Do_It)
    { writes 70 into the first and only memory location of FIRST_KEY }
    pgs_set_key_val(FIRST_KEY, 0, 70)

    { writes 50 into the first and 60 into the last memory location of NEXT_KEY }
    pgs_set_key_val(NEXT_KEY, 0, 50)
    pgs_set_key_val(NEXT_KEY, 127, 60)
end on

次に、以下のスクリプトを他の任意のスロットに挿入します:

on init
    declare ui_knob $First (0, 100, 1)
    declare ui_table %Next[128] (5, 2, 100)
end on

on pgs_changed
    { checks if FIRST_KEY and NEXT_KEY have been declared }
    if (pgs_key_exists(FIRST_KEY) and _pgs_key_exists(NEXT_KEY))
        $First := pgs_get_key_val(FIRST_KEY, 0)      { in this case 70 }
        %Next[0] := pgs_get_key_val(NEXT_KEY, 0)     { in this case 50 }
        %Next[127] := pgs_get_key_val(NEXT_KEY, 127) { in this case 60 }
    end if
end on

上の例で示したとおり、pgs_set_key_val()コマンドが実行されるたびに実行されるコールバックも用意されています。

PGSキーはいくつでも持つことができますが、各キーが持てる要素は最大で256個までです。

PGS文字列の基本的な扱いは通常のPGSキーと同じですが、1つだけ違いがあります。PGS文字列キーは、すでにご存じの標準的なPGSキーのような配列ではなく、通常の文字列変数のように機能します。

PGS文字列コマンド

pgs_create_str_key(<key-id>)

pgs_str_key_exists(<key-id>)

pgs_set_str_key_val(<key-id>, <string>)

<string> := pgs_get_str_key_val(<key-id>)


Advanced Engineタブ

Advanced Engineタブは、Instrumentやスクリプトのパフォーマンスをデバッグしたり測定したりするのに役立つツールです。

Engineタブ(KontaktのSide PaneにあるMonitorタブのサブタブ)でもパフォーマンスの統計を分かりやすく表示できますが、Advanced版はCPU使用率などをより高い精度で表示し、Kontaktをプラグインとして使用している場合には複数インスタンスの情報も表示します。

Advanced Engineタブを表示する

先に述べたとおり、EngineタブはMonitorタブのサブセクションで、KontaktのSide Paneにあります。

  • Advanced Engineタブにアクセスするには、[Alt](Windows)または[Opt](macOS)キーを押しながらEngineタブをクリックします。
  • 通常のEngineタブに戻るには、キーを押さずにもう一度Engineタブをクリックします。

インスタンスの概要

DAWやホストでKontaktをプラグインとして複数インスタンス実行している場合、それぞれのインスタンスがこのセクションに1項目として表示されます。Kontaktをスタンドアローンで使用している場合は、現在のインスタンスのみが表示されます。

ここでは5種類のパフォーマンス統計を確認できます:

  • CPU:現在のCPU負荷をパーセントで表示します(Kontakt内の他のCPU表示よりも高い分解能で表示されます)。あわせて、記録された最も高いCPUのピーク値も表示されます(括弧内に表示されます)。ピーク値は、Kontaktのインターフェース右上にある「!」ボタンをクリックしてインスタンスを再初期化することでリセットできます。
  • Voices:現在のKontaktインスタンスで使用されているボイスの総数を表示します。
  • Voices killed:CPUのオーバーロード(左側に表示されます)とDFDのオーバーロード(右側に表示されます)によって強制終了されたボイスの総数を表示します。
  • Process buffer:現在のオーディオバッファーサイズをサンプル数で表示します。
  • Events:現在イベントキューに入っているイベントの総数を表示します。ボイスが再生されているサンプルに相当するのに対して、イベントはエンジンが処理するMIDIノートメッセージにより近い概念です。たとえば、1つのノートに3つのサンプルがマッピングされている場合、1つのイベントが3つのボイスを生成することがあります。さらに、MIDIキーを押さえたままトリガーされたサンプルの再生が終わった場合、ボイスは終了しますが、イベントはキューに残ります。そのため、この表示はハングしているイベントを追跡するのに役立ちます。ハングしたボイスとは違って、必ずしも音として聞こえるとはかぎらないからです。

合計

下部のセクションには、現在ロードされているすべてのKontaktインスタンスのパフォーマンス統計の合計が表示されます。以下のパラメーターがあります:

  • VoicesVoices killed:インスタンスの概要にある表示と同じですが、すべてのインスタンスの合計値です。
  • DFD load:DFDモードを使用するInstrumentを再生している場合、それらのハードディスクへのアクセスを測定します。実質的には、KontaktのHeaderにあるDiskメーターをより正確にしたものです。
  • DFD memory:DFDストリームの処理にどれだけのRAMが使われているかを測定した値です。
  • DFD requests:Kontaktがハードディスクからデータを読み込むために行ったリクエストの総数です。

参照元情報:Advanced Concepts
https://docs.native-instruments.com/online-guides/ksp-manual/en/advanced-concepts