ASOC machine部分工作

嵌入式linux ASoC架构声卡驱动开发 嵌入式linux ASoC架构声卡驱动开发 文章目录嵌入式linux ASoC架构声卡驱动开发需求分析ASoC架构下声卡驱动代码结构codec驱动snd_soc_register_codec分析平台驱动板驱动devm_snd_soc_register_card函数分析 需求分析 基于linux操作系统,使用ASoC框架,将系统中的音频文件从扬声器中播放出来。 首先,各种格式的音频文件,mp3,wav,FLAC,都是将模拟量以一定的规范进行了编码,才能保存下来的,所以对应的你需要一个播放器。播放器会将音频解 阅读详情

由前面可知,ASoC被分为Machine、Platform和Codec三大部分,其中的Machine驱动负责Platform和Codec之间的耦合以及部分和设备或板子特定的代码,Machine为CPU、Codec、输入输出设备提供了一个载体。单独的Platform和Codec驱动是不能工作的,它必须由Machine驱动把它们结合在一起才能完成整个设备的音频处理工作。ASoC的一切都从Machine驱动开始,包括声卡的注册,绑定Platform和Codec驱动等等。

Machine关键数据结构如下

//代表 Machine
struct snd_soc_card 

//rtd 记录单个完整链路的组成信息(codec,platform,dais)
struct snd_soc_pcm_runtime *rtd;

//用于创建CPU DAI 和 Codec DAI的连接
struct snd_soc_dai_link

以WM8994的一款Samsung的开发板SMDK为例子做说明,WM8994是一颗Wolfson生产的多功能Codec芯片。

kernel\sound\soc\samsung\smdk_wm8994.c

/*
 * SMDK WM8994 DAI operations.
 */
static struct snd_soc_ops smdk_ops = {
	.hw_params = smdk_hw_params,
};

/*
指定了Platform、Codec、codec_dai、cpu_dai的名字
稍后Machine驱动将会利用这些名字去匹配已经在系统中注册的platform,codec,dai
*/
static struct snd_soc_dai_link smdk_dai[] = {
	{ /* Primary DAI i/f */
		.name = "WM8994 AIF1",
		.stream_name = "Pri_Dai",
		.cpu_dai_name = "samsung-i2s.0",
		.codec_dai_name = "wm8994-aif1",
		.platform_name = "samsung-i2s.0",
		.codec_name = "wm8994-codec",
		.init = smdk_wm8994_init_paiftx,
		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
			SND_SOC_DAIFMT_CBM_CFM,
		.ops = &smdk_ops,
	}, { /* Sec_Fifo Playback i/f */
		.name = "Sec_FIFO TX",
		.stream_name = "Sec_Dai",
		.cpu_dai_name = "samsung-i2s-sec",
		.codec_dai_name = "wm8994-aif1",
		.platform_name = "samsung-i2s-sec",
		.codec_name = "wm8994-codec",
		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
			SND_SOC_DAIFMT_CBM_CFM,
		.ops = &smdk_ops, //!!!
	},
};

//machine 
static struct snd_soc_card smdk = {
	.name = "SMDK-I2S",
	.owner = THIS_MODULE,
	.dai_link = smdk_dai, //snd_soc_dai_link
	.num_links = ARRAY_SIZE(smdk_dai),//2
};


static int smdk_audio_probe(struct platform_device *pdev)
{
	
	struct snd_soc_card *card = &smdk;
	
	card->dev = &pdev->dev;
	
	/*
		struct platform_device *pdev
			struct device	dev;

		struct snd_soc_card *card
	*/
	ret = devm_snd_soc_register_card(&pdev->dev, card);
	
}


static struct platform_driver smdk_audio_driver = {
	.driver		= {
		.name	= "smdk-audio-wm8994",
		.of_match_table = of_match_ptr(samsung_wm8994_of_match),
		.pm	= &snd_soc_pm_ops,
	},
	.probe		= smdk_audio_probe,
};

module_platform_driver(smdk_audio_driver);

kernel\sound\soc\soc-devres.c

/*
	struct platform_device *pdev
		struct device	dev;

	struct snd_soc_card *card
*/
int devm_snd_soc_register_card(struct device *dev, struct snd_soc_card *card)
{
	struct snd_soc_card **ptr;
	int ret;

	ptr = devres_alloc(devm_card_release, sizeof(*ptr), GFP_KERNEL);
	if (!ptr)
		return -ENOMEM;

	ret = snd_soc_register_card(card);
	if (ret == 0) {
		*ptr = card;
		devres_add(dev, ptr);
	} else {
		devres_free(ptr);
	}

	return ret;
}
EXPORT_SYMBOL_GPL(devm_snd_soc_register_card);




/**
 * snd_soc_register_card - Register a card with the ASoC core
 *
 * @card: Card to register
 *
 */
int snd_soc_register_card(struct snd_soc_card *card)
{
	int i, ret;
	struct snd_soc_pcm_runtime *rtd;

	if (!card->name || !card->dev)
		return -EINVAL;

...

	//初始化 rtd_list链表
	INIT_LIST_HEAD(&card->rtd_list);
	card->num_rtd = 0;

...

	ret = snd_soc_instantiate_card(card);
	if (ret != 0)
		return ret;

...
	return ret;
}
EXPORT_SYMBOL_GPL(snd_soc_register_card);

//主要工作就在这里 !!!

static int snd_soc_instantiate_card(struct snd_soc_card *card)
{
	struct snd_soc_pcm_runtime *rtd;
	struct snd_soc_dai_link *dai_link;
	int ret, i, order;

...
	/* bind DAIs */
	//1 根据指定 的 codec platform 的 dai name信息 查找已经注册的目标dai, 并得到其所属的组件(codec platform)。全部整到 snd_soc_pcm_runtime 
	for (i = 0; i < card->num_links; i++) {
		
		/*
		根据snd_soc_dai_link结构体中的name,到全局组件链表中找到相应的  codec_dai, cpu_dai。platform 找到之后将这些 以及 所属的 codec,platform 全部放入结构体 snd_soc_pcm_runtime 的相应位置
		很明显 本例程有两个dai_link 即会填充两个 rtd
		所以 rtd 就是用来记录单个链路(codec,platform,dais)的信息
		*/
		ret = soc_bind_dai_link(card, &card->dai_link[i]);
		
	}

...
	//2 创建声卡逻辑设备  类型:control
	/* card bind complete so register a sound card */
	ret = snd_card_new(card->dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
			card->owner, 0, &card->snd_card);
	if (ret < 0) {
		dev_err(card->dev,
			"ASoC: can't create sound card for card %s: %d\n",
			card->name, ret);
		goto base_error;
	}

...


	/* probe all components used by DAI links on this card */
	//3 调用 platform  codec  的probe()
	for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
			order++) {
		//很明显 本例程rtd_list链表上有两个 rtd 
		list_for_each_entry(rtd, &card->rtd_list, list) {
			ret = soc_probe_link_components(card, rtd, order);
			if (ret < 0) {
				dev_err(card->dev,
					"ASoC: failed to instantiate card %d\n",
					ret);
				goto probe_dai_err;
			}
		}
	}

	...



	/* probe all DAI links on this card */
	//4 调用 platform codec 的 DAIS probe()
	for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
			order++) {
		list_for_each_entry(rtd, &card->rtd_list, list) {
			ret = soc_probe_link_dais(card, rtd, order);
			if (ret < 0) {
				dev_err(card->dev,
					"ASoC: failed to instantiate card %d\n",
					ret);
				goto probe_dai_err;
			}
		}
	}
	
	...
	
	//5 注册声卡
	ret = snd_card_register(card->snd_card);
	if (ret < 0) {
		dev_err(card->dev, "ASoC: failed to register soundcard %d\n",
				ret);
		goto probe_aux_dev_err;
	}


	...
	return ret;
}

这里简单说说明一下 工作1和工作2。

工作1:
根据指定 的 codec platform 的 dai name信息 查找已经注册的目标dai, 并得到其所属的组件(codec platform)。全部整到 snd_soc_pcm_runtime

static int soc_bind_dai_link(struct snd_soc_card *card,
	struct snd_soc_dai_link *dai_link)
{
	struct snd_soc_pcm_runtime *rtd;
	struct snd_soc_dai_link_component *codecs = dai_link->codecs;
	struct snd_soc_dai_link_component cpu_dai_component;
	struct snd_soc_component *component;
	struct snd_soc_dai **codec_dais;
	struct device_node *platform_of_node;
	const char *platform_name;
	int i;

	if (dai_link->ignore)
		return 0;

	dev_dbg(card->dev, "ASoC: binding %s\n", dai_link->name);

	if (soc_is_dai_link_bound(card, dai_link)) {
		dev_dbg(card->dev, "ASoC: dai link %s already bound\n",
			dai_link->name);
		return 0;
	}

//创建 snd_soc_pcm_runtime
	rtd = soc_new_pcm_runtime(card, dai_link);
	if (!rtd)
		return -ENOMEM;

/*
在已注的组件链表中 遍历所有组件。依次遍历每一个组件的 dai list 链表。查找目标名字的 cpu_dai
*/
	cpu_dai_component.name = dai_link->cpu_name;
	cpu_dai_component.of_node = dai_link->cpu_of_node;
	cpu_dai_component.dai_name = dai_link->cpu_dai_name;
	rtd->cpu_dai = snd_soc_find_dai(&cpu_dai_component);
	if (!rtd->cpu_dai) {
		dev_info(card->dev, "ASoC: CPU DAI %s not registered\n",
			 dai_link->cpu_dai_name);
		goto _err_defer;
	}
	snd_soc_rtdcom_add(rtd, rtd->cpu_dai->component);

	rtd->num_codecs = dai_link->num_codecs;

	/* Find CODEC from registered CODECs */
	codec_dais = rtd->codec_dais;
	for (i = 0; i < rtd->num_codecs; i++) {
		codec_dais[i] = snd_soc_find_dai(&codecs[i]);
		if (!codec_dais[i]) {
			dev_err(card->dev, "ASoC: CODEC DAI %s not registered\n",
				codecs[i].dai_name);
			goto _err_defer;
		}
		snd_soc_rtdcom_add(rtd, codec_dais[i]->component);
	}

	/* Single codec links expect codec and codec_dai in runtime data */
	rtd->codec_dai = codec_dais[0];

	/* if there's no platform we match on the empty platform */
	platform_name = dai_link->platform_name;
	if (!platform_name && !dai_link->platform_of_node)
		platform_name = "snd-soc-dummy";

	/* find one from the set of registered platforms */
	list_for_each_entry(component, &component_list, list) {
		platform_of_node = component->dev->of_node;
		if (!platform_of_node && component->dev->parent->of_node)
			platform_of_node = component->dev->parent->of_node;

		if (dai_link->platform_of_node) {
			if (platform_of_node != dai_link->platform_of_node)
				continue;
		} else {
			if (strcmp(component->name, platform_name))
				continue;
		}

		snd_soc_rtdcom_add(rtd, component);
	}

	soc_add_pcm_runtime(card, rtd);
	return 0;

_err_defer:
	soc_free_pcm_runtime(rtd);
	return  -EPROBE_DEFER;
}


/** 搜索所有已注册的组件 和 DAIs
 * snd_soc_find_dai - Find a registered DAI
 *
 * @dlc: name of the DAI or the DAI driver and optional component info to match
 
 * 此函数将搜索所有已注册的组件及其DAIs
 * This function will search all registered components and their DAIs to
 * find the DAI of the same name. The component's of_node and name
 * should also match if being specified.
 *
 * Return: pointer of DAI, or NULL if not found.
 */
struct snd_soc_dai *snd_soc_find_dai(
	const struct snd_soc_dai_link_component *dlc)
{
	struct snd_soc_component *component;
	struct snd_soc_dai *dai;
	struct device_node *component_of_node;

	lockdep_assert_held(&client_mutex);

	/* Find CPU DAI from registered DAIs*/
	/*
	component_list 全局组件链表(包含已注册的所有组件以及DAIS)
	*/
	list_for_each_entry(component, &component_list, list) {
		component_of_node = component->dev->of_node;
		if (!component_of_node && component->dev->parent)
			component_of_node = component->dev->parent->of_node;

		if (dlc->of_node && component_of_node != dlc->of_node)
			continue;
		if (dlc->name && strcmp(component->name, dlc->name))
			continue;
		list_for_each_entry(dai, &component->dai_list, list) {
			if (dlc->dai_name && strcmp(dai->name, dlc->dai_name)
			    && (!dai->driver->name
				|| strcmp(dai->driver->name, dlc->dai_name)))
				continue;

			return dai;
		}
	}

	return NULL;
}
EXPORT_SYMBOL_GPL(snd_soc_find_dai);

工作2 创建声卡逻辑设备 类型:control

int snd_card_new(struct device *parent, int idx, const char *xid,
		    struct module *module, int extra_size,
		    struct snd_card **card_ret)
{
	//声卡设备
	struct snd_card *card;
	int err;

	if (snd_BUG_ON(!card_ret))
		return -EINVAL;
	*card_ret = NULL;

	if (extra_size < 0)
		extra_size = 0;
	card = kzalloc(sizeof(*card) + extra_size, GFP_KERNEL);
	if (!card)
		return -ENOMEM;
	if (extra_size > 0)
		card->private_data = (char *)card + sizeof(struct snd_card);

	...
	
	err = snd_ctl_create(card);

	err = snd_info_card_create(card);

	*card_ret = card;
	return 0;

      __error_ctl:
	snd_device_free_all(card);
      __error:
	put_device(&card->card_dev);
  	return err;
}
EXPORT_SYMBOL(snd_card_new);

int snd_ctl_create(struct snd_card *card)
{
	static struct snd_device_ops ops = {
		.dev_free = snd_ctl_dev_free,
		.dev_register =	snd_ctl_dev_register,
		.dev_disconnect = snd_ctl_dev_disconnect,
	};
	int err;

	if (snd_BUG_ON(!card))
		return -ENXIO;
	if (snd_BUG_ON(card->number < 0 || card->number >= SNDRV_CARDS))
		return -ENXIO;

	snd_device_initialize(&card->ctl_dev, card);
	dev_set_name(&card->ctl_dev, "controlC%d", card->number);

	//创建类型为 SNDRV_DEV_CONTROL 的 snd_device,并挂入 snd_card 的devices链表
	err = snd_device_new(card, SNDRV_DEV_CONTROL, card, &ops);
	if (err < 0)
		put_device(&card->ctl_dev);
	return err;
}

整理后
machine codec platform codec_DAI platform_DAI 以及声卡设备 声卡逻辑设备 组成如下关系:

在这里插入图片描述

四、Audio-ALSA框架中的machine驱动 machine简介 ASoC被分为Machine、Platform和Codec三大部分,其中的Machine驱动负责Platform和 Codec之间的耦合以及部分和设备或板子特定的代码,再次引用上一节的内容: Machine驱动负责处理机器特有的一些控件和音频事件(例如,当播放音频时,需要先行打开一个放大器)﹔单独的Platform和Codec驱动是不能工作的,它必须由Machine驱动把它们结合在一起才能完成整个设备的音频处理工作 ASoC的一切都从Machine驱动开始,包括声卡的注册,绑定Platf 阅读详情

相关推荐

三、Audio-ALSA 中的platfrom、machine、codec

一、Linux ALSA 音频系统框架 ● ALSA CORE alsa 核心层,向上提供逻辑设备(PCM/CTL/MIDI/TIMER/…)系统调用,向下驱动硬件设备(Machine/I2S/DMA/CODEC) ● ASoC CORE ASoC:ALSA System on Chip,是建立在标准 ALSA 驱动上,为了更好支持嵌入系系统 和 应用于移动设备的音频 codec 的一套软件体系,它依赖于标准 ALSA 驱动框架。 由三大部分组成,分别是 Machine、Platform、Codec。

一只青木呀 1897

devm_snd_soc_register_card

* dai_link下的component和pcm绑定,就是确定了pcm下cpu dai对应的component和codec dai对应的component。/* 根据dai_link下的codec/cpu/platform去查找对应的component *//* 1. 统计"dai-link"子节点的个数num,也即最终会生成pcm设备的个数 *//* 5.1 遍历声卡下的所有dai_link *//* 3. 解析声卡节点的各个属性,以及每个dai-link子节点的各类属性 */

lihemian的专栏 483

Android音频驱动-ASOC之Machine

欢迎使用Markdown编辑器写博客本Markdown编辑器使用StackEdit修改而来,用它写博客,将会带来全新的体验哦: Markdown和扩展Markdown简洁的语法 代码块高亮 图片链接和图片上传 LaTex数学公式 UML序列图和流程图 离线写博客 导入导出Markdown文件 丰富的快捷键 快捷键 加粗 Ctrl + B 斜体 Ctrl + I 引用 Ctrl

Vincentywj的博客 1360

Linux ALSA驱动:Machine驱动(五)

ASoC被分为Machine、Platform和Codec三大部分,其中的Machine驱动负责Platform和Codec之间的耦合以及部分和设备或板子特定的代码,再次引用之前的内容:Machine驱动负责处理机器特有的一些控件和音频事件(例如,当播放音频时,需要先行打开一个放大器);单独的Platform和Codec驱动是不能工作的,它必须由Machine驱动把它们结合在一起才能完成整个设备的音频处理工作。

m0_51231887的博客 1131

Linux ALSA声卡驱动之五:移动设备中的ALSA(ASoC)

整理自: https://blog.youkuaiyun.com/DroidPhone/article/details/7165482 https://www.cnblogs.com/blogs-of-lxl/p/6538769.html 1. ASoC--ALSA System on Chip:   建立在标准ALSA驱动层上,为了更好地支持嵌入式处理器和移动设备 中的音频Codec的一套软件体系。在ASoc出现之前,内核对于SoC中的音频已经有部分的支持,不过会有 一些局限性:...

qianxuedegushi的博客 1287

GDI文字绘制和windows下opengl文字绘制小结

GDI绘制文字,要设置文字的属性,主要就是通过设置DC中的font对象来实现的。 font对象的创建可以由createfont()、createfontIndirect()来实现。 HFONT CreateFont( int nHeight, // height of font int nWidth, // average

T_W_S的专栏 5321

手撕ALSA和ASOC有感。

手撕ALSA和ASOC有感。 文中图片引用自https://me.youkuaiyun.com/DroidPhone博主的文章。 ALSA ALSA其实就是一个字符设备驱动。万变不离其宗,和其他设备驱动套路一样。 1、首先搞个类:class_create 在sound_core.c中 sound_class = class_create(THIS_MODULE, "sound"); 2、然后搞个f...

多核异构SOC和显示 1677

Ollama最新快速上手指南:从安装到精通本地AI模型部署

想让Ollama跑你的"私房模型"?三种主流格式全支持,总有一款适合你!GGUF格式(推荐新手首选)创建Modelfile文件:执行创建命令:运行你的专属模型:PyTorch/Safetensors格式(适合进阶玩家)先用库测试模型能否正常加载确保模型结构完整后再导入Ollama官方文档有详细转换指南专业小贴士GGUF格式最轻量,PyTorch最灵活,Safetensors最安全遇到问题?试试用llama.cpp进行格式转换7B参数模型推荐使用q4_0量化级别想让AI用马里奥。

全世界的博客 2309

ASoc音频框架驱动小结

以下文章转载于: http://blog.chinaunix.net/uid-20672559-id-3515392.html 在学习asoc之前我们先了解一些专业术语: ASoC currently supportsthe three main Digital Audio Interfaces (DAI) found on SoC controllers and portable

nickol51的专栏 1113

别再凭感觉估算!用ADS的EBOND库精确仿真Bonding线寄生电感(附完整参数设置指南)

本文详细介绍了在ADS中使用EBOND库精确仿真Bonding线寄生电感的方法,帮助射频工程师在毫米波频段实现高精度建模。通过三维物理参数和电磁场求解算法,EBOND模型能将误差控制在5%以内,显著提升电路性能。文章还提供了完整的参数设置指南和实战操作步骤,适用于5G毫米波前端模块等高频应用场景。

weixin_28730131的博客 504

合宙Air780EP速连OneNET:AT+MQTT应用指南

本文详细讲解了合宙Air780EP使用AT指令通过MQTT接入OneNET的过程。

2401_82812461的博客 1388

Linux ALSA声卡驱动之六:ASoC架构中的Machine

linuxcodecplaybacklist数据结构struct 目录(?)[+] 前面一节的内容我们提到,ASoC被分为Machine、Platform和Codec三大部分,其中的Machine驱动负责Platform和Codec之间的耦合以及部分和设备或板子特定的代码,再次引用上一节的内容:Machine驱动负责处理机器特有的一些控件和音频事件(例如,当播放音频

u012498713的专栏 545

为何LPDDR4支持on-die ECC,但是DDR4却不支持呢?

DRAM的ECC,目前的编码方式都是128bit data,产生8bit parity或者ECC code. 而且必须要128bit才行。这8bit的ECC code是要被写入到DRAM内存里面的,从而read的时候,可以读取这8bit ECC code来判定read data是否有错,如果是SBF,就可以纠错了,如果是double bit,大部分时候是可以detect到错误,即所谓的SEC(Single Error Correct) + DED(Double Error Detect).

一个DRAM从业者的告白 1555

嵌入式Linux驱动笔记(十九)------音频子系统(ASOC框架)之Machine

你好!这里是风筝的博客, 欢迎和我一起交流。 我们知道, Linux 内核驱动可以都是遵循一个逐层抽象的架构: 最上层的抽象层便于系统软件的访问, 中间层的实现硬件协议细节,同时提供上下两层连接的接口, 对于最下层的 driver 来说就是要定义底层驱动要实现的接口和实际的设备控制, 由于 Linux 内核各类驱动的框架支持,driver 可以更加关注设备本身的特性。 AS...

风筝 4474

从数据到图片:手把手构建FMCW雷达人体行为识别数据集(行走、跌倒、喝水等6类动作)

本文详细解析了如何利用FMCW雷达构建人体行为识别数据集,涵盖行走、跌倒、喝水等6类动作。通过多普勒特征可视化、图像标准化处理和自动化流水线设计,将原始雷达信号转化为高质量时频图像数据集,为智能家居和健康监护等应用提供可靠数据支持。

weixin_30706691的博客 384

【HALCON工业视觉应用探索】08. C#+Halcon视觉引导机器人抓取:从入门到工业级实战(附完整代码+部署指南)

摘要:本文聚焦C#+Halcon在视觉引导机器人抓取领域的落地应用,从新手友好的“二十分钟基础引导系统”切入,逐步深入工业级场景(汽车变速箱壳体抓取)。内容涵盖核心概念(手眼标定原理、坐标转换、机器人通信协议)、完整技术流程(图像采集→目标定位→标定转换→机器人执行→结果反馈)、工业级代码实现(多目标识别、智能抓取策略、实时状态监控),以及现场部署关键技巧(硬件选型、通信配置、精度优化)。

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 1263

alsa架构分析

前面一节的内容我们提到,ASoC被分为Machine、Platform和Codec三大部分,其中的Machine驱动负责Platform和Codec之间的耦合以及部分和设备或板子特定的代码,再次引用上一节的内容:Machine驱动负责处理机器特有的一些控件和音频事件(例如,当播放音频时,需要先行打开一个放大器);单独的Platform和Codec驱动是不能工作的,它必须由Machine驱动把它们结

haohenghai的专栏 696

【技能】OpenClaw Skills学习及手搓一个极简skill

本文介绍了OpenClaw Skills的基础概念与使用方法。Skills是OpenClaw代理使用工具的核心载体,通过SKILL.md文件定义技能属性和执行方式。技能加载遵循"工作区>本地>内置>自定义目录"的优先级规则。用户可通过ClawHub一键安装现成技能,也可自定义开发技能:创建技能目录,编写包含YAML元数据和执行指令的SKILL.md文件,放置于工作区skills目录进行测试。文章还介绍了多代理场景下的技能共享、插件集成以及安全注意事项,包括沙箱使用和敏感

海兰 3975

alsa 驱动介绍

Machine 以装配有CS4270的一款android 智能电视的为例 /sound/soc/samsung/exynos.c Platform 以Samsung cpu exynos4412为例 /sound/soc/samsung/ Codec 以wolfson的Codec芯片cs4270为例 /sound/soc/codecs/cs4270.c ALSA 框架介绍 Alsa 太多太杂,很难...

zz460833359的博客 1922

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Linux音频驱动-AOSC之Platform

概述在ASOC在Platform部分,主要是平台相关的DMA操作和音频管理。大概流程先将音频数据从内存通过DMA方式传输到CPU侧的dai接口,然后通过CPU的dai接口(通过I2S总线)将数据从达到Codec中,数据会在Codec侧会解码的操作,最终输出到耳机/音箱中。依然已下图作为参考:在platfrom侧的主要功能有:  音频数据管理,音频数据传输通过dma; 数据如何通过cpudai传入到...

zjy900507的博客 336

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

android audio arch

android audio arch ALSA System on Chip(ASoC) ASoC 驱动将一个audio子系统分成四个部分: Machine driver, Platform driver, CPU driver以及Codec driver。 Machine 驱动 将平台,CPU以及codec驱动绑定在一块实现在kernel/sound/soc/msm/定义前端F

shichaog的专栏 3852

android下调试声卡驱动之概述

在Android中音频系统使用的是ALSA系统架构。ASoC--ALSA System on Chip 。是建立在标准ALSA驱动层上,为了更好地支持 嵌入式处理器和移动设备中的音频Codec的一套软件体系。在音频设备驱动中ASoC被分为Machine、Platform和Codec三大部分。 Codec部分:负责音频解码,这部分代码全然无平台无关(设备原厂提供)...

weixin_30892763的博客 202

Linux ALSA音频驱动(二)

Linux ALSA音频驱动(二)http://www.cnblogs.com/cslunatic/archive/2013/05/17/3083239.html 根据一我们发现创建声卡的全过程基本都在snd_soc_instantiate_cards()函数实现。我们要了解声卡的创建过程,就必须了解ASoC的软件架构(详细http://blog.youkuaiyun.com/droid...

weixin_33928467的博客 117

ALSA使用总结

Linux音频驱动个人总结

weixin_41579856的博客 788

Android Audio序列3(分析 )

Android Audio序列3(分析 )---Linux ALSA音频系统分析

ListQ的博客 253
上一篇: Camera启动过程简述(MTK)
下一篇: ALSA之Codec注册过程
Ma浩然
博客等级 码龄9年 1万+粉丝 462原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ma浩然

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值