0

AudioRecord の使用に問題があります。

splmeterプロジェクトから派生したコードの一部を使用した例:

private static final int FREQUENCY = 8000;
private static final int CHANNEL = AudioFormat.CHANNEL_CONFIGURATION_MONO;
private static final int ENCODING = AudioFormat.ENCODING_PCM_16BIT;
private int BUFFSIZE = 50;
private AudioRecord recordInstance = null;

...

android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
recordInstance = new AudioRecord(MediaRecorder.AudioSource.MIC, FREQUENCY, CHANNEL, ENCODING, 8000);
recordInstance.startRecording();
short[] tempBuffer = new short[BUFFSIZE];
int retval = 0;

while (this.isRunning) {
   for (int i = 0; i < BUFFSIZE - 1; i++) {
      tempBuffer[i] = 0;
   }

   retval = recordInstance.read(tempBuffer, 0, BUFFSIZE);
   ... // process the data
}

これは、HTC Dream と HTC Magic ではログの警告やエラーなしで完全に機能しますが、エミュレーターと Nexus One デバイスでは問題が発生します。

Nexus では、有用なデータが返されることはありません。リモートの友人にテストを行ってもらっているため、他の有用な情報を提供することはできません。

エミュレーター (Android 1.5、2.1、および 2.2) では、AudioFlinger から奇妙なエラーが発生し、AudioRecordThread でバッファー オーバーフローが発生します。また、UI の応答性が大幅に低下します (記録は UI とは別のスレッドで行われますが)。

私が間違っていることは明らかですか?Nexus One ハードウェアについて何か特別なことをする必要はありますか?

編集

問題を部分的に解決しました... AudioRecordのドキュメントには次のように書かれています:

public static int getMinBufferSize (int sampleRateInHz, int channelConfig, int audioFormat)

AudioRecord オブジェクトを正常に作成するために必要な最小バッファ サイズを返します。このサイズは、負荷がかかった状態でのスムーズな録音を保証するものではないことに注意してください。AudioRecord インスタンスが新しいデータについてポーリングされると予想される頻度に従って、より高い値を選択する必要があります。

だから私はバッファの長さを

private static final int BUFFSIZE = AudioRecord.getMinBufferSize(FREQUENCY, CHANNEL, ENCODING);

そして今、エミュレーターはうまく動作します。

しかし

ハードウェアはそうではありません。エミュレーターはその呼び出しから 640 の値を返しますが (1 秒あたり 12.5 ポーリングを行う)、8khz に基づいて、HTC ハードウェアは 4096 を返します! つまり、1 秒あたり約 2 回のポーリングと、0.5 秒の音声遅延です。さらに、Nexus One で同じ呼び出しを行うと、8192 が返されます。つまり、完全な 1 秒の遅延です。

それで終わったらいいのですが、HTCデバイスとすべてのエミュレーターが動作するようになったにもかかわらず、nexus oneはまだオーディオを返しません(まだ自分自身を持っていないので、適切なデバッグ情報を取得できません)。 (一部が他よりも遅れている場合でも)。

ここで何かひどく間違ったことをしていますか?

4

1 に答える 1

2

解決しました!

私は (誤って) AudioRecord クラスのコンストラクターで使用される魔法の 8000 数が周波数変数の複製であると想定しました。実際には、使用するバッファ サイズになるはずです。

残念ながら、これは splmeter のバッファ長 (デフォルトは 320 - 最初のコード ブロックで 50 に変更しました) と異なるだけでなく、Nexus One で許容される最小バッファ サイズは 8192 であるため、AudioRecord インスタンスが作成されていない必要があります。ちゃんと。

そのため、バッファー長を (getMinBufferSize から) 変更し、魔法の 8000 をそれに置き換え、Frequency 変数を提案された 44100 に増やした場合、すべてのプラットフォーム/エミュレーターですべてが完全に機能します。

したがって、パッチが適用される前に splmeter コード ベースを使用する予定がある場合は、次の 3 つのことを考慮してください。

正直に言うと、splmeter のコードは HTC デバイスでも動作しないはずです。それが私の開発デバイスが HTC Magic = P という名前になっている理由だと思います

于 2010-06-16T15:57:36.807 に答える