Sound Font2(SF2)から波形データを取り出す
目的
Sound Font2は元々Sound Blaster用の音源用のSound Table形式ファイルですが、汎用的に使われるようになり、fluidsynthやtimidity等のMIDI音源でも使われるファイル形式となっています。
今回は、そのファイルから波形データを取り出す方法です。
プログラム1
音源データ一覧表示
from sf2utils.sf2parse import Sf2File
filepath = r'd:\temp\FluidR3_GM.sf2'
with open(filepath, 'rb') as sf2_file:
sf2 = Sf2File(sf2_file)
for idx,sample in enumerate(sf2.samples):
print(idx,sample)
結果
0 Sample Gun at 0 + 15394 (loop at 8 + 15378) sampled at 11025Hz MONO
1 Sample Orchcrash(L) at 15440 + 115915 (loop at 8 + 115899) sampled at 32000Hz LEFT
2 Sample Orchcrash(R) at 131401 + 115915 (loop at 8 + 115899) sampled at 32000Hz RIGHT
3 Sample whistle at 247362 + 16449 (loop at 16015 + 419) sampled at 44100Hz MONO
4 Sample Alto G#6(L) at 263857 + 23744 (loop at 17038 + 6612) sampled at 32000Hz LEFT
5 Sample Alto G#6(R) at 287647 + 23744 (loop at 17038 + 6612) sampled at 32000Hz RIGHT
6 Sample Alto F#6(L) at 311437 + 27264 (loop at 20531 + 6620) sampled at 32000Hz LEFT
7 Sample Alto F#6(R) at 338747 + 27264 (loop at 20531 + 6620) sampled at 32000Hz RIGHT
8 Sample Alto E6(L) at 366057 + 17344 (loop at 11266 + 6023) sampled at 32000Hz LEFT
9 Sample Alto E6(R) at 383447 + 17344 (loop at 11266 + 6023) sampled at 32000Hz RIGHT
プログラム2
出力されるファイル形式はWAVやMP3、OGGではなくRAWデータです。 Audacity等で読込むことが可能です。
from sf2utils.sf2parse import Sf2File
filepath = r'd:\temp\FluidR3_GM.sf2'
target_dir = r'd:\temp\sound_font'
start_idx = 313
end_idx = 340
with open(filepath, 'rb') as sf2_file:
sf2 = Sf2File(sf2_file)
for idx in range(start_idx ,end_idx+1):
sample = sf2.samples[idx]
out_filepath = os.path.join(target_dir,'out-%d.raw'%(idx))
sample.export(out_filepath)
with open(out_filepath,'rb') as fp:
raw = fp.read()
name = '%s - %dHz %dbit - 1.normal'%(sample.name,sample.sample_rate,sample.sample_width*8)
out_filepath = os.path.join(target_dir,'%s.raw'%(name))
with open(out_filepath,'bw+') as fp:
fp.write(raw[0 :(sample.start_loop-1) *sample.sample_rate])
name = '%s - %dHz %dbit - 2.loop'%(sample.name,sample.sample_rate,sample.sample_width*8)
out_filepath = os.path.join(target_dir,'%s.raw'%(name))
with open(out_filepath,'bw+') as fp:
fp.write(raw[sample.start_loop *sample.sample_width:sample.end_loop*sample.sample_width])
おすすめ記事
全国の町丁目レベル(189,540件)の住所データのオープンデータをPython Pandasで処理してみた
その他ネタもの - Python
サーバー以外の端末から接続する方法(開発環境版向け、本番環境以外向け) - Django
OpenCVで動画作成 VideoWriter - Python徹底解説
PythonでSeleniumでスクレイピング時にClickでElementClickInterceptedException例外で失敗する。
プログラムは独学が良いか、スクールが良いか?【無償カウンセリング、無料体験あり】
Supponsered
外部サイト
↓プログラムを学んでみたい場合、学習コースなどもおすすめです!