shingoushori's dialy

音信号処理を専ら研究していた元博士後期課程の学生によるメモ

Web Audio API を使用した音声を埋もれさせない音信号混合法の簡易実装

Web Audio APIはてなブログに埋め込むテスト

Web Audio API を使用した 音声を埋もれさせない音信号混合法の簡易実装 です。

WAV+WAV or WAV+マイク を、WAVに書き出します。マイクはFirefoxのみ。

前回からの進展として、"音声を埋もれさせない音信号混合法" の簡易実装をやってみました。
スペクトルは ↓こちら↓ を元に作成しました。
Web Audio API 解説 - 12.アナライザーの使い方 | g200kg Music & Software
FFT点数は1024で、低い方から256ビン表示しています。
埋もれさせたくない音声をFile0側にセットしてください。File0とFile1のどちらかを空にしておくと、空にした側をマイクからとれます。ただしFirefoxのみ。

"音声を埋もれさせない音信号混合法" とは、音声とBGMを混ぜた時に音声が埋もれて聞こえなくなるのは残念なので、そうならないような調整を自動的にやってくれるミキサーがあると便利では?という提案、 およびそのアルゴリズムの提案などなどです。
発表題目として現れる最初の発表はこちら
今回のコンテンツとしては、Web Audio APIにあるNodeを使っての簡易実装です。
"音声を埋もれさせない音信号混合法"として提案されている内容では、上位概念の提案も兼ねられています。 それは、時間周波数平面同士の重ね合わせをゴリゴリ行う、リッチなミキサーの構成法です。
本ブログの当初は、そのリッチなミキサーの構成法のWeb Audio APIでの実現を検討してきました。 やはりパフォーマンスの面で問題がありました。
そこで今回、発想を変えました。"音声を埋めさせない音信号混合法"の名の下、リッチなミキサーの構成法を用いての知見から、Web Audio APIで実現できる程度の簡易実装で効果が出せるかを検討しました。 知見の出所はこちら

File0
File1

 mixing result :                   

 mixing source0 :                   
 mixing source1 :                   

 mixing result2 :                   

 

Analyser

SmoothingTimeConstant :
MinDecibels :
MaxDecibels :

 

mixed
audio0
audio1
result2

 

チェックボックス"spectrogram"と"source rec"は、それぞれスペクトログラムとFile1およびFile2のミキシング結果と同じ時区間での切り出しです。
再生時間が5分の楽曲をフルでミキシングしたところ、処理落ちと思われるガタガタが発生しました。このため、一部の機能にon/offをつけてみました。
この辺りはWeb Audio APIの弱点なのかなと、同一ブラウザで複数タブを開きまくれたりしますので。

なお、このコンテンツについては日本音響学会2019年春季研究発表会にて発表します。
処理の中身であるとか、レジュメで引き合いに出した一般的なミキシング手法であるマルチバンドダッカー、ミラードイコライゼーションなどについては、また別の記事で。
別記事に仕切り直しする理由としては、パフォーマンス面が主です。 レジュメを書いた時に組んだローカルホストでのコンテンツで、 6秒 程度のサンプルデータでやる分には、マルチバンドダッカー、ミラードイコライゼーションについても問題なく処理できました。
ところが、はてなブログに埋め込んで、普通にwebコンテンツとして動かしてみたところ、先述の通りパフォーマンス問題が発生しました。調子に乗って、5分の楽曲をフルでミキシングしたからかもしれませんが。
その上に、マルチバンドダッカー、ミラードイコライゼーションを載せるのは、あまり有用とも思えませんでした。
その前にJavaScriptとWebAudioAPIをもっとちゃんと勉強して、パフォーマンス改善に取り組みたいところ。その実、廃止が謳われているScriptNodeに頼っていますので、AudioWorklet移植が必要です。なんということだ。

Web Audio API で内蔵マイクで録音+ミキシングに、大事そうな周波数帯域推定を追加

Web Audio APIはてなブログに埋め込むテスト

WAV+WAV or WAV+マイク を、WAVに書き出します。マイクはFirefoxのみ。

前回からの進展として、スペクトログラムを加工しました。
スペクトルは ↓こちら↓ を元に作理ました。
Web Audio API 解説 - 12.アナライザーの使い方 | g200kg Music & Software
FFT点数は1024で、低い方から256ビン表示しています。
加工のポイントとして、大事そうな周波数帯域推定の結果を示しています。音声を想定。フォルマントをしっかり計算しないでも、複数の帯域を区切ってのセントロイド同士での平均音量の比較でも、それなりに特徴は捉えられるとの思いつきです。
上位2帯域は目立つ色、それ以外は目立ちにくい色にしています。
なお、表示するパワーについては周波数が高い帯域ほどゲタを履かせています。そうでもしないと1 kHzどころか、100 Hzより下のパワーばかりに判定が引っ張られます。

File0
File1

 mixing result :                   

 mixing source0 :                   
 mixing source1 :                   

 

Analyser

SmoothingTimeConstant :
MinDecibels :
MaxDecibels :

 

mixed
audio0
audio1

 

うまくいっているのかといえば、劇的にうまくいってはいないです。
それでも、明らかな破擦音が入った時、歌い方に息かドスかの違いをつけた時 ... では、大事そうな周波数帯域の上位2帯域が入れ替わります。
音声は経験上、3 kHzあたりのパワーが上がらない傾向にありそうです。これが厄介。これにより、3 kHzを中心に双峰性のパワーの大きい帯域を平均すると、パワーの小さい 3 kHz ばかりが大事だと錯覚することになります。
素直にフォルマント帯域を推定した方がよかったかもしれない。

Web Audio API で内蔵マイクで録音+ミキシングに、スペクトログラムを追加

Web Audio APIはてなブログに埋め込むテスト

WAV+WAV or WAV+マイク を、WAVに書き出します。マイクはFirefoxのみ。

前回からの進展として、スペクトログラムを追加しました。
↓こちら↓ を元に、1 kHz と 4 kHz ? あたりに線を入れてみたりしました。
Web Audio API 解説 - 12.アナライザーの使い方 | g200kg Music & Software
FFT点数は1024で、低い方から256ビン表示しています。

File0
File1

 mixing result :                             

 mixing source0 :                             
 mixing source1 :                             

 

Analyser

SmoothingTimeConstant :
MinDecibels :
MaxDecibels :

 

mixed
audio0
audio1

 

canvas要素は、記事にベタがきすると消えてしまいました。ローカルホストでやっている分には消えないのですが。
慌てて、用意しておいたdivにcreateElementで追加する方法に書き換えました。
さらに、そのdivまで空だと消されてしまいます。仕方なく、ダミーの文字列を入れておいて、canvasを入れるタイミングで空文字列に置き換えています。

Web Audio API で、内蔵マイクで録音+ミキシングを、はてなブログ埋め込み

Web Audio APIはてなブログに埋め込むテスト

WAV+WAV or WAV+マイク を、WAVに書き出します。マイクはFirefoxのみ。

前回からの進展として、stopするまでの入力信号もそれぞれDLできるようにしました。
検討用にはミキシング前の入力信号も、出力信号と同じ長さのファイルであった方が便利です。

File0
File1

 mixing result :               

 mixing source0 :               
 mixing source1 :               

 

もっとしっかり関数化すれば、もっとコードを圧縮できそう。
入力ファイルはドラッグ&ドロップの方が楽そう。

Web Audio API で、内蔵マイクで録音を、はてなブログ埋め込み

Web Audio APIはてなブログに埋め込むテスト

WAV+WAV or WAV+マイク を、WAVに書き出します。マイクはFirefoxのみ。

File1
File2

 mixing result :       

 

その実、↓の記事のはてなブログ埋め込みバージョン になります。 

 

これらの記事ではjsdo.itさんでした。が、どうも動いていないので。

Simutransで, 信号場アドオン作成 / 駅アドオンの信号場アドオン化

Simutrans(http://japanese.simutrans.com)は, 素晴らしい.

駅は3タイプの積荷の取扱可否があります。
・旅客
・郵便
・貨物
で、何も取扱できなければ信号場になるはずです。

pak64では Signal Stop / 信号所セット アドオン/railtool - Simutrans日本語化・解説
pak128では Signal Stop / 木造信号所  Addon128/RailTools 1 - Simutrans日本語化・解説 が出てました。

増解結の本体改造に先立って、信号場の作り方を調べてみました。

[用語]
ここでは"信号場"とします。Wikipedia(信号場 - Wikipedia)に従って。
留置場、引き上げ線、検車場、操車場 ... いろいろあるので、何と呼称するべきか微妙なところ。
ソースコード場としては、enables が NOT_ENABLE : 0。
取扱を何もしないhaltestelle ~ 停車場 というだけです。

[アドオン素材の場所]
私はpak64でやっているので、pak64のアドオン素材の場所をメモ。
pak64の駅のソースの場所 : simutrans / Code / [r1997] /pak64/player
なぜ、駅が player っていうディレクトリにあるのだろう... わかりにくいなあ。

 

[アドオン datファイルの指定の仕方]
アドオン開発/datファイル記述リファレンス/building(建築物)2 - Simutrans日本語化・解説 より、

enables_pax= 1 駅用。このフラグが真(1)ならこの駅は乗客を集めることができます
enables_post= 1 駅用。このフラグが真(1)ならこの駅は郵便を集めることができます
enables_ware= 1 駅用。このフラグが真(1)ならこの駅は貨物の受け入れと集荷ができます

これらを削除 / コメントアウト(行頭に # )でOK。
何も指定しないと makeobj がエラーを出すかと思ったのですが、大丈夫でした。

 

[駅アドオンの信号場アドオン化]
バイナリエディタで、0x005E番目の32ビットを 00 に変更
ここが 01 だと旅客、02 だと郵便、03 だと旅客+郵便 ... 
とりあえず、バイナリエディタで見ると冒頭あたりに SimObjects 0.1.3exp って書いてあるアドオンなら、これでいけると思います。

Simutrans本体改造で学ぶC/C++ 〜 全駅強制旅客郵便貨物駅化

以下のような簡単な改造で、全駅強制旅客郵便貨物駅化できます!

f:id:shingoushori:20190202205357p:plain

Visual Studio Code での改造例

このように、enum は同じ数字に複数の愛称を持たせることができます。

同じセーブデータを改造前後のビルドで読み込ませると、こんな感じになります。

f:id:shingoushori:20190202211321p:plain

改造前後の動作比較 左:改造前 右:改造後