録音について
Silverlightでは、マイク入力が可能になり、PCMでの録音、再生が可能になりました。
WPFは、「音に関する一覧」の通り、標準的なクラスが提供されていないようです。
Windows Vista 以降の、サウンドの入出力は Core Audio と言う機構になったようです。
具体的なプログラミング上のことは、「プログラミング Tips」「Core Audio」以下に書きます。
今までの考え方
サウンドカードは、電圧の変化を一定間隔でサンプリングするもので、オシロスコープにもなります。
サンプリングによって得られるPCMデータをどう使うかはアプリケーション次第でした。
Fig.1 音声データの処理のイメージ
マイクロフォンなどの
電圧(電流)の変化 |
|
→ |
解析 |
→ |
グラフィック
表示 |
Core Audio
Core Audio の考え方は、タスクバーにあるスピーカーマークの上でのコンテキストメニュー(マウスの右ボタンで表示されるメニュー)から想像できます。
-
「音量ミキサー」では、音を再生するアプリケーションが並ぶようになっています。
-
XPではミキサー表示の「オプション」「プロパティ」から「録音コントロール」が開け、入力の切替がアプリケーションの動作中にも可能でした。
これに相当するものは、「サウンド」ダイアログの「録音」タブです。有効/無効、既定のデバイス、既定の通信デバイスと言った設定になっています。
機能的にはXPと同じではないようです。
1.のことから以下のようなイメージだと考えます。DirectShowフィルタを連ねてプレーヤーソフトを作った場合、それは Core Audio のミキサの入力となり、ボリューム制御も基本的には、自身の音量を制御することになるものと考えられます。
Fig.2 ボリュームの論理的な位置
マイク |
→ |
Volume |
→ |
|
|
|
|
→ |
Volume |
→ |
→ |
Volume |
→ |
スピーカー
ヘッドフォン |
→ |
Volume |
→ |
|
|
|
|
→ |
Volume |
→ |
|
|
|
|
2.についてはたくさんのオプション設定がありなかなか全体が把握できません。
MSDNには、下記のような記述があります。
-
電話の場合、スピーカーからは相手の声が聞こえるが、自身のマイクの音は流れない。
-
「声」の場合、背景音を除去できる。
-
電話の着信なら、聞いていた音楽の音量を絞る。
これも合わせて考えると音声をキャプチャするアプリケーションの構成は以下のようになるものと思います。
Fig.3 Core Audioの音声入力
|
→ |
サンプリング
(A/D) |
→ |
エコーキャンセラ―、
ノイズリダクション |
→ |
アプリケーション
による選択、設定 |
→ |
|
コーデック |
→ |
ファイルに
格納する
など |
|
|
ピークメータ― |
← |
→ |
|
ピーク
メータ |
|
|
|
|
音量コントロール |
|
|
|
|
|
|
|
|
|
著作権保護 |
|
|
|
|
|
|
|
|
→ |
レガシ・オーディオ
インターオペラビリティ |
→ |
解析 |
→ |
グラフィック
表示 |
要点は、
-
電話の機能が重要視されている。
-
A/D変換の結果そのものではなく各種フィルタが機能した結果がアプリケーションの入力となる。
-
統合的な管理になっている。おそらく Core Audio がデジタル・ミキシングを行う。
-
これにともなって、アプリケーションは、デバイス関連変更通知やボリューム変更通知に対応する必要がある。
-
旧来は周期的な処理ができない前提で大きなバッファを使っていたが、デジタルミキシングの都合上、周期に応じた単位でデータが扱われる。
音声入力の目的の分類
目的によって、要求が変わるので挙げてみます。
-
PCMデータが必要か
たいていの場合、PCMが必要なわけではなく適当な圧縮後にファイルやストリーミングになれば良いものと思います。
PCMデータは、時間に対する電圧の測定をしているのでオシロスコープになります。
周波数分析や騒音計もあります。
こうした目的には、マイクの振動版の振幅がそのままPCMデータとして得られることが必要になります。
-
声か音楽か
OSが電話(VIOP)対応になっていて、電話に使えるようになっています。
反面、音楽は著作権保護などの問題を抱えていて、批判をかわすようなものになっているように見えます。
パソコンは既にオーディオ機器としては見捨てられているのかもしれませんが、能力的には強力なことに変わりありません。
「忠実」と「ノイズ・リダクション」は背反ですが、Core Audio は「声」のことを対象にしているのは確かそうです。
-
リアルタイム性
パソコンの一時的な負荷で、処理が間に合わないことが起きた時、VIOP なら、それまでのデータは捨てて立て直す必要があります。
これが録音なら多少遅延しても抜けがない方が正しい処理になると思います。つまりバッファリングが有効なケースです。
また、無音はVIOPではデータを送らないことを意味すると思いますが、音楽の録音なら無音と感じられる区間もデータが存在します。
Core Audo + DirectShow
多くの場合、PCMデータが必要なわけではありません。
Core Audio の扱うデバイスは、DirectShowのフィルタとして扱うことができます。
Windows7では、「サウンド」ダイアログで録音デバイスを切り替えると、左図のようにフィルタの一覧にも反映します。
「Audio Capture Sources」に、マイク や ミキサーが表示され、標準でフィルタとして登録されていることを知りました。
下図のようにフィルタを繋げば、Stereo Mix の音がファイルに保存できます。
また、「DMO Audio Effects」には「AEC」「Echo」などのフィルタが登録されています。
音声入力方法による差異
いろいろなAPIがあって良くわからないのですが、WaveIO7ライブラリを作って知ったことです。
-
「サウンド」ダイアログの設定は、下表にあるすべての方式に影響する。
-
音量は、Kernel Stream と、他の方式で差がある。
-
Core Audioの推奨であるWaveRTドライバをわたしは持っていない。
-
WASAPI以外は、旧来通り、秒単位のバッファがないと正常に動作しない。
これは、WaveRTドライバがある環境では別なのかもしれない。
-
WASAPIの場合は、入出力単位は10msとか30msと言った時間になり、自由に設定できない。
わたしの環境では音切れする。
WaveRTドライバがないためだとは思うが、また、録音再生どちらの問題かも定かでないが。
方式 |
mmsystem.h
winmm.dll |
今まで使ってきた方法。
Core Audioでも レガシ―・オーディオ・オペラビリティとして記述がある。関数を呼び出す方法。 |
dsound.h
dsound.dll |
最初のキャプチャ、レンダーの生成以外は、COMインタフェースによる方法。
Windowのハンドルを引数にとり、フォーカスがなくなると停止すると言った仕組みがある。 |
AudioClient.h |
COMインタフェースによる方法。
音声認識や圧縮で採用されている短い時間(40ms以下)の周期性の処理が可能だと言う前提でできている。データの入出力単位は主に自動的に決められる。最小の周期は3msのよう。 |
mmdeviceapi.h |
WASAPIと同じ意味で使われるが、おそらく「サウンド」ダイアログによる設定変更通知、音量変更通知などの仕組みは、すべての方式で有効だと思う。 |
ks.h
KsMedia.h
ks.sys
portcls.sys
stream.sys
|
CreateFile()でハンドルを取得するなど、専用のAPI群ではなく、ドライバ一般の手順による。
音量が他の方式と異なる。
レンダーデバイスにもキャプチャできるPinがあるが、機能は同じ。
|
axcore.idl
strmif.h |
前述の方式のいずれかでソースフィルタを作成すればDirect Showの仕組みでエンコードやファイル出力ができる。特に、WASAPIでは、直接Direct Showフィルタ・インタフェースを得ることができる。しかし、PM2などのエンコーダとつなぐと理由はわからないが試した限り2分数十秒で停止する。(GSMは停止しない。音質と関連あるものと推測) |
ボリュームについて
概念の問題として、ボリュームは重要な要素になるようです。
ボリュームは機器に実装されたものやWindowsのミキサに表示されたりします。
また、「サウンド」ダイアログの「録音」「再生」デバイスそれぞれにもあります。
たいていボリュームは、マイクやスピーカーなどの物理的なデバイスに対応しているように思っていますが、良く考えてみるとスピーカー以外の音量設定にはどんな意味があるのか良くわかりません。
マイクのボリューム
XPなら「録音コントロール」に、Win7なら「サウンド」ダイアログのスピーカーやマイクデバイスのプロパティに、マイクのボリュームが表示されます。(「サウンド」ダイアログのスピーカーのプロパティにもあります。)
しかし、マイク自体には通常ボリュームに相当する機能はありません。パソコンのボリューム操作で、A/Dコンバータの入力は変化しないので、これをPCMデータにする段階で定数が掛けられていると解釈しています。
ボリュームの意味
アナログオーディオ機器なら、大きな音を出すときには大きな電流が流れています。
これに対して、PCMデータの振幅が大きくても小さくてもパソコン内では何の変化もありません。「ボリューム」と言う言葉は、全く別なものを指して使われています。
-
スピーカーやヘッドホンを駆動する電流の制御
-
PCMデータの振幅(値)の大小
論理的にはどこにボリュームがあるのか
ストリーミングで音楽を聴いているときに、電話の通話が始まったら、音楽のボリュームを下げると言った動作(ダッキング)をするようです。
マイクからの声以外は、相手に送られないと言ったスイッチングも考えられています。
個々のファイルやストリーミング再生もデバイスと同じように、音量調節やスイッチングの対象になります。
Windows標準のミキサーにも再生アプリケーションが並ぶようになっています。
ボリュームの機能
-
ハード的なボリュームが付いているデバイスではその設定を得る
-
個々のデバイスのボリューム設定
-
個々のデバイスのボリューム取得
-
マスターのデバイスのボリューム設定
-
マスターのデバイスのボリューム取得
-
音量変更通知
グローバルな通知機能
-
ボリューム変更通知
-
ダッキング通知
-
デバイス有効無効切り替え通知
-
デバイス設定変更通知
-
入力レベル通知
ボリュームのマキシマイズ
スピーカーやヘッドフォンのボリューム以外はPCMの表す振幅が音量を表します。
PCMデータの値のレンジいっぱいに使うのが有効です。
-
実際のスピーカーの出力エネルギーとPCMデータの示す振幅の関係では、比例はしても絶対値については関係が定められていないものと思います。
音量の調整にPCMデータの値を書き換えるのは良い方法とは思えません。
-
すべての音声データがマキシマイズされていて、それに合わせてスピーカーボリュームが調整されていれば突然大きな音が出るようなことはなくせる。
ただし、前述の図のように論理的なボリュームはPCMデータの振幅を調整してミキシングします。この段階でのデータは演算によってオーバーフローしないように扱う必要があります。
また、マキシマイズは、概念であって実現するのは困難です。
-
最大音量はすべてのデータを見ないとわからない。ライブやストリーミングではピークを知りえない。
-
ピークをそろえても「同じ音量」と感じられるとは限らない。多くの場合、「会話部分」でそろえる必要がある。
-
たとえ「会話部分」のボリュームを知り得ても、どの部分を比較すれば良いかはわからない。
PCMデータの形式
SDKのサンプルを実行してみると、PCMデータは 32ビット整数やFloatだったりします。
これは、入力は演算されるので、float形式が内部的に使われていることによるものと考えます。
(デジタルでミキシングするためにはPCMデータ形式をそろえる必要がある。)
|