#00 準備・基礎編―MATLAB & Simulinkでオーディオエフェクト

#はじめに
高校のプログラミングの授業で自由課題が出され，私はMATLABでオーディオエフェクトを作ることにした．レポートの代わりにQiita記事を提出することが許されたので，ここにまとめることにする．

#対象読者
基本的に自分と同じレベルの人が読めることを目標に書いている．具体的には以下の条件を満たす人を対象とする．

* MATLAB Simulinkを触ったことがない．
* 音声処理初心者
* プログラミング自体の経験はある（関数，配列，forループ程度）

#注意
本記事ではMATLABコード自体の詳細な説明はしない．MATLABの文法は直観的なので，読めば何となく理解できるはずである．注意すべき文法には言及する．

また，本記事では「オーディオエフェクトを形にする」ことを第一目標とする．したがって効率化などは考慮しない．

#開発環境
開発環境は以下の通りである．

* MATLAB 2020a
* Simulink 10.1
* Signal Processing Toolbox 8.4
* Audio Toolbox 2.2

#基本操作
ここでは基本操作を説明する．
##Simulinkを開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397506/07af63bf-8bf7-44e7-ca0d-be31761e5d45.png)
MATLABのメニューバーにSimulinkがある．これを押してSimulinkを立ち上げる．

##テンプレートを開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397506/86db6334-be13-d868-51ac-367c32031db1.png)
`Audio Toolbox`の欄に`Basic Audio Player`というテンプレートがある．これを開く．

##ブロックの追加
テンプレートを開くと以下のような画面が評される．見て分かる通り，左のブロックは音源（入力）を表し，右のブロックはスピーカー（出力）を表す．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397506/9a49c94e-16b0-580d-6305-3116eb99ee39.png)
メニューバーのライブラリブラウザーから，新たなブロックを追加することができる．試しに，`Audio Toolbox`の`Spectrum Analyzer`を追加する．検索窓を活用すると素早く見つけることができる．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397506/f572d64c-4b15-2387-8934-e34a7186f405.png)
ライブラリブラウザからドラッグアンドドロップすることで，ブロックを追加できる．ブロックを追加したら，音源とスピーカーをつないでいる矢印上で右クリックし，新たな矢印を伸ばして，それをスペクトラムアナライザに接続する．スペクトラムアナライザはダブルクリックで表示できる．メニューバーにある`実行`ボタンを押せば音源の再生が開始され，スペクトラムアナライザで音源が可視化される．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397506/8ea9b23a-d0c5-3b75-9f0d-80667d133892.png)

##基本的なブロック
ここで，基本的なブロックをいくつか挙げておく．

* Gain：信号の強さを変える
* Constant：定数を出力する
* Time Scope：オシロスコープを表示する
* Spectrum Analyzer：スペクトラムアナライザを表示する

#Dashboardブロックによるリアルタイムでのパラメータ調整
モデル内のパラメータをリアルタイムで操作するには，Dashboardブロックが有効である．Dashboardブロックは以下のようなものである．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397506/2a22de1e-3d47-49dd-dbb2-5f9e794b10b4.png)
ここでは，Dashboardブロックを用いてリアルタイムで音量を調節するものを作る．まずは以下のようにブロックを配置する．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397506/642dfa7b-7926-5282-159e-a3db82799b6a.png)
次に，Dashboardブロックの一つである，`Knob`ブロックを追加する．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397506/db6e6c4c-efc1-5508-3cd8-33420c48ef41.png)
`Knob`ブロック上にマウスカーソルを合わせると，`接続`ボタンが表示される．これをクリックした後，Gainブロックをクリックし，1秒程度待つと，以下のような画面が現れる．この〇印をクリックし，画面右上の✖印を押せばDashboardと変数との接続が完了する．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397506/269f1287-5c4d-de74-8a6d-5902ec93d1ed.png)
パラメータの範囲はブロック パラメータウィンドウで調整できる．これは`Knob`ブロックをダブルクリックして開ける．ブロック パラメータウィンドウでは最大値・最小値の他に，スケールタイプを線形・対数の二つから選ぶこともできる．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397506/53964324-780a-27a4-3857-4190b3805912.png)
Knobブロックは実行時にマウスで操作できる．

#MATLAB Function ブロック
Simulinkには豊富なブロックが用意されているが，自分でプログラムを書く必要もいずれ生じる．そのような場合には，`MATLAB Function` ブロックが有効である．`MATLAB Function` ブロックでは，MATLABのコードを記述することで自由に処理を行える．ここでは，`MATLAB Function` ブロックを用いてデシベル単位のGainブロックを作る．

##デシベルとは何か
デシベルとは振幅の比を対数を用いて扱いやすくしたものである．デシベル$L$は振幅の比$r$を用いて以下のように表される．
$$
L = 20\,\mbox{log}_{10}r
$$

##デシベルから振幅の比を求める．
上記の式を変形し，デシベルの値から振幅の比を求めると，以下のようになる．
$$
r=10^{\frac{L}{20}}
$$

##MATLAB Functionブロックで上記の式を再現
デシベルから振幅の比を求める式が得られたので，これを実際に`MATLAB Function`ブロックで再現する．まずは以下のようにブロックをつなぐ．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397506/dcef26d6-789b-9f43-2999-788d0b00a476.png)
次に，`MATLAB Function`ブロックをダブルクリックしてエディタを開く．初期の状態では以下のようなコードが書かれている．

```matlab
function y = fcn(u)

y = u;
```
このコードでは，`u`が入力で，`y`が出力である．Gainブロックでは，入力信号とGainの値の二つの引数が必要である．したががってdB値を表す変数`L`を追加する．さらに，前述の式でプログラムを書き換える．

```matlab
function y = fcn(u,L)   %変数L [dB]を追加
    r = 10^(L/20);      %Lを用いて振幅の比を表す
    y = u*r;            %求めた振幅の比を入力信号に乗算し，出力
```

これを保存すると，以下のように，入力に`L`が追加されているのが分かる．`L`に対して，`Conctant`ブロックから値を送り，`Constant`ブロックの定数を`Knob`ブロックで操作できるようにすると，以下のようなモデルが組める．本記事では，`Knob`ブロックの最小値を-30，最大値を12とする．各ブロックの下の名前を変更するとそれっぽくなる．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397506/16a6e562-5b55-d653-6774-d9d1fe9b937f.png)
これを実行すると以下の動画のように音量を調整できていることが分かる．

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">はじめてSimulinkで音声処理してみた．ただのGainだけど．コードだけで考えるよりも扱いやすくて良い． <a href="https://t.co/2zBKF1qem9">pic.twitter.com/2zBKF1qem9</a></p>&mdash; 9W3R7Y (@qwerty_16180339) <a href="https://twitter.com/qwerty_16180339/status/1338935156673953792?ref_src=twsrc%5Etfw">December 15, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

#終わりに
今回は，MATLAB Simulinkでの音声処理を行うための基礎知識を述べた．[次回](https://qiita.com/9W3R7Y/private/5b360aa05517c72cd964)はDistortionを作成する．

#GitHub
以下で完成したオーディオエフェクトを公開している．
https://github.com/qwerty16180339/matlab_audio_effects

#参考文献

* MathWorks, Simulink 入門 https://jp.mathworks.com/help/simulink/getting-started-with-simulink.html
* MathWorks, Knob https://jp.mathworks.com/help/simulink/slref/knob.html
* 小野測器 dB（デシベル）とは https://www.onosokki.co.jp/HP-WK/c_support/newreport/decibel/images/db_equ3_3.gif