int snd_pcm_plugin_build(struct snd_pcm_substream *plug,
const char *name,
struct snd_pcm_plugin_format *src_format,
struct snd_pcm_plugin_format *dst_format,
size_t extra,
struct snd_pcm_plugin **ret)
{
struct snd_pcm_plugin *plugin;
unsigned int channels;
if (snd_BUG_ON(!plug))
return -ENXIO;
if (snd_BUG_ON(!src_format || !dst_format))
return -ENXIO;
plugin = kzalloc(sizeof(*plugin) + extra, GFP_KERNEL);
if (plugin == NULL)
return -ENOMEM;
plugin->name = name;
plugin->plug = plug;
plugin->stream = snd_pcm_plug_stream(plug);
plugin->access = SNDRV_PCM_ACCESS_RW_INTERLEAVED;
plugin->src_format = *src_format; // src放音音频量化位数,比如AFMT_U8
plugin->src_width = snd_pcm_format_physical_width(src_format->format); // src放音音频实际量化位数占用位数,字节数*8
snd_BUG_ON(plugin->src_width <= 0);
plugin->dst_format = *dst_format; // dst放音音频量化位数,比如AFMT_U8
plugin->dst_width = snd_pcm_format_physical_width(dst_format->format); // dst放音音频实际量化位数占用位数,字节数*8
snd_BUG_ON(plugin->dst_width <= 0);
if (plugin->stream == SNDRV_PCM_STREAM_PLAYBACK)
channels = src_format->channels; // 如果是放音,那么声道数以src放音声道个数为基准,这样如果src为1个,dst可以复制出3路
else
channels = dst_format->channels; // 如果是录音,那么声道数以dst录音声道个数为基准
plugin->buf_channels = kcalloc(channels, sizeof(*plugin->buf_channels), GFP_KERNEL); // 申请管理channels个声道的控制结构体
if (plugin->buf_channels == NULL) {
snd_pcm_plugin_free(plugin);
return -ENOMEM;
}
plugin->client_channels = snd_pcm_plugin_client_channels; // 返回plugin->buf_channels指针
*ret = plugin;
return 0;
}
阅读(1132) | 评论(0) | 转发(3) |