我的 Android Java 应用程序需要将音频数据记录到 RAM 中并进行处理。这就是我使用“AudioRecord”类而不是“MediaRecorder”(仅记录到文件)的原因。
到现在为止,我对音频数据使用了带有“read()”的繁忙循环轮询。到目前为止,这一直有效,但它过多地与 CPU 挂钩。在两次轮询之间,我将线程置于睡眠状态以避免 100% 的 CPU 使用率。但是,这并不是一个真正干净的解决方案,因为不能保证睡眠时间,您必须减去安全时间才能不丢失音频片段。这不是 CPU 最优的。对于并行运行的线程,我需要尽可能多的空闲 CPU 周期。
现在我使用“OnRecordPositionUpdateListener”实现了录制。根据 SDK Docs,这看起来很有希望,也是正确的方法。一切似乎都正常(打开音频设备,读取()数据等),但从未调用过 Listner。
有人知道为什么吗?
信息:我正在使用真正的设备,而不是在模拟器下。使用忙碌循环的录音基本上可以工作(但不能令人满意)。只有回调监听器永远不会被调用。
这是我的源代码中的一个片段:
public class myApplication extends Activity {
/* audio recording */
private static final int AUDIO_SAMPLE_FREQ = 16000;
private static final int AUDIO_BUFFER_BYTESIZE = AUDIO_SAMPLE_FREQ * 2 * 3; // = 3000ms
private static final int AUDIO_BUFFER_SAMPLEREAD_SIZE = AUDIO_SAMPLE_FREQ / 10 * 2; // = 200ms
private short[] mAudioBuffer = null; // audio buffer
private int mSamplesRead; // how many samples are recently read
private AudioRecord mAudioRecorder; // Audio Recorder
...
private OnRecordPositionUpdateListener mRecordListener = new OnRecordPositionUpdateListener() {
public void onPeriodicNotification(AudioRecord recorder) {
mSamplesRead = recorder.read(mAudioBuffer, 0, AUDIO_BUFFER_SAMPLEREAD_SIZE);
if (mSamplesRead > 0) {
// do something here...
}
}
public void onMarkerReached(AudioRecord recorder) {
Error("What? Hu!? Where am I?");
}
};
...
public void onCreate(Bundle savedInstanceState) {
try {
mAudioRecorder = new AudioRecord(
android.media.MediaRecorder.AudioSource.MIC,
AUDIO_SAMPLE_FREQ,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT,
AUDIO_BUFFER_BYTESIZE);
} catch (Exception e) {
Error("Unable to init audio recording!");
}
mAudioBuffer = new short[AUDIO_BUFFER_SAMPLEREAD_SIZE];
mAudioRecorder.setPositionNotificationPeriod(AUDIO_BUFFER_SAMPLEREAD_SIZE);
mAudioRecorder.setRecordPositionUpdateListener(mRecordListener);
mAudioRecorder.startRecording();
/* test if I can read anything at all... (and yes, this here works!) */
mSamplesRead = mAudioRecorder.read(mAudioBuffer, 0, AUDIO_BUFFER_SAMPLEREAD_SIZE);
}
}