DVK-UDA01買いました。
PCオーディオにはまってしまいました。
もう随分前になりますが、ミニコンポの音が随分ショボイ気がして、スピーカー変えたことがあるんです。
お店ではいい音出てるのに、家ではなんとなくな音。それはないだろうと思ってアンプを変えたら音が大化けした経験があるのです。
アンプなんて単なる音の増幅装置と思ってたのですが、調べてみると色々とあるようで、
例えばで言うと・・・パソコンの電源をワット数だけで選んでもダメで、GPUが瞬間の要求に答えれるかってことが大切ってことと同じかな。
音の急激な変化に対応できなきゃだめとか結構奥が深いってことを当時知りました。
でも、とっても高価だったんですよね。手が出なかった。
で、今。
PCオーディオってたしかに上限はすっごく高いんですけど、そこそこでも結構楽しめるんですよ。
しかも、自作がわりと手軽にできる。
ってことで、とりあえず、件のキットを買ってみました。
ジブリジャズの「君をのせて」をFLAC圧縮したものを
DAC系はfoobar2000でUSBオーディオでダイレクトに出力
オンボードは、VLCで再生。
DVK-UDA01がヘッドホンで聞くには音がでかすぎるので、
すべて、BoseのCompanion20につないで、スピーカー側のボリュームを固定でDVK-UDA01の大きさに合わせた。
アクティブスピーカーで結構、加工していそうな気がするけど、共通で聞くってことでよしとした。
一応聞いた感じだと、
オンボード < DVK-UDA01 < DocMagicPlus
オンボードって高音部を強調しているような音・・・エフェクタ全部外してるんだけどなぁ。
DVK-UDA01とDocMagicPlusは近いけど、DocMagicPlusの方が綺麗で豊かな感じ
ただ、ぼーっと聞いている分にはどれも違わないねぇ。趣味の世界だわ。うんうん。
オンボードでも結構いい音はしてるんだけど、スキャットの小さな声が全部同じ音に聞こえる。
DVK-UDA01では、何となく違うって分かる
DocMagicPlusではちゃんと違って聞こえる。
エージングがいるらしいので、しばらくして聞いてみると変わるのかなぁ
ちょいかじりの音声認識
発端
音声認識が普通にできるようになってずいぶん立ちます。ちゃんと音声認識やるなら、Windowsにも、あるいは認識ソフトとかもあるからそれを使えば、ずいぶん認識率の高い環境を作れます。
それは、そうなのですが、
どうやっているかの一端ぐらいは知りたい!
まぁ、イッチョカミの性ですかね。
ツールを使えばそれなりにできるけど、それぞれの意味を実感したい。新しいことをするというより、いろいろな資料の追認かな。
ということで、言語から。
何でもいいんだけど、画面に図を描く関係から最初は馴染んだ言語のほうがいいかなってことで
言語 | Java JDK1.6 |
環境 | Eclipse 3.7 |
図 | Swing |
入力 | wave file |
って環境で実施。
準備
- まずは、音声ファイルがない。ネットから取得した講義とかのフラッシュ動画があるから、そこからWaveファイルを抽出。
- JDKのドキュメントによると、javax.sound.sampled.* あたりに音声ファイル関連のクラスがあるので利用
- ファイル形式とフレーム取り込み
データが16ビットだったので、2バイトをどうやって数字にするのかで躓く。
バイト型なのに負の数が入っているから、マスクかけるとかしてからシフトしないと行けないんだろうなぁ。C言語と違うところかな。
誤
frame[j] = audioBytes[i + j * 2 + 1] << 8 | audioBytes[i + j * 2 + 0];
正
frame[j] = audioBytes[i + j * 2 + 1] * 256 + audioBytes[i + j * 2 + 0];
- グラフ化の記述はあまり苦労しない。というか、適当に手抜き。とりあえず出るところまで作成。
音声認識(1)
- 資料いろいろ見てみると、
- FFTで周波数分析
- スペクトルの上位成分を除去
- ピークを周波数の低い方からF1,F2という感じで2つ取り出す
で取り出した、F1とF2のそれぞれをX/Y軸としてグラフにすると(母音)は音素によって
固まりとなるらしい。
なので、まず、FFTを使う。
FFTは、基底が2のべき乗じゃないといけないので、データ数から2を基底にした数字を求める。
FFT自体は複素数対応だったけど、とりあえず、実数部分にセット。取り出すときも実数部分のみ。
虚数部分は無視!
音声認識(2)
FFTを使うときに気づいていたのですが、FFTは領域が繰り返すことを前提としている。
今回は、適当な範囲で区切っているので、領域の開始と終了で一致もしないし繰り返しもしない。
すると、ぶちんと切れることになるので、高周波部分にすごいノイズが乗る。
これってどうするんだろうと見ると、窓関数なるものを使うらしい。
領域の両端でゼロになるような関数を適応して非周期性のデータをFFTで使えるようにするのが窓関数らしい。・・・なるほどそれで窓関数っているのか。
それにしても、8192個のFFTなのに結構早い。1秒どころかほとんど瞬時。昔、1024個のFFTで1秒なんて言ってたのが夢のようなスピードだわ。これなら、リアルタイムでFFTってのも可能だわな。
音声認識(3)
窓関数にハミング関数ってモノを使う。説明によると、音声認識みたいなものではよく使われているとのこと。
で、スペクトル、出るには出たけど、よく見る形と全然違う。
どうやら、縦軸(強度)の方は、対数として扱うみたい。
早速変更
お、出たでた
音声認識(4)
次に特徴(フォルマントという)抽出
スペクトルはそのままだと、ガタガタなので、スペクトルから高周波成分を除く。
これで、高次のガタガタがない線になるので、ピークを抽出して、周波数の低い方から2つ取り出す。
Scala感想
Scalaでは、1ファイル内に複数のPublic相当のClassを定義できる。定義したクラスはコンパイルされるとそれぞれの名前のClassファイルとなる
なので、複数のファイルで同じClass(例えばMain)を使う場合、普通にかぶってしまう。
Javaではファイル名=Class名なので、Packageを同じ機能なりの単位で作っていくがScalaでは命名規則を作る(基本人任せ)かPackageを1ファイル単位にしないと共同で作業する場合、名前が衝突する。クラス名の先頭にファイル名をつけてくれてたらよかったのに・・・(オプションであるのかな)
この辺は、CやC++のよくないところに戻った感があるなぁ。