目录
1.1.3 struct snd_pcm_substream
2.1.2 snd_pcm_stream_proc_init
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