处理大型WAV文件的播放方法
作者:鸡__腿孜然小朋友 | 来源:互联网 | 2024-11-30 16:41
本文探讨了在多媒体软件开发中处理大型WAV音频文件的策略。由于Windows提供的`sndPlaySound`API仅适用于小文件,对于大型WAV文件,我们介绍了使用MCI(MediaControlInterface)命令的一种有效解决方案。
在多媒体软件开发中,处理音频文件是一项常见的任务。对于小型WAV文件,可以通过Windows提供的API `sndPlaySound`轻松实现播放功能。然而,当WAV文件超出可用内存时,`sndPlaySound`将无法正常工作。这时,就需要采用MCI(Media Control Interface)来解决这一问题。 MCI支持多种音频文件格式,包括MIDI的RMI文件和波形音频WAV文件。本文主要介绍如何使用MCI命令来播放大型WAV文件。与`sndPlaySound`不同,MCI允许分段加载和播放文件,从而支持大型文件的播放。 为了简化MCI命令的使用,本文创建了一个名为`CWave`的类,该类封装了MCI命令的执行过程。`CWave`类提供了几个关键的成员函数,如`OpenDevice`、`CloseDevice`、`Play`和`Stop`,用于控制波形音频设备的打开、关闭、播放和停止操作。 具体来说,`CWave`类的`OpenDevice`函数通过发送`MCI_OPEN`命令来打开波形音频设备,并获取设备标识符。`Play`函数则负责打开WAV文件并开始播放。为了实现异步播放,`Play`函数会设置回调窗口句柄,以便在播放完成后接收通知消息。播放结束后,`Stop`函数会关闭当前的WAV文件,而`CloseDevice`函数则负责释放波形音频设备。 以下是`CWave`类的定义和部分实现代码示例: ```cpp // Wave.h #include class CWave { public: CWave(); virtual ~CWave(); DWORD OpenDevice(); DWORD CloseDevice(); DWORD Play(CWnd *pWnd, LPCSTR pFileName); DWORD Stop(); protected: void DisplayErrorMsg(DWORD dwError); protected: MCIDEVICEID m_nDeviceID; MCIDEVICEID m_nElementID; }; ``` ```cpp // Wave.cpp #include "Wave.h" CWave::CWave() : m_nDeviceID(0), m_nElementID(0) {} CWave::~CWave() { if (m_nElementID) Stop(); if (m_nDeviceID) CloseDevice(); } DWORD CWave::OpenDevice() { MCI_OPEN_PARMS mciOpenParms = {0}; mciOpenParms.lpstrDeviceType = (LPSTR)MCI_DEVTYPE_WAVEFORM_AUDIO; DWORD dwResult = mciSendCommand(0, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_ELEMENT, (DWORD)&mciOpenParms); if (!dwResult) { m_nDeviceID = mciOpenParms.wDeviceID; } else { DisplayErrorMsg(dwResult); } return dwResult; } DWORD CWave::CloseDevice() { if (m_nDeviceID) { DWORD dwResult = mciSendCommand(m_nDeviceID, MCI_CLOSE, 0, 0); if (!dwResult) { m_nDeviceID = 0; } else { DisplayErrorMsg(dwResult); } } return 0; } DWORD CWave::Play(CWnd *pWnd, LPCSTR pFileName) { MCI_OPEN_PARMS mciOpenParms = {0}; mciOpenParms.lpstrElementName = pFileName; DWORD dwResult = mciSendCommand(m_nDeviceID, MCI_OPEN, MCI_OPEN_ELEMENT, (DWORD)&mciOpenParms); if (!dwResult) { m_nElementID = mciOpenParms.wDeviceID; MCI_PLAY_PARMS mciPlayParms = {0}; mciPlayParms.dwCallback = (DWORD)pWnd->m_hWnd; dwResult = mciSendCommand(m_nElementID, MCI_PLAY, MCI_NOTIFY, (DWORD)&mciPlayParms); if (dwResult) { DisplayErrorMsg(dwResult); Stop(); } } else { DisplayErrorMsg(dwResult); } return dwResult; } DWORD CWave::Stop() { if (m_nElementID) { DWORD dwResult = mciSendCommand(m_nElementID, MCI_CLOSE, 0, 0); if (!dwResult) { m_nElementID = 0; } else { DisplayErrorMsg(dwResult); } } return 0; } void CWave::DisplayErrorMsg(DWORD dwError) { if (dwError) { char szErrorMsg[MAXERRORLENGTH] = {0}; mciGetErrorString(dwError, szErrorMsg, sizeof(szErrorMsg)); AfxMessageBox(szErrorMsg); } } ``` 通过上述方法,开发者可以有效地处理和播放大型WAV文件,提升多媒体应用的用户体验。
推荐阅读
题目Link题目学习link1题目学习link2题目学习link3%%%受益匪浅!----- ...
[详细]
蜡笔小新 2024-12-26 15:55:56
本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ...
[详细]
蜡笔小新 2024-12-27 11:26:39
golang常用库:配置文件解析库管理工具-viper使用-一、viper简介viper配置管理解析库,是由大神SteveFrancia开发,他在google领导着golang的 ...
[详细]
蜡笔小新 2024-12-28 13:47:52
Explore how Matterverse is redefining the metaverse experience, creating immersive and meaningful virtual environments that foster genuine connections and economic opportunities. ...
[详细]
蜡笔小新 2024-12-28 09:44:49
本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ...
[详细]
蜡笔小新 2024-12-27 17:40:42
本文详细探讨了VxWorks操作系统中双向链表和环形缓冲区的实现原理及使用方法,通过具体示例代码加深理解。 ...
[详细]
蜡笔小新 2024-12-26 13:26:16
本教程涵盖OpenGL基础操作及直线光栅化技术,包括点的绘制、简单图形绘制、直线绘制以及DDA和中点画线算法。通过逐步实践,帮助读者掌握OpenGL的基本使用方法。 ...
[详细]
蜡笔小新 2024-12-26 12:24:25
Dashboard-CodeforcesRound#566(Div.2)-CodeforcesA.FillingShapes题意:给你一个的表格,你 ...
[详细]
蜡笔小新 2024-12-25 18:41:21
本文详细探讨了KMP算法中next数组的构建及其应用,重点分析了未改良和改良后的next数组在字符串匹配中的作用。通过具体实例和代码实现,帮助读者更好地理解KMP算法的核心原理。 ...
[详细]
蜡笔小新 2024-12-28 11:30:01
2019独角兽企业重金招聘Python工程师标准一、先在cmake官网下个最新的cmake源码包cmake官网:https:www.cmake.org如此时最新 ...
[详细]
蜡笔小新 2024-12-27 17:49:56
c# – UWP:BrightnessOverride StartOverride逻辑 ...
[详细]
蜡笔小新 2024-12-27 16:56:40
本文详细介绍了Akka中的BackoffSupervisor机制,探讨其在处理持久化失败和Actor重启时的应用。通过具体示例,展示了如何配置和使用BackoffSupervisor以实现更细粒度的异常处理。 ...
[详细]
蜡笔小新 2024-12-27 15:04:09
学习链接:http:blog.csdn.netlwt36articledetails48908031学习扫描线主要学习的是一种扫描的思想,后期可以求解很 ...
[详细]
蜡笔小新 2024-12-26 20:04:36
This document outlines the recommended naming conventions for HTML attributes in Fast Components, focusing on readability and consistency with existing standards. ...
[详细]
蜡笔小新 2024-12-26 19:13:45
本实验主要探讨了二叉排序树(BST)的基本操作,包括创建、查找和删除节点。通过具体实例和代码实现,详细介绍了如何使用递归和非递归方法进行关键字查找,并展示了删除特定节点后的树结构变化。 ...
[详细]
蜡笔小新 2024-12-26 15:32:56