はじめに
マイクから生データを受信するには、クラスが責任を負います
android.media.AudioRecord android.media.AudioRecord 。 内部バッファにデータを書き込むため、定期的にデータを収集する必要があります。
コンストラクター
オブジェクトを作成するには、次を指定する必要があります。
| audioSource | 録音はどこから来ましたか? 私たちの場合、これ MediaRecorder.AudioSource.MIC |
|---|
| sampleRateInHz | ヘルツのサンプルレート。 ドキュメントは、44100Hzがすべてのデバイスでサポートされていると主張しています |
|---|
| channelconfig | チャネル構成 たぶん CHANNEL_IN_MONO CHANNEL_IN_MONOまたは CHANNEL_IN_STEREO CHANNEL_IN_STEREO モノはどこでも動作します。
重要:これらの定数は、それらが示すチャネルの数と一致しません。 このパラメーターに1または2を渡すことはできません。
|
|---|
| audioFormat | コーデックとしてよく知られている入力データ形式。 たぶん ENCODING_PCM_16BIT ENCODING_PCM_16BITまたは ENCODING_PCM_8BIT
|
|---|
| bufferSizeInBytes | 同じ内部バッファのサイズ。 それから、オーディオストリームを読み取ることができます。 読み取り部分のサイズはこの値を超えないようにしてください。 このパラメーターの最小許容値は、次の方法で取得できます getMinBufferSize() getMinBufferSize() 。
|
|---|
オブジェクトは、作成中に必要なシステムリソースを取得しようとします。 彼がどれだけ成功したか、関数を呼び出すことで見つけることができます
getState() getState() 。 彼女が戻ったら
STATE_INITIALIZED STATE_INITIALIZED 、その後、すべてが正常である場合、
STATE_UNINITIALIZED STATE_UNINITIALIZEDは、エラーが発生したことを意味します。
エラーの原因は2つあります。小さすぎるバッファーと無効なフォーマットです。 1つ目は
、 getMinBufferSize()呼び出す
ことで回避すること
getMinBufferSize() 。 第二に、実際、彼による。
getMinBufferSize()
この静的メソッドは、
AudioRecordオブジェクトが機能する内部バッファーの最小サイズを生成します。 パラメーターは、コンストラクターと同じ意味を持ちます。 書き込みにこの特定の値を使用することはお勧めできません。 システムがまだ何かでビジーである場合、プログラムはまだ行のすべてのデータを読み取る時間がない可能性があり、レコードに穴があります。 私は、サイズを10倍大きくするようアドバイスしました。
リスト形式
getMinBufferSize()メソッドには素晴らしい機能があります-
このデバイスに対して無効なパラメーターを誓う
ため 、
ERROR_BAD_VALUE ERROR_BAD_VALUEまたは
ERROR ERROR つまり、考えられるすべての組み合わせを調べて、デバイスがサポートしている形式を見つけることができます。
たとえば、次のように:
int[] rates = {8000, 11025, 22050,44100, 48000, 96000 }; int[] chans = {AudioFormat.CHANNEL_IN_MONO, AudioFormat.CHANNEL_IN_STEREO}; int[] encs = {AudioFormat.ENCODING_PCM_8BIT, AudioFormat.ENCODING_PCM_16BIT}; for(int enc : encs) { for(int ch : chans) { for(int rate : rates) { int t = AudioRecord.getMinBufferSize(rate, ch, enc); if((t != AudioRecord.ERROR) && (t != AudioRecord.ERROR_BAD_VALUE)) {
データ読み取り
内部バッファからデータを取得するには、メソッドを使用します
read() read() 。 次の3つのバージョンがあります。
read(byte[] audioData, int offsetInBytes, int sizeInBytes)read(short[] audioData, int offsetInShorts, int sizeInShorts)read(ByteBuffer audioBuffer, int sizeInBytes)
それらのパラメーター:
| audioData | データが書き込まれる配列 |
|---|
| audioBuffer | データが書き込まれるバッファ |
|---|
offsetInBytes / offsetInShorts | 記録を開始するインデックス |
|---|
| sizeInShorts | 要求されたデータブロックのサイズ。 ByteBufferおよびbyte[]単位、 short[]短整数byte[] |
|---|
すべてが正常であれば、メソッドは
ByteBufferまたは
byte[]バリアントである場合、または
short[]短整数を読み取る場合、読み取られたバイト数を返します。 呼び出し時にオブジェクトが正しく初期化されていなかった場合、
ERROR_INVALID_OPERATIONを
返し 、パラメーターに何か問題がある場合
-ERROR_BAD_VALUE重要:メソッドは、要求された量のデータを読み取るまで呼び出しスレッドをブロックします。 内部バッファーに十分な数がない場合、
read()はマイクから来るまで待機します。 したがって、メソッドは
別のスレッドから呼び出す必要があります。そうしないと、アプリケーションがハングします。
アプローチ、リトリート、固定
プログラムがマイクからデータを受信できるように、AndroidManifestのxmlファイルで適切な解像度を指定する必要があります。
<uses-permission android:name="android.permission.RECORD_AUDIO" />
記録を開始するには、メソッドを呼び出す必要があります
startRecording() startRecording() 、そして終了する-
stop() stop() 。 録音は何度でも開始および停止できます。
オブジェクトの処理が完了したら、メソッドを呼び出す必要があります
release() release() 。 オブジェクトによってキャプチャされたすべてのシステムリソースを解放します。 その後、オブジェクト
は使用
できず 、オブジェクト
を参照する変数を
nullに設定する必要があり
null 。
重要:これら3つのメソッドは、前述のメソッドとは異なり、スローされます
IllegalStateException IllegalStateException 、それらが初期化されていない(つまり... ...)オブジェクトに対して、または間違った順序で呼び出された場合。 したがって、それらは「慎重に」処理する必要があります。
tryブロックを介して。
使用例
以下のクラスは、上記のすべてを実行します。 さらに、彼は彼に登録済みを送ります
Handler 受信したデータに関する
Handlerメッセージ。 このデータは別のスレッドで処理されるため、まだ処理されていないデータを新しいデータで上書きしないように、循環バッファーが使用されます。
コードは
AudioFormatInfoクラスを使用します。 これは、記録フォーマットを記述する3つのフィールドを持つ
POJOです:
sampleRateInHz 、
audioFormatおよび
audioFormat package com.MyCompany; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import android.media.AudioFormat; import android.media.AudioRecord; import android.media.MediaRecorder; import android.os.Handler; import android.os.Process;