ALSA学习(3)——声卡的创建
创始人
2024-05-30 23:42:20
0

文章目录

  • 一、声卡的属性
  • 二、声卡的创建

许久没有更新关于audio的东西了,因为项目原因,接下来又要继续搞audio的东西了,所以继续写一些文章,作为一个温故知新的过程吧。
首先看一下声卡的架构驱动把

一、声卡的属性

开源代码路径

struct snd_card {int number;         /* number of soundcard (index to snd_cards) */char id[16];            /* id string of this card */char driver[16];        /* driver name */char shortname[32];     /* short name of this soundcard */char longname[80];      /* name of this soundcard */char irq_descr[32];     /* Interrupt description */char mixername[80];     /* mixer name */char components[128];       /* card components delimited with space */struct module *module;      /* top-level module */void *private_data;     /* private data for soundcard */void (*private_free) (struct snd_card *card); /* callback for freeing of  private data */struct list_head devices;   /* devices */struct device ctl_dev;      /* control device */unsigned int last_numid;    /* last used numeric ID */struct rw_semaphore controls_rwsem; /* controls list lock */rwlock_t ctl_files_rwlock;  /* ctl_files list lock */int controls_count;     /* count of all controls */int user_ctl_count;     /* count of all user controls */struct list_head controls;  /* all controls for this card */struct list_head ctl_files; /* active control files */struct snd_info_entry *proc_root;   /* root for soundcard specific files */struct proc_dir_entry *proc_root_link;  /* number link to real id */struct list_head files_list;    /* all files associated to this card */struct snd_shutdown_f_ops *s_f_ops; /* file operations in the shutdown state */spinlock_t files_lock;      /* lock the files for this card */int shutdown;           /* this card is going down */struct completion *release_completion;struct device *dev;     /* device assigned to this card */struct device card_dev;     /* cardX object for sysfs */const struct attribute_group *dev_groups[4]; /* assigned sysfs attr */bool registered;        /* card_dev is registered? */int sync_irq;           /* assigned irq, used for PCM sync */wait_queue_head_t remove_sleep;size_t total_pcm_alloc_bytes;   /* total amount of allocated buffers */struct mutex memory_mutex;  /* protection for the above */
#ifdef CONFIG_PMunsigned int power_state;   /* power state */wait_queue_head_t power_sleep;
#endif
#if IS_ENABLED(CONFIG_SND_MIXER_OSS)struct snd_mixer_oss *mixer_oss;int mixer_oss_change_count;
#endifANDROID_KABI_RESERVE(1);ANDROID_KABI_RESERVE(2);
};

这里面每个参数都有对应的说明,比较重要的应该就是两个连表

struct list_head devices;   /* devices */ //记录该声卡下所有逻辑设备的链表 
struct list_head controls;  /* all controls for this card */ //记录该声卡下所有的控制单元的链表
struct list_head ctl_files; /* active control files */ // 用于管理该card下的active的control设备

这些从代码来看就是定义好了的,没有什么问题需要去修改。

二、声卡的创建

以前是通过 snd_card_create 去创建一个声卡,随着kernel的版本迭代,现在已经变为了 snd_card_new,具体是在哪个版本更新的不知道。这个可能需要注意以下。
基本上创建声卡的函数都是在驱动的probe函数里,
不同的平台可能函数也有一些不一样,这个大家得注意。

xxx_probe {error = snd_card_new(dev, index[n], id[n], THIS_MODULE,sizeof(struct snd_es1688), &card);
}
/*
这里面会传递一些参数dev  				总线index          	 	一个整数值,该声卡的编号id                		字符串,声卡的标识符第四个参数    	该参数决定在创建snd_card实例时,需要同时额外分配的私有数据的大小,该数据的指针最终会赋值给snd_card的private_data数据成员card             		返回所创建的snd_card实例的指针
*/

开源代码说明

声卡的专用数据主要用于存放该声卡的一些资源信息,例如中断资源、io资源、dma资源等.可以有两种创建方法:
通过上一步中snd_card_create()中的第四个参数,让snd_card_create自己创建

In general, there are two ways of allocating the chip record.1. Allocating via :c:func:`snd_card_new()`.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~As mentioned above, you can pass the extra-data-length to the 5th
argument of :c:func:`snd_card_new()`, i.e.::err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,sizeof(struct mychip), &card);struct mychip is the type of the chip record.In return, the allocated record can be accessed as::struct mychip *chip = card->private_data;With this method, you don't have to allocate twice. The record is
released together with the card instance.2. Allocating an extra device.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~After allocating a card instance via :c:func:`snd_card_new()`
(with ``0`` on the 4th arg), call :c:func:`kzalloc()`.::struct snd_card *card;struct mychip *chip;err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,0, &card);.....chip = kzalloc(sizeof(*chip), GFP_KERNEL);The chip record should have the field to hold the card pointer at least,::struct mychip {struct snd_card *card;....};Then, set the card pointer in the returned chip instance.::chip->card = card;Next, initialize the fields, and register this chip record as a
low-level device with a specified ``ops``,::static const struct snd_device_ops ops = {.dev_free =        snd_mychip_dev_free,};....snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);:c:func:`snd_mychip_dev_free()` is the device-destructor
function, which will call the real destructor.::static int snd_mychip_dev_free(struct snd_device *device){return snd_mychip_free(device->device_data);}where :c:func:`snd_mychip_free()` is the real destructor.The demerit of this method is the obviously more amount of codes.
The merit is, however, you can trigger the own callback at registering
and disconnecting the card via setting in snd_device_ops.
About the registering and disconnecting the card, see the subsections
below.

英语不好读起来真的吃力阿 。。。

第一种方法相对来说会简单一些,不需要释放两次内存

然后就是设置driver的ID和名字

              strcpy(card->driver, "My Chip");strcpy(card->shortname, "My Own Chip 123");sprintf(card->longname, "%s at 0x%lx irq %i",card->shortname, chip->port, chip->irq);

snd_card的driver字段保存着芯片的ID字符串,user空间的alsa-lib会使用到该字符串,所以必须要保证该ID的唯一性.shortname字段更多地用于打印信息,longname字段则会出现在/proc/asound/cards中.

当一个声卡注册完毕过后,就会去注册这些声卡的功能,包括Mixer和PCM这些,
而这些都是通过各个函数创建的

比如这种:

err = snd_pcm_new(chip->card, "My Chip", 0, 1, 1, &pcm);

在上面那个开源的文章里面,有很多例子,可以仔细去看看。
当所有的东西都农好了过后,最后就把这个声卡注册上去。

             /* (6) */err = snd_card_register(card);if (err < 0)goto error;

当使用完毕过后再释放这个声卡

/* (7) */pci_set_drvdata(pci, card);dev++;return 0;

内核文档真的写的很详细,有时间还是需要自己多去看看。

相关内容

热门资讯

藏海花2什么时候出书 藏海花2什么时候出书藏海花是南派三叔继《盗墓笔记》之后又一力作,故事从《盗墓笔记》故事结束后的第五个...
儿童绕口令大全100首 儿童绕口令大全100首 1、树上一只鸟,地上一只猫。地上的猫想咬树上的鸟,树上的鸟想啄猫的毛。2、小...
牛顿发现万有引力的故事 牛顿发现万有引力的故事1
有趣的发现教学设计 有趣的发现教学设计有趣的发现教学设计有趣的发现教学设计
请问新概念英语第一册的英语单词... 请问新概念英语第一册的英语单词,是英音,还是美音?急~~~~~!请问describe是读英音还是美音...
求,冀教版四年级上册的英语教案... 求,冀教版四年级上册的英语教案!新版的,第1课是Skirt and Pants.我们这还没有发书,新...
《三生三世十里桃花》白浅为什么... 《三生三世十里桃花》白浅为什么恨夜华 素素失去双眼原因是什么素素失去双眼,是因为被素锦陷害,让人认为...
摩羯男爱一个人的表现 准到爆 摩羯男爱一个人的表现 准到爆摩羯座真正爱一个人会告诉你内心的秘密摩羯座是非常内敛的一个星座,不轻易和...
我是大二学生,准备大三考研,不... 我是大二学生,准备大三考研,不知道该注意什么准备什么,请给点建议~不知道你考不考数学?英语和数学是公...
小孩不愿意读书怎么办? 小孩不愿意读书怎么办?采取聊天的方式,了解孩子的内心的想法,成为孩子的朋友,慢慢告诉她读书的重要性。...
双鱼座喜欢和别人搞暧昧关系吗? 双鱼座喜欢和别人搞暧昧关系吗?双鱼座面对别人的追求,会不接受也不拒绝吗?... 双鱼座面对别人的追...
彩虹岛工程师用什么斗兽装备好 彩虹岛工程师用什么斗兽装备好体力斗兽吧,饰品用幸运的。
伤心童话中刘同得的什么病 伤心童话中刘同得的什么病淋巴癌晚期。
楚留香传奇,秋瓷炫-石观音和琳... 楚留香传奇,秋瓷炫-石观音和琳琅在哪一集出现,总共出现在多少集,我指的是央视播的?从第十四集到第三十...
用英语怎莫说 你是天使? 用英语怎莫说 你是天使?你是天使吗?ARE YOU ANGEL?Are you an angelho...
最小的是? 最小的是?面积最小的是北冰洋
刻舟求剑的含义是什么 刻舟求剑的含义是什么 刻舟求剑,比喻事物已发生变化而仍静止地看待问题。是《吕氏春秋·察今》吕不韦记...
大学考试成绩,当学生干部,拿奖... 大学考试成绩,当学生干部,拿奖助学金都靠关系,我受不了这样的环境个人觉得,要是你做到自己应该做的了,...
以第三人称写小说,人物的心理描... 以第三人称写小说,人物的心理描写要怎样写?是要描写仰或是不要?如果要,怎样写更好?以第三人称来写,最...
中秋佳节演讲稿 中秋佳节演讲稿第一个回答我知道,我们班同学已讲过了 中秋之夜,月圆如镜,月华如洗.当家家户户摆出月...