Audio Stream and Volume Gain
音频outstream简介
audio框架在Android系统中 占据很大用户市场,音频的复杂,Android框架一直在调整中。
看一张高通的音频各个场景的路径:
这张图片来着高通,各个芯片方案路线基本一致。对于HAL上层已经在前面两篇文章进行了分析,这篇重要分析HAL、 Kernel、CODEC寄存器。
用项目RK3399 来理解。
HAL
HAL hardware Layer是与kernel最接近的一层,通过IOCTL与kernel进行通信。将对应的操作封装到厂商动态链接库。
简述如何实现HAL层模块。
先简单介绍重要的三个结构体:
hw_module_t: 描述硬件模块基类
hw_device_t: 描述硬件设备基类
hw_module_methods_t: 打开硬件模块种包含的硬件设备,获得指向硬件设备结构体的指针。
Audio HAL实现步骤
1 struct audio_module
/**
* Every hardware module must have a data structure named HAL_MODULE_INFO_SYM
* and the fields of this data structure must begin with hw_module_t
* followed by module specific information.
*/
struct audio_module {
struct hw_module_t common;
};
定义 audio_module 的 HAL_MODULE_INFO_SYM 变量
struct audio_module HAL_MODULE_INFO_SYM = {
.common = {
.tag = HARDWARE_MODULE_TAG,
.module_api_version = AUDIO_MODULE_API_VERSION_0_1,
.hal_api_version = HARDWARE_HAL_API_VERSION,
.id = AUDIO_HARDWARE_MODULE_ID,
.name = "QCOM Audio HAL",
.author = "The Linux Foundation",
.methods = &hal_module_methods,
},
};
2 struct audio_hw_device
struct audio_hw_device {
/**
* Common methods of the audio device. This *must* be the first member of audio_hw_device
* as users of this structure will cast a hw_device_t to audio_hw_device pointer in contexts
* where it's known the hw_device_t references an audio_hw_device.
*/
struct hw_device_t common;
/** set the audio volume of a voice call. Range is between 0.0 and 1.0 */
int (*set_voice_volume)(struct audio_hw_device *dev, float volume);
int (*set_master_volume)(struct audio_hw_device *dev, float volume);
int (*get_master_volume)(struct audio_hw_device *dev, float *volume);
int (*set_mode)(struct audio_hw_device *dev, audio_mode_t mode);
/* mic mute */
int (*set_mic_mute)(struct audio_hw_device *dev, bool state);
int (*get_mic_mute)(const struct audio_hw_device *dev, bool *state);
/* set/get global audio parameters */
int (*set_parameters)(struct audio_hw_device *dev, const char *kv_pairs);
char * (*get_parameters)(const struct audio_hw_device *dev,
const char *keys);
size_t (*get_input_buffer_size)(const struct audio_hw_device *dev,
const struct audio_config *config);
int (*open_output_stream)(struct audio_hw_device *dev,
audio_io_handle_t handle,
audio_devices_t devices,
audio_output_flags_t flags,
struct audio_config *config,
struct audio_stream_out **stream_out,
const char *address);
void (*close_output_stream)(struct audio_hw_device *dev,
struct audio_stream_out* stream_out);
/** This method creates and opens the audio hardware input stream */
int (*open_input_stream)(struct audio_hw_device *dev,
audio_io_handle_t handle,
audio_devices_t devices,
struct audio_config *config,
struct audio_stream_in **stream_in,
audio_input_flags_t flags,
const char *address,
audio_source_t source);
void (*close_input_stream)(struct audio_hw_device *dev,
struct audio_stream_in *stream_in);
int (*set_master_mute)(struct audio_hw_device *dev, bool mute);
int (*get_master_mute)(struct audio_hw_device *dev, bool *mute);
...
};
audio_hw_device 的定义中,第一个结构体成员就是 struct hw_device_t 类型的,而其他的结构体成员都是函数指针, open_output_stream 函数就是用来打开播放音频的扬声器设备,open_input_stream 函数则是用来打开录音用的麦克风设备。
3 struct hw_module_methods_t 函数列表
hardware\qcom\audio\hal\audio_hw.c
static struct hw_module_methods_t hal_module_methods = {
.open = adev_open,
};
hardware\qcom\audio\hal\audio_hw.c
static int adev_open(const hw_module_t *module, const char *name,
hw_device_t **device)
{
int i, ret;
/hw_device 初始化
adev->device.common.tag = HARDWARE_DEVICE_TAG;
adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
adev->device.common.module = (struct hw_module_t *)module;
adev->device.common.close = adev_close;
/函数列表...
adev->device.init_check = adev_init_check;
adev->device.set_voice_volume = adev_set_voice_volume;
adev->device.set_master_volume = adev_set_master_volume;
adev->device.get_master_volume = adev_get_master_volume;
adev->device.set_master_mute = adev_set_master_mute;
adev->device.get_master_mute = adev_get_master_mute;
adev->device.set_mode = adev_set_mode;
adev->device.set_mic_mute = adev_set_mic_mute;
adev->device.get_mic_mute = adev_get_mic_mute;
adev->device.set_parameters = adev_set_parameters;
adev->device.get_parameters = adev_get_parameters;
adev->device.get_input_buffer_size = adev_get_input_buffer_size;
adev->device.open_output_stream = adev_open_output_stream;
adev->device.close_output_stream = adev_close_output_stream;
adev->device.open_input_stream = adev_open_input_stream;
adev->device.close_input_stream = adev_close_input_stream;
adev->device.dump = adev_dump;
...
return 0
看Audio HAL层时,按照HAL层的三个结构体来看,此方法推广到其它HAL定义。
kernel
这里不再分析ALSA中 codec driver ,platform driver 和machine driver .
来两个其他case