前回、音声信号をScilabにロードするために音声関係関数をさらってみました。全体の雰囲気は分かったのだけれど、解析用のプロットまで手が回らなかったです。そこで今回は前回積み残し部分を練習。しかしその前にWindows上での音声データの生成のところでまた一つ悶着あり。音声データなど普段扱わないから無知なのよ。
※「手習ひデジタル信号処理」投稿順 Indexはこちら
Windows 11のサウンドレコーダ、トリミング無なのね
前回、Windows10上の標準録音アプリ「ボイスレコーダ」が、Windows11上ではいつの間にか「サウンドレコーダ」に戻っていた件書きました。もっと以前のWindowsでは「サウンドレコーダ」だったので先祖返りデス。おかげで「ボイスレコーダ」で非圧縮のPCMで録音するwav形式が無くなったとブーたれていた件は「サウンドレコーダ」で解決。
しかし「サウンドレコーダ」で無くなった機能がありました(以下はWindows11のサウンドレコーダの画面。)
無くなった機能はトリミング機能です。確か以前はこの辺からこの辺を切り出してね、といった操作が出来た気がしたのだけれども現行の「サウンドレコーダ」ではそんな機能は無くなってしまったみたいです。
今回はScliab上で音声データ処理(変復調の実験に使うつもり)する予定なのでトリミング機能はScilab上で自前実装することにいたします。
一方、大昔の「サウンドレコーダ」では、メニューからいろいろ設定できた筈の「サンプリング・レート」、サウンドレコーダ上からの設定が見当たりませんん。これはWindowsのシステム設定で指定したものがそのまま使われるみたいです。
Windows11のサウンドのプロパティ画面の入力形式のところが以下に。
手元の装置では、2チャンネル(ステレオ)16ビットの48000Hzがデフォルトみたいです。RTLSDRからのIQデータから復調の音声データはサンプリングレート44100Hzとしてあったので、今回はそれに合わせてCD Qualityに変更した場合のテストデータも作っておきます。
Scilab上へWAVファイルをロードしてサンプリングレート確認
前回やったとおり、Scilab関数でwav形式ファイルの「諸元」を確認することが可能です。上記の形式設定のDVD QualityとCD Qualityの指定毎、内蔵マイクで「ただいまマイクの試験中~」を録音したものを用意してみました。
上のDVD品質のもの、黄色のマーカー部の1は録音形式が非圧縮のPCM、2は2チャンネル(ステレオ)、48000がサンプリングレートです。
下のCD品質のもの、黄色のマーカー部の1は録音形式が非圧縮のPCM、2は2チャンネル(ステレオ)、44100がサンプリングレートです。
今回はCD品質の方のファイルをロードして処理してみます。
[y, Fs, bits] = wavread('micTestCD.wav'); yL = y(1,:); yR = y(2,:);
上記ではステレオ信号を変数 y にロードするついでに、サンプリングレートをFs、ビット幅をbitsに入力。さらに左チャネルをyL、右チャネルをyRなる変数に分離して格納もしてみました。
Scilab上での音声データのトリミング処理
さて、Windows上でトリミング処理できなかったので、以下のような自前関数を用意してみました。ロードしたステレオ信号の所望のチャネルの所望の位置からの所望のサンプル数を切り出してくるものです。
// Trim Sound Data // y: sound data // Fs: sampling frequency [Hz] // ch: channel // startT: start time [sec] // sLen: sample length function tdata=trimSoundData(y, Fs, ch, startT, sLen) [nr, nc]=size(y); stepT=1.0/Fs; startP=startT/stepT; if startP > nc then disp("ERROR: startT"); abort; end endP=startP + sLen - 1 if endP > nc then disp("ERROR: sLen"); abort; end if ch > nr then disp("ERROR: ch"); abort; end tdata = y(ch, startP:endP); plot2d(tdata) endfunction
上の方でロードしたステレオ信号 y の開始1.0秒後からの8192サンプル分の左チャネルのデータを切り出す場合が以下に。
ch1y1s = trimSoundData(y, Fs, 1, 1.0, 8192);
上記の関数定義にはプロットも含まれるので、切り出し後、以下のように波形も観察できます。これが音声の時間波形であると(ファイル上の16ビットPCMが-1から1までの正規化音声に変換されている。)
analyze()関数で音声データを周波数解析
さて上記で切り出した音声波形を、analyze関数に掛けてみます。周波数プロットを描いてくれるもの。
clf; analyze(ch1y1s); xtitle('CH1(L) sound data', 'Frequency[Hz]', 'MAG');
結果のプロットが以下に。
mapsound()関数でSpectrogram
さてさて、続いて mapsound()関数にスペクトログラムを描いてもらいます。スペクトログラムは長めのデータでないと見栄えが悪いので、左チャネルの全データを対象に描いてもらいます。なお、チャンクといって処理単位を指定する必要ありですが、0.04秒としてます。これはScilabのHelpでそういう値を使っていたから。周波数の上限は1500Hzとしてます。これは上記の周波数プロットの上限1500Hz(デフォルト値)とあわせるためです。また、サンプリング周波数はロード時に代入したFsを使ってます(mapsoundのデフォルト値は異なるので、サンプリング周波数の設定を忘れるとマズイです。)
clf; mapsound(y(1,:), 0.04, 1500, Fs);
さっきの周波数プロットはTime=1のときの縦方向のスナップショットと言う感じ。トリミングする場合は先にスペクトログラムで全体を観察してから切り出し位置を決めると良いかも。