AudioRecord的getMinBufferSize函數的分析
1.java用法樣本
此方法是靜態方法,可以直接調用,測試案例如下,測試此函數的取得的最小buffer:
int size = AudioRecord.getMinBufferSize(44100, AudioFormat.CHANNEL_IN_DEFAULT, AudioFormat.ENCODING_PCM_16BIT); Log.d("TEST", "size = " + size);
2.調用路線圖
(1)AudioRecord.java檔案的getMinBufferSize函數
通過調用jni函數native_get_min_buff_size取得buffer大小。
(2)在android_media_AudioRecord.cpp檔案的native_get_min_buff_size函數,對應jni的函數為android_media_AudioRecord_get_min_buff_size函數
通過調用AudioRecord::getMinFrameCount函數,取得frameCount,用於計算buffer大小。
取得frameCount後,再通過以下公式計算出最終的buffer大小。
frameCount * nbChannels * (audioFormat == javaAudioRecordFields.PCM16 ? 2 : 1);
(3)AudioRecord.cpp檔案的AudioRecord::getMinFrameCount函數,取得frameCount
然後再通過以下公式計算出最小buffer:
frameCount * nbChannels * (audioFormat == javaAudioRecordFields.PCM16 ? 2 : 1);
(4)AudioRecord::getMinFrameCount函數用又調用AudioSystem.cpp檔案的AudioSystem::getInputBufferSize函數取得buffer size後,
通過以下公式計算最小buffer:
// We double the size of input buffer for ping pong use of record buffer. size <<= 1; if (audio_is_linear_pcm(format)) { size /= channelCount * audio_bytes_per_sample(format); } *frameCount = size;
(5)AudioSystem::getInputBufferSize函數又通過調用AudioFlinger的
gInBuffSize = af->getInputBufferSize(sampleRate, format, channelCount);
(6)繼續調用AudioFlinger的getInputBufferSize方法,取得buffer大小
size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, int format, int channelCount){ return mAudioHardware->getInputBufferSize(sampleRate, format, channelCount);}
直接返回從硬體取得的緩衝值,沒有做其他處理。
在AudioFlinger的getInputBufferSize方法中,需要根據具體硬體實現,調用實際的硬體buffer大小。
(7)調用AudioHardwareALSA類的getInputBufferSize取得buffer大小
AudioHardwareALSA類位於hardware目錄下,根據不同的cpu廠商實現,此類位於不同的目錄下,並且getInputBufferSize的實現也不同。需要根據不同的錄音機硬體來實現。
下面是具體代碼實現,根據採樣率和聲道數不同,返回不同的buffer大小。
size_t AudioHardwareALSA::getInputBufferSize(uint32_t sampleRate, int format, int channelCount){ size_t bufferSize; if (format != AudioSystem::PCM_16_BIT) { LOGW("getInputBufferSize bad format: %d", format); return 0; } if(sampleRate == 16000) { bufferSize = DEFAULT_IN_BUFFER_SIZE * 2 * channelCount; } else if(sampleRate < 44100) { bufferSize = DEFAULT_IN_BUFFER_SIZE * channelCount; } else { bufferSize = DEFAULT_IN_BUFFER_SIZE * 12; } return bufferSize;}
返回給上級調用者後,還需要根據具體情況再做調整,最終結果值才是應用程式層要取得的最小緩衝大小,單位為位元組。
例如,在我的華為U8500 2.2版本上取得的值是4096位元組。
整個函數調用流程圖如下: