Sound Font2(SF2)から波形データを取り出す

 

{{DZ_TITLE}}
Sound Font2から波形データを取り出す方法です。

目的

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で処理してみた
全国の町丁目レベル(189,540件)の住所データのオープンデータをPython Pandasで処理してみた
その他ネタもの - Python
その他ネタもの - Python
サーバー以外の端末から接続する方法(開発環境版向け、本番環境以外向け) - Django
サーバー以外の端末から接続する方法(開発環境版向け、本番環境以外向け) - Django
OpenCVで動画作成 VideoWriter - Python徹底解説
OpenCVで動画作成 VideoWriter - Python徹底解説
PythonでSeleniumでスクレイピング時にClickでElementClickInterceptedException例外で失敗する。
PythonでSeleniumでスクレイピング時にClickでElementClickInterceptedException例外で失敗する。
プログラムは独学が良いか、スクールが良いか?【無償カウンセリング、無料体験あり】
プログラムは独学が良いか、スクールが良いか?【無償カウンセリング、無料体験あり】
Supponsered

外部サイト
↓プログラムを学んでみたい場合、学習コースなどもおすすめです!

Comments

comments powered by Disqus