私は次のことをしようとしています:
- 私が質問をしているメロディー (wav に録音された " Hey? " という単語) を抽出して、他の録音/合成された音声に適用できるメロディー パターンを取得します (基本的に、F0 が時間とともにどのように変化するか)。
- 多項式補間 (Lagrange?) を使用して、メロディーを記述する関数を取得します (ほぼ当然です)。
- 関数を別の録音された音声サンプルに適用します。(例: " Hey. " という単語を質問 " Hey? " に変換するか、文末を質問のように変換します [例: " Is it ok. " => " Is it ok? "]) . ほら、それだけです。
私がやった事?ここはどこ? まず、fft と信号処理 (基本) の背後にある数学に飛び込みました。プログラムでやりたいので、pythonを使うことにしました。
「 Hey? 」の音声サンプル全体に対して fft を実行し、周波数領域のデータを取得しました (y 軸の単位は気にしないでください。正規化していません)。
ここまでは順調ですね。次に、信号をチャンクに分割して、より明確な周波数情報 (ピークなど) を取得することにしました。これはブラインド ショットであり、周波数を操作してオーディオ データを分析するというアイデアを把握しようとしています。しかし、少なくとも私が望む方向には行きません。
さて、これらのピークを取り、それらから補間関数を取得し、その関数を別の音声サンプル (音声サンプルの一部、もちろんこれも ffted) に適用し、逆 fft を実行すると、必要な結果が得られません。、 右?メロディー自体には影響しないように大きさだけ変えます(そう思います)。
次に、 librosaのspecメソッドとpyinメソッドを使用して、実際の F0-in-time (" Hey? "という質問のメロディー) を抽出しました。予想どおり、周波数値の増加がはっきりとわかります。
今、私は自分のアルゴリズム/プロセスを構築するためのブロックを持っていると思いますが、ボンネットの下で何が起こっているのかについての私の理解にはいくつかの空白があるため、それらを組み立てる方法はまだわかりません.
スペクトログラムの F0-in-time 曲線を「純粋な」FFT データにマッピングし、そこから補間関数を取得して、その関数を別の音声サンプルに適用する方法を見つける必要があると思います。
これを行うためのエレガントな(エレガントでなくても大丈夫です)方法はありますか?近くにいると感じることができるので、正しい方向に向ける必要がありますが、基本的に立ち往生しています。
上記のチャートの背後で動作するコードは、librosa docs およびその他の stackoverflow の質問から取得したものです。これは単なるドラフト/POC であるため、可能であればスタイルについてコメントしないでください :)
チャンク単位の fft:
import numpy as np
import matplotlib.pyplot as plt
from scipy.io import wavfile
import os
file = os.path.join("dir", "hej_n_nat.wav")
fs, signal = wavfile.read(file)
CHUNK = 1024
afft = np.abs(np.fft.fft(signal[0:CHUNK]))
freqs = np.linspace(0, fs, CHUNK)[0:int(fs / 2)]
spectrogram_chunk = freqs / np.amax(freqs * 1.0)
# Plot spectral analysis
plt.plot(freqs[0:250], afft[0:250])
plt.show()
スペクトログラム:
import librosa.display
import numpy as np
import matplotlib.pyplot as plt
import os
file = os.path.join("/path/to/dir", "hej_n_nat.wav")
y, sr = librosa.load(file, sr=44100)
f0, voiced_flag, voiced_probs = librosa.pyin(y, fmin=librosa.note_to_hz('C2'), fmax=librosa.note_to_hz('C7'))
times = librosa.times_like(f0)
D = librosa.amplitude_to_db(np.abs(librosa.stft(y)), ref=np.max)
fig, ax = plt.subplots()
img = librosa.display.specshow(D, x_axis='time', y_axis='log', ax=ax)
ax.set(title='pYIN fundamental frequency estimation')
fig.colorbar(img, ax=ax, format="%+2.f dB")
ax.plot(times, f0, label='f0', color='cyan', linewidth=2)
ax.legend(loc='upper right')
plt.show()
ヒント、質問、コメントは大歓迎です。