【转】vc api 录音
一、数字音频基础知识
Fourier级数:
任何周期的波形可以分解成多个正弦波,这些正弦波的频率都是整数倍。级数中其他正线波的频率是基础频率的整数倍。基础频率称为一级谐波。
PCM:
pulse code modulation,脉冲编码调制,即对波形按照固定周期频率采样。为了保证采样后数据质量,采样频率必须是样本声音最高频率的两倍,这就是Nyquist频率。
样本大小:采样后用于存储振幅级的位数,实际就是脉冲编码的阶梯数,位数越大表明精度越高,这一点学过数字逻辑电路的应该清楚。
声音强度:
波形振幅的平方。两个声音强度上的差常以分贝(db)为单位来度量,
计算公式如下:
20*log(A1/A2)分贝。A1,A2为两个声音的振幅。如果采样大小为8位,则采样的动态范围为20*log(256)分贝=48db。如果样本大小为16位,则采样动态范围为20*log(65536)大约是96分贝,接近了人听觉极限和痛苦极限,是再线音乐的理想范围。windows同时支持8位和16位的采样大小。
二、相关API函数,结构,消息
对于录音设备来说,windows 提供了一组wave***的函数,比较重要的有以下几个:
打开录音设备函数
1.MMRESULT waveInOpen(2.LPHWAVEIN phwi, //输入设备句柄3.UINT uDeviceID, //输入设备ID4.LPWAVEFORMATEX pwfx, //录音格式指针5.DWORD dwCallback, //处理MM_WIM_***消息的回调函数或窗口句柄,线程ID6.DWORD dwCallbackInstance, 7.DWORD fdwOpen //处理消息方式的符号位8.);为录音设备准备缓存函数
1.MMRESULT waveInPrepareHeader( HWAVEIN hwi, LPWAVEHDR pwh, UINT bwh );给输入设备增加一个缓存
1.MMRESULT waveInAddBuffer( HWAVEIN hwi, LPWAVEHDR pwh, UINT cbwh );开始录音
1.MMRESULT waveInStart( HWAVEIN hwi );清除缓存
1.MMRESULT waveInUnprepareHeader( HWAVEIN hwi,LPWAVEHDR pwh, UINT cbwh);停止录音
1.MMRESULT waveInReset( HWAVEIN hwi );关闭录音设备
1.MMRESULT waveInClose( HWAVEIN hwi );Wave_audio数据格式
01.typedef struct {02.WORD wFormatTag; //数据格式,一般为WAVE_FORMAT_PCM即脉冲编码03.WORD nChannels; //声道04.DWORD nSamplesPerSec; //采样频率05.DWORD nAvgBytesPerSec; //每秒数据量06.WORD nBlockAlign;07.WORD wBitsPerSample;//样本大小08.WORD cbSize;09.} WAVEFORMATEX;waveform-audio 缓存格式
01.typedef struct {02.LPSTR lpData; //内存指针03.DWORD dwBufferLength;//长度04.DWORD dwBytesRecorded; //已录音的字节长度05.DWORD dwUser;06.DWORD dwFlags;07.DWORD dwLoops; //循环次数08.struct wavehdr_tag * lpNext;09.DWORD reserved;10.} WAVEHDR;相关消息
1.MM_WIM_OPEN:打开设备时消息,在此期间我们可以进行一些初始化工作2.MM_WIM_DATA:当缓存已满或者停止录音时的消息,处理这个消息可以对缓存进行重新分配,实现不限长度录音3.MM_WIM_CLOSE:关闭录音设备时的消息。相对于录音来说,回放就简单的多了,用到的函数主要有以下几个:
打开回放设备
1.MMRESULT waveOutOpen(2.LPHWAVEOUT phwo, 3.UINT uDeviceID, 4.LPWAVEFORMATEX pwfx, 5.DWORD dwCallback, 6.DWORD dwCallbackInstance, 7.DWORD fdwOpen 8.);为回放设备准备内存块
1.MMRESULT waveOutPrepareHeader(2.HWAVEOUT hwo, 3.LPWAVEHDR pwh,4.UINT cbwh 5.);写数据(放音)
1.MMRESULT waveOutWrite(2.HWAVEOUT hwo, 3.LPWAVEHDR pwh,4.UINT cbwh 5.);相应的也有三个消息,用法跟录音的类似:
三、程序设计
一个录音程序的简单流程:
打开录音设备waveInOpen===>准备wave数据头waveInPrepareHeader===>
准备数据块waveInAddBuffer===>开始录音waveInStart===>停止录音(waveInReset) ===>
关闭录音设备(waveInClose)
当开始录音后当buffer已满时,将收到MM_WIM_DATA消息,处理该消息可以保存已录好数据。
回放程序比这个要简单的多:
打开回放设备waveOutOpen===>准备wave数据头waveOutPrepareHeader===>写wave数据waveOutWrite===>停止放音(waveOutRest) ===>关闭回放设备(waveOutClose)
如何处理MM消息:
MSDN告诉我们主要有 CALLBACK_FUNCTION、CALL_BACKTHREAD、CALLBACK_WINDOW 三种方式,常用的是
Thread,window方式。
线程模式
waveInOpen(&hWaveIn,WAVE_MAPPER,&waveform,m_ThreadID,NULL,CALLBACK_THREAD),我们可以继承MFC的CwinThread类,只要相应的处理线程消息即可。
MFC线程消息的宏为:
1.ON_THREAD_MESSAGE,可以这样添加消息映射:
1.ON_THREAD_MESSAGE(MM_WIM_CLOSE, OnMM_WIM_CLOSE)窗口模式
类似于线程模式,参见源程序即可。
【转】http://www.lihuasoft.net/article/show.php?id=124
http://www.vckbase.com/index.php/wv/664
【转】vc api 录音的更多相关文章
- 小程序API录音后Silk格式转码MP3
问题 客户端使用小程序,需要录音功能然后到后台页面播放,由于微信提供的录音API压缩后的格式为 .silk格式的,但是这个格式其他播放器都是播放不了的,更何况html页面的audio标签更是不可能播放 ...
- VC API常用函数简单例子大全(1-89)
第一个:FindWindow根据窗口类名或窗口标题名来获得窗口的句柄,该函数返回窗口的句柄 函数的定义:HWND WINAPI FindWindow(LPCSTR lpClassName ,LPCST ...
- (转载博文)VC++API速查
窗口处理 2.1 窗口简介 2.2.1 创建普通窗口(CreateWindow.CreateWindowEx) 2.2.2 关闭窗口(CloseWindow) 2.2.3 销毁窗口(DestroyWi ...
- 小程序API录音 微信录音后 Silk格式转码MP3
http://www.cnblogs.com/wqh17/p/6911748.html
- VC/MFC 编程技巧大总结
1 toolbar默认位图左上角那个点的颜色是透明色,不喜欢的话可以自己改. 2 VC++中 WM_QUERYENDSESSION WM_ENDSESSION 为系统关机消息. 3 Java学习书推荐 ...
- 【微信JSSDK】PHP版微信录音文件下载
微信的录音文件上传到微信服务器上,只能保存三天. 因此需要做一个转存到自己服务器,或者七牛云的操作. 转存到自己服务器 调用微信JSSDK API 录音, 录音结束,上传到微信服务器,获取录音文件的 ...
- gcc编译器基本命令
1 unix操作系统 ubuntu 12版本Unix内核0.5天 常用命令2 c语言:标准c 十天主要练习动手能力 小案例水平高的 自己去写案例水平低的 理解并跟着写3 c++:5天高级语言的特点:面 ...
- Gdi+实用入门
大部分是参照其它资料,然后加以自己的理解,那是什么,总结.算不得什么教程.......汗,自己看着就行了..如果别人能看那就更好了. 首先下载GDI+文件包,一个动态链接库,使用GDI+就是调用那个动 ...
- 微信小程序:将中文语音直接转化成英文语音
作者:瘟小驹 文章来源<微信小程序个人开发全过程> 准备工作: 准备工具:Eclipse.FileZilla.微信开发者工具.一个配置好SSL证书(https)的有域名的服务器 所需 ...
随机推荐
- 使用VBS控制声音
Set Ws = CreateObject("Wscript.Shell") Ws.Sendkeys "…" '静音 'Ws.Sendkeys "爱爱 ...
- Array对象(prototype)
- java 多线程之:yield() 方法
yield()介绍 yield()的作用是让步.它能让当前线程由"运行状态"进入到"就绪状态",从而让其它具有相同优先级的等待线程获取执行权:但是,并不能保证在 ...
- yii 获取当前模块名、控制器名 、动作名
yii1 1. 获取控制器名 在控制器中获取控制器名: $name = $this->getId(); 在视图中获取控制器名: $name = Yii::app()->controller ...
- SpringCloud初体验:五、Sidecar 将 PHP 这类非 Java 生态语言的服务接入 Spring Cloud
先起一个 Sidecar 服务,一个PHP服务一个应用,和PHP服务部署在同一台机子,通过 localhost 访问,这样就解决了网络开销,相当于本地进程间调用 Sidecar 服务比较简单, 1.这 ...
- MySqli 执行多条SQL语句
使用multi_query(); 去执行SQL语句,执行多条语句多个SQL语句用“;”分开 一:没有结果集的语句: $sql="insert into products (cid,name ...
- bzoj 4842: [Neerc2016]Delight for a Cat
Description ls是一个特别堕落的小朋友,对于n个连续的小时,他将要么睡觉要么打隔膜,一个小时内他不能既睡觉也打隔膜 ,因此一个小时内他只能选择睡觉或者打隔膜,当然他也必须选择睡觉或打隔膜, ...
- [转] AForge.NET 图像处理类
https://www.nuget.org/packages?q=AForge.NET https://baike.baidu.com/item/AForge.NET/114415?fr=aladdi ...
- 亚马逊云VPS AWS更改LINUX为ROOT权限密码登陆
LINUX VPS没有ROOT权限是很难受的事,并且密码登陆也方便一些.首先用AWS证书验证的账户登录,1.修改ROOT密码sudo passwd root2.sudo chmod 777 /etc/ ...
- js将UTC时间转化为当地时区时间
js将UTC时间转化为当地时区时间(UTC转GMT) 我们在进行网站开发的时候有可能会涉及到国外的用户或者用户身在国外,这时就会存在时差问题,比如说我们在中国的时间是08:00,但是此时韩国的时间 ...