惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

B
Blog RSS Feed
B
Blog
N
Netflix TechBlog - Medium
量子位
月光博客
月光博客
博客园_首页
博客园 - Franky
酷 壳 – CoolShell
酷 壳 – CoolShell
Last Week in AI
Last Week in AI
T
The Blog of Author Tim Ferriss
Hugging Face - Blog
Hugging Face - Blog
雷峰网
雷峰网
M
MIT News - Artificial intelligence
J
Java Code Geeks
大猫的无限游戏
大猫的无限游戏
D
DataBreaches.Net
腾讯CDC
Engineering at Meta
Engineering at Meta
云风的 BLOG
云风的 BLOG
L
LangChain Blog
GbyAI
GbyAI
IT之家
IT之家
Y
Y Combinator Blog
人人都是产品经理
人人都是产品经理

博客园 - 酸辣大白菜

排序算法 终结版 (C#) --数据结构 做人学会说NO,写程序学会说NULL。----------设计模式 用于主题检测的临时日志(bf1783d2-27ab-4079-a1c6-08a661824368 - 3bfe001a-32de-4114-a6b4-4005b770f6d7) windows mobile网络设备 ------------- DMProcessConfigXML android 系统配置 常用命令 - linux qt 信号与槽机制 用于主题检测的临时日志(b9c62a98-6395-4fa6-b30d-70521beaf329 - 3bfe001a-32de-4114-a6b4-4005b770f6d7) 无绳电话系统 C++ 数据类型转换 关于内存泄漏检测 发布一个边看电子书边听英语的小工具 C++ 工厂模式 xml 解析库 msxml6.dll IE 8 与vs2005的兼容性问题 c++ vector用法 关于msxml.dll download WM6.5.3 SDK about CreateFileMapping on wince about MarshalledBuffer
音频驱动的3种模式
酸辣大白菜 · 2010-05-11 · via 博客园 - 酸辣大白菜

音频驱动有3种模式:1.MDD/PDD模式.2.Wavedev2模式.3.UAM模式

它们相同的地方很明显:它们公开相同的接口,因为是流驱动!都是透过流接口与上层的waveapi.dll交互.接着,细说它们的差异:

    第一种MDD/PDD模式是最早被提供的模式,也是其他驱动常见分层模式.如果我们使用CE提供的MDD(wavemdd.lib)我们会受到一些限制:

Only supports one device ( waveOutGetNumDevs always returns 1)

Only supports one stream per device

No reliable support for looping

Poor support for streaming

当然,源码是提供的,你可以自己修改MDD突破这些限制.

    第二种Wavedev2模式是因为2000年的Smartphone项目产生了新的要求,这些需求需要大改MDD/PDD.比如,我们看看上面的限制Only supports one stream per device.根据ce开发历史,此时,waveapi.dll也不支持software mixer.这岂不是说只能同时只能允许一个应用在播放?所以,根据当时情况,ce的多媒体开发团队设计了Wavedev2这个模式.这是一个单体的(不分层)的驱动模式.平台相关的模块都在hwctxt.h和hwctxt.cpp中.此外,还加入了midi支持,software mixer,支持S/PDIF接口,增加'gain class'接口,增加'forcespeaker'接口等等.因此,开发Smartphone或者PPC,这个模式是挺适合的.

    第三:统一音频模型(Unified Audio Model)根据历史,在开发WinCE4.2时候,要增加对DirectSound的支持,而且有一些音频设备是支持硬件mixer的,对此,使用UAM是很好的选择.

细说'gain class'

    智能手机Smartphone有一种情况不得不被考虑,就是在播放音乐的时候,突然收到来电.在播放来电和通话过程中,要求应用程序调整音量或者静音.显而易见的办法是让所有应用程序去适应这种情况,自行调整音量.但这是好办法吗?肯定不是.

    应用程序控制音量是通过waveOutSetVolume这个api.如果第一个参数是DeviceID,那么改变整个设备的音量,如果第一个参数是waveOutOpen返回的handler,那么只是改变这个音频流的音量.

     Wavedev2提出了gain class这样的机制.首先,每一个音频流都要自己独立的音量控制,其次就是将音频流进行分类.然后对每一类音频流音量进行统一控制.在Wavedev2中大概分成4种类型:0,1,2,3.普通的应用程序播放都属于默认的0类型.这一类型的音频流在通话过程中被静音.像报警,通话中再次来电通知这些音频属于第2类型.在通话过程中仍然能够播放.而且不受系统音量的影响.应用程序如何把自己注册成为第2类型?

     waveOutOpen(&hWaveOut, ...);

     ...

     // Set gain class to 2

     waveOutMessage(hWaveOut, MM_WOM_SETSECONDARYGAINCLASS, 2, 0);

细说'ForceSpeaker'

    强制选择音频流输出设备为系统speaker.为什么要这个功能?因为Smartphone除了自带一个喇叭,一般还有耳机接口.插上耳机后,所有的音频流都通过耳机发声,但是对于来电通知,以及设备掉电,低电通知等等这样的音频流,更好的选择是通过系统的喇叭发声;况且,有时候,用户插上了耳机,却没有带上耳机这样的情况也会发生.

    于是,ce的开发组在Wavedev2上加入了这样的机制.它定义了一个消息MM_WOM_FORCESPEAKER,上层应用程序使用

waveOutMessage(<DeviceID|hWaveOut>,MM_WOM_FORCESPEAKER, bSpeaker, 0)来通知驱动,这个音频流应该通过系统喇叭来发出.