0

マイクからオーディオを録音し、オーディオに対してリアルタイムで後処理を実行するアプリケーションがあるためAudioRecord、標準の代わりにクラスを使用する必要がありますMediaRecorder。記録用の私のコードは次のとおりです。

DataOutputStream dataOutputStreamInstance = new DataOutputStream(bufferedStreamInstance);
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);

int bufferSize = AudioRecord.getMinBufferSize((int)sampleRate, channelConfiguration, DEFAULT_AUDIO_ENCODING) * 2;
short[] microphoneBuffer = new short[bufferSize];
float[] processingBuffer = new float[bufferSize];
short[] outputBuffer = new short[bufferSize];

AudioRecord microphoneRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize);

microphoneRecorder.startRecording();
while(isRecording) {
  synchronized(mutex) { ... check for pause condition, wait, etc. ... }
  int numSamplesRead = microphoneRecorder.read(microphoneBuffer, 0, bufferSize);

  // Convert 16-bit short data to floating point
  getFloatingPointBufferFromPcmData(microphoneBuffer, processingBuffer, bufferSize);

  doProcessingStuff(processingBuffer, bufferSize);

  if(numSamplesRead == AudioRecord.ERROR_INVALID_OPERATION) {
    throw new IllegalStateException("read() returned AudioRecord.ERROR_INVALID_OPERATION");
  }
  else if(numSamplesRead == AudioRecord.ERROR_BAD_VALUE) {
    throw new IllegalStateException("read() returned AudioRecord.ERROR_BAD_VALUE");
  }

  try {
    // Dump the output to the target file in 16-bit short format
    getShortPcmBufferFromFloatingPointData(processingBuffer, outputBuffer, bufferSize);
    for(int bufferIndex = 0; bufferIndex < numSamplesRead; bufferIndex++) {
      dataOutputStreamInstance.writeShort(outputBuffer[bufferIndex]);
    }
  }
  catch(Exception e) {
    Log.e("MyApp", "Error while writing audio data to file: " + e.getMessage());
    e.getStackTrace();
  }
}

microphoneRecorder.stop();

上記のコードは正常に動作し、実際にデバイスからオーディオを録音でき、自分の声などが聞こえます。問題は、数秒後、信号全体がかき消されるまで、非常に奇妙な歪みのパターンが現れ始めることです。これは、マイクの上にテープを置き、アプリに 1 分ほど録音させて作成した無音録音のスクリーンショットです。

Wave ファイルの歪みのスクリーンショット

元の wave ファイルは、ここからダウンロードできます

この問題は間違いなく私のエフェクト処理コードによるものではありません。コメントアウトを試みたところ、どちらの場合も同じ結果が得られたからです。他のコードや同様の問題を経験している可能性のある人をウェブで探しましたが、何も見つかりませんでした。

4

3 に答える 3

2

私は Android SDK についてまったく知りませんがgetFloatingPointBufferFromPcmDatagetShortPcmBufferFromFloatingPointData素敵な命名規則にもかかわらず、標準の API 関数のようには見えません。:)

これらは自分で書いたのですか?おそらく、彼らは共有された状態を使用し、ループの反復全体で結果を蓄積していますか? これらがあなたの実装である場合は、実際の問題を特定できるように、これらのコードを共有してください。

また、PCM データを間違った形式 (ビット数、エンディアン) で書き込んでいる可能性や、オーディオ エディターが別の形式に従ってデータを解釈している可能性もあります。何らかの蓄積効果が発生しています。

これらの問い合わせのいずれも問題の解決につながらない場合、次の推奨事項は、while ループ全体で単一のインスタンスを使用するのではなく、ループの反復ごとに新しいmicrophoneBuffer インスタンスを作成することです。

繰り返しますが、私は Android SDK の専門家ではないので、これらは事実上すべての種類の API とその実装の詳細を扱ってきた長年の経験から得られた一般的なアドバイスです。

問題の診断に役立つことを願っています!

于 2010-10-14T15:08:50.407 に答える
0

実は、問題は Android のせいではなく、生の PCM データを WAV 形式に変換するために使用していたソフトウェアが原因でした。ARM チップはビッグ エンディアンであり、WAV はリトル エンディアンであるため、エンディアン変換には明らかに何らかのエラーがあります。生の PCM ファイルを Audacity で開いてみたところ、問題ないように見えました。

于 2010-10-15T10:26:52.033 に答える
0

無音の場合、自動ゲイン コントロールが入力ゲインを理屈を超えて増加させ、記録する「何か」を見つけようとしている可能性があります (もちろん、ノイズ フロアを見つけます)。

PC のスピーカーを適切なオーディオ周波数の正弦波を再生するように設定するとどうなりますか?ノイズがまだ発生しますか?それとも正弦波を録音し続けますか?

于 2010-10-14T15:52:06.047 に答える