音频设备测试无法播放声音

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了音频设备测试无法播放声音相关的知识,希望对你有一定的参考价值。

首先,我确定耳机没有问题,然后在设备管理器中也看不到有什么问号,也就是驱动都正常,设备显示正常工作,但是就是在测试音频硬件的时候提示无法播放声音,这到底是怎么回事?用千千静听播放文件时提示无法打开

一.播放声音文件的简单方法
在VC++ 中的多媒体动态连接库中提供了一组与音频设备有关的函数。利用这些函数可以方便地播放声音。最简单的播放声音方法就是直接调用VC++中提供的声音播放函数BOOL sndPlaySound ( LPCSTR lpszSound,UINT fuSound ); 或BOOL PlaySound( LPCSTR lpszSound, HMODULE hmod, DWORD fuSound );其中参数lpszSound是需要播放声音的.WAV文件的路径和文件名, hmod在这里为NULL,fuSound是播放声音的标志,详细说明请参考VC++中的帮助。 例如播放C:soundmusic.wav可以用sndPlaySound ("c:\sound\music.wav",SND_ASYNC);或PlaySound("c:\sound\music.wav",NULL, SND_ASYNC|SND_NODEFAULT );如果没有找到music.wav文件,第一种格式将播放系统默认的声音,第二种格式不会播放系统默认的声音。

二.将声音文件加入到程序中
在VC++的程序设计中,可以利用各种标准的资源,如位图,菜单,对话框等。同时VC++也允许用户自定义资源,因此我们可以将声音文件作为用户自定义资源加入程序资源文件中,经过编译连接生成EXE文件,实现无.WAV文件的声音播放。
要实现作为资源的声音文件的播放,首先要在资源管理器中加入待播放的声音文件(实现过程并不复杂,这里不在叙述)。假设生成的声音文件资源标识符为IDR_WAVE1。在播放时只需要调用下面的语句:
PlaySound(MAKEINTRESOURCE(IDR_WAVE1),AfxGetResourceHandle(), SND_ASYNC|SND_RESOURCE|SND_NODEFAULT|SND_LOOP);
其中MAKEINTRESOURCE()宏将整数资源标识符转变为字符串,AfxGetResourceHandle()函数返回包含资源的模块句柄,
SND_RESOURCE是必须的标志。
作为资源的声音文件的第二种播放方法是把资源读入内存后作为内存数据播放。具体步骤入下:
1.获得包含资源的模块句柄:
HMODULE hmod=AfxGetResourceHandle();
2.检索资源块信息:
HRSRC hSndResource=FindResource(hmod,MAKEINTRESOURCE(IDR_WAVE1),_T("WAVE"));
3. 装载资源数据并加锁:
HGLOBAL hGlobalMem=LoadResource(hmod,hSndResource);
LPCTSTR lpMemSound=(LPCSTR)LockResource(hGlobalMem);
4.播放声音文件:
sndPlaySound(lpMemSound,SND_MEMORY));
5.释放资源句柄:
FreeResource(hGlobalMem);

三.播放声音文件的高级方法
在VC++中提供了一组对音频设备及多媒体文件直接进行操作的函数。利用这些函数可以灵活地对声音文件进行各种处理。
首先介绍几个要用到的数据结构。WAVEFORMATEX结构定义了WAVE音频数据文件的格式。WAVEHDR结构定义了波形音频缓冲区。读出的数据首先要填充此缓冲区才能送音频设备播放。WAVEOUTCAPS结构描述了音频设备的性能。MMCKINFO结构包含了RIFF文件中一个块的信息。详细的说明请参考VC++中的帮助。
下面给出程序流程简图及程序源代码清单,在VC++环境下可直接使用:

源程序清单如下:
LPSTR szFileName;//声音文件名
MMCKINFO mmckinfoParent;
MMCKINFO mmckinfoSubChunk;
DWORD dwFmtSize;
HMMIO m_hmmio;//音频文件句柄
DWORD m_WaveLong;
HPSTR lpData;//音频数据
HANDLE m_hData;
HANDLE m_hFormat;
WAVEFORMATEX * lpFormat;
DWORD m_dwDataOffset;
DWORD m_dwDataSize;
WAVEHDR pWaveOutHdr;
WAVEOUTCAPS pwoc;
HWAVEOUT hWaveOut;
//打开波形文件
if(!(m_hmmio=mmioOpen(szFileName,NULL,MMIO_READ|MMIO_ALLOCBUF)))

//File open Error
Error("Failed to open the file.");//错误处理函数
return false;

//检查打开文件是否是声音文件
mmckinfoParent.fccType =mmioFOURCC(’W’,’A’,’V’,’E’);
if(mmioDescend(m_hmmio,(LPMMCKINFO)&mmckinfoParent,NULL,MMIO_FINDRIFF))

//NOT WAVE FILE AND QUIT

//寻找 ’fmt’ 块
mmckinfoSubChunk.ckid =mmioFOURCC(’f’,’m’,’t’,’ ’);
if(mmioDescend(m_hmmio,&mmckinfoSubChunk,&mmckinfoParent,MMIO_FINDCHUNK))

//Can’t find ’fmt’ chunk

//获得 ’fmt ’块的大小,申请内存
dwFmtSize=mmckinfoSubChunk.cksize ;
m_hFormat=LocalAlloc(LMEM_MOVEABLE,LOWORD(dwFmtSize));
if(!m_hFormat)

//failed alloc memory

lpFormat=(WAVEFORMATEX*)LocalLock(m_hFormat);
if(!lpFormat)

//failed to lock the memory

if((unsigned long)mmioRead(m_hmmio,(HPSTR)lpFormat,dwFmtSize)!=dwFmtSize)

//failed to read format chunk

//离开 fmt 块
mmioAscend(m_hmmio,&mmckinfoSubChunk,0);
//寻找 ’data’ 块
mmckinfoSubChunk.ckid=mmioFOURCC(’d’,’a’,’t’,’a’);
if(mmioDescend(m_hmmio,&mmckinfoSubChunk,&mmckinfoParent,MMIO_FINDCHUNK))

//Can’t find ’data’ chunk

//获得 ’data’块的大小
m_dwDataSize=mmckinfoSubChunk.cksize ;
m_dwDataOffset =mmckinfoSubChunk.dwDataOffset ;
if(m_dwDataSize==0L)

//no data in the ’data’ chunk

//为音频数据分配内存
lpData=new char[m_dwDataSize];
if(!lpData)

//faile

if(mmioseek(m_hmmio,SoundOffset,SEEK_SET)<0)

//Failed to read the data chunk

m_WaveLong=mmioRead(m_hmmio,lpData,SoundLong);
if(m_WaveLong<0)

//Failed to read the data chunk

//检查音频设备,返回音频输出设备的性能
if(waveOutGetDeVCaps(WAVE_MAPPER,&pwoc,sizeof(WAVEOUTCAPS))!=0)

//Unable to allocate or lock memory

//检查音频输出设备是否能播放指定的音频文件
if(waveOutOpen(&hWaveOut,DevsNum,lpFormat,NULL,NULL,CALLBACK_NULL)!=0)

//Failed to OPEN the wave out devices

//准备待播放的数据
pWaveOutHdr.lpData =(HPSTR)lpData;
pWaveOutHdr.dwBufferLength =m_WaveLong;
pWaveOutHdr.dwFlags =0;
if(waveOutPrepareHeader(hWaveOut,&pWaveOutHdr,sizeof(WAVEHDR))!=0)

//Failed to prepare the wave data buffer

//播放音频数据文件
if(waveOutWrite(hWaveOut,&pWaveOutHdr,sizeof(WAVEHDR))!=0)

//Failed to write the wave data buffer

//关闭音频输出设备,释放内存
waveOutReset(hWaveOut);
waveOutClose(hWaveOut);
LocalUnlock(m_hFormat);
LocalFree(m_hFormat);
delete [] lpData;
说明:1)以上使用的音频设备和声音文件操作函数的声明包含在mmsystem.h头文件中,因此在程序中必须用#include "mmsystem.h"语句加入头文件。同时在编译时要加入动态连接导入库winmm.lib,具体实现方法是从Developer Studio的Project菜单中选择Settings,然后在Link选项卡上的Object/Library Modules控制中加入winmm.lib。2)在pWaveOutHdr.lpData中指定不同的数据,可以播放音频数据文件中任意指定位置的声音。3) 以上程序均在VC++6.0中调试通过,在文中省略了对错误及异常情况的处理,在实际应用中必须加入。
四.结论
在VC++中可以根据应用需要采用不同的方法播放声音文件。简单应用可以直接调用声音播放函数。第二种方法可以把声音作为资源加入可执行文件中。如果在播放之前要对声音数据进行处理,可用第三种方法。
参考技术A 可以试试安全模式运行,点击右下角的喇叭按钮,等检测完毕后,如果没有其他问题,只出现未安装,那么正常模式重启后应该就好了。我的就是这样解决的

如何在 Windows 上使用 C++ 在特定音频设备上播放声音?

【中文标题】如何在 Windows 上使用 C++ 在特定音频设备上播放声音?【英文标题】:How to play sound on specific audio device with C++ on windows? 【发布时间】:2021-04-08 19:40:08 【问题描述】:

我知道winapi提供了PlaySound()函数,但是如何选择输出音频设备呢? 我希望我的程序在特定设备上播放声音,有没有办法在 Windows 上的 C++ 上做到这一点?

【问题讨论】:

您已经看过here 并想要一个代码示例? 我想看一个简单的代码示例来理解 并检查this one,您可以使用waveOutGetNumDevs 获取设备数量,然后使用waveOutGetDevCaps 返回给定设备的能力,使用waveOutWrite 将数据块发送到给定的波形音频输出设备等 ma1169,谢谢!这看起来像是我一直在寻找的东西 【参考方案1】:

检查这个库mmeApi,这里是audio streaming sample code from microsoft

【讨论】:

以上是关于音频设备测试无法播放声音的主要内容,如果未能解决你的问题,请参考以下文章

音频无法在所有 iOS 设备上播放

电脑无法播放声音,提示没有音频设备,这该怎么办?

台式电脑音频管理器无法播放测试音频,电脑没有音频输出没有声音,怎么解决?

系统声音服务连接到汽车的蓝牙时不会播放音频

在 C# 中的录音设备上播放声音

如何在 Windows 上使用 C++ 在特定音频设备上播放声音?