Web Audio APIで作った音をwavで保存する


Web Audio APIで作った音を保存したい。

前回作ったピアノ音をブラウザで wav 形式に保存することを考えます。

 

Web Audio API の記事は思ったより少なくマイクなどからの録音関係の内容ばかりだったので、手探りで進めていきます。

マイク録音をする記事ですが「ブラウザで録音してwavで保存」のコードをメインで参考にしています。

ScriptProcessorNode とその後継の AudioWorklet

音が鳴るたびに処理を挟むような用途で使う。

参考元でも言及される AudioWorklet ですが数年前から最近の記事まで「実験的、限定的、特定の環境でのみ動く」など書かれていたのでイマイチ手を出しにくい。

一応使ってみましたが AudioWorkletProcessor が見つからなかった。

全体的な処理の流れ

参考元ではマイク音声を navigator.mediaDevices.getUserMedia からとってきて MediaStream を作って処理ノードを通して出力しているようです。

 

このストリームの代わりに前回作った GainNode をコネクトすればよさそうです。

ScriptProcessorNode から AudioDestinationNode に繋いでもいいはずですが、今回のコードだと音が出なくなったのでこの形で作ります。この方法で動かなくなったので追記参照

実際のコード

GainNodeScriptに繋いでonAudioProcessで配列に入れる。

配列をexportWAVblob形式にして保存させます。

exportWAV は TypeScript で書いて変数をできるだけ const に変えてますが中身は参考元と同じです。

前回のコードに1行追記して使えます。

require("./save").saveBuff(audioContext, gain);

 

10秒で切ってるので終わりがぶつ切りですが、ちゃんと保存できてます。

 

あとはちゃんと終了検知して、リセットもできるようにしておけばいいかな。

もっと簡単な方法とかもあるんじゃないかと思いつつも、やりたいことが出来たのでとりあえず満足です。

追記

コード整形しているうちに上記コードで保存できなくなった。

どうも onaudioprocess が動作していない様子。

destination につなげると動くようになるので正しくつなげる必要があるってことなんでしょうが、じゃあなんで前は動いたんだ。

多少の不信感を覚えつつも正しく ScriptProcessorNode をつなぎます。

 

上記コードのままだと output が空で、保存はできるが音は出ない状態なので入力をそのまま出力に渡す処理を追加します。

 

正しい理屈でちゃんと動いたのはいいんですが、じゃあなんで最初はこうならなかったんだという気持ちも。多分初心者特有の勘違いで何かやらかしてたんだろうと思うことにします。


コメントを残す

メールアドレスが公開されることはありません。