Platform: Rockchip
OS: Android 6.0
Kernel: 3.10.92
以采样率和buffer size为线索来跟踪开机时Audio Hal第一次初始化:
AudioPolicyManager ->
ConfigParsingUtils::loadAudioPolicyConfig -> AUDIO_POLICY_CONFIG_FILE是/system/etc/audio_policy.conf, 对应/device/rockchip/common/audio_policy_rk30board.conf
loadHwModules ->
loadHwModule ->
config_find(root, INPUTS_TAG); //INPUTS_TAG是inputs,在audio_policy.conf能找到.
module->loadInput ->
HwModule::loadInput ->
profile->loadSamplingRates -> 找到SAMPLING_RATES_TAG的内容,即sampling_rates
mSamplingRates.add //所有支持采样率都存下来,其他如format, channel也一样被各自存下来
mInputProfiles.add //一个input节点当做一个profile存下来
new AudioInputDescriptor(inProfile); -> 根据上面profile来创建
profile->pickSamplingRate //获取最大采样率,这里就是48kHz, channel也是类似.
mpClientInterface->openInput -> 将上面获取的sample rate以及channel还有format组成config传给hal看是否真支持,不支持的话HAL会重新配置.
AudioFlinger::openInput_l ->
inHwHal->open_input_stream ->
adev_open_input_stream -> audio_hw.c
上层通过in_get_buffer_size()来获取buffer size
OS: Android 6.0
Kernel: 3.10.92
以采样率和buffer size为线索来跟踪开机时Audio Hal第一次初始化:
AudioPolicyManager ->
ConfigParsingUtils::loadAudioPolicyConfig -> AUDIO_POLICY_CONFIG_FILE是/system/etc/audio_policy.conf, 对应/device/rockchip/common/audio_policy_rk30board.conf
loadHwModules ->
loadHwModule ->
config_find(root, INPUTS_TAG); //INPUTS_TAG是inputs,在audio_policy.conf能找到.
module->loadInput ->
HwModule::loadInput ->
profile->loadSamplingRates -> 找到SAMPLING_RATES_TAG的内容,即sampling_rates
mSamplingRates.add //所有支持采样率都存下来,其他如format, channel也一样被各自存下来
mInputProfiles.add //一个input节点当做一个profile存下来
new AudioInputDescriptor(inProfile); -> 根据上面profile来创建
profile->pickSamplingRate //获取最大采样率,这里就是48kHz, channel也是类似.
mpClientInterface->openInput -> 将上面获取的sample rate以及channel还有format组成config传给hal看是否真支持,不支持的话HAL会重新配置.
AudioFlinger::openInput_l ->
inHwHal->open_input_stream ->
adev_open_input_stream -> audio_hw.c
static int adev_open_input_stream(struct audio_hw_device *dev, audio_io_handle_t handle, audio_devices_t devices, struct audio_config *config, //从audio_policy.conf得到的最大支持配置 struct audio_stream_in **stream_in, //传进来是新的 audio_input_flags_t flags, const char *address __unused, audio_source_t source __unused) { struct audio_device *adev = (struct audio_device *)dev; struct stream_in *in; int ret; *stream_in = NULL; //不管它传进来是哪种,直接定死为双声道. config->channel_mask = AUDIO_CHANNEL_IN_STEREO; #ifdef ALSA_IN_DEBUG //用来调试抓取pcm数据 in_debug = fopen("/data/debug.pcm","wb");//please touch /data/debug.pcm first #endif ...... in = (struct stream_in *)calloc(1, sizeof(struct stream_in)); if (!in) return -ENOMEM; ...... //audio_policy.conf中的最大采样率,是48kHz in->requested_rate = config->sample_rate; ...... in->channel_mask = config->channel_mask; ALOGE("in->channel_mask:%d", in->channel_mask); ...... //默认用的是pcm_config_in //struct pcm_config pcm_config_in = { //.channels = 2, //.rate = 44100, //.period_size = 16, //.period_count = 128, //.format = PCM_FORMAT_S16_LE, //}; struct pcm_config *pcm_config = flags & AUDIO_INPUT_FLAG_FAST ? &pcm_config_in_low_latency : &pcm_config_in; in->config = pcm_config; //用pcm_config_in的配置来计算, audio_stream_in_frame_size(&in->stream)调用的是 //in_get_format(),固定是AUDIO_FORMAT_PCM_16_BIT, audio_channel_count_from_out_mask()用来转换 //channel宏定义为实际的number.不过这里有疑问的是这样不是多了一个pcm_config->channels了? //audio_stream_in_frame_size()已经包含了channel了,我觉得它是多申请了. in->buffer = malloc(pcm_config->period_size * pcm_config->channels * audio_stream_in_frame_size(&in->stream)); ...... //当上层采样率和HAL配置的采样率不想等时,要resample,当然,数据最终也是从resample后的buffer中获取. if (in->requested_rate != pcm_config->rate) { //和正常非resample的获取kernel录音数据方式一样. in->buf_provider.get_next_buffer = get_next_buffer; in->buf_provider.release_buffer = release_buffer; ALOGD("pcm_config->rate:%d,in->requested_rate:%d,in->channel_mask:%d", pcm_config->rate,in->requested_rate,audio_channel_count_from_in_mask(in->channel_mask)); ret = create_resampler(pcm_config->rate, in->requested_rate, audio_channel_count_from_in_mask(in->channel_mask), RESAMPLER_QUALITY_DEFAULT, &in->buf_provider, &in->resampler); if (ret != 0) { ret = -EINVAL; goto err_resampler; } } ...... *stream_in = &in->stream; return 0; ...... }
上层通过in_get_buffer_size()来获取buffer size
static size_t in_get_buffer_size(const struct audio_stream *stream) { struct stream_in *in = (struct stream_in *)stream; ALOGE("in_get_buffer_size"); //还是和前面说的一样, 第一请求用的是audio_policy.conf中的值. //in->requested_rate=48kHz //audio_channel_count_from_in_mask(in_get_channels(stream))在前面被固定了,因此为2. return get_input_buffer_size(in->requested_rate, AUDIO_FORMAT_PCM_16_BIT, audio_channel_count_from_in_mask(in_get_channels(stream)), (in->flags & AUDIO_INPUT_FLAG_FAST) != 0); } static size_t get_input_buffer_size(unsigned int sample_rate, audio_format_t format, unsigned int channel_count, bool is_low_latency) { const struct pcm_config *config = is_low_latency ? &pcm_config_in_low_latency : &pcm_config_in; size_t size; //考虑了对齐以及采样率不一致的因素. size = (config->period_size * sample_rate) / config->rate; size = ((size + 15) / 16) * 16; //一次采样的大小就是period size * channel * format. return size * channel_count * audio_bytes_per_sample(format); }