ALSA声卡之PCM设备

目录

1.核心数据结构

1.1 alsa中的数据结构

1.1.1 struct snd_pcm

1.1.2 struct snd_pcm_str

1.1.3 struct snd_pcm_substream

1.1.4 snd_pcm_hw_params 

1.2 asoc中的数据结构

1.2.1 snd_soc_pcm_stream

1.2.2 snd_soc_pcm_runtime 

2.核心API

2.1 ALSA创建PCM设备(snd_pcm_new)

2.1.1 snd_pcm_new_stream

2.1.2 snd_pcm_stream_proc_init

2.1.3 snd_pcm_dev_register

2.1.4 时序图

3.PCM设备文件

3.1 在应用层打开pcm设备

3.1.1  snd_pcm_open_substream

3.1.2 soc_pcm_open

3.2 应用层调用ioctl函数

3.2.1 snd_pcm_ioctl

3.2.2 snd_pcm_common_ioctl


1.核心数据结构

1.1 alsa中的数据结构

1.1.1 struct snd_pcm

pcm使用struct pcm_new数据结构来描述,一个pcm实例由一个playback stream和一个capture stream组成,这两个stream又分别由一个或多个substream组成

snd_pcm的数据结构定义在include/sound/pcm.h

struct snd_pcm {
	struct snd_card *card;    //声卡设备
	struct list_head list;
	int device; /* device number */    //pcm设备编号
	unsigned int info_flags;
	unsigned short dev_class;
	unsigned short dev_subclass;
	char id[64];
	char name[80];
	struct snd_pcm_str streams[2];    /*数组长度为2,strams[0]指向playback stream设备,                    
                                      stream[1]指向capture stream设备*/
	struct mutex open_mutex;
	wait_queue_head_t open_wait;
	void *private_data;
	void (*private_free) (struct snd_pcm *pcm);
	bool internal; /* pcm is for internal use only */
	bool nonatomic; /* whole PCM operations are in non-atomic context */
	bool no_device_suspend; /* don't invoke device PM suspend */
#if IS_ENABLED(CONFIG_SND_PCM_OSS)
	struct snd_pcm_oss oss;
#endif
};

1.1.2 struct snd_pcm_str

struct snd_pcm_str用于表示pcm stream,定义在include/sound/pcm.h

struct snd_pcm_str {
   
	int stream;				 /*stream 类型,SNDRV_PCM_STREAM_PLAYBACK表示播放,        
                              SNDRV_PCM_STREAM_CAPTURE表示录音*/
	struct snd_pcm *pcm;     //指向pcm设备
	/* -- substreams -- */
	unsigned int substream_count;    //substreamn的个数
	unsigned int substream_opened;    //substream的打开标志
	struct snd_pcm_substream *substream;    /*保存所有的substream,snd_pcm_substream 是一个链                                            
                                             表节点类的数据结构*/
#if IS_ENABLED(CONFIG_SND_PCM_OSS)
	/* -- OSS things -- */
	struct snd_pcm_oss_stream oss;
#endif
#ifdef CONFIG_SND_VERBOSE_PROCFS
	struct snd_info_entry *proc_root;
#ifdef CONFIG_SND_PCM_XRUN_DEBUG
	unsigned int xrun_debug;	/* 0 = disabled, 1 = verbose, 2 = stacktrace */
#endif
#endif
	struct snd_kcontrol *chmap_kctl; /* channel-mapping controls */
	struct device dev;        //设备驱动模型中的deice,可以将snd_pcm_str看作其子类
};

1.1.3 struct snd_pcm_substream

struct snd_pcm_substream用于表示pcm的substream,定义在include/sound/pcm.h

struct snd_pcm_substream {
	struct snd_pcm *pcm;    //pcm设备
	struct snd_pcm_str *pstr;
	void *private_data;		/* copied from pcm->private_data */
	int number;
	char name[32];			/* substream name */
	int stream;			/* stream (direction) */
	struct pm_qos_request latency_pm_qos_req; /* pm_qos request */
	size_t buffer_bytes_max;	/* limit ring buffer size */
	struct snd_dma_buffer dma_buffer;
	size_t dma_max;
	/* -- hardware operations -- */
	const struct snd_pcm_ops *ops;    /*pcm操作集,这部分的实际操作需要实现者的参与,留给实现            
                                        者的函数指针集,user空间通过alsa-lib来对驱动的请求就        
                                        是由这个结构中的函数处理*/
  	/* -- runtime information -- */
	struct snd_pcm_runtime *runtime;    //记录这个substream的一些重要的软件和硬件参数
        /* -- timer section -- */
	struct snd_timer *timer;		/* timer */
	unsigned timer_running: 1;	/* time is running */
	long wait_time;	/* time in ms for R/W to wait for avail */
	/* -- next substream -- */
	struct snd_pcm_substream *next;    //指向下一个substream,用于将多个substream连接在一起
	/* -- linked substreams -- */
	struct list_head link_list;	/* linked list member */
	struct snd_pcm_group self_group;	/* fake group for non linked substream (with substream lock inside) */
	struct snd_pcm_group *group;		/* pointer to current group,用户可以通过        
                                           SNDRV_PCM_IOCTL_LINK将多个substream连接起来,然            
                                           后对这些substream做统一操作*/
	/* -- assigned files -- */
	int ref_count;
	atomic_t mmap_count;
	unsigned int f_flags;
	void (*pcm_release)(struct snd_pcm_substream *);
	struct pid *pid;
#if IS_ENABLED(CONFIG_SND_PCM_OSS)
	/* -- OSS things -- */
	struct snd_pcm_oss_substream oss;
#endif
#ifdef CONFIG_SND_VERBOSE_PROCFS
	struct snd_info_entry *proc_root;
#endif /* CONFIG_SND_VERBOSE_PROCFS */
	/* misc flags */
	unsigned int hw_opened: 1;
#ifdef CONFIG_AUDIO_QGKI
	spinlock_t runtime_lock;
#endif
	unsigned int hw_no_buffer: 1; /* substream may not have a buffer */
};

1.1.4 snd_pcm_hw_params 

struct snd_pcm_hw_params是用于配置硬件参数的结构体,比如通道数,采样率,数据格式等

/* SoC PCM stream information */
struct snd_soc_pcm_stream {
	const char *stream_name;
	u64 formats;			/* SNDRV_PCM_FMTBIT_* */
	unsigned int rates;		/* SNDRV_PCM_RATE_* */
	unsigned int rate_min;		/* min rate */
	unsigned int rate_max;		/* max rate */
	unsigned int channels_min;	/* min channels */
	unsigned int channels_max;	/* max channels */
	unsigned int sig_bits;		/* number of bits of content */
	const char *aif_name;		/* DAPM AIF widget name */
};

1.2 asoc中的数据结构

1.2.1 snd_soc_pcm_stream

struct snd_soc_pcm_stream是ASoc中定义的pcm stream,定义在include/sound/soc.h,用于描述soc pcm stream的信息

/* SoC PCM stream information */
struct snd_soc_pcm_stream {
	const char *stream_name;
	u64 formats;			/* SNDRV_PCM_FMTBIT_* */
	unsigned int rates;		/* SNDRV_PCM_RATE_* */
	unsigned int rate_min;		/* min rate */
	unsigned int rate_max;		/* max rate */
	unsigned int channels_min;	/* min channels */
	unsigned int channels_max;	/* max channels */
	unsigned int sig_bits;		/* number of bits of content */
	const char *aif_name;		/* DAPM AIF widget name */
};

   ▪ stream_name:stream的名称

   ▪ formats:位深度,也就是数据传输的位宽

   ▪ rates:音频采样率

   ▪ rate_min:最低采样率

   ▪ rate_max:最高采样率

   ▪ channels_min:最小的通道数

   ▪ channels_max:最大的通道数

   ▪ sig_bits:采样位宽

1.2.2 snd_soc_pcm_runtime 

struct snd_soc_pcm_runtime 是ASoc中定义的pcm runtime,定义在include/sound/soc.h,

这个结构非常重要,在注册ASoc声卡的时候会调用soc_new_pcm_runtime为每一个音频数据链路(struct snd_soc_dai_link)分配一个snd_soc_pcm_runtime,snd_soc_pcm_runtime是ASoc的桥梁,保存音频数据链路的dai,以及dai所属的component等信息

/* SoC machine DAI configuration, glues a codec and cpu DAI together */
struct snd_soc_pcm_runtime {
	struct device *dev;
	struct snd_soc_card *card;
	struct 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值