SoundFont からサンプル抜出しのループ対応
これの続き → SoundFont から PCM データ抜出し - yoyaのメモ
ループ対応しました。変更内容 → http://openpear.org/changeset/2959
IO_SoundFont 1.0.2 としてリリースしました。
使い方
yoya@sakura:~/svn/IO_SoundFont$ php sample/sfextractsample.php emuaps_8mb.sf2 1
のように SoundFont ファイルの次の引数に秒数を指定して実行すると、SoundFont内の PCM データを抜き出す際に指定秒数ループして wav に保存します。
- http://diary.awm.jp/~yoya/data/2013/06/08/ (生成されたファイル)
エンベロープ ADSR をかけてないので不自然な音に聞こえると思います。減衰(Decay)ないので。
次の課題にします。
備考
直観で実装してたら、emuaps_8mb.sf2 の Glockenspiel D6 のようにループの短いサンプルでノイズが混ざったり、Flute では loopStart 前後で音程が変わりました。
WebAudio で鳴らす時は SoundFont の loopEnd をそのまま設定してるので気にしませんでしたが、End ポイントのオフセット自体でなく、その1つ次のオフセットを指すようです。
図にするとこんな感じ。(等幅フォントでご覧ください)
+start loopStart loopEnd (end は分からないので省略) | | | +--------------------------- | | | | | | | | | | | +--------------------------- <---------> 実際の loop 範囲 ○ <-----------> 期待してた範囲 ×
(end はまだよく分かりません。実用上はどうでも良さそうなので理解は後回し)
違和感がそのままコードにコメントとして残ってしまいました。
$loopCount = $looptime * $sampleRate / ($endLoop - $startLoop /*+ 1*/); $loopCount = ceil($loopCount); // round up $sampleData = substr($data, $start * 2 , ($startLoop - $start) * 2); $sampleData .= str_repeat(substr($data, $startLoop * 2 , ($endLoop - $startLoop /*+ 1*/) * 2), $loopCount); $sampleData .= substr($data, ($endLoop /*+ 1*/) * 2 , ($end - $endLoop + 1) * 2);
コメントを削るかどうか迷ってます。