環境にできるだけ依存せずにグラフを描いたりしたいとなるとHTML5かなぁと思い、はじめてのJavaScript。まだ配列の使い方を調べていないので、sinもcosも直に計算&描画してます。
使ったHTMLファイルは以下。
続きを読む環境にできるだけ依存せずにグラフを描いたりしたいとなるとHTML5かなぁと思い、はじめてのJavaScript。まだ配列の使い方を調べていないので、sinもcosも直に計算&描画してます。
使ったHTMLファイルは以下。
続きを読む給油日 | オドメーター (km) | 給油量 (L) | 単価 (円/L) | 燃費 (km/L) | 距離単価 (円/km) |
---|---|---|---|---|---|
2017-03-18 | 8559.6 | 2.76 | 125.72 | 45.94 | 2.74 |
2017-04-29 | 8703.9 | 2.77 | 127.80 | 52.09 | 2.45 |
2017-04-29 | 8905.9 | 3.21 | 128.97 | 62.93 | 2.05 |
2017-04-30 | 9032.5 | 2.20 | 131.82 | 57.55 | 2.29 |
2017-05-01 | 9190.3 | 2.70 | 127.04 | 58.44 | 2.17 |
2017-05-01 | 9325.7 | 2.52 | 128.97 | 53.73 | 2.40 |
2017-05-01 | 9469.7 | 2.17 | 129.03 | 66.36 | 1.94 |
2017-05-02 | 9625.3 | 3.71 | 133.96 | 41.94 | 3.19 |
2017-05-02 | 9787.8 | 2.81 | 125.98 | 57.83 | 2.18 |
2017-09-15 | 10004.7 | 3.09 | 123.96 | 53.03 | 2.34 |
2017-10-04 | 10152.2 | 2.08 | 125.96 | 70.91 | 1.78 |
燃費が良すぎて何かがおかしい気がする。長距離巡航だったけど、それにしても……。
MatlabやOctaveにはfreqz
という関数があり、FIR/IIRフィルタの周波数特性・位相特性を計算しグラフ表示してくれます。PythonでもSciPy.signalに同名の関数があります。似たことをJuliaでやってみました。
今回は双二次フィルタを見てみましょう。標本化周波数44,100 Hz、中心周波数1,000 Hz、ゲイン12 dB、Q=2.0のピークフィルタを準備しました。
samprate = 44100; B = [1.1417, -1.9797, 0.8583]; A = [1.0356, -1.9797, 0.9644];
特性を見たい周波数範囲を設定し、それをzさらにsへと変換して使います。ここでは16 Hz〜ナイキスト周波数を256段階の対数分割してみました。
# calculate frequency # (using logspace since we are going to use semilogx for plotting) fL = 16; fH = samprate/2; f = logspace(log10(fL), log10(fH), 256); z = f / sampfreq * 2*pi; s = exp.(-1.0im * z); # convert from digital frequency
次に、各周波数での伝達関数の値を計算します。下の式に代入して計算するだけ。
# calculate transfer function H = (B[1] + B[2].*s + B[3].*s.*s) ./ (A[1] + A[2].*s + A[3].*s.*s);
Polynomialパッケージを使って汎用性を高めても良いのですが、僕の考えている使用用途は双二次フィルタだけなので、このままで。
さて、振幅特性をグラフにしてみましょう。abs.()
で絶対値を計算してからデシベルにします。
using PyPlot semilogx(f, 20*log10.(abs.(H))); grid(); xlabel("Frequency (Hz)"); ylabel("Gain (dB)"); savefig("freqz_abs.png")
次に位相特性もグラフにしてみましょう。今度はangle.()
で位相を抜き出し、ラジアンを角度に変換しています。
semilogx(f, angle.(H)*180/pi); grid(); xlabel("Frequency (Hz)"); ylabel("Phase (angle)"); savefig("freqz_phase.png")
Matlabのfreqz
のグラフと見比べてみましたが、だいたい同じ結果になっているようでした。Matlab版は横軸が線形になっているので見た目が違いますが。
とある場所で振幅スペクトルのリアルタイム可視化をデモすることになったので、久しぶりにProcessingのプログラムを書きました。Minimに入っていた例をほぼそのまま使っています。(左右方向は20 Hz〜ナイキストを対数軸で、上下方向は-60〜0 dBを表示しています)
import ddf.minim.analysis.*; import ddf.minim.*; Minim minim; AudioPlayer jingle; FFT fft; void setup() { size(1024, 256, P3D); minim = new Minim(this); jingle = minim.loadFile("hogehoge.mp3", 1024); jingle.loop(); fft = new FFT(jingle.bufferSize(), jingle.sampleRate()); } void draw() { // set background color background(#0D2B36); // compute FFT fft.forward(jingle.mix); // draw foreground stroke(#EEE8D5); strokeWeight(2); for(int i = 0; i < fft.specSize(); i++) { float y = fft.getBand(i) * 2.0 / fft.specSize(); float xlog = log(float(i) / fft.specSize()) / log(10); float ylog = 20 * log(y) / log(10); // adjust x/y positions to fit into window xlog = (3.0 + xlog) / 3.0 * width; ylog = height - (ylog+60)/60 * height; // color based on amplitude stroke(color(255*ylog/height, 255*ylog/height*0.8, (255-255*ylog/height)*0.5)); line(xlog, height, xlog, ylog); } }
どれも1行〜2行の変更だけでできるので、楽しくてついつい必要以上のことをやってしまう。アレンジしだいで色々できるし、子どもの頃にこういうのがあったら無限にやってただろうな。(下のスクリーンショットは、周波数と振幅を極座標系で表示し、左右対称にコピーしたもの。蝶みたいに見える。)
給油日 | オドメーター (km) | 給油量 (L) | 単価 (円/L) | 燃費 (km/L) | 距離単価 (円/km) |
---|---|---|---|---|---|
2017-03-18 | 8559.6 | 2.76 | 125.72 | 45.94 | 2.74 |
2017-04-29 | 8703.9 | 2.77 | 127.80 | 52.09 | 2.45 |
2017-04-29 | 8905.9 | 3.21 | 128.97 | 62.93 | 2.05 |
2017-04-30 | 9032.5 | 2.20 | 131.82 | 57.55 | 2.29 |
2017-05-01 | 9190.3 | 2.70 | 127.04 | 58.44 | 2.17 |
2017-05-01 | 9325.7 | 2.52 | 128.97 | 53.73 | 2.40 |
2017-05-01 | 9469.7 | 2.17 | 129.03 | 66.36 | 1.94 |
2017-05-02 | 9625.3 | 3.71 | 133.96 | 41.94 | 3.19 |
2017-05-02 | 9787.8 | 2.81 | 125.98 | 57.83 | 2.18 |
2017-09-15 | 10004.7 | 3.09 | 123.96 | 53.03 | 2.34 |
10,000 km乗りました。「3ヶ月で!!」とかならかっこいいけど、2,000 km/年なので自慢できるものではないですが……。
MacBook Pro (15in, 2017)ですが、「Audio MIDI設定」の画面でマイク設定を確認してみると4 ch入力ができるかのように書いてあります。
最高で96 kHz / 24 bit / 4 chまでいけるとなれば、マイクロホンとヘッドアンプの性能によっては本体だけでもかなり面白いことができるのでは、と思います。(実際、電気グルーヴがGarage Bandと内蔵マイクで多くの部分を録音したアルバムなんてのもありますし)
カタログスペックを調べてみると、
となっていました。「マイクロホン×3」って! 奇数のADCを載せるのは面倒(かえって高くつく?)から、マイクは3つだけどDACは4 chのものを搭載しておこうということなのでしょうか。
試しにAudacityを使って4 ch録音をしてみました。画像では見にくいかもしれませんが、たしかに1〜3 chは録音された波形が違い、4 ch目は3 ch目と同じ波形です。
これら3つのマイクを何に使っているかですが、「システム環境設定」→「サウンド」でも表示されるように(「Audio MIDI設定」でマイクを2 chにしたときのみ表示)、これらを使って暗騒音や環境音の除去をやっているんでしょう。話者方向の推定とかにも使えるかもですね。
Apple MacBook Pro (2017)とエレコムのDST-C01SVとで講義デビュー。
DST-C01SVは、ギガビット・イーサ、VGA、HDMI、Mini Display Port、ステレオミニジャック(入出力対応)、USB 3.0×3口、SDスロット、microSDスロットに加えて、充電専用のUSB Type-C端子までついているという、現時点で敵なしのすごいやつです。MacBook AirのようにType-Cポートが少ない機種でも充電しながら他のものも接続できて、これ一つでどこでも行ける。欲を言えば、本体から出てるType-Cケーブルは(Apple純正の電源アダプタのように断線防止のために)着脱できるようにしておいて欲しかった。
ただ今日は、映像を使おうとすると、HDMIもVGAも認識しようとして固まった後、15秒ほどして認識を諦めてしまうという現象に遭遇。いろいろ試すも対処法が見つからず結局ダメ。
そのためなんと今日の講義は3時間以上にわたって「実物投影機でMacBookの液晶画面を撮影しながらそれをプロジェクション」というすごいことになってしまった。RetinaディスプレイとフルHDのプロジェクタだったので画質はまぁまぁでしたが、講義室の機材卓では実物投影機からの映像入力とPCからのオーディオ入力が同時利用できなかったので、絵と音を一緒に見せられない。音の波形を拡大して一部分だけループ再生、みたいなことができませんでした。
帰り着いて、なんとかならないかとググったら以下のページが。
……結局、僕の場合は「NVRAMリセット(PRAMリセット)」でHDMIに映像が出力できました。明日からの3日間は(その翌日からの別の3日間出張も)なんとかなりそうです。
ただし、いったん接続状態で本体がスリープしてしまうと再接続ができず、またNVRAMリセットが必要になる気がする。完全解決はまだですなー。おそらくmacOSのアップデートが必要です。
(後日談:OSアップデートで解決しました。今は快適です。)