MATLABでGUI付きアプリ開発 ~ App Designer を使おう(1)~フィルター特性を変えてグラフ表示
MATLABでGUI付きアプリ開発 ~ App Designer を使おう(2)~ストリーミングオーディオをフィルター処理
MATLABでGUI付きアプリ開発 ~ App Designer を使おう(3)~タイマー割り込みでスペクトル表示(非同期FIFOを使う)
MATLABでGUI付きアプリ開発 ~ App Designer を使おう(4)~ フィルター周波数・バンド幅をマウスで操作
前書き
MATLABでGUI付きプログラムを書く方法は何種類かあります。
Simulink の Dashboard、カスタムGUI、
(SimulinkでカスタムGUI)
ちょっと試すなら Live Editor、
オーディオ系の処理で、操作GUIのみで良いから高速化したいときは VST化(要 AudioToolbox)、
(MATLABでVSTプラグイン開発 [初級編]~数分?で作れるVST~LMSで無相関プラグイン)
(夏休みはVST! MATLABで楽々(?)VSTプラグイン開発)
しかし、もう少しGUIに凝りたい場合や、他の人と共有したい場合は App Designer が適しています。
MathWorks のオススメも App Designer です。
Getting Started with App Designer
複雑すぎると編集動作もかなり遅くなったりとかしますが。(;¬_¬)
(15000行超えたヤツ、エディターが終了できない・・。)
以前の記事 「MATLAB/Simulink で気軽に始める音響信号処理 ~ App Designer で GUIアプリも簡単開発!」でも App Designer には触れているのですが、そこそこ機能を詰め込んだのにろくに説明もしていなかったので、今回はもっと単純な例で順を追って解説したいと思います。
一部重複する部分もありますがご容赦ください。
デモの関係で Audio Toolbox を使っていますが、App Designer 自体は MATLAB の基本機能なので、同様のやり方で何にでも使えると思います。
MATLAB Compiler があればスタンドアローンアプリ化できますが、HOME版にはMATLAB Compiler製品自体がないので、HOME版では毎回 appdesigner から、もしくはMATLABコマンドウィンドウからmlappファイルを起動(拡張子なしのファイル名で起動)する形になります。
実際にコードを書いてみよう!
オクターブフィルター
スクリプトで
> octFilt = octaveFilter();
> visualize(octFilt);
とすれば、デフォルトの中心周波数 = 1kHz、バンド幅 = 1 octave のフィルターオブジェクトが生成され、その周波数特性が表示されます。
ここでさらに、
> octFilt.CenterFrequency = 100;
> octFilt.Bandwidth = '1/12 octave';
とすれば、特性が変わりグラフも更新されます。
このオブジェクトには、
freqz():周波数応答
getFilter():biquadフィルターオブジェクト変換
なども使用できます。
もちろん、オーディオデータに対して処理を掛けることもできます。
とても便利な関数なので、これを題材に使います。
起動
> appdesigner
で起動し、目的に近いテンプレート、もしくは空のテンプレートから作ることができます。ここで短い対話式チュートリアルを見ることもできます。
メニューの 新規 -> アプリ または アプリタブの「アプリの設計」でも起動できます。
今回は、「空のアプリ」を選択します。
「名前を付けて保存」で、OctaveFilter1.mlapp として保存します。
次回からは、コマンドウインドウで
> appdesigner OctaveFilter1
と打つか、
ファイルビューで mlapp ファイルをダブルクリックします。
GUIコンポーネントの追加
左ペインのコンポーネントライブラリからコンポーネントを選んでキャンバスに置き、右ペインでラベル等プロパティを書き換えます。
・ドロップダウン(BandwidthDropDown)
ラベル:Bandwidth
Value、Items を消します(後でコード内で設定します)
・スピナー(CenterFrequencySpinner)
ラベル:CenterFrequency
Value:1000
Limits:20,20000
Step:100
RoundFractionalValues:✔
とします
・座標軸(UIAxes)
Title String:Octave Filter
XLavel String:Frequency (Hz)
YLabel String:Gain (dB)
とします
右ペイン最上部に表示されているのがコンポーネント名ですが、ダブルクリックで書き換えることもできます。コードを書いた後でも、ここで変更するとコードは自動的に修正されるので、自分でいちいち直す必要はありません。
ここから「コードビュー」に切り替えて、実際のコードを書いていきます。
プロパティ
使用する変数やオブジェクト等の宣言をします。
左ペインのコードブラウザー -> プロパティ -> ➕ とすると
Property % Description
と表示されて自動的にそこに移動するので、以下のように書き換えます。
properties (Access = private)
fs = 44100; % sampling frequency
octFilt % octave filter object
end
コールバック
各GUIコンポーネントを操作したときの動作を記述します。
一旦「設計ビュー」に戻り、各コンポーネントを右クリック -> コールバック -> ~コールバックの追加、でコールバックを生成します。
作成後は、
各コンポーネントを右クリック -> コールバック -> ~コールバックに移動
でそのコード部分に飛べます。
・BandwidthDropDown
Bandwidth で選択した値をオクターブフィルターにセットし、周波数応答描画関数(後述)を呼び出します。
function BandwidthDropDownValueChanged(app, event)
value = app.BandwidthDropDown.Value;
app.octFilt.Bandwidth = value;
drawFrequencyResponse(app);
end
・CenterFrequencySpinner
同様に CenterFrequency で設定した値をオクターブフィルターにセットし、周波数応答描画関数を呼び出します。
function CenterFrequencySpinnerValueChanged(app, event)
value = app.CenterFrequencySpinner.Value;
app.octFilt.CenterFrequency = value;
drawFrequencyResponse(app);
end
コールバックを消したいときは右クリックで削除します。
コードビューで勝手に書いたり消したりしてしまうと、コードブラウザーと整合が取れなくなることがあるので注意してください。
内部関数
内部で使うサブルーチンを定義します。
左ペインのコードブラウザー -> 関数 -> ➕
drawFrequencyResponse と入力して、周波数応答グラフを描画する関数を定義します。
返り値は必要ないので削除します。
function drawFrequencyResponse(app)
[h,w] = freqz(app.octFilt);
hdB = 20*log10(abs(h));
semilogx(app.UIAxes, w/(2*pi)*app.fs, hdB);
grid(app.UIAxes, "on")
xlim(app.UIAxes, [20, app.fs/2])
ylim(app.UIAxes, [-80 0])
end
startupFcn
アプリ起動時に実行されるブロックです。
右ペイン[コンポーネント ブラウザー] の階層最上位のアプリノード(OctaveFilter1)を右クリックし、[コールバック] 、 [StartupFcn コールバックの追加] で追加します。
先ほど消した BandwidthDropDown の設定(Items、 Value)と、デフォルト設定での周波数特性グラフを描画します。
function startupFcn(app)
app.BandwidthDropDown.Items = {'1 octave', '2/3 octave', '1/2 octave', ...
'1/3 octave', '1/6 octave', '1/12 octave', '1/24 octave', '1/48 octave'};
app.BandwidthDropDown.Value = '1 octave';
app.octFilt = octaveFilter; % octave filter object
drawFrequencyResponse(app);
end
BandwidthDropDown.Items は「設計ビュー」の右ペインで手動で入れても良いのですが、今回は長いのでコード上で入れています。セル形式で入れます。
こちらも返り値は必要ないので削除します。
UIFigureCloseRequest
最後に、設計ビューのコンポーネントがないところで右クリック -> コールバック で、UIFigureCloseRequest を追加し、
release(app.octFilt)
を入れておきます。
function UIFigureCloseRequest(app, event)
release(app.octFilt)
delete(app)
end
これでオクターブフィルターの中心周波数とバンド幅を指定して、その周波数応答を表示するGUIアプリができました。
自分で追加したコードは以下の部分のみです。
fs = 44100; % sampling frequency
octFilt % octave filter object
function drawFrequencyResponse(app)
[h,w] = freqz(app.octFilt);
hdB = 20*log10(abs(h));
semilogx(app.UIAxes, w/(2*pi)*app.fs, hdB);
grid(app.UIAxes, "on")
xlim(app.UIAxes, [20, app.fs/2])
ylim(app.UIAxes, [-80 0])
end
app.BandwidthDropDown.Items = {'1 octave', '2/3 octave', '1/2 octave', ...
'1/3 octave', '1/6 octave', '1/12 octave', '1/24 octave', '1/48 octave'};
app.BandwidthDropDown.Value = '1 octave';
app.octFilt = octaveFilter; % octave filter object
drawFrequencyResponse(app);
app.octFilt.Bandwidth = value;
drawFrequencyResponse(app);
app.octFilt.CenterFrequency = value;
drawFrequencyResponse(app);
release(app.octFilt)
実行結果
GIFがアップロードされないので動画で(音声なし)。
まとめ
いかがでしたでしょうか?
フィルターの周波数特性を表示させるだけとは言え、わずか20行足らずで一応インタラクティブな GUI アプリが作れてしまいます。
中には、「MATLABでGUIアプリが作れること自体知らなかった!」という方もいらっしゃるのではないでしょうか?
動作スピードや編集時の反応はイマイチな部分もあるのですが、コードの補間機能等もあるモダンな作りで、昔の GUIDE に比べると各段に開発効率が上がっています。
まだ使ったことがない方がいらっしゃったら、ぜひお試しください!
この記事が気に入ったらサポートをしてみませんか?