[注意] (2020年6月20日記)

macOS Mojave (10.14.x) からセキュリティが強化され、プログラムからマイクへのアクセスには特別な権限が必要になりました。 「システム環境設定」→「セキュリティとプライバシー」→「マイク」とすると マイクロフォンへのアクセスが許されているアプリケーションの一覧が表示されます。 ここに"+"ボタンがないというバグ(あえてバグと表記します)のため、Javaを追加することができず、 javaにマイクへのアクセス権限を付与できません。

このためjavaのプログラムからマイクへのアクセスができなくなりました。 エラーは起きませんが、データがとれず all 0 となります。 他のアプリケーションでは Info.plistをいじると一覧に追加できる場合もあるようですが、 OpenJDKのjavaではうまくいかないようです。 このバグは macOS Catalina (10.15.x) になっても解消されていません。

したがって、以下で解説しているJavaプログラムからマイクへのアクセス方法は、 WindowsおよびmacOS10.13以前のMacのみで通用するものです。



Javaで音声を扱う


Java で音声を扱う方法は「 Java Sound プログラマーズ・ガイド 」を参考にするとよいでしょう。



音声

音は波(疎密波、縦波)として伝播する。 音声データは、1定時間毎に変位をサンプリング(sampling, 標本化) することで得られる。 毎回のサンプリングで得られた1つ1つのデータを記憶するのに 何ビット使用するかで個々のデータの精度が決まる。 また、どれだけの頻度でサンプリングするかで、元の音声の 時間軸方向の変化をどれだけ忠実にデータ化できるかが決まる。 したがって、bit幅が大きく、またサンプリング周波数が高い (サンプリングの間隔が短い)ほど、元の音声に忠実にデータ化し、 正しく再生できる可能性が高い。 ただし精度が高いほどデータ量も膨大になる。
    (例)8bit、モノラル、サンプリング周期8KHzの音声データ量は
        8(bit) ÷ 8 (bit/byte) × 1 (channel) × 8K(hz) = 8Kbyte/sec
    (例2)16bit、ステレオ、サンプリング周期44KHzの音声データ量は
        16(bit) ÷ 8 (bit/byte) × 2 (channel) × 44K(hz) = 176Kbyte/sec
音声の波形 サンプリング
サンプリングによって得られるデータ データの再生

音声ファイルのフォーマット

音声ファイルのフォーマットにはいろいろあるが、その中でも 以下の3種類に関しては知っておくことが望ましい。



[注意] macOS Mojave (10.14.x) および Catalina (10.15.x) 上のjavaでマイクを使うには

最近のmacOS ではセキュリティが強化されており、 マイクにアクセスするアプリケーションを実行する時は macOSはユーザにその許可を求めます。 しかし、この部分にバグがあり、java プログラムからからマイクにアクセスしようとしても セキュリティの承認が求められるわけではなく、単にデータが取れない状態が生じます。 appleはこのバグを放置したままです。

これを回避する方法は stack overflow にあります。 だが、この方法は普通のjavaアプリケーションでは取れない。

/Library/Java/JavaVirtualMachines/jdk-14.0.1.jdk/Contents/info.plist に "Privacy - Microphone Usage Description" を追加しても駄目だった。



音声データの取得

Javaで音声入力を扱うための AudioInput クラスを作成しました。 AudioInputクラスの利用方法は TestAudioInput.java の // (*)がコメントについた行 を参照して下さい。

(注意)音声データをファイルに保存する場合は、wav, aiff, au などの書式付きサウンドファイルとして保存することが望ましいでしょう。 ここでは、演習のプログラムで利用しやすいように、敢えてリニアPCMのデータをそのまま(raw)保存しています。









TestAudioInputの実行例
$ javac AudioInput.java TestAudioInput.java
$ java TestAudioInput
$ ls -l audio_raw.dat
-rw-r--r--  1 nitta  staff  64000  4  6 12:46 audio_raw.dat

音声データの再生

Java で音声再生を扱うための AudioOutputクラスを作成しました。 AudioOutputクラスの利用方法は TestAudioOutput.java の // (*)がコメントについた行 を参照して下さい。








TestAudioOutputの実行例
$ javac AudioOutput.java TestAudioOutput.java
$ java TestAudioOutput
4秒ほどの音声が再生される。再生ボリュームに気をつけること。