(五)MFC学习之使用directSound播放音频文件
环境:windows10+vs2017
音频格式要求:.wav (8位24khz)(这是默认的)
directx只能播放wav格式文件
DirectSound提供了各种音效处理的支持,如:低延迟、3d立体和协调硬件等功能
vs2012开始,vs已经集成directx
步骤:
- 创建DirectSound对象
- 设定协作等级(协调使用硬件的权限)
- 创建主缓存区
- 从音频文件加载音频到次缓冲区
- 播放音频
相关概念:
- 主缓存区:DiectSound播放声音、产生混音效果的区域。默认播放格式是(8bit,22kHz)如果不需要播放其他格式(指的是不同位,不同频率的音频,但是都是wav格式),就不需要手动创建主缓存区,否则需要先创建主缓冲区(16bit,44kHz),对其格式进行设定。(相当于舞台)
- 次缓冲区:主要用于存储要播放的音频数据及播放格式,可以建立数个次缓冲区来存放多个要播放的声音(相当于舞台幕后)
示意图:
WAVE音频文件格式:
是RIFF文件(Resource InterChange File Format ),DirectSound只接受“.wav”文件
使用到的类:
窗体程序基本就用到CMyApp,CMyWnd
其余就是:
LPDIRECTSOUND;
LPDIRECTSOUNDBUFFER ;
HRESULT
代码:
#include <afxwin.h>
#include <mmsystem.h>
#include <dsound.h>//常量定义
//#define SOUND_FILE_NAME "SOUND.WAV";
//线程部分HANDLE threadHandle;DWORD threadId;DWORD funcRun(LPVOID lParam);class CMyWnd :public CFrameWnd {
private:CDC *mdc;CBitmap* bmp[2];//优先级最高 []//优先级最低 ,
// CRect rect;CRect * rect;int mFrameNo;int x;//声音部分LPDIRECTSOUND pDs;LPDIRECTSOUNDBUFFER pDSB_BK, pDSB_MG;HRESULT result;public:CMyWnd();LPDIRECTSOUNDBUFFER CreateSecondBuffer(LPSTR filename);DECLARE_MESSAGE_MAP()afx_msg void OnPaint();};
CMyWnd::CMyWnd() {Create(NULL, "TestThread");mdc = new CDC;CClientDC dc(this);mFrameNo = 0;//客户区大小rect = new CRect;GetClientRect(rect);x = 63;//创建线程threadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)funcRun, this, 0, &threadId);mdc->CreateCompatibleDC(&dc);for (int i = 0; i < 2; i++) {bmp[i] = new CBitmap;}//springf_s;bmp[0]->m_hObject = LoadImage(NULL, "bground.bmp",IMAGE_BITMAP, rect->right, rect->bottom, LR_LOADFROMFILE);bmp[1]->m_hObject = LoadImage(NULL, "crimer1.bmp",IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);//1,创建directSound//音频设备指针, 第三个必须为NULL,result = DirectSoundCreate(NULL, &pDs, NULL);if (result != DS_OK) {MessageBox(_T("建立DirectSound失败!"));}//2,设定程序协作等级result = pDs->SetCooperativeLevel(m_hWnd, DSSCL_PRIORITY);if (result != DS_OK) {MessageBox(_T("设定程序协调等级失败"));}//加载背景音乐char szMusicName[40];sprintf_s(szMusicName, "wavs/jump.wav");/*CString fileName = "wavs/bgm.wav";*/pDSB_BK = CreateSecondBuffer(szMusicName);pDSB_BK->Play(0, 0, 1);}
//创建次缓冲区
LPDIRECTSOUNDBUFFER CMyWnd:: CreateSecondBuffer(LPSTR filename) {//声音部分HMMIO hmmio;MMRESULT mmresult;//函数返回值//1,打开音频文件hmmio = mmioOpen(filename, NULL, MMIO_ALLOCBUF | MMIO_READ);if (NULL == hmmio) {MessageBox(_T("文件打开失败"));}// 2,确认是否为riff文件MMCKINFO ckriff;//WAVE文件信息结构ckriff.fccType = mmioFOURCC('W', 'A', 'V', 'E');mmresult = mmioDescend(hmmio, &ckriff, NULL, MMIO_FINDRIFF);//最后一个常量是查找类型if (MMSYSERR_NOERROR != mmresult) {MessageBox(_T("文件类型不是wave"));}//3,进入fmt区块,读取音频格式,然后退出fmt区块MMCKINFO ckinfo;ckinfo.ckid = mmioFOURCC('f', 'm', 't', ' ');//设定区块类型mmresult = mmioDescend(hmmio, &ckinfo, &ckriff, MMIO_FINDCHUNK);//此方法退出区块if (MMSYSERR_NOERROR != mmresult) {MessageBox(_T("进入fmt区域错误"));}WAVEFORMATEX swfmt;//读取音频格式if (-1 == mmioRead(hmmio, (HPSTR)&swfmt, sizeof(swfmt))) {MessageBox("读取音频文件格式失败");}//4,进入data区块,读取音频长度mmioAscend(hmmio, &ckinfo, 0);ckinfo.ckid = mmioFOURCC('d','a','t', 'a');mmresult = mmioDescend(hmmio, &ckinfo, &ckriff, MMIO_FINDCHUNK);if (MMSYSERR_NOERROR != mmresult) {MessageBox("进入data区域失败");}//5,创建音频次缓冲区LPDIRECTSOUNDBUFFER pTempBuf ;DSBUFFERDESC desc;//用以描述缓冲区结构memset(&desc, 0, sizeof(desc));desc.dwSize = sizeof(desc);desc.lpwfxFormat = &swfmt;desc.dwFlags = DSBCAPS_STATIC;//static表示可多次播放,当然还可以指定其他的使用| 连接desc.dwBufferBytes = ckinfo.cksize;result = pDs->CreateSoundBuffer(&desc, &pTempBuf, NULL);if (DS_OK != result) {MessageBox("创建次缓冲失败");return NULL;}// 6,从文件读取音频数据存入次缓冲区LPVOID pAudio;DWORD BytesAudio;pTempBuf->Lock(0, ckinfo.cksize, &pAudio, &BytesAudio, NULL, NULL, NULL);if (-1 == mmioRead(hmmio, (HPSTR)pAudio, BytesAudio)) {MessageBox("读取音频数据失败");}pTempBuf->Unlock(pAudio, BytesAudio, NULL, NULL);//7,关闭文件mmioClose(hmmio, 0);return pTempBuf;
}
class CMyApp :public CWinApp
{BOOL InitInstance();};
BOOL CMyApp::InitInstance() {CMyWnd * pf = new CMyWnd;
// pf->Create(0,"hello");pf->ShowWindow(m_nCmdShow);pf->UpdateWindow();this->m_pMainWnd = pf;return TRUE;
}BEGIN_MESSAGE_MAP(CMyWnd, CFrameWnd)
ON_WM_PAINT()
END_MESSAGE_MAP()void CMyWnd::OnPaint()
{//这里只能使用CPaintDcCPaintDC dc(this); // device context for painting// TODO: 在此处添加消息处理程序代码// 不为绘图消息调用 CFrameWnd::OnPaint()mdc->SelectObject(bmp[0]);dc.BitBlt(0, 0, rect->right, rect->bottom, mdc, 0, 0, SRCCOPY);mdc->SelectObject(bmp[1]);switch (mFrameNo){case 0:dc.BitBlt(x, rect->bottom/2-70,49, 154, mdc,49, 0, SRCAND);dc.BitBlt(x, rect->bottom/2-70, 49, 154, mdc, 0, 0, SRCPAINT);mFrameNo = 1;break;case 1:dc.BitBlt(x, rect->bottom /2-70, 49, 154, mdc, 49, 154, SRCAND);dc.BitBlt(x, rect->bottom /2-70, 49, 154, mdc, 0, 154, SRCPAINT);mFrameNo =0;break;default:break;}x += 63;if (x > rect->right) {x = 63;}}
//线程方法实现
DWORD funcRun(LPVOID lParam) {CMyWnd* wnd = (CMyWnd*)lParam;while (1) {wnd->Invalidate();Sleep(500);}return 0;}CMyApp TheApp;
注意使用directsound需要注意依赖库:
- 头文件:“mmsystem.h”和“sdound.h”
- 项目->属性->链接器->附加依赖项中添加:“dxguid.lib”、“dsound.lib”、"winmm.lib"库
此代码可以直接运行!
需要注意音频文件位置。
wav声音制作:
使用软件:Cool Edit pro 即可,使用方便(附上网盘链接 )
链接:https://pan.baidu.com/s/1DgLTYgSBwgq-T0HP-1dxCw
提取码:l886
以将mp3转为 8位,22khz的wav文件为例:
file-》open(选择mp3文件-》edit-》convert ...->设置一些参数-》等待几秒即可完成转换-》file->save as(选择wav格式保存即可)
设置参数:
(五)MFC学习之使用directSound播放音频文件相关推荐
- DirectSound播放音频应用程序开发快速入门
[来源天极网] 摘要:DirectSound编程的入门介绍,通过实例讲解了如何利用DirectSound最基本的功能-----播放音频,并提供了DirectSound播放音频文件的两种方式(Stati ...
- Unity 播放音频文件
Unity 播放音频文件参考代码: 1 public void Play(string strSoundName, float autoDestroyTime = 0f, bool bLoop = f ...
- ArcGIS API for Silverlight 当DataGrid选中项时,地图聚焦弹出窗口,并可以播放音频文件...
原文:ArcGIS API for Silverlight 当DataGrid选中项时,地图聚焦弹出窗口,并可以播放音频文件 先看效果图,然后上代码: <UserControl x:Class= ...
- C#调用mciSendString播放音频文件
mciSendString函数是一个WinAPI,主要用来向MCI(Media Control Interface)设备发送字符串命令. 一.函数的声明如下: private static exter ...
- 使用DirectSound播放MP3文件
http://www.cppblog.com/codejie/archive/2009/03/26/77916.html 使用DirectSound播放MP3文件 将对MP3的支持代码加入到DSoun ...
- 如何实现在直播中播放音频文件
在我们看直播的时候,经常会在直播过程中听到有掌声.口哨声.背景音乐等音效,那么这些声音特效是如何实现的呢大家有没有想过?anyRTC下面就为大家简单介绍一下如何实现在直播过程中播放音频文件. 功能描述 ...
- js 自动播放音频文件,报警提示音等
js 自动播放音频文件,报警提示音等 谷歌浏览器的音频,默认是不能在页面载入时直接自动播放的. 至少需要用户点击一下页面,才可以播放音频,这个策略的目的是保证用户的体验感,如果每个页面都能在用户未接触 ...
- python播放音频文件_详解使用pygame播放一段MP3音频文件
近日,在梳理pygame模块的时候发现一个很有用的模块mixer模块,这个模块翻译过来就是混音器,它可以加载和播放音频文件,甚至可以对混音器进行设置和处理,其功能非常强大.今天,我们一起来梳理一下混音 ...
- 使用树莓派播放音频文件
使用树莓派播放音频文件 一.首先,我们需要对树莓派的音频输出进行设置 步骤1:登录树莓派,打开终端,执行sudo raspi-config命令 步骤2:选择第7项Advanced Options高级选 ...
最新文章
- OpenCV中使用YOLO对象检测
- netsh与用法--XP的各种网络命令
- html溢出自动滚动,html – 溢出-y:使用overflow-x滚动:可见
- php业务网站资源网,企业创意业务网站模板
- MSSqlServer基础学习01
- 【转】ubuntu16.04安装配置tftp服务
- 一个小故事,玩转Python-while循环
- oracle 只导出指定的表格,expdp带条件导出单个表的数据
- mekko 教程_Power BI桌面Mekko图表
- php当前工作目录路径,Linux_Linux下使用Shell脚本改变当前工作路径, She - phpStudy...
- 「python爬虫之路day9」:实战之使用正则表达式爬取抓狂网,古诗文网信息
- R语言 K-M生存分析,ggplot2制作好看的生存曲线
- 刹车刹不住,太危险?我在绿源杭州电动车店提的新车超稳哒~
- 马云给员工的超牛演讲
- [区块链笔记10] remix部署合约并连接Ganache 前端web3与智能合约交互
- 我如何使用iPad作为学习工具
- iphone为什么不能连接到服务器未响应,苹果手机(iPhone)连接电脑没反应?(这样就可以解决!)...
- 2020-CIKM-DisenHAN: Disentangled Heterogeneous Graph Attention Network for Recommendation
- 四种代码洁癖类型,程序员看了直呼内行
- 小程序移植公众号网页,laravel,vue
热门文章
- 逻辑强化(08)削弱质疑 答案解析
- 拒绝字面意思的忽悠:scheduleWithFixedDelay与scheduleAtFixedRate的真正区别
- 用Keras建立自动编码器
- 2017oracle嘉年华,2017年国产8.5分剧情片《嘉年华》国语中字
- java访问器不做处理压根就不安全
- 线路板行业含铜废水处理,铜箔废水深度处理和铜回收
- 90后,27岁转行软件测试,从月入3000+到月薪过万,打开了人生新篇章~
- JavaScript中的自执行函数和闭包实现过程
- DMPC-PEG-双酚A抗体/莱克多巴胺多克隆抗体/OTA/尼妥珠单克隆抗体/HBsAg羊抗
- 三大升级!百度智能云加速文心一言产业化落地