使用WindowsAPI获取录音音频的方法
方法 使用 获取 音频 录音 WindowsAPI
2023-06-13 09:15:43 时间
本文实例介绍了使用winmm.h进行音频流的获取的方法,具体步骤如下:
一、首先需要包含以下引用对象
#include<Windows.h> #include"mmsystem.h" #pragmacomment(lib,"winmm.lib")
二、音频的获取需要调用7个函数
1.waveInGetNumDevs:返回系统中就绪的波形声音输入设备的数量
UINTwaveInGetNumDevs(VOID);
2.waveInGetDevCaps:检查指定波形输入设备的特性
MMRESULTwaveInGetDevCaps( UINT_PTRuDeviceID, LPWAVEINCAPSpwic, UINTcbwic ); //uDeviceID音频输入设备标识,也可以为一个打开的音频输入设备的句柄. //个人认为如果上一步获得了多个设备,可以用索引标识每一个设备. // //pwic对WAVEINCAPS结构体的一个指针,包含设备的音频特性. // //cbwicWAVEINCAPS结构体的大小,使用sizeof即可. // //MMRESULT函数执行的结果 //MMSYSERR_NOERROR表示执行成功 //MMSYSERR_BADDEVICEID索引越界 //MMSYSERR_NODRIVER没有就绪的设备 //MMSYSERR_NOMEM不能分配或者锁定内存
介绍WAVEINCAPS结构体的含义:
typedefstruct{ WORDwMid;//音频设备制造商定义的驱动程序标识 WORDwPid;//音频输入设备的产品标识 MMVERSIONvDriverVersion;//驱动程序版本号 TCHARszPname[MAXPNAMELEN];//制造商名称 DWORDdwFormats;//支持的格式,参见MSDN WORDwChannels;//支持的声道数 WORDwReserved1;//保留参数 }WAVEINCAPS;
3.waveInOpen:打开指定的音频输入设备,进行录音
MMRESULTwaveInOpen( LPHWAVEINphwi,//接收打开的音频输入设备标识的HWAVEIN结构的指针 UINT_PTRuDeviceID,//指定一个需要打开的设备标识.可以使用WAVE_MAPPER选择一个按指定录音格式录音的设备 LPWAVEFORMATEXpwfx,//一个所需的格式进行录音的WAVEFORMATEX结构的指针 DWORD_PTRdwCallback,//指向一个回调函数、事件句柄、窗口句柄、线程标识,对录音事件进行处理. DWORD_PTRdwCallbackInstance,//传给回调机制的参数 DWORDfdwOpen//打开设备的方法标识,指定回调的类型.参见CSDN );
介绍WAVEFORMATEX结构体的含义:
typedefstruct{ WORDwFormatTag;//波形声音的格式,单声道双声道使用WAVE_FORMAT_PCM.当包含在WAVEFORMATEXTENSIBLE结构中时,使用WAVE_FORMAT_EXTENSIBLE. WORDnChannels;//声道数量 DWORDnSamplesPerSec;//采样率.wFormatTag为WAVE_FORMAT_PCM时,有8.0kHz,11.025kHz,22.05kHz,和44.1kHz. DWORDnAvgBytesPerSec;//每秒的采样字节数.通过nSamplesPerSec*nChannels*wBitsPerSample/8计算 WORDnBlockAlign;//每次采样的字节数.通过nChannels*wBitsPerSample/8计算 WORDwBitsPerSample;//采样位数.wFormatTag为WAVE_FORMAT_PCM时,为8或者16 WORDcbSize;//wFormatTag为WAVE_FORMAT_PCM时,忽略此参数 }WAVEFORMATEX;
介绍dwCallback回调函数格式:
voidCALLBACKwaveInProc( HWAVEINhwi,//回调此函数的设备句柄 UINTuMsg,//波形声音输入信息,标识关闭(WIM_CLOSE)、缓冲区满(WIM_DATA)、打开(WIM_OPEN). DWORD_PTRdwInstance,//用户在waveInOpen指定的数据 DWORD_PTRdwParam1,//(LPWAVEHDR)dwParam1,用户指定的缓冲区 DWORD_PTRdwParam2 );
4.waveInPrepareHeader:为音频输入设备准备一个缓冲区
MMRESULTwaveInPrepareHeader( HWAVEINhwi,//音频输入设备句柄 LPWAVEHDRpwh,//指向WAVEHDR结构的指针,标识准备的缓冲区 UINTcbwh//WAVEHDR结构的大小,使用sizeof即可 );
介绍WAVEHDR结构:
typedefstructwavehdr_tag{ LPSTRlpData;//指向波形格式的缓冲区 DWORDdwBufferLength;//缓冲区的大小 DWORDdwBytesRecorded;//当前存储了多少数据 DWORD_PTRdwUser;//用户数据 DWORDdwFlags;//为缓冲区提供的信息,在waveInPrepareHeader函数中使用WHDR_PREPARED DWORDdwLoops;//输出时使用,标识播放次数 structwavehdr_tag*lpNext;//reserved DWORD_PTRreserved;//reserved }WAVEHDR,*LPWAVEHDR;
5.waveInAddBuffer:将缓冲区发送给设备,若缓冲区填满,则不起作用。(参数同上)
MMRESULTwaveInAddBuffer( HWAVEINhwi, LPWAVEHDRpwh, UINTcbwh );
6.waveInStart:开始进行录制
MMRESULTwaveInStart( HWAVEINhwi//设备句柄 );
7.waveInClose:关闭设备
MRESULTwaveInClose( HWAVEINhwi//设备句柄 );
三、完整实例代码如下:
//Run.c文件 #include<Windows.h> #include<stdio.h> #include"mmsystem.h" #pragmacomment(lib,"winmm.lib") voidPlayMusi(); voidWaveInitFormat(LPWAVEFORMATEXm_WaveFormat,WORDnCh,DWORDnSampleRate,WORDBitsPerSample); DWORDCALLBACKMicCallback(HWAVEINhwavein,UINTuMsg,DWORDdwInstance,DWORDdwParam1,DWORDdwParam2); voidRecordWave(); voidmain() { //PlayMusi(); RecordWave(); while(1); } voidRecordWave() { intcount=waveInGetNumDevs();//1 printf("\n音频输入数量:%d\n",count); WAVEINCAPSwaveIncaps; MMRESULTmmResult=waveInGetDevCaps(0,&waveIncaps,sizeof(WAVEINCAPS));//2 printf("\n音频输入设备:%s\n",waveIncaps.szPname); if(MMSYSERR_NOERROR==mmResult) { HWAVEINphwi; WAVEFORMATEXpwfx; WaveInitFormat(&pwfx,1,8000,8); printf("\n请求打开音频输入设备"); printf("\n采样参数:单声道8kHz8bit\n"); mmResult=waveInOpen(&phwi,WAVE_MAPPER,&pwfx,(DWORD)(MicCallback),NULL,CALLBACK_FUNCTION);//3 if(MMSYSERR_NOERROR==mmResult) { WAVEHDRpwh1; charbuffer1[10240]; pwh1.lpData=buffer1; pwh1.dwBufferLength=10240; pwh1.dwUser=1; pwh1.dwFlags=0; mmResult=waveInPrepareHeader(phwi,&pwh1,sizeof(WAVEHDR));//4 printf("\n准备缓冲区1"); WAVEHDRpwh2; charbuffer2[10240]; pwh2.lpData=buffer2; pwh2.dwBufferLength=10240; pwh2.dwUser=2; pwh2.dwFlags=0; mmResult=waveInPrepareHeader(phwi,&pwh2,sizeof(WAVEHDR));//4 printf("\n准备缓冲区2\n"); if(MMSYSERR_NOERROR==mmResult) { mmResult=waveInAddBuffer(phwi,&pwh1,sizeof(WAVEHDR));//5 printf("\n将缓冲区1加入音频输入设备"); mmResult=waveInAddBuffer(phwi,&pwh2,sizeof(WAVEHDR));//5 printf("\n将缓冲区2加入音频输入设备\n"); if(MMSYSERR_NOERROR==mmResult) { mmResult=waveInStart(phwi);//6 printf("\n请求开始录音\n"); } } } } } DWORDCALLBACKMicCallback(HWAVEINhwavein,UINTuMsg,DWORDdwInstance,DWORDdwParam1,DWORDdwParam2) { switch(uMsg) { caseWIM_OPEN: printf("\n设备已经打开...\n"); break; caseWIM_DATA: printf("\n缓冲区%d存满...\n",((LPWAVEHDR)dwParam1)->dwUser); waveInAddBuffer(hwavein,(LPWAVEHDR)dwParam1,sizeof(WAVEHDR)); break; caseWIM_CLOSE: printf("\n设备已经关闭...\n"); break; default: break; } return0; } voidWaveInitFormat(LPWAVEFORMATEXm_WaveFormat,WORDnCh,DWORDnSampleRate,WORDBitsPerSample) { m_WaveFormat->wFormatTag=WAVE_FORMAT_PCM; m_WaveFormat->nChannels=nCh; m_WaveFormat->nSamplesPerSec=nSampleRate; m_WaveFormat->nAvgBytesPerSec=nSampleRate*nCh*BitsPerSample/8; m_WaveFormat->nBlockAlign=m_WaveFormat->nChannels*BitsPerSample/8; m_WaveFormat->wBitsPerSample=BitsPerSample; m_WaveFormat->cbSize=0; } voidPlayMusi() { interror=mciSendString("openC:\\Users\\Angel\\Desktop\\有多少爱可以重来.mp3aliasmyDivece",NULL,0,NULL); if(error==0) { mciSendString("playmyDivece",NULL,0,NULL);//播放 } }
相关文章
- 一顿饭的时间,教你怎样快速使用 动态代理ip 做一个获取Steam 热销商品 的方法
- opencv中cvCircle的使用方法「建议收藏」
- VB使用XMLHTTP实现Post与Get的方法分享
- 【Android 安全】DEX 加密 ( 代理 Application 开发 | 加载 dex 文件 | 使用反射获取方法创建本应用的 dexElements | 各版本创建 dex 数组源码对比 )
- dotnet 警惕使用 StackTrace 加获取方法标记 Attribute 特性在 Release 下被内联
- Oracle 等待事件 ksxr wait for mount shared 官方解释,作用,如何使用及优化方法
- 使用Oracle获取最新数据的方法(oracle获取最新数据)
- 「Redis常用方法」,快速提升 Redis 使用效率,让您在数据存储与读取中游刃有余。(redis常用方法)
- Linux下使用as86汇编器的方法详解(linuxas86)
- MySQL哈希表原理及使用方法详解(mysqlhash表)
- 日使用SQL Server快速获取月末日的方法(sqlserver取月末)
- Linux系统中快速确定文件权限的方法(linux判断文件权限)
- 使用Oracle中的SUM字段获取总和的简单方法(oracle sum字段)
- 使用C语言优雅地操作MySQL 带参数值的调用方法(c mysql 带参数值)
- 极速提升网站性能使用Redis缓存管理技术(redis缓存用哪个方法)
- header中Content-Disposition的作用与使用方法
- 使用C#获取系统特殊文件夹路径的解决方法
- 使用C#Winform应用程序获取网页源文件的解决方法
- 使用Smarty获取当前日期时间和格式化日期时间的方法详解
- 使用jquery获取网页中图片高度的两种方法
- javasystem类使用方法示例获取系统信息
- 使用Jquery获取带特殊符号的ID标签的方法
- node.js中的fs.openSync方法使用说明
- 使用JavaScript获取地址栏参数的方法
- php使用fputcsv()函数csv文件读写数据的方法
- 使用text方法获取Html元素文本信息示例