方向性としてはかなり正しいです。ただ、現状の「振幅包絡 + 相互相関」は、まさに今回の問題(可変テンポ・構成変更・繰り返し)に弱い特徴量を使っているので、精度の壁に当たっているように見えます。
この手の問題は音楽情報検索(MIR)では audio synchronization / cover song alignment / score following に近く、定番はやはり 特徴量 + DTW系 です。
結論から言うと、
「Remixボーカル → 原曲ボーカル」の対応付けを作りたいなら、
Demucs → Vocal stem → 音素/歌唱特徴量 → multi-scale DTW → 局所補正
の構成が一番精度が出そうです。
特に「原曲ボーカル流用Remix」という前提はかなり有利です。
なぜ包絡相関が厳しいのか
RMS包絡は
母音が続くと平坦
歌詞情報を持たない
テンポ変化に弱い
ドラム被りで汚れる
ため、
「あーーー」
と
「おーーー」
がほぼ同じ形になります。
リップシンクしたいなら、
どの音節が歌われているか
を識別できる特徴量が欲しいです。
第一候補:MFCC + DTW
まず最も定番。
mfcc = librosa.feature.mfcc(
y=vocal,
sr=sr,
n_mfcc=20
)
で特徴量を作る。
距離
cosine_distance
または
euclidean
を使って DTW。
librosa なら
from librosa.sequence import dtw
D, wp = dtw(
X=mfcc_remix,
Y=mfcc_original,
metric="cosine"
)
MFCCは
テンポ変化に比較的強い
EQ変化に強い
Remix処理に強い
ので包絡よりかなり改善します。
さらに良い:Chromaではなく Vocal Features
一般的な音楽同期では
Chroma + DTW
が定番ですが、
今回は
歌詞同期
が目的です。
なので実はChromaは微妙。
理由:
Remixで
キー変更
ピッチシフト
ハーモナイズ
される可能性がある。
むしろ
MFCC
や
Mel spectrogram
の方がボーカル同期には向いています。
ベストに近い:Wav2Vec2 / HuBERT特徴量
最近の研究だと、
歌声同期は
MFCC
Chroma
より
HuBERT
Wav2Vec2
Whisper encoder
特徴量がかなり強いです。
例えば
facebook/hubert-base-ls960
から
hidden_states
を取り出して
T x 768
特徴量列にする。
すると
同じ歌詞
異なるテンポ
異なる音程
異なるミックス
でも一致しやすい。
実際かなり効きます。
可変テンポ対応
ここはDTWの本領です。
DTWは
1秒 → 0.8秒
1秒 → 1.4秒
みたいな局所伸縮を吸収できます。
つまり
原曲 BPM 128
Remix BPM 150
でも問題ない。
あなたの
BPM比で一律stretch
はむしろ不要になります。
理想的には
feature extraction
↓
cost matrix
↓
DTW
↓
warping path
だけで十分。
しかし普通のDTWだけでは壊れる
Remixだと
Verse
Chorus
Verse
Drop
↓
Verse
Drop
Chorus
Chorus
みたいになる。
ここで普通のDTWを使うと
強制的に単調対応を作るため、
誤マッチします。
subsequence DTW
ここで使う。
sync-toolboxにもあります。
考え方:
Remix区間
↓
原曲全体のどこか
を探す。
つまり
local alignment
です。
例えば
Remixを
8秒〜12秒
の窓に分け、
それぞれ
原曲のどこに一致するか
を探す。
実務的には HMM 化する
私ならこうします。
Step1
Remixを
5秒
窓で分割
Step2
各窓について
top_k_matches
取得
例
Window 32
原曲 41.2s
score 0.92
原曲 102.8s
score 0.89
原曲 181.4s
score 0.87
Step3
Viterbi
または
networkx
で
全体として最も自然な経路
を選ぶ
すると
サビ反復
Verse再利用
にも強い。
sync-toolbox はかなり有力
おすすめです。
特に
Sync Toolbox
は
Chroma
onset
multiscale DTW
が実装済み。
論文ベース。
考え方も近い。
粗同期
↓
局所DTW
↓
高解像度補正
をやっています。
リップシンク精度を出す後段
ここが重要。
DTWだけだと
100〜300ms
程度の誤差が残る。
口パクは厳しい。
私なら二段階にします。
粗同期
HuBERT + DTW
↓
±200ms
程度
微調整
音節レベル
具体的には
ボーカルstemから
spectral_flux
や
onset_strength
を計算。
歌唱の
子音開始
は強いピークになる。
例えば
k
t
p
s
など。
これを局所相関。
±500ms
範囲で探索。
結果
DTW
↓
子音ピーク合わせ
になる。
さらに本気でやるなら Forced Alignment
歌詞が取得できるなら、
双方に対して
Whisper
↓
forced alignment
をかける。
例えば
WhisperX
MFA (Montreal Forced Aligner)
など。
すると
"love"
2.53s
"is"
2.82s
"you"
3.14s
みたいな単語境界が得られる。
Remixと原曲で
同じ単語
を対応させる。
リップシンク精度としてはこれが最強です。
もし自分が組むなら
最終的にはこうします。
Demucs
↓
Vocal stem
↓
HuBERT feature
↓
subsequence DTW
↓
候補区間抽出
↓
Viterbi/HMMで
全体経路推定
↓
局所DTW
↓
子音ピーク合わせ
↓
映像warp
この構成なら、
BPM変化
ハーフタイム
サビ反復
構成変更
にかなり耐えられます。
特に現状の「RMS包絡 + BPM比stretch」から改善するなら、まずは 「ボーカルstem → HuBERT特徴量 → subsequence DTW」 を試す価値が高いです。ここだけでも同期精度はかなり上がるはずです。