//环境:win10 + DirectX9.0bSDK

一.准备工作

1.WavDestFilter

//采集音频写入WAV文件需要用到DirectShow的一个Filter,这个Filter用于将音频数据写入完毕时加入WAV格式数据!

//DirectXSDK目录\Samples\C++\DirectShow\Filters\WavDest

//拷贝wavdest.h,wavdest.cpp 这里采用源码拷贝走修改方式使用DirectShow提供的Filter!

2.创建Win32项目

//删除Win32自动生成代码

// DirectShowAudioCaptureWav.cpp : 定义应用程序的入口点。
//#include "stdafx.h"
#include "DirectShowAudioCaptureWav.h"int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,_In_opt_ HINSTANCE hPrevInstance,_In_ LPTSTR    lpCmdLine,_In_ int       nCmdShow)
{return 0;
}

//环境配置

// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
//#pragma once#include "targetver.h"#define WIN32_LEAN_AND_MEAN             //  从 Windows 头文件中排除极少使用的信息
// Windows 头文件:
#include <windows.h>// C 运行时头文件
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>// TODO:  在此处引用程序需要的其他头文件
#include "streams.h"#ifdef _DEBUG
#pragma comment(lib,"strmbasd.lib")
#else
#pragma comment(lib,"STRMBASE.lib")
#endif

//添加wavdest.h,wavdest.cpp

1.修改wavdest.cpp

#include <streams.h> #include "wavdest.h" -> 改成 #include "stdafx.h"

stdafx.h 添加 #include "wavdest.h"

2.挪走GUID代码至wavdest.h

// {3C78B8E2-6C4D-11d1-ADE2-0000F8754B99}
static const GUID CLSID_WavDest =
{ 0x3c78b8e2, 0x6c4d, 0x11d1, { 0xad, 0xe2, 0x0, 0x0, 0xf8, 0x75, 0x4b, 0x99 } };

const AMOVIESETUP_FILTER sudWavDest =
{
    &CLSID_WavDest,           // clsID
    L"WAV Dest",              // strName
    MERIT_DO_NOT_USE,         // dwMerit
    0,                        // nPins
    0                         // lpPin
};

3.挪走wavdest.cpp 中全局数据

// Global data
CFactoryTemplate g_Templates[]= {
    {L"WAV Dest", &CLSID_WavDest, CWavDestFilter::CreateInstance, NULL, &sudWavDest},
};

int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);

//此时编译一下看看

我们会发现报错:

stdafx.h 加入:#pragma comment(lib,"winmm.lib")

这里我们就可以正式编写我们的音频采集代码!

二.代码实现

// DirectShowAudioCaptureWav.cpp : 定义应用程序的入口点。
//#include "stdafx.h"
#include "DirectShowAudioCaptureWav.h"
#include <vector>
#include <map>using namespace std;// Global data
CFactoryTemplate g_Templates[] = {{ L"WAV Dest", &CLSID_WavDest, CWavDestFilter::CreateInstance, NULL, &sudWavDest },
};int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);///AddFilterToGraph
HRESULT AddFilterToGraph(IGraphBuilder* pGraph, const GUID& clsId, LPCWSTR wstrName, IBaseFilter** pFilter)
{if (!pGraph || !pFilter)return E_POINTER;*pFilter = NULL;//CreateFilterIBaseFilter* pBaseFilter = NULL;HRESULT hr = CoCreateInstance(clsId, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pBaseFilter);if (SUCCEEDED(hr)){//AddFilterToGraphhr = pGraph->AddFilter(pBaseFilter, wstrName);if (SUCCEEDED(hr)){//SaveFilter*pFilter = pBaseFilter;}else{//FreeFilterpBaseFilter->Release();}}return hr;
}
///GetFilterDirectionPin
HRESULT GetUnconnectedPin(IBaseFilter* pFilter, PIN_DIRECTION pinDirection, IPin** ppPin)
{if (!pFilter || !ppPin)return E_POINTER;//获取pin枚举器*ppPin = NULL;IEnumPins* pEnumPin = NULL;HRESULT hr = pFilter->EnumPins(&pEnumPin);if (FAILED(hr)){return hr;}//遍历pin枚举器IPin* pPin = NULL;while (pEnumPin->Next(1, &pPin, NULL) == S_OK){//查pin方向PIN_DIRECTION curPinDirection;pPin->QueryDirection(&curPinDirection);if (curPinDirection == pinDirection){IPin* tmpPin = NULL;//尝试连接hr = pPin->ConnectedTo(&tmpPin);if (SUCCEEDED(hr)){//可以连接tmpPin->Release();}else{pEnumPin->Release();*ppPin = pPin;return S_OK;}}}//释放pin枚举器pEnumPin->Release();return E_FAIL;
}
///FilterConnectedToFilter
//PinToFilterPinConnected
HRESULT ConnectedFilters(IGraphBuilder* pGraph, IPin* pOutPin, IBaseFilter* pDstFilter)
{if (!pGraph || !pOutPin || !pDstFilter)return E_POINTER;//获取输入pinIPin* pInPin = NULL;HRESULT hr = GetUnconnectedPin(pDstFilter, PINDIR_INPUT, &pInPin);if (FAILED(hr))return hr;//连接输入pinhr = pGraph->Connect(pOutPin, pInPin);pInPin->Release();return hr;
}
//FilterToFilterConnected
HRESULT ConnectedFilters(IGraphBuilder* pGraph, IBaseFilter* pSrcFilter, IBaseFilter* pDstFilter)
{if (!pGraph || !pSrcFilter || !pDstFilter)return E_POINTER;//获取输入pinIPin* pOutPin = NULL;HRESULT hr = GetUnconnectedPin(pSrcFilter, PINDIR_OUTPUT, &pOutPin);if (FAILED(hr))return hr;//连接输入pinhr = ConnectedFilters(pGraph, pOutPin, pDstFilter);pOutPin->Release();return hr;
}HRESULT EnumDeviceInfo(vector<wstring>& devicesNames, map<wstring, IMoniker*>& devicesInfo, const IID InputDeviceCategory)
{//创建系统设备枚举器ICreateDevEnum* pSystemDevEnum = NULL;HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pSystemDevEnum);if (FAILED(hr)){return hr;}//创建设备枚举器IEnumMoniker* pEnumMoniker = NULL;hr = pSystemDevEnum->CreateClassEnumerator(InputDeviceCategory, &pEnumMoniker, 0);if (hr == S_OK){IMoniker* pMoniker = NULL;ULONG cFetched;while (pEnumMoniker->Next(1, &pMoniker, &cFetched) == S_OK){IPropertyBag* pPropertyBag = NULL;hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pPropertyBag);if (SUCCEEDED(hr)){//获取设备信息VARIANT varName;VariantInit(&varName);hr = pPropertyBag->Read(L"FriendlyName", &varName, 0); //获取友好名if (SUCCEEDED(hr)){//保存设备信息devicesNames.push_back(varName.bstrVal);devicesInfo.insert(pair<wstring, IMoniker*>(varName.bstrVal, pMoniker));}VariantClear(&varName);}else{return hr;}pPropertyBag->Release();}}pEnumMoniker->Release();pSystemDevEnum->Release();return hr;
}HRESULT FindAudioCaptureFilter(IMoniker* pMoniker, IBaseFilter** pFilter)
{if (!pFilter || !pMoniker)return E_POINTER;*pFilter = NULL;HRESULT hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, (void**)pFilter);if (FAILED(hr)){return E_FAIL;}return S_OK;
}int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,_In_opt_ HINSTANCE hPrevInstance,_In_ LPTSTR    lpCmdLine,_In_ int       nCmdShow)
{///COM_Begin:if (FAILED(::CoInitialize(NULL))){MessageBox(NULL, L"CoInitialize failed!", L"ErrWnd", NULL);return 0;}///FilterGraph IGraphBuilderIGraphBuilder* pGraph = NULL;IBaseFilter* pAudioCaptureFilter = NULL,*pDestWavFilter = NULL, *pWriteFilter = NULL;HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&pGraph);if (FAILED(hr)){MessageBox(NULL, L"IFilterGraph failed!", L"ErrWnd", NULL);return 0;}///AudioCaptureFiltervector<wstring> audioDeviceNamesVector;map<wstring, IMoniker*> audioDeviceFriendlyMap;EnumDeviceInfo(audioDeviceNamesVector, audioDeviceFriendlyMap, CLSID_AudioInputDeviceCategory);hr = FindAudioCaptureFilter(audioDeviceFriendlyMap[audioDeviceNamesVector[0]], &pAudioCaptureFilter);if (FAILED(hr)){MessageBox(NULL, L"FindAudioCaptureFilter failed!", L"ErrWnd", NULL);return 0;}pGraph->AddFilter(pAudioCaptureFilter, L"AudioCaptureFilter");///WavDestFilterpDestWavFilter = new CWavDestFilter(NULL, &hr);if (FAILED(hr)){MessageBox(NULL, L"WavDestFilter failed!", L"ErrWnd", NULL);return 0;}pGraph->AddFilter(pDestWavFilter, L"WavDestFilter");///WriteFilterhr = AddFilterToGraph(pGraph, CLSID_FileWriter, L"WriteFilter", &pWriteFilter);if (FAILED(hr)){MessageBox(NULL, L"WriteFilter failed!", L"ErrWnd", NULL);return 0;}IFileSinkFilter* pFileSinkFilter;hr = pWriteFilter->QueryInterface(IID_IFileSinkFilter, (void**)&pFileSinkFilter);if (FAILED(hr)){MessageBox(NULL, L"IFileSinkFilter failed!", L"ErrWnd", NULL);return 0;}pFileSinkFilter->SetFileName(L"E:\\TestFile\\AudioCapture.wav", NULL);///ConnectedFiltersConnectedFilters(pGraph, pAudioCaptureFilter, pDestWavFilter);ConnectedFilters(pGraph, pDestWavFilter, pWriteFilter);///MediaControlIMediaControl* pControl = NULL;hr = pGraph->QueryInterface(IID_IMediaControl, (void**)&pControl);if (FAILED(hr)){MessageBox(NULL, L"QueryInterface IMediaControl Failed!", L"ErrWnd", NULL);return 0;}//hr = pControl->Run();if (SUCCEEDED(hr)){Sleep(10000);pControl->Stop();}///COM_End:::CoUninitialize();return 0;
}

//上面API函数:均是DirectShow教程中封装的函数,我们可以封装起来拿来用!

DirectShow之音频录制Wav相关推荐

  1. html在线录音并上传,一种网页版在线录制wav音频的方法与流程

    本发明涉及网页版音频录制的技术领域,特别涉及一种网页版在线录制wav音频的方法. 背景技术: 随着国内经济的快速发展,人们的生活水平越来越高,而随之带动了电子产品的广泛应用与高速发展,电子已普及到人们 ...

  2. ffmpeg js转换音频_将微信jssdk录制的speex高清音频转换为wav/mp3

    今天在做微信开发的时候需要将jssdk录制的音频上传到微信平台,但是jssdk录制的是speex高清格式,不能直接转换为mp3或者wav格式, 微信官方提供了一个说明: [如果speex音频格式不符合 ...

  3. iOS 音频录制AMR和WAV互转(支持64位)

    公司项目中涉及到语音录制的功能,在录音格式方面遇到一些小问题现在拿出来与大家分享一下. 众所周知,iOS 音频录制是不支持AMR格式的.但 Android 好像是默认是AMR格式的.两边格式不同必然有 ...

  4. Android开发音效中录制WAV音频和录制MP3音频的讲解及实战(超详细 附源码)

    需要源码请点赞关注收藏后评论区留下QQ~~~ 一.录制WAV音频 无论是MediaRecoredr录制的AMR和AAC音频,还是AudioRecord录制的PCM音频,都不能在计算机上直接播放,因为它 ...

  5. audiorecord怎么释放_Android 开发 AudioRecord音频录制

    前言 Android SDK 提供了两套音频采集的API,分别是:MediaRecorder 和 AudioRecord,前者是一个更加上层一点的API,它可以直接把手机麦克风录入的音频数据进行编码压 ...

  6. .NET NAudio音频录制方法 2021-02-13

    .NET NAudio音频录制方法 写在前面 文章主要内容 说明 检测录音电平 调节录音电平 开始录音 调整音频 保存音频 关于作者 讨论 SomeONe Clint Nate Greenwood C ...

  7. 如何进行音频录制?实用的音频录制方法合集

    音频录制是一种重要的技能,可以用于各种场合,比如我们可以使用音频录制技术录制不同乐器和声音的音频,并在后期进行处理和混音,制作出完整的音乐作品等等.但是,要想录制出高质量的音频并不容易,需要掌握一些专 ...

  8. Android 开发 AudioRecord音频录制

    前言 Android SDK 提供了两套音频采集的API,分别是:MediaRecorder 和 AudioRecord,前者是一个更加上层一点的API,它可以直接把手机麦克风录入的音频数据进行编码压 ...

  9. 音频录制软件怎么在电脑上下载,如何在线录音

    音频软件是每个人都会使用到的小功能,但是也是无法被替代的,不管是在学习还是工作中,都会多多少少的用到,可能我们平时使用的都是手机录音,但是手机中的功能很少,一般无法满足我们对录音的需求,那音频录制软件 ...

  10. 1.Java实现音频录制和音频播放

    在做项目的时候需要用到音频录制,于是就百度学习了一下,综合了一下实际可用的例子. 使用代码如下: package audio;public class Test {public static void ...

最新文章

  1. 探索JAVA并发 - 如何减少锁的竞争
  2. javascript中new Date浏览器兼容性处理
  3. SQLServer Always On FCI 脑裂及可疑状态修复
  4. 计算机组成原理实验箱使能开关,计算机组成原理微程序计数器实验报告
  5. C++ chrono 库中的 steady_clock 、 system_clock、high_resolution_clock区别
  6. Android 百度地图Demo
  7. 验证dropdownlist必选
  8. matlab 棍,双足机器人行走棍图怎么用MATLAB画出来
  9. 【OpenCV】腐蚀膨胀
  10. 汇编语言典型例子详解_汇编语言例子_汇编语言 举例子
  11. unity使用VideoPlayer播放视频
  12. js如何实现数组随机排序【附洗牌算法心得】
  13. Word题库转成Excel题库的方法
  14. 马化腾:谈谈我创办腾讯这些年
  15. mysql删除日志文件_mysql删除日志文件,定时清理日志
  16. ping计算机名获取IP
  17. CorelDraw绘图技巧十九招
  18. 双屏显示 鼠标不能从左侧滑入右侧竖屏
  19. [RK3568 Android11] 开发之开发者选项中添加USB OTG模式切换(二)
  20. 考研英语 - word-list-1

热门文章

  1. 【技术美术图形部分】2.1 色彩空间
  2. 针对前端项目选择不同的前端框架
  3. ubuntu android驱动,ubuntu中正确设置android手机驱动程序
  4. 多渠道打包之动态修改App名称,图标,applicationId,版本号,添加资源
  5. 3DMAX里怎样打包贴材质的文件不丢失贴图材质?
  6. 与骗子约会:浅谈欺诈性约会APP的生态
  7. 使用最小二乘法计算机器学习算法之线性回归(计算过程与python实现)
  8. 4、python简单线性回归代码案例(完整)_Python:简单线性回归(不需要调用任何库,math都不要)...
  9. 深度学习 | 深度学习算法中英文对照表
  10. 2000-2021年款雷克萨斯原厂全套维修手册+电路图资料下载