Android Audio系统分析(三)写驱动

这里直接从hardware层开始分析

hardware/rockchip/audio/legacy_hal/AudioHardware.cpp

1
2
ssize_t AudioHardware::AudioStreamOutALSA::write(const void* buffer, size_t bytes)
ret = pcm_write(mHardware->getPcm(),(void*) p, bytes);

hardware/rockchip/audio/legacy_hal/alsa_pcm.c

1
2
int pcm_write(struct pcm *pcm, void *data, unsigned count)
if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_WRITEI_FRAMES, &x)) {

#define SNDRV_PCM_IOCTL_WRITEI_FRAMES _IOW('A', 0x50, struct snd_xferi)

这里可以看到,Audio通过了ioctl控制进入驱动层写数据

那么再找找pcm->fd是哪个节点

hardware/rockchip/audio/legacy_hal/alsa_pcm.c

1
2
3
4
5
6
struct pcm *pcm_open(unsigned flags) {
const char *dfmt = "/dev/snd/pcmC%uD%u%c";
sprintf(dname, dfmt, card, device, flags & PCM_IN ? 'c' : 'p');
pcm->fd = open(dname, O_RDWR|O_CLOEXEC);
// ...
}

上面我打印,得到的路经是 /dev/snd/pcmC0D0p,路经位置可以进入adb shell来验证
ioctl用法参考:http://blog.sina.com.cn/s/blog_ba08e8e00101bw4e.html
http://www.cnblogs.com/geneil/archive/2011/12/04/2275372.html

接下来就是看驱动层是怎么通过ioctl来实现播放声音的

1
2
# cd kernel/sound
# grep pcmC -nr .

kernel/sound/core/pcm.c, 但是发现不是在里,后面我是通过宏来定位地方的,整体目录还是在这core里的

include/uapi/sound/asound.h
#define SNDRV_PCM_IOCTL_WRITEI_FRAMES _IOW('A', 0x50, struct snd_xferi)

kernel/sound/core/pcm_native.c

1
2
3
4
5
6
7
8
9
static int snd_pcm_playback_ioctl1(struct file *file,
struct snd_pcm_substream *substream,
unsigned int cmd, void __user *arg)
{
switch (cmd) {
case SNDRV_PCM_IOCTL_WRITEI_FRAMES:
// 具体不研究了,估计就这样映入codec内存寄存器了
result = snd_pcm_lib_write(substream, xferi.buf, xferi.frames);
__put_user(result, &_xferi->result);

总结,通过hw层写byte数据,然后通过ioctl定位至驱动层,写入相应寄存器发声,大致一对一的关系

文章作者: 二十I邊界
文章链接: https://xuie0000.com/post/2016-10-24-2019/Android-Audio系统分析(三)写驱动.html
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 二十I邊界