Android AudioRecord 初始化延迟
Posted
技术标签:
【中文标题】Android AudioRecord 初始化延迟【英文标题】:Android AudioRecord Initialization delay 【发布时间】:2013-09-03 10:43:02 【问题描述】:这是我正在处理的相关代码的示例:
AudioRecord recorder = setupAudio();
recorder.startRecording();
SetupAudio 方法:
public AudioRecord setupAudio()
AudioRecord recorder;
minBufferSizeInBytes = AudioRecord.getMinBufferSize(
RECORDER_SAMPLERATE, AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT);
Log.e("MoverAudio","BufferSize: " + minBufferSizeInBytes);
recorder = new AudioRecord(MediaRecorder.Audiosource.CAMCORDER,
RECORDER_SAMPLERATE, AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT, minBufferSizeInBytes);
return recorder;
RECORDER_SAMPLERATE = 8000;
我正在尝试找出是否有任何方法可以缩短初始化所需的时间。
目前我正在用 3 台设备对其进行测试,结果如下:
银河 S3
设置音频:~200 毫秒 startRecording() : ~280ms银河 S3 迷你
设置音频:~10 毫秒 startRecording() : ~290ms银河系
设置音频:~10 毫秒 startRecording() : ~235ms缓冲区大小:
连结:704 s3: 1024 s3 迷你:640但是,只有来自银河系的数据是可用的。 为了我的应用程序的目的,我必须能够尽快获得音频数据。使用当前值,只有 Nexus 在可接受的时间内。
S3 mini 可能看起来很快,因为它只需要比 Nexus 多一点的时间,但是前约 200 毫秒的样本被列为 0,因此它不可用。
根据我在分析收集到的数据后了解到的情况,S3 和 S3 mini 上的音频似乎以某种方式被过滤了,因为由此产生的 FFT 更加干净,低频声音总是不那么明显。 以下是 S3mini 和 Galaxy Nexus 录制音频的示例:
http://img41.imageshack.us/img41/4177/ox7h.png S3迷你
http://img690.imageshack.us/img690/8717/iya6.png Galaxy Nexus
【问题讨论】:
您使用什么采样率和通道配置?您将缓冲区大小设置为多少? setupAudio 方法将使用以下配置初始化录音机:RECORDER_SAMPLERATE = 8000; minBufferSizeInBytes = AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);录音机 = 新 AudioRecord(MediaRecorder.AudioSource.MIC,RECORDER_SAMPLERATE,AudioFormat.CHANNEL_IN_MONO,AudioFormat.ENCODING_PCM_16BIT,minBufferSizeInBytes);通过使用 CAMCORDER,我设法使用了来自 S3 mini 的数据。然而,S3 在 startRec() 中仍有约 450 毫秒的延迟。 【参考方案1】:如果您请求一个长缓冲区,那么您必须等待操作系统以当前采样率填充它。如果您请求的采样率与硬件 ADC 正在运行的采样率不同,则您必须另外等待重采样器滤波器延迟。不同的 android 设备和操作系统版本可能支持不同的最小缓冲区大小和本机硬件采样率。
隐藏延迟的一种方法是在应用生命周期的早期开始录制,并一直丢弃音频样本,直到应用需要它们。这样就没有启动开销了。
已添加:在某些设备/操作系统版本上,数据可能会真正以某种硬件采样率(例如 4096,44.1k 或 48kHz)捕获到更长的操作系统驱动程序缓冲区中,并且只有在其中几个缓冲区被填充、转换后到另一个采样率,并切成更短的请求缓冲区长度,音频命令开始向应用程序发送数据。要绕过,如果可能的话,您可能需要修改操作系统并编写自己的 ADC 驱动程序。但请尝试使用更高的采样率(44.1k 或 48k)并首先请求更短的缓冲区。
【讨论】:
我使用 8K sampleRate 并且 bufferSize 使用 AudioRecord.getMinBufferSize()(S3 = 1024, Mini = 640, Nexus = 704) 是动态的。使用大小为 1024 和 8k 采样率的缓冲区,最多需要 128 毫秒才能填充。据我了解,这仅在我已经记录数据时才相关,并且从接收音频数据到实际记录它可能会有一点延迟。但是,当前的问题是我运行 startRecording() 所花费的时间。 我理解,这很有意义。但是,我认为这不是问题所在。我不必分析“onTheFly”数据。我只需要它尽快开始捕获麦克风数据,因此我的开始请求和第一个麦克风数据之间的时间可能小于 ~250 毫秒。因此,如果操作系统需要 600 毫秒来获取我的一些音频数据,那没关系,只要它能够在 250 毫秒的录制请求命令内给我数据。以上是关于Android AudioRecord 初始化延迟的主要内容,如果未能解决你的问题,请参考以下文章
Android技术分享| Android WebRTC 对 AudioRecord 的使用
Android技术分享| Android WebRTC 对 AudioRecord 的使用
<AudioRecord> "无法获得记录源 1 的音频输入"