c++实现waveinopen录音功能

使用waveInOpen方法录音 保存成wav格式 即录即播 64位 采用winmm的waveinopen方法进行录音 相比于简单的winmm录音方法, waveinopen更加灵活:选择录音设备,或者更多的参数设定。在网上寻找的工程文件都是运行在32为,64位设备会报无法找到实例错误。在google上寻找了很久解决办法进行了修复。原工程无法保存文件,是一个即录即播放的工程,我也加入了保存功能。 立即下载

转载自:http://blog.youkuaiyun.com/xbk123123/article/details/53611283


本周的第一篇博客,自己想讲讲刚学习的新知识,Windows下怎样录制音频。因为自己的需要写一个关于网络电话的程序。这个程序毫无疑问必须用到录制音频和播放音频这样的基本功能。首先先说说怎样录制音频:

在Windows中提供了相应的API函数(waveIn这个族的函数)实现录音功能(具体的播放功能是使用waveOut族的函数)

在使用这些函数是,一定要引入相应的头文件:

#include<windows.h>

#include <MMSYSTEM.H>
#pragma comment(lib, "WINMM.LIB")

1)、在开始录音之前,需要首先定义音频流的相关信息:使用WAVEFORMATEX结构体,设置相关的音频流信息。以下是MSDN中的定义:

typedef struct
{
WORD wFormatTag;//表示:波形音频的格式,一般的情况下设置为WAVE_FORMAT_PCM
WORD nChannels;//表示:音频声道的数量。可以是1或者2(现在电脑基本上都是左右两个声道,因此一般设置为2)
DWORD nSamplesPerSec;//表示:每个声道播放和接收的音频的样本频率(一般的频率为8khz,11.025khz,22.05khz,41.1khz)
DWORD nAvgBytesPerSec;//表示:平均的数据传输率,单位为byte/s
WORD nBlockAlign;//表示:以字节为单位的块对齐的大小,一般为: (nChannels*wBitsPerSample)/8
WORD wBitsPerSample;//表示:根据wFormatTag设置的类型,设置采样率的大小,如果设置为WAVE_FORMAT_PCM,则大小为8的整数倍
WORD cbSize;//表示:额外的空间,一般不需要,设置为0
} WAVEFORMATEX; *PWAVEFORMATEX;

定义一个WAVEFORMATEX对象,根据自己的要求设置音频流的信息,如下:

[cpp]  view plain  copy
  1. BOOL CIP_PHONEDlg::initAudioDevice()  
  2. {  
  3.     try  
  4.     {  
  5.         waveForm.nSamplesPerSec = 44100; /* sample rate */  
  6.         waveForm.wBitsPerSample = 16; /* sample size */  
  7.         waveForm.nChannels= 2; /* channels*/  
  8.         waveForm.cbSize = 0; /* size of _extra_ info */  
  9.         waveForm.wFormatTag = WAVE_FORMAT_PCM;  
  10.         waveForm.nBlockAlign = (waveForm.wBitsPerSample * waveForm.nChannels) >> 3;  
  11.         waveForm.nAvgBytesPerSec = waveForm.nBlockAlign * waveForm.nSamplesPerSec;  
  12.         return TRUE;  
  13.     }  
  14.     catch(...)  
  15.     {  
  16.         return FALSE;  
  17.     }  
  18. }  
2)、当音频流信息设置完成后,接下来需要启动录音设备:使用waveInOpen函数

该函数在使用时,需要一个设备句柄,以后就是在这个设备上录音的。定义一个设备对象:HWAVEIN hWaveIn;//输入设备

[cpp]  view plain  copy
  1. MMRESULT mRet=waveInOpen(&hWaveIn, WAVE_MAPPER, &waveForm,(DWORD)MicCallBack, (DWORD)this, CALLBACK_FUNCTION);  
  2. if (mRet != MMSYSERR_NOERROR)  
  3. {  
  4.     return FALSE;  
  5. }  
waveInOpen函数的第一个参数表示:一个特定的录音设备指针,如果设备启动成功,该参数的值将会被赋值为启动的设备

第二参数表示:需要启动的设备ID。一般不会手动的指定某个设备,而是通过设置WAVE_MAPPER,通过系统查找可用的设备

第三个参数表示:音频流信息对象的指针。这个参数就是我们第一步设置的对象

第四个参数表示:录音消息的处理程序,可以设置为一个函数、或者事件句柄、窗口句柄、一个特定的线程。也就是说录音消息产生后,由这个参数对应的值来处理该消息。包括关闭录音、缓冲区已满、开启设备。

第5个参数表示:第四个参数的参数列表

第6个参数表示:打开设备的标示符。对应第四个参数,如果第四个参数设置为函数,则第6个参数的值为CALLBACK_FUNCTION;如果是事件,则为CALLBACK_EVENT;如果为窗体句柄(第5个参数设置为0),则为CALLBACK_WINDOW;如过设置为0,则为CALLBACK_NULL;如果为线程,则为CALLBACK_THREAD

表示的意思就是当录音产生消息后,由谁来处理相应的消息。

注意:要想该函数成功执行,必须在开始之前,有录音设备的存在(台式电脑一定要插入麦克风才可以被检测到)

3)、当录音设备启动后,接下来需要声明两个缓冲区和两个缓冲区头部结构体WAVEHDR对象,缓冲区用来存放录音音频,并用缓冲区初始化头部对象

[cpp]  view plain  copy
  1. <span style="white-space:pre;"> </span>pBuffer1 = new BYTE[bufsize];  
  2.     if (pBuffer1 == NULL)  
  3.     {  
  4.         return FALSE;  
  5.     }  
  6.     memset(pBuffer1,0,bufsize);  
  7.     Whdr1.lpData = (LPSTR)pBuffer1;  
  8.     Whdr1.dwBufferLength = bufsize;  
  9.     Whdr1.dwBytesRecorded = 0;  
  10.     Whdr1.dwUser = 0;  
  11.     Whdr1.dwFlags = 0;  
  12.     Whdr1.dwLoops = 1;  
  13.   
  14.     pBuffer2 = new BYTE[bufsize];  
  15.     if (pBuffer2 == NULL)  
  16.     {  
  17.         return FALSE;  
  18.     }  
  19.     memset(pBuffer2,0,bufsize);  
  20.     Whdr2.lpData = (LPSTR)pBuffer2;  
  21.     Whdr2.dwBufferLength = bufsize;  
  22.     Whdr2.dwBytesRecorded = 0;  
  23.     Whdr2.dwUser = 0;  
  24.     Whdr2.dwFlags = 0;  
  25.     Whdr2.dwLoops = 1;  

WAVEHDR对象定义如下:

typedef struct { 
    LPSTR      lpData;//缓冲区存放的内容
    DWORD      dwBufferLength; //缓冲区的大小
    DWORD      dwBytesRecorded; //缓冲区中存放的字节数
    DWORD_PTR  dwUser; //
    DWORD      dwFlags; //
    DWORD      dwLoops; //
    struct wavehdr_tag * lpNext;// 
    DWORD_PTR reserved; //
} WAVEHDR;
4)、接下来将这两个头部对象,加入到准备的录音缓冲区中。该过程使用waveInPrepareHeader函数。

[cpp]  view plain  copy
  1. waveInPrepareHeader(hWaveIn, &Whdr1, sizeof(WAVEHDR));//准备一个波形数据块头用于录音  
  2. waveInPrepareHeader(hWaveIn, &Whdr2, sizeof(WAVEHDR));//准备二个波形数据块头用于录音  
waveInPrePareHeader的第一个参数表示:录音设备句柄;第二个参数表示:录音的缓冲区对象;第三个参数表示:录音缓冲区结构体的大小。

5)、当准备好录音缓冲区之后,就可以将录音缓冲区加入到指定的录音设备中。该步骤使用waveInAddBuffer函数

[cpp]  view plain  copy
  1. waveInAddBuffer(hWaveIn, &Whdr1, sizeof (WAVEHDR));//指定波形数据块为录音输入缓存  
  2. waveInAddBuffer(hWaveIn, &Whdr2, sizeof (WAVEHDR));//指定波形数据块为录音输入缓存  
分别将缓冲区1和2设置为录音缓冲区。这些缓冲区将会被加入到录音缓冲队列中,缓冲区循环执行。

6)、开始录音,使用waveInStart函数

waveInStart(hWaveIn);//开始录音

这个函数的意思就是,通过hWaveIn录音设备,将波形音频放入录音缓冲区(前面已经指定了缓冲区)

7)、当缓冲区满时,waveinstart函数,就会自动的调用waveInOpen函数中制定的函数/窗体/事件;通过该函数,用户可以将缓冲区的波形文件发送给其他的用户,也可以将缓冲区的文件保存,即就是用户对缓冲区的拷贝。声卡自动将音频缓冲区从缓冲队列中删除。拷贝完成后,就将该缓冲区以及对应的音频头文件初始化,并通过waveInAddBuffer函数重新加入录音缓冲队列中。

[cpp]  view plain  copy
  1. DWORD CIP_PHONEDlg::MicCallBack(HWAVEIN hWaveIn,UINT uMsg,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2)  
  2. {//所有的这些录音消息都是有录音函数自动触发的,开发者不需要自己触发  
  3.     CIP_PHONEDlg* pwnd=(CIP_PHONEDlg*)dwInstance;//表示录音的窗体  
  4.     PWAVEHDR whd=(PWAVEHDR)dwParam1; //录音的头结构体对象  
  5.     switch(uMsg)  
  6.     {  
  7.     case WIM_OPEN://打开录音设备,这里不做处理  
  8.         break;  
  9.     case WIM_DATA://表示数据缓冲区已满,我们将信息写入一个pcm文件  
  10.         //保存数据  
  11.         pwnd->pf=fopen( pwnd->soundName, "ab+");//一定要以二进制数据写入,否则录制的音频会出现杂音  
  12.         Sleep(1000);//等待声音录制1s  
  13.         fwrite(whd->lpData, 1, whd->dwBufferLength, pwnd->pf);  
  14.         if (pwnd->isGetSound)  
  15.         {  
  16.             waveInAddBuffer(hWaveIn,whd,sizeof(WAVEHDR));  
  17.         }  
  18.         fclose(pwnd->pf);  
  19.         break;  
  20.     case WIM_CLOSE://停止录音  
  21.         waveInStop(hWaveIn);  
  22.         waveInReset(hWaveIn);     
  23.         waveInClose(hWaveIn);  
  24.         break;  
  25.     default:  
  26.         break;  
  27.     }  
  28.     return 0;  
  29. }  
8)、停止录音,使用waveInClose函数执行该操作

[cpp]  view plain  copy
  1. delete []pBuffer1;  
  2. delete []pBuffer2;//将开辟的缓冲区空间释放  
  3. waveInClose(hWaveIn);//停止录音  
停止录音时,将会触发WIM_CLOSE消息。

在这个过程中首先执行waveInStop函数:表示禁止向输入缓冲区中输入波形数据;

然后执行waveInReset函数:表示停止波形数据的输入并且将当前的位置为0,将所有挂起的输入缓冲区设置为完成,并返回给应用程序(其实就是一个复位操作)

最后执行waveInClose函数:表示关闭录音设备

通过上面8步运行,可以正常的录入一段音频了。

详细的代码:

类的定义:

[cpp]  view plain  copy
  1. #include <MMSYSTEM.H>  
  2. #pragma comment(lib, "WINMM.LIB")  
  3.   
  4. class CIP_PHONEDlg : public CDialog  
  5. {  
  6. private://音频的采集  
  7.     BOOL initAudioDevice();//初始话音频结构体  
  8.     BOOL getSound();//采集声音  
  9.     static DWORD CALLBACK MicCallBack(HWAVEIN hWaveIn,UINT uMsg,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2);//采集声音的信息处理函数  
  10.     void getTimeStr();//获得录音文件的名称  
  11. public://采集声音时的变量  
  12.     HWAVEIN hWaveIn;//输入设备  
  13.     WAVEFORMATEX waveForm;//采集声音的格式,结构体  
  14.     BYTE *pBuffer1,*pBuffer2;//采集声音的缓冲区  
  15.     WAVEHDR Whdr1,Whdr2;//采集音频时数据缓冲的结构体  
  16.     bool isGetSound;//是否采集声音  
  17.     FILE *pf;//音频文件的句柄  
  18.     CString soundName;//录音的音频文件名称  
  19. };  
具体的代码实现
[cpp]  view plain  copy
  1. BOOL CIP_PHONEDlg::initAudioDevice()  
  2. {  
  3.     try  
  4.     {  
  5.         waveForm.nSamplesPerSec = 44100; /* sample rate */  
  6.         waveForm.wBitsPerSample = 16; /* sample size */  
  7.         waveForm.nChannels= 2; /* channels*/  
  8.         waveForm.cbSize = 0; /* size of _extra_ info */  
  9.         waveForm.wFormatTag = WAVE_FORMAT_PCM;  
  10.         waveForm.nBlockAlign = (waveForm.wBitsPerSample * waveForm.nChannels) >> 3;  
  11.         waveForm.nAvgBytesPerSec = waveForm.nBlockAlign * waveForm.nSamplesPerSec;  
  12.         return TRUE;  
  13.     }  
  14.     catch(...)  
  15.     {  
  16.         return FALSE;  
  17.     }  
  18. }  
  19. void CIP_PHONEDlg::getTimeStr()  
  20. {//获得录音文件的名称  
  21.     try  
  22.     {  
  23.         SYSTEMTIME times;  
  24.         ::GetSystemTime(×);  
  25.         CString sTimeStr="";  
  26.         sTimeStr.Format("%d_%d_%d_%d_%d_%d_%d",times.wYear,times.wMonth,times.wDay,times.wHour,times.wMinute,times.wSecond,times.wMilliseconds);  
  27.         this->soundName="./RecordSounds\\"+sTimeStr+".pcm";//获得音频的存放路径  
  28.     }  
  29.     catch(...)  
  30.     {  
  31.         this->soundName="./RecordSounds\\出错文件.pcm";//获得音频的存放路径  
  32.     }  
  33.       
  34.     return ;  
  35. }  
  36. BOOL CIP_PHONEDlg::getSound()  
  37. {  
  38.     if (!initAudioDevice())  
  39.     {  
  40.         return FALSE;  
  41.     }  
  42.     MMRESULT mRet=waveInOpen(&hWaveIn, WAVE_MAPPER, &waveForm,(DWORD)MicCallBack, (DWORD)this, CALLBACK_FUNCTION);  
  43.     if (mRet != MMSYSERR_NOERROR)  
  44.     {  
  45.         return FALSE;  
  46.     }  
  47.     getTimeStr();//生成录音文件的名称  
  48.     pBuffer1 = new BYTE[bufsize];  
  49.     if (pBuffer1 == NULL)  
  50.     {  
  51.         return FALSE;  
  52.     }  
  53.     memset(pBuffer1,0,bufsize);  
  54.     Whdr1.lpData = (LPSTR)pBuffer1;  
  55.     Whdr1.dwBufferLength = bufsize;  
  56.     Whdr1.dwBytesRecorded = 0;  
  57.     Whdr1.dwUser = 0;  
  58.     Whdr1.dwFlags = 0;  
  59.     Whdr1.dwLoops = 1;  
  60.   
  61.     pBuffer2 = new BYTE[bufsize];  
  62.     if (pBuffer2 == NULL)  
  63.     {  
  64.         return FALSE;  
  65.     }  
  66.     memset(pBuffer2,0,bufsize);  
  67.     Whdr2.lpData = (LPSTR)pBuffer2;  
  68.     Whdr2.dwBufferLength = bufsize;  
  69.     Whdr2.dwBytesRecorded = 0;  
  70.     Whdr2.dwUser = 0;  
  71.     Whdr2.dwFlags = 0;  
  72.     Whdr2.dwLoops = 1;  
  73.     waveInPrepareHeader(hWaveIn, &Whdr1, sizeof(WAVEHDR));//准备一个波形数据块头用于录音  
  74.     waveInPrepareHeader(hWaveIn, &Whdr2, sizeof(WAVEHDR));//准备二个波形数据块头用于录音  
  75.     waveInAddBuffer(hWaveIn, &Whdr1, sizeof (WAVEHDR));//指定波形数据块为录音输入缓存  
  76.     waveInAddBuffer(hWaveIn, &Whdr2, sizeof (WAVEHDR));//指定波形数据块为录音输入缓存  
  77.     waveInStart(hWaveIn);//开始录音  
  78.   
  79.     delete []pBuffer1;  
  80.     delete []pBuffer2;  
  81.     waveInClose(hWaveIn);//停止录音  
  82.     return TRUE;  
  83. }  
  84.   
  85. DWORD CIP_PHONEDlg::MicCallBack(HWAVEIN hWaveIn,UINT uMsg,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2)  
  86. {  
  87.     CIP_PHONEDlg* pwnd=(CIP_PHONEDlg*)dwInstance;  
  88.     PWAVEHDR whd=(PWAVEHDR)dwParam1;   
  89.     switch(uMsg)  
  90.     {  
  91.     case WIM_OPEN:  
  92.         break;  
  93.     case WIM_DATA:  
  94.         //保存数据  
  95.         pwnd->pf=fopen( pwnd->soundName, "ab+");//一定要以二进制数据写入,否则录入的音频会有杂音  
  96.         fwrite(whd->lpData, 1, whd->dwBufferLength, pwnd->pf);  
  97.         if (pwnd->isGetSound)  
  98.         {  
  99.             waveInAddBuffer(hWaveIn,whd,sizeof(WAVEHDR));  
  100.         }  
  101.         fclose(pwnd->pf);  
  102.         break;  
  103.     case WIM_CLOSE:  
  104.         waveInStop(hWaveIn);  
  105.         waveInReset(hWaveIn);     
  106.         waveInClose(hWaveIn);  
  107.         break;  
  108.     default:  
  109.         break;  
  110.     }  
  111.     return 0;  
  112. }  

 

注意:在录音时,可能需要设置自己的电脑,使麦克风可以录音。

好了关于录音的相关操作,今天就写在这里,具体的播放音频的操作,将在下一节讲解。

surfer10与Arcgis10.3 完美生成等值线和等值面方法 surfer10 与Arcgis10.3生成等值线和等值面的步骤如下: 1.准备surfer用的Book1.dat文件,格式如下: "x" "y" "z" 116.471992 40.809975 232 116.335556 40.700542 1235 116.541626 40.713333 214 116.73349 40.798607 566 2.在surfer中,选择Gr 阅读详情

相关推荐

实战解析:在.NET中实现Dify API流式请求与响应的完整方案

本文详细解析了在.NET应用中对接Dify API时实现流式请求与响应的完整方案。针对传统后端“接收完才返回”的痛点,文章提供了基于ASP.NET Core的实战代码,通过配置HttpCompletionOption.ResponseHeadersRead和手动Flush响应流,构建高效的中转管道,确保AI回复能够像ChatGPT一样实时逐字推送到前端,显著提升用户体验。

weixin_29267307的博客 296

WaveInOpen线程版,解决waveInStop死锁

Window api,waveIn录音

WuSk__的博客 935

【电机学复习笔记】同步电机的特性及参数的求取

同步电机的主要特性包括:空载特性、短路特性、零功率因数负载特性、外特性和调整特性。 基于以上特性我们可以实现: 从空载特性和短路特性求同步电抗的不饱和值和短路比; 从零功率因数负载特性和空载特性确定保梯电抗(定子漏抗)和电枢反应电动势

Pantrick_的博客 2万+

蓝易云 - c++实现waveinopen录音功能

需要注意的是,实际使用中可能需要更多的错误处理和资源管理。同时,这个示例是基于Windows的,使用了Windows Multimedia API来进行音频录制。函数来录制音频数据,然后通过回调函数。这是一个简单的C++示例,使用。

高性价比服务器就选:蓝易云 245

UG/NX二次开发实战:用Python脚本批量更新100个零件参数,解放你的双手

本文详细介绍了如何利用NXOpen Python API进行UG/NX二次开发,实现批量更新100个零件参数的自动化流程。通过环境配置、框架设计、核心代码实现及性能优化,帮助工程师高效完成参数化设计任务,显著提升工作效率。

weixin_28694169的博客 276

6、Dialogflow 开发全解析:从基础到高级应用

本文全面解析了 Dialogflow 的核心功能与高级应用,涵盖意图与实体的创建、上下文管理、后续意图设置以及高级实体类型的实际应用场景。详细介绍了自定义实体的导入导出规则、编程添加方法及数量限制,并通过流程图和实例说明了上下文生命周期与对话连贯性设计。结合电商、旅游、问卷调查等实际业务场景,展示了模糊匹配、自动扩展、复合实体等功能的强大灵活性。最后提供了开发最佳实践建议,帮助开发者构建高效、智能的对话系统。

kafka6courier的博客 104

C++ 采集音频流(PCM裸流)实现录音功能

与上一篇的“C++ 播放音频流(PCM裸流)” 点击打开链接 相对应,本篇是关于用C++实现录音功能的。同样是直接建一个win32控制台程序然后将代码拷过去改个文件名就可以用,也可以下载本人上传的相关工程,这个工程是用VS2013写的,如果是较低的版本就呵呵了。点击打开链接代码部分如下:[cpp] view plain copy#include "stdafx.h"  #include &lt;s...

imxiangzi的专栏 1307

MIKE水动力笔记13_数字化海图2之克里金插值

在进行MIKE水动力建模之初,需要准备好水深数据,本专题系列博文主要讲解如何将扫描版JPG格式海图数据在ArcGIS中进行数字化并制作成xyz水深地形数据,用的克里金插值方法,仅供参考。

晏长街的博客 2881

C++ 採集音频流(PCM裸流)实现录音功能

与上一篇的“C++ 播放音频流(PCM裸流)”点击打开链接相相应,本篇是关于用C++实现录音功能的。相同是直接建一个win32控制台程序然后将代码拷过去改个文件名称就能够用,也能够下载本人上传的相关project,这个project是用VS2013写的,假设是较低的版本号就呵呵了。点击打开链接 代码部分例如以下: #include "stdafx.h" #include ...

weixin_30711917的博客 136

无线通信技术及其在机器人中的应用

本文系统阐述了无线通信技术在机器人领域的应用框架与技术选型。首先构建了无线通信的三层理论架构:物理层解决信号传输问题,链路层处理接入控制,网络层实现组网管理。随后详细分析了主流无线技术的特性与适用场景:BLE适用于低功耗传感器节点,Wi-Fi适合高带宽视频传输,5G专网满足工业AGV的广域覆盖需求,星闪技术凭借20μs超低时延和4096台并发连接能力,为高端机器人应用提供突破性解决方案。通过鄂尔多斯隆基5G专网等典型案例,验证了5G在工业AGV规模化部署中的优势,并展望了通感算智融合、星闪+5G协同等未来发

weiyvyy的博客 1115

第110章 PCL PointCloudFusing 点云融合重建详细讲解

点云融合是指将多个不同视角、不同位置、不同传感器获取的点云数据进行合并,得到一个更加完整、准确的三维模型。多视角扫描:从多个相机或传感器获取点云数据,需要将这些数据融合成一个统一的三维模型。传感器融合:例如将激光雷达(LiDAR)点云与相机的图像数据融合,以便获得更高质量的三维重建。动态场景重建:动态环境中的物体,点云数据不断更新,如何平滑地融合这些点云是一个重要课题。点云融合的目标是将不同来源的点云数据准确地合并,消除冗余,减少噪声,并提高整体的点云密度和精度。

yumeiguo的博客 503

c++获取系统pcm_C++ 采集音频流(PCM裸流)实现录音功能 | 学步园

与上一篇的“C++ 播放音频流(PCM裸流)”点击打开链接相对应,本篇是关于用C++实现录音功能的。同样是直接建一个win32控制台程序然后将代码拷过去改个文件名就可以用,也可以下载本人上传的相关工程,这个工程是用VS2013写的,如果是较低的版本就呵呵了。点击打开链接代码部分如下:#include "stdafx.h"#include #include #pragma comment(lib, ...

weixin_39906499的博客 419

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

c++采集声卡输出_C++ 采集音频流(PCM裸流)实现录音功能

与上一篇的“C++ 播放音频流(PCM裸流)”点击打开链接相对应,本篇是关于用C++实现录音功能的。同样是直接建一个win32控制台程序然后将代码拷过去改个文件名就可以用,也可以下载本人上传的相关工程,这个工程是用VS2013写的,如果是较低的版本就呵呵了。点击打开链接代码部分如下:#include "stdafx.h"#include #include #pragma comment(lib, ...

weixin_39607090的博客 980

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

NAudio用法详解(5)底层库详解_waveInOpen

NAudio用法详解(5)底层库详解_waveInOpen 本篇翻译自以下地址: https://docs.microsoft.com/zh-cn/windows/win32/api/mmeapi/nf-mmeapi-waveinopen 为了便于大家批评指正,原文大部分并未删除。为了简单理解,有些复杂的描述,并未翻译,大部分情况下不影响使用。 方框内的内容为本人额外的补充说明。 上篇中,本人部分翻译了waveOutOpen函数,本篇翻译waveInOpen,这两个函数都来自Winmm.dll,掌握了这两

赵解放的专栏 2149

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

windows平台,实现录音功能详解

  音频处理分为播放和录音两类。对这些处理,微软提供了一些列函数,称之为Waveform Functions。这篇文章讨论录音功能。会对微软提供的函数做简单说明,并对这些函数封装成c++类,再进一步封装成c#类。 1 Waveform Functions函数简介 根据录音处理步骤,对这些函数做简单介绍。   1.1  waveInOpen MMRESULT waveInOpen( ...

1023

C++和Win32实现录音器功能

最近在学习的过程中要求写一个录音器的小demo,在网上找了好多资料发现都写得不完整,或者是简单地对函数的介绍,或者使用的MFC,或者只有部分代码片段。这对初学者造成了很大的学习困难和困惑。近日我想把我写的一个录音器程序贴到网上,希望更多地读者能够看到,学到。避免我曾经的困难疑惑。 一. 首先需要包含以下引用对象 #include "windows.h" #includ

易大飞 2337
上一篇: (转载)Electron & C++ 快速开发桌面Web "混合"应用
下一篇: (转载)nginx下支持PATH_INFO详解
xiaolu289
博客等级 码龄19年 8粉丝 21原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值