ピッチ補正とノート編集
ピッチ補正は、音を現在のピッチから目標へ寄せます。
ノート編集は、選んだ区間(伸ばした 1 音、タイミングの調整)を、他に触れずに整形します。外科的で区間を意識しているのはこのノート編集のほうです。ピッチ補正は区間を取らず、渡されたバッファ全体を補正します。本ページはこの 2 つを libsonare の PitchCorrector と NoteEditor に根拠づけます。用語は 編集の基礎 を読んでください。
現在のピッチは呼び出し側が渡す
pitchCorrectToMidi は、歌った音を自動で推測しません。現在の音を呼び出し側が渡します。
使う流れは次の通りです。
pitchYin、pitchPyin、または独自の検出器で現在のピッチを推定する。- そのピッチを MIDI ノート番号として読む、または変換する。
- 測定した値を現在の MIDI ノートとして渡す。
- 寄せたい音を目標の MIDI ノートとして渡す。
MIDI ノート番号は半音単位のインデックスです。
| 例 | 意味 |
|---|---|
69 | A4、440 Hz |
68.7 | A4 より少し低い音 |
60 | C4、中央のド |
歌い手が音にぴったり乗ることは稀なので、小数値は普通に起こります。
補正の強さと自然さ
補正の実体はピッチシフトなので、同じアーティファクト則が当てはまります — 小さな音程は透明、大きな音程はフェーズボコーダのにじみを露呈します。自然なボーカルには、大きく跳ばすより最も近い音階音へ小さく補正します。完全にスナップさせる強い補正は、透明な修正ではなくクリエイティブな効果です。
pitchCorrectToMidi はバッファ全体を補正する
pitchCorrectToMidi(samples, sampleRate, currentMidi, targetMidi) には区間の引数がありません。音程差を 1 つ求め、全サンプルをその量だけ移調するので、テイク全体を渡せば聴いていた 1 音だけでなくテイク全体が動きます。さらに音程差は ±12 半音でクランプされ、その事実は報告されないため、2 オクターブを要求しても黙って 1 オクターブぶんしか動きません。
テイクの中の 1 音だけを直したい場合は、その区間を自分でバッファから切り出して補正するか、時間変化版を使ってください。時間変化版では、フレームごとの F0 輪郭と voiced フラグが補正を局所化します。無声フレームは手つかずで残り、有声フレームはそれぞれ固有の補正量を受け取ります。
ノート区間: 秒ではなくサンプル
noteStretch のような区間ベースの編集は、秒ではなくサンプル位置を取ります。サンプル位置は正確でずれないからです。samples = round(seconds × sampleRate) で変換します — 48 kHz なら 0.25 秒はサンプル 12000 です。区間はオンセットサンプルとオフセットサンプル(音の始まりと終わりの位置)を持ち、stretchRatio > 1 はその区間を長くします。このとき区間より後ろの音声は同じ量だけ後ろへずれ、クリップ全体も長くなります。区間の外側は、継ぎ目に入る短い equal-power クロスフェードを除けば手つかずのまま残ります。
UI が秒で区間を扱う場合は、関数を呼ぶ直前にサンプルへ変換するのが安全です。秒のまま小数で渡すと丸め方によって 1 サンプルずれることがあり、ループのつなぎ目でわずかなノイズになり得ます。サンプル位置で考えれば、編集が常に正確な位置に当たります。
libsonare が補正・編集をどう行うか
pitchCorrectToMidi は現在→目標の MIDI 音程をピッチシフトへ対応づけ、タイムストレッチとピッチシフト のフェーズボコーダ経路を再利用します。区間編集は、オンセット/オフセットのサンプル位置で定義される NoteRegion に対して NoteEditor(NoteEditorConfig)を使い、NoteSegmenter が区間の特定を助けます。noteStretch は区間限定のストレッチ比を適用します。すべてデコード済みのモノラルサンプルに作用し、Audio も同じ操作をメソッドとして公開するので、ファイルワークフローでは一度読み込んで編集できます。