KSPリファレンスマニュアル 16 - ミュージックインフォメーションリトリーバル(Music Information Retrieval)

KSPリファレンスマニュアル 16 - ミュージックインフォメーションリトリーバル(Music Information Retrieval)


一般情報

ミュージックインフォメーションリトリーバル(MIR)を使うと、ピッチやサンプルの音量レベルといった、意味のある特徴量をオーディオファイルから抽出できます。新しいKSPコマンドによって、こうしたパラメーターをスクリプト経由でサンプルから抽出できます。MIR関数はon initコールバックでは非同期ではありませんが、それ以外のすべてのコールバックでは非同期で実行されます。

注意:以下に挙げるタイプ検出の関数(Sample Type、Drum Type、Instrument Type)は、ワンショットのオーディオサンプルを処理することを想定して設計されています。


detect_key()

detect_key(<zone-id>, <key-result>)

<key-result>に、オーディオサンプルの音楽的なキーを表す$NI_DETECT_KEYタグを割り当てます。検出に失敗した場合、この関数は$NI_DETECT_KEY_INVALIDを返します。

<zone-id>

ゾーンのIDです。

<key-result>

検出された音楽的なキーです。次のいずれかになります:

$NI_DETECT_KEY_C_MAJOR

$NI_DETECT_KEY_CSHARP_MAJOR

$NI_DETECT_KEY_D_MAJOR

$NI_DETECT_KEY_DSHARP_MAJOR

$NI_DETECT_KEY_E_MAJOR

$NI_DETECT_KEY_F_MAJOR

$NI_DETECT_KEY_FSHARP_MAJOR

$NI_DETECT_KEY_G_MAJOR

$NI_DETECT_KEY_GSHARP_MAJOR

$NI_DETECT_KEY_A_MAJOR

$NI_DETECT_KEY_ASHARP_MAJOR

$NI_DETECT_KEY_B_MAJOR

$NI_DETECT_KEY_C_MINOR

$NI_DETECT_KEY_CSHARP_MINOR

$NI_DETECT_KEY_D_MINOR

$NI_DETECT_KEY_DSHARP_MINOR

$NI_DETECT_KEY_E_MINOR

$NI_DETECT_KEY_F_MINOR

$NI_DETECT_KEY_FSHARP_MINOR

$NI_DETECT_KEY_G_MINOR

$NI_DETECT_KEY_GSHARP_MINOR

$NI_DETECT_KEY_A_MINOR

$NI_DETECT_KEY_ASHARP_MINOR

$NI_DETECT_KEY_B_MINOR


detect_pitch()

detect_pitch(<zone-id>, <pitch-result>)

オーディオサンプルの基本周波数を、セミトーンとセントの単位で表した実数値を返します。検出に失敗した場合、この関数は~NI_DETECT_PITCH_INVALIDを返します。

<zone-id>

ゾーンのIDです。

<pitch-result>

検出されたピッチのMIDIノート値です。


detect_loudness()

detect_loudness(<zone-id>, <loudness-result>)

オーディオサンプルのラウドネスをデシベルで表した実数値を返します。ラウドネスは、国際電気通信連合が定めた規格「Algorithms to measure audio program loudness and true-peak audio level - ITU-R BS.1770-4(2015)」に従って測定されます。検出に失敗した場合、この関数は~NI_DETECT_LOUDNESS_INVALIDを返します。

<zone-id>

ゾーンのIDです。

<loudness-result>

検出されたラウドネスをデシベルで表した実数値です。


detect_peak()

detect_peak(<zone-id>, <peak-result>)

オーディオサンプルのピークレベルをデシベルで表した実数値を返します。ピークは、国際電気通信連合が定めた規格「Algorithms to measure audio program loudness and true-peak audio level - ITU-R BS.1770-4(2015)」に従って測定されます。検出に失敗した場合、この関数は<peak-result>~NI_DETECT_PEAK_INVALIDを設定します。

<zone-id>

ゾーンのIDです。

<peak-result>

検出されたピークレベルをデシベルで表した実数値です。


detect_rms()

detect_rms(<zone-id>, <rms-result>)

オーディオサンプルのRMSレベルをデシベルで表した実数値を返します。検出に失敗した場合、この関数は~NI_DETECT_RMS_INVALIDを返します。

<zone-id>

ゾーンのIDです。

<rms-result>

オーディオサンプルのRMSレベルをデシベルで表した実数値です。


detect_tempo()

detect_tempo(<zone-id>, <tempo-result>)

オーディオサンプルから検出されたテンポを、BPMの単位で表した実数値を返します。検出に失敗した場合、この関数は~NI_DETECT_TEMPO_INVALIDを返します。

<zone-id>

ゾーンのIDです。

<tempo-result>

検出されたテンポのBPM値です。


detect_sample_type()

detect_sample_type(<zone-id>, <sample-type-result>)

<sample-type-result>に、オーディオサンプルがドラムか楽器かを表す$NI_DETECT_SAMPLE_TYPEタグを割り当てます。検出に失敗した場合、この関数は$NI_DETECT_SAMPLE_TYPE_INVALIDを返します。

<zone-id>

ゾーンのIDです。

<sample-type-result>

検出されたサンプルタイプです。次のいずれかになります:

$NI_DETECT_SAMPLE_TYPE_INVALID

$NI_DETECT_SAMPLE_TYPE_INSTRUMENT

$NI_DETECT_SAMPLE_TYPE_DRUM


detect_drum_type()

detect_drum_type(<zone-id>, <drum-type-result>)

<drum-type-result>に、オーディオサンプルのドラムタイプを表す$NI_DETECT_DRUM_TYPEタグを割り当てます。detect_sample_type()が、対象のオーディオサンプルは$NI_DETECT_SAMPLE_TYPE_DRUMタイプであると判定した場合に、この関数を使用できます。検出に失敗した場合、この関数は~NI_DETECT_DRUM_TYPE_INVALIDを返します。

<zone-id>

ゾーンのIDです。

<drum-type-result>

検出されたドラムタイプです。次のいずれかになります:

$NI_DETECT_DRUM_TYPE_INVALID

$NI_DETECT_DRUM_TYPE_KICK

$NI_DETECT_DRUM_TYPE_SNARE

$NI_DETECT_DRUM_TYPE_CLOSED_HH

$NI_DETECT_DRUM_TYPE_OPEN_HH

$NI_DETECT_DRUM_TYPE_TOM

$NI_DETECT_DRUM_TYPE_CYMBAL

$NI_DETECT_DRUM_TYPE_CLAP

$NI_DETECT_DRUM_TYPE_SHAKER

$NI_DETECT_DRUM_TYPE_PERC_DRUM

$NI_DETECT_DRUM_TYPE_PERC_OTHER


detect_instrument_type()

detect_instrument_type(<zone-id>, <instr-type-result>)

<instr-type-result>に、オーディオサンプルの楽器タイプを表す$NI_DETECT_INSTRUMENT_TYPEタグを割り当てます。ヒント:detect_sample_type()が、対象のオーディオサンプルは$NI_DETECT_SAMPLE_TYPE_INSTRUMENTタイプであると判定した場合に、この関数を使用してください。検出に失敗した場合、この関数は$NI_DETECT_INSTRUMENT_TYPE_INVALIDを返します。

<zone-id>

ゾーンのIDです。

<instr-type-result>

検出された楽器タイプです。次のいずれかになります:

$NI_DETECT_INSTRUMENT_TYPE_INVALID

$NI_DETECT_INSTRUMENT_TYPE_BASS

$NI_DETECT_INSTRUMENT_TYPE_BOWED_STRING

$NI_DETECT_INSTRUMENT_TYPE_BRASS

$NI_DETECT_INSTRUMENT_TYPE_FLUTE

$NI_DETECT_INSTRUMENT_TYPE_GUITAR

$NI_DETECT_INSTRUMENT_TYPE_KEYBOARD

$NI_DETECT_INSTRUMENT_TYPE_MALLET

$NI_DETECT_INSTRUMENT_TYPE_ORGAN

$NI_DETECT_INSTRUMENT_TYPE_PLUCKED_STRING

$NI_DETECT_INSTRUMENT_TYPE_REED

$NI_DETECT_INSTRUMENT_TYPE_SYNTH

$NI_DETECT_INSTRUMENT_TYPE_VOCAL


on init
    message("")

    declare ~pitch_result

    set_num_user_zones(1)

    declare ui_mouse_area $Drop
    declare ui_label $Info (1, 1)

    set_text($Info, "Drop sample here!")

    move_control_px($Drop, 66, 2)
    move_control_px($Info, 66, 2)

    set_control_par(get_ui_id($Drop), $CONTROL_PAR_DND_ACCEPT_AUDIO, $NI_DND_ACCEPT_ONE)
    set_control_par(get_ui_id($Drop), $CONTROL_PAR_WIDTH, 150)
    set_control_par(get_ui_id($Info), $CONTROL_PAR_WIDTH, 150)

    set_zone_par(%NI_USER_ZONE_IDS[0], $ZONE_PAR_HIGH_KEY, 127)
    set_zone_par(%NI_USER_ZONE_IDS[0], $ZONE_PAR_LOW_VELO, 1)
    set_zone_par(%NI_USER_ZONE_IDS[0], $ZONE_PAR_HIGH_VELO, 127)
    set_zone_par(%NI_USER_ZONE_IDS[0], $ZONE_PAR_GROUP, 0)
end on

on ui_control ($Drop)
    if ($NI_MOUSE_EVENT_TYPE = $NI_MOUSE_EVENT_TYPE_DROP)
        wait_async(set_sample(%NI_USER_ZONE_IDS[0], !NI_DND_ITEMS_AUDIO[0]))

        wait_async(detect_pitch(%NI_USER_ZONE_IDS[0], ~pitch_result))
        wait_async(set_zone_par(%NI_USER_ZONE_IDS[0], ...
                                $ZONE_PAR_ROOT_KEY, ...
                                int(round(~pitch_result))))
        wait_async(set_zone_par(%NI_USER_ZONE_IDS[0], ...
                                $ZONE_PAR_TUNE, ...
                                int(100.0 * (round(~pitch_result) - ~pitch_result))
    end if
end on

ピッチの検出結果を整数値に丸めてゾーンのルートキーを設定し、続いてピッチのずれを補正するようにゾーンのチューンを設定します。

on init
    message("")

    set_num_user_zones(1)

    declare ui_mouse_area $Drop
    declare ui_label $Info (1, 1)

    declare $sample_type
    declare $instrument_type
    declare $drum_type
    declare !drum_types[10]
    !drum_types[$NI_DETECT_DRUM_TYPE_KICK]       := "Kick"
    !drum_types[$NI_DETECT_DRUM_TYPE_SNARE]      := "Snare"
    !drum_types[$NI_DETECT_DRUM_TYPE_CLOSED_HH]  := "Closed Hi-Hat"
    !drum_types[$NI_DETECT_DRUM_TYPE_OPEN_HH]    := "Open Hi-Hat"
    !drum_types[$NI_DETECT_DRUM_TYPE_TOM]        := "Tomr"
    !drum_types[$NI_DETECT_DRUM_TYPE_CYMBAL]     := "Cymbal"
    !drum_types[$NI_DETECT_DRUM_TYPE_CLAP]       := "Clap"
    !drum_types[$NI_DETECT_DRUM_TYPE_SHAKER]     := "Shaker"
    !drum_types[$NI_DETECT_DRUM_TYPE_PERC_DRUM]  := "Drum Percussion"
    !drum_types[$NI_DETECT_DRUM_TYPE_PERC_OTHER] := "Misc Percussion"
    declare !instrument_types[12]
    !instrument_types[$NI_DETECT_INSTRUMENT_TYPE_BASS]           := "Bass"
    !instrument_types[$NI_DETECT_INSTRUMENT_TYPE_BOWED_STRING]   := "Bowed String"
    !instrument_types[$NI_DETECT_INSTRUMENT_TYPE_BRASS]          := "Brass"
    !instrument_types[$NI_DETECT_INSTRUMENT_TYPE_FLUTE]          := "Flute"
    !instrument_types[$NI_DETECT_INSTRUMENT_TYPE_GUITAR]         := "Guitar"
    !instrument_types[$NI_DETECT_INSTRUMENT_TYPE_KEYBOARD]       := "Keyboard"
    !instrument_types[$NI_DETECT_INSTRUMENT_TYPE_MALLET]         := "Mallet"
    !instrument_types[$NI_DETECT_INSTRUMENT_TYPE_ORGAN]          := "Organ"
    !instrument_types[$NI_DETECT_INSTRUMENT_TYPE_PLUCKED_STRING] := "Plucked String"
    !instrument_types[$NI_DETECT_INSTRUMENT_TYPE_REED]           := "Reed"
    !instrument_types[$NI_DETECT_INSTRUMENT_TYPE_SYNTH]          := "Synth"
    !instrument_types[$NI_DETECT_INSTRUMENT_TYPE_VOCAL]          := "Vocal"

    set_text($Info, "Drop sample here!")

    move_control_px($Drop, 66, 2)
    move_control_px($Info, 66, 2)

    set_control_par(get_ui_id($Drop), $CONTROL_PAR_DND_ACCEPT_AUDIO, $NI_DND_ACCEPT_ONE)
    set_control_par(get_ui_id($Drop), $CONTROL_PAR_WIDTH, 150)
    set_control_par(get_ui_id($Info), $CONTROL_PAR_WIDTH, 150)

    set_zone_par(%NI_USER_ZONE_IDS[0], $ZONE_PAR_HIGH_KEY, 127)
    set_zone_par(%NI_USER_ZONE_IDS[0], $ZONE_PAR_LOW_VELO, 1)
    set_zone_par(%NI_USER_ZONE_IDS[0], $ZONE_PAR_HIGH_VELO, 127)
    set_zone_par(%NI_USER_ZONE_IDS[0], $ZONE_PAR_GROUP, 0)
end on

on ui_control ($Drop)
    if ($NI_MOUSE_EVENT_TYPE = $NI_MOUSE_EVENT_TYPE_DROP)
        wait_async(set_sample(%NI_USER_ZONE_IDS[0], !NI_DND_ITEMS_AUDIO[0]))
        wait_async(detect_sample_type(%NI_USER_ZONE_IDS[0], $sample_type))

        select ($sample_type)
            case $NI_DETECT_SAMPLE_TYPE_INSTRUMENT
                wait_async(detect_instrument_type(%NI_USER_ZONE_IDS[0], $instrument_type))
            case $NI_DETECT_SAMPLE_TYPE_DRUM
                wait_async(detect_drum_type(%NI_USER_ZONE_IDS[0], $drum_type))
            case $NI_DETECT_SAMPLE_TYPE_INVALID
                set_text($Info, "Cannot recognize sample type!")
        end select

        if ($sample_type = $NI_DETECT_SAMPLE_TYPE_INSTRUMENT)
            if ($instrument_type = $NI_DETECT_INSTRUMENT_TYPE_INVALID)
                set_text($Info, "Cannot recognize instrument type!")
            else
                set_text($Info, "Instrument: " & !instrument_types[$instrument_type])
            end if
        else
            if ($drum_type = $NI_DETECT_DRUM_TYPE_INVALID)
                set_text($Info, "Cannot recognize drum type!")
            else
                set_text($Info, "Instrument: " & !drum_types[$drum_type])
            end if
        end if
    end if
end on

サンプルのタイプが楽器かドラムかを検出し、それに応じたドラムタイプまたは楽器タイプを検出します。


参照元情報:Music Information Retrieval
https://docs.native-instruments.com/online-guides/ksp-manual/en/music-information-retrieval