ピッチ補正とノート編集
ピッチ補正は、音を現在のピッチから目標へ寄せます。
ノート編集は、伸ばした 1 音やタイミングのずれのような選んだ区間だけを、残りのクリップに触れずに整形します。区間を意識した局所的な処理はこちらです。ピッチ補正は区間を取らず、渡されたバッファ全体を補正します。このページでは、この 2 つを libsonare の PitchCorrector と NoteEditor に沿って説明します。用語は 編集の基礎 を参照してください。
現在のピッチは呼び出し側が渡す
pitchCorrectToMidi は、歌った音を自動で推測しません。現在の音を呼び出し側が渡します。
使う流れは次のとおりです。
pitchYin、pitchPyin、または独自の検出器で現在のピッチを推定する。- そのピッチを MIDI ノート番号として読む、または変換する。
- 測定した値を現在の MIDI ノートとして渡す。
- 寄せたい音を目標の MIDI ノートとして渡す。
MIDI ノート番号は半音単位のインデックスです。
| 例 | 意味 |
|---|---|
69 | A4、440 Hz |
68.7 | A4 より少し低い音 |
60 | C4、中央のド |
歌い手がぴったり音に乗ることは稀なので、小数値になるのが普通です。
補正の強さと自然さ
補正の実体はピッチシフトなので、同じ法則が当てはまります。小さな音程差なら補正はほとんど聞き取れず、大きな音程差では再合成の痕跡が表に出ます。どんな痕跡になるかは処理を担うエンジンで変わります(次の節を参照)。自然なボーカルに仕上げるなら、大きく跳ばすのではなく最も近い音階音へ少しだけ補正します。最も近い音へ完全に寄せる強い補正は、目立たない修正ではなくクリエイティブな効果です。
再合成エンジンは 2 種類
libsonare は 2 通りの方法で音高を変えます。どちらを使うかで、フォルマント(声道の共鳴。ボイスとフォルマントを参照)の扱いが決まります。
| エンジン | 仕組み | フォルマント | 典型的な痕跡 | 使う呼び出し |
|---|---|---|---|---|
| フェーズボコーダ+リサンプリング | STFT 領域で音を伸ばしてから、元の長さへリサンプリングする(タイムストレッチとピッチシフト) | 音高と一緒に動く(いわゆる早回しの声) | 位相のにじみ、アタックのぼやけ | pitchShift、pitchCorrectToMidi、voiceChange のピッチ段、renderNotes の pitchShiftSemitones |
| TD-PSOLA(時間領域のピッチ同期重畳加算) | 波形を 1 周期ぶんの断片に切り分け、間隔を詰めたり広げたりして並べ直す | 断片ごとにスペクトル包絡を保つので、ほぼ元の位置に残る | 息の多い声や雑音の多い声でのざらつき・うなり。使える F0 が必要 | pitchCorrectToMidiTimevarying、pitchCorrectTimevarying、autoTune、ボーカル編集セッション、renderNotes のビブラート・ドリフト編集 |
TD-PSOLA はフレームごとの補正量に従って断片を動かすので、有声フレームだけに作用し、渡した F0 輪郭を必要とします。1 回の処理で扱えるのは 6 半音までで、それより大きな補正は複数回に分けて適用されます。フェーズボコーダの経路はピッチ輪郭を必要としないため、一定の音程差を適用する呼び出しはこちらを使います。
pitchCorrectToMidi はバッファ全体を補正する
pitchCorrectToMidi(samples, sampleRate, currentMidi, targetMidi) には区間の引数がありません。音程差を 1 つ求め、全サンプルをその量だけ移調するので、テイク全体を渡せば聴いていた 1 音だけでなくテイク全体が動きます。
音程差そのものは丸ごと適用されます。両端の値はどちらも呼び出し側が決めるため、これは補正ではなく移調であり、C3 → C5 ならバッファは 24 半音ぶん動きます。max_correction_semitones が制限するのは、測定したピッチから補正量を求めるリチューンの経路だけなので、ここには効きません。2 つの MIDI 番号はどちらも [0, 127] に収まるか検証され、範囲外の値は黙って丸められるのではなくエラーになります。
テイクの中の 1 音だけを直したい場合は、その区間を自分でバッファから切り出して補正するか、時間変化版を使ってください。時間変化版では、フレームごとの F0 輪郭と voiced フラグが補正を局所化します。無声フレームは手つかずで残り、有声フレームはそれぞれ固有の補正量を受け取ります。
音階に合わせる
1 つの音へ寄せる補正は、伸ばした 1 音のようなケースに向きます。ライン全体は、代わりにキーへ向けて補正します。有声フレームを音階の最も近い構成音へ引き寄せ、効き方は 3 つのコントロールで決まります。リチューン量はフレームを目標へどこまで寄せるか、リチューン速度はどれだけ速く寄せるか、ビブラートしきい値は、すでに音程が合っているとみなす偏差の大きさです。歌のビブラート(一般に ±50〜±100 セント)は既定のしきい値 20 セントより大きいので、ビブラートが残るのは主にリチューン速度を遅めにしたときです。補正がひと揺れごとではなく平均的な音高を追うようになります。オプションの一覧は編集 DSP、テイク 1 本を通した流れは歌のピッチを直すを参照してください。
ノート区間: サンプル位置
noteStretch のような区間ベースの編集は、正確でずれないサンプル位置を取ります。onsetSec / offsetSec で同じ境界を秒でも指定でき、最も近いサンプルに丸められます。samples = round(seconds × sampleRate) で、負の位置は拒否されます。48 kHz なら 0.25 秒はサンプル 12000 です。区間はオンセットサンプルとオフセットサンプル(音の始まりと終わりの位置)を持ちます。stretchRatio > 1 は置換区間を長くし、noteStretch はその始端と終端で元のサンプルを 等電力クロスフェードで混ぜます。クロスフェードは置換区間内で完結し、隣接音声のサンプルを重ねて消費しません。そのためクリップ全体の長さと区間より後ろの音声の移動量は、置換区間の長さの差分に従います。stretchRatio: 1 ではクリップ全体の長さは変わりません。他の比率では時間ストレッチのサンプル丸めにより数サンプルの差が出ることがあります。入力の端に接する側には隣接音声がないため、その側のクロスフェードはありません。継ぎ目の両側はよく似た信号なので、持続音では継ぎ目の中のレベルが数 dB 動くことがあります。測定値は編集 DSPにあります。
秒は呼び出しのサンプルレートで 1 回だけ丸められます。位置が解析から得られた値なら、サンプル値のまま渡してください。
libsonare が補正・編集をどう行うか
pitchCorrectToMidi は現在→目標の MIDI 音程をピッチシフトへ対応づけ、タイムストレッチとピッチシフト のフェーズボコーダ経路を再利用します。輪郭に沿う補正関数は、フレームごとの補正量を TD-PSOLA の経路である PitchCorrector::resynthesize に渡します。PitchCorrectionConfig::max_correction_semitones(既定 12)が制限するのは、測定した F0 から補正量を導く経路(F0Track を取るオーバーロードとフレーム単位のパイプライン)だけで、呼び出し側が指定した音程差には一切かかりません。区間編集は、オンセット/オフセットのサンプル位置で定義される NoteRegion に対して NoteEditor(NoteEditorConfig)を使い、NoteSegmenter が区間の特定を助けます。noteStretch は区間限定のストレッチ比を適用します。すべてデコード済みのモノラルサンプルに作用し、Audio も同じ操作をメソッドとして公開するので、ファイルワークフローでは一度読み込んで編集できます。