我在线程中使用以下代码从麦克风捕获原始音频样本并通过扬声器播放。
public void run(){
short[] lin = new short[SIZE_OF_RECORD_ARRAY];
int num = 0;
// am = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE); // -> MOVED THESE TO init()
// am.setMode(AudioManager.MODE_IN_COMMUNICATION);
record.startRecording();
track.play();
while (passThroughMode) {
// while (!isInterrupted()) {
num = record.read(lin, 0, SIZE_OF_RECORD_ARRAY);
for(i=0;i<lin.length;i++)
lin[i] *= WAV_SAMPLE_MULTIPLICATION_FACTOR;
track.write(lin, 0, num);
}
// /*
record.stop();
track.stop();
record.release();
track.release();
// */
}
其中record
是AudioRecord
而track
是Audiotrack
。我需要详细了解(如果可能的话,以简化的方式)AudioRecord如何存储PCM数据和AudioTrack如何播放PCM数据。这就是我到目前为止所理解的:
当while()循环连续运行时,record
获得SIZE_OF_RECORD_ARRAY个样本数(现在为1024),如图所示。样本在lin []短路阵列中连续保存(16位短路,因为我使用的是16位PCM编码)。这是由record.read()
完成的。然后track.write()
将这些样本放在由硬件播放的扬声器中。这是正确的还是我错过了什么?
答案 0 :(得分:1)
关于如何将样品布置在记忆中;它们只是声波线性近似的数组,在不连续的时间拍摄(如图所示)。在立体声的情况下,样本将是交错的(LRLRLRLR ...)。
当谈到音频所采用的路径时,你基本上是正确的,尽管还有一些步骤:
将数据写入Java AudioTrack
会导致它对native helper class进行JNI(Java本地接口)调用,然后调用native AudioTrack
class。
AudioTracks归AudioFlinger
所有,它定期从给定输出线程(由AudioMixer
混合)的所有AudioTrack中获取数据并将其写入{ {3}}
从内置麦克风录音时,您的步骤大致相同,只不过它们的顺序相反。
请注意,其中一些步骤(基本上来自音频HAL及其下方的所有步骤)都是特定于平台的,因此不同供应商的平台(甚至来自同一供应商的不同平台)可能会有所不同。