问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

directsound create failed什么意思

发布网友 发布时间:2022-04-23 00:57

我来回答

4个回答

热心网友 时间:2023-09-28 16:50

Introction (序)
这一章我们学习怎样用DX来播放声音和音乐。我们将会使用DirectX Audio来播放WAV和MIDI文件,使用DirectShow来播放MP3文件。此章我们仍然有一个简单的程序作例子,它会播放MP3的背景音乐,当用户用鼠标点击某个数字时它会播放一些音效。

DirectX Audio and DirectShow (DirectX Audio和 DirectShow)
我们已经学习过Direct3D和DirectInput了,现在,我要介绍另外两个DirectX组件:DirectX Audio和DirectShow。我们用DirectX Audio来播放WAV和MIDI文件;用DirectShow来播放媒体流,例如AVI和MP3。在此教程中,我们只学习一下用DirectShow播放MP3的方法。

Wav, Midi and Mp3 - When should I use what?
(WAV,MIDI和MP3——什么时候该用什么?)
那末,什么时候用什么格式好呢?嗯,这基本上取决于你的个人爱好。下面是这些格式的简介,过后我会说一下我的选择:

Wav files (WAV文件)
WAV是一种未经压缩的数字音频,CD音质,但是体积非常庞大。

Midi files (MIDI文件)
MIDI文件并没有保存音频记录,它实际上更像是一套演奏指令,所以,它的体积是非常小的。MIDI的音质完全取决于演奏设备(如我们的声卡),它在高端的设备上能表现出色,而在低端设备上则表现较差。

Mp3 files (MP3文件)
同WAV文件一样,MP3也是一种数字音频格式。不同的是,MP3文件是经过压缩的,而且是有损压缩,这意味着它的体积将大大地减小,而音质上将会有一些失真(实际上接近CD音质,基本听不出失真)。而且,MP3是一种媒体流,这意味着在播放它的时候不会将它整个的读入,取而代之的是分期的做部分读入。

My preference (我的选择)
你大概会选择MP3或MIDI来作背景音乐,特别是当你希望用户能从网上下载你的程序时。MP3和MIDI格式文件的体积都比较小,它们适合做长时间的背景音乐播放。而当需要播放简短的声效时,例如爆炸声等,我更趋向于使用WAV文件,品质能稍好一些。如果文件的体积不是问题的话,实际上我们可以使用WAV文件来播放所有的声音和音乐。

Include and Library files (头文件与库文件)
我们的项目需要增加以下的头文件和库文件:

o dmusici.h
o dsound.h
o dshow.h
o dsound.lib
o strmiids.lib

Setting up DirectX Audio (设置DirectX Audio)
要使用Direct Audio我们需要创建两个对象:演奏对象(Performance Object,有些资料翻译为执行对象)和加载器(Loader)。演奏对象是Direct Audio中的最高级对象,用于处理从源到合成器的数据流。加载器用于把文件(WAV或MIDI)加载到声音段以待播放。这两个对象在整个应用程序中我们每样只需要一个,所以,我们已经把它们创建为CGame的成员变量了。下面是它们的定义:

IDirectMusicPerformance8* m_pDirectAudioPerformance;
IDirectMusicLoader8* m_pDirectAudioLoader;

由于Direct Audio是一个纯COM,所以我们需要初始化COM。其实很简单,我们只需要在CGame的构造函数中调用CoInitialize函数即可:

CoInitialize(NULL);

初始化COM后,我们就可以创建上述的那两个DirectX Audio对象了。为此,我们给CGame做了一个新的函数InitialiseDirectAudio,它将会在Initialise函数中被调用。代码如下:

bool CGame::InitialiseDirectAudio(HWND hWnd)
{
LogInfo("<br>Initialise DirectAudio:");

//Create the DirectAudio performance object
if(CoCreateInstance(CLSID_DirectMusicPerformance, NULL, CLSCTX_INPROC,
IID_IDirectMusicPerformance8,
(void**) &m_pDirectAudioPerformance) != S_OK)
{
LogError("<li>Failed to create the DirectAudio perfomance object.");
return false;
}
else
{
LogInfo("<li>DirectAudio perfomance object created OK.");
}

//Create the DirectAudio loader object
if(CoCreateInstance(CLSID_DirectMusicLoader, NULL, CLSCTX_INPROC,
IID_IDirectMusicLoader8,
(void**) &m_pDirectAudioLoader) != S_OK)
{
LogError("<li>Failed to create the DirectAudio loader object.");
return false;
}
else
{
LogInfo("<li>DirectAudio loader object created OK.");
}

//Initialise the performance object
if(FAILED(m_pDirectAudioPerformance->InitAudio(NULL, NULL, hWnd,
DMUS_APATH_SHARED_STEREOPLUSREVERB,
64, DMUS_AUDIOF_ALL, NULL)))
{
LogError("<li>Failed to initialise the DirectAudio perfomance object.");
return false;
}
else
{
LogInfo("<li>Initialised the DirectAudio perfomance object OK.");
}

//Get the our applications "sounds" directory.
CHAR strSoundPath[MAX_PATH];
GetCurrentDirectory(MAX_PATH, strSoundPath);
strcat(strSoundPath, "\\Sounds");

//Convert the path to unicode.
WCHAR wstrSoundPath[MAX_PATH];
MultiByteToWideChar(CP_ACP, 0, strSoundPath, -1, wstrSoundPath, MAX_PATH);

//Set the search directory.
if(FAILED(m_pDirectAudioLoader->SetSearchDirectory(GUID_DirectMusicAllTypes,
wstrSoundPath, FALSE)))
{
LogError("<li>Failed to set the search directory '%s'.", strSoundPath);
return false;
}
else
{
LogInfo("<li>Search directory '%s' set OK.", strSoundPath);
}

return true;
}

我们用CoCreateInstance函数创建了演奏对象和加载器,然后调用了InitAudio模块来初始化演奏对象。上面代码中给InitAudio的参数是很典型的,所以你可以沿用它(查看一下SDK中的关于InitAudio函数以及它的参数的内容以获得更多的了解)。最后,我们设置了搜索目录。搜索目录应该被设置为存放声音文件的目录,以便加载器可以正确的加载声音文件。在本例中,搜索目录被设置为“Sounds”文件夹,它应该在本例的项目文件夹当中。

A new class - CSound (一个新的类——CSound)
我们已经为使用DirectX Audio作了必要的准备工作,现在,我们就可以加载、播放声音和音乐了。为此,我们做了一个新的类CSound,下面是它的代码,稍后我会解释它是怎样工作的:

CSound::CSound()
{
m_pDirectAudioPerformance = NULL;
m_pDirectAudioLoader = NULL;
m_pSegment = NULL;
m_pGraph = NULL;
m_pMediaControl = NULL;
m_pMediaPosition = NULL;
m_enumFormat = Unknown;

LogInfo("<li>Sound created OK");
}

void CSound::InitialiseForWavMidi(IDirectMusicPerformance8* pDirectAudioPerformance, IDirectMusicLoader8* pDirectAudioLoader)
{
m_pDirectAudioPerformance = pDirectAudioPerformance;
m_pDirectAudioLoader = pDirectAudioLoader;

m_enumFormat = WavMidi;
}

void CSound::InitialiseForMP3()
{
CoCreateInstance(CLSID_FilterGraph, NULL,
CLSCTX_INPROC, IID_IGraphBuilder, (void**)&m_pGraph);

m_pGraph->QueryInterface(IID_IMediaControl, (void**)&m_pMediaControl);

m_pGraph->QueryInterface(IID_IMediaPosition, (void**)&m_pMediaPosition);

m_enumFormat = MP3;
}

CSound::~CSound()
{
Stop();

SafeRelease(m_pSegment);
SafeRelease(m_pGraph);
SafeRelease(m_pMediaControl);
SafeRelease(m_pMediaPosition);

LogInfo("<li>Sound destroyed OK");
}

bool CSound::LoadSound(const char* szSoundFileName)
{
WCHAR wstrSoundPath[MAX_PATH];
CHAR strSoundPath[MAX_PATH];

switch(m_enumFormat)
{
case MP3:
//Get the our applications "sounds" directory.
GetCurrentDirectory(MAX_PATH, strSoundPath);
strcat(strSoundPath, "\\Sounds\\");
strcat(strSoundPath, szSoundFileName);

//Convert the path to unicode.
MultiByteToWideChar(CP_ACP, 0, strSoundPath, -1,
wstrSoundPath, MAX_PATH);

m_pGraph->RenderFile(wstrSoundPath, NULL);
break;
case WavMidi:
//Convert the filename to unicode.
MultiByteToWideChar(CP_ACP, 0, szSoundFileName, -1,
wstrSoundPath, MAX_PATH);

//Load a sound
m_pDirectAudioLoader->LoadObjectFromFile(CLSID_DirectMusicSegment,
IID_IDirectMusicSegment8,
wstrSoundPath,
(void**) &m_pSegment);

m_pSegment->Download(m_pDirectAudioPerformance);
break;
default:
return false;
}

return true;
}

bool CSound::Play(DWORD dwNumOfRepeats)
{

switch(m_enumFormat)
{
case MP3:
//Make sure that we are at the start of the stream
m_pMediaPosition->put_CurrentPosition(0);

//Play mp3
m_pMediaControl->Run();
break;
case WavMidi:
//Set the number of times the sound repeats
m_pSegment->SetRepeats(dwNumOfRepeats); //To loop the sound forever, pass
//in DMUS_SEG_REPEAT_INFINITE

//Play the loaded sound
m_pDirectAudioPerformance->PlaySegmentEx(m_pSegment, NULL, NULL, 0, 0,
NULL, NULL, NULL);
break;
default:
return false;
}

return true;
}

bool CSound::Stop()
{
switch(m_enumFormat)
{
case MP3:
m_pMediaControl->Stop();
break;
case WavMidi:
//Stop the loaded sound
m_pDirectAudioPerformance->StopEx(m_pSegment, 0, 0);
break;
default:
return false;
}

return true;
}

bool CSound::IsPlaying()
{
switch(m_enumFormat)
{
case MP3:
REFTIME refPosition;
REFTIME refDuration;

m_pMediaPosition->get_CurrentPosition(&refPosition);
m_pMediaPosition->get_Duration(&refDuration);

if(refPosition < refDuration)
{
return true;
}
else
{
return false;
}
break;
case WavMidi:
if(m_pDirectAudioPerformance->IsPlaying(m_pSegment, NULL) == S_OK)
{
return true;
}
else
{
return false;
}
break;
default:
return false;
}
}

那末,怎样用CSound来播放音乐呢?这很简单。首先,创建一个CSound对象,然后根据你想播放的声音类型来调用InitialiseForWavMidi或是InitialiseForMP3,二者选其一。接着,调用LoadSound读取声音文件。最后,调用Play模块来播放声音即可。很简单,不是吗?嗯,还有两个模块:Stop模块用来停止播放;IsPlaying模块用来检测声音是否正在播放。下面介绍了各个模块是怎样工作的:

InitialiseForWavMidi
InitialiseForWavMidi模块用于初始化CSound对象以待播放WAV或MIDI文件。它的两个输入参数是我们在CGame中创建好的演奏对象和加载器的接口指针,然后这两个指针会被保存为它的成员变量以备用。我们会把CSound的格式设置为WavMidi。

InitialiseForMP3
InitialiseForMP3模块用于初始化CSound对象以待播放MP3文件,它没有输入参数。InitialiseForMP3调用CoCreateInstance函数创建了一个DirectShow过滤器图管理器对象。我们能使用CoCreateInstance是因为我们在CGame的构造函数中已经调用过CoInitialize函数了。有了过滤器图管理器对象之后,我们调用它的模块QueryInterface来创建另外两个对象:一个媒体控制对象和一个媒体定位对象。这三个对象的指针将会被保存为CSound对象的成员变量。同理,我们把CSound的格式设置为MP3;

LoadSound
初始化好CSound对象后,我们就可以调用LoadSound来读取声音文件了。LoadSound只有一个参数,就是声音文件的文件名。这里不是一个路径而是一个文件名是因为所有的声音文件都应该在我们的项目的“Sounds”目录中。

如果这个CSound对象的格式为MP3,我们首先会构造出一个完整的文件路径,然后把它转换为Unicode字符集的字符串。接着,我们只需要调用过滤器图管理器对象的RenderFile模块并构造一个用于播放指定文件的过滤器图即可。

如果这个CSound对象的格式为WavMidi,我们首先会把文件名转换成Unicode字符集的字符串。接着我们会调用LoadObjectFromFile,它会载入文件并返回一个段(segment)指针。最后,我们调用段的Download模块下载波段到演奏对象里。

现在我们已经准备好来播放声音了。

Play
当文件载入后,我们就能播放它了。Play模块唯一的可选参数(默认为0)就是重复播放次数,只在播放WAV或MIDI时有效。

如果这个CSound对象的格式为MP3,我们首先会调用媒体定位对象的put_CurrentPosition模块来确认一下我们是否在媒体流的开始处。然后,我们调用媒体控制对象的Run模块来播放MP3。

如果这个CSound对象的格式为WavMidi,我们首先会设置重复次数。然后我们调用PlaySegmentEx来播放已经载入的段。如果你想让声音永远重复,输入DMUS_SEG_REPEAT_INFINITE恒量。

Stop
这能简单地停止正在播放的声音。如果是MP3,就调用媒体控制对象的Stop模块。如果是WAV或MIDI,就调用演奏对象的StopEx模块并输入要停止的段。

IsPlaying
最后,IsPlaying模块用于检测当前是否正在播放。是就返回true,不是则返回false。如果是MP3,我们会根据当前的媒体流定位与整个媒体流的长度做对比,以得知我们是否正在播放(看是否在流的终点)。如果是WAV,我们就调用演奏对象的IsPlaying模块并输入要检测的段以测试。

Cleaning up (清理)
在Csound的析构函数中我们会停止声音的播放并释放对象。在CGame中有一个新的函数CleanUpDirectAudio代码如下:

void CGame::CleanUpDirectAudio()
{
//Stop all sounds.
m_pDirectAudioPerformance->Stop(NULL, NULL, 0, 0);

//CleanUp
m_pDirectAudioPerformance->CloseDown();

SafeRelease(m_pDirectAudioLoader);
SafeRelease(m_pDirectAudioPerformance);

LogInfo("<li>CleanUpDirectAudio finished.");
}

Here we first stop all sounds from playing (just in case), then we close down the performance object before releasing it and the loader object. Also, in the CGame deconstructor we need to call CoUninitialize to close down the COM library (shown below).
这里我们首先停止所有声音的播放,然后关闭演奏对象,释放演奏对象和加载器。而且,在CGame的析构函数中我们会调用CoUninitialize来关掉COM:

CoUninitialize();

那末现在我们能在程序中播放音乐和声音了。当程序开始时,MP3的背景音乐就会开始播放。移动鼠标并点击不同的数字我们对听到不同的声音。这里的背景MP3只是一个小片断的循环,愿意的话你可以替换成你喜欢的音乐。(译者:我把我的MP3都放了一遍爽)

Summary (摘要)
In this tutorial we learnt how to play sounds and music using two new DirectX components, DirectX Audio and DirectShow. In the next tutorial we will use all of the skills we have seen so far to create our first game: 3D Pong. This game will be simple, but will have all of the key features that you would expect from any game.

热心网友 时间:2023-09-28 16:50

这句话在不同的地方有不同的意思,要具体看实在哪里出现的。
一般都是软件或者系统故障提示。这时,往往意思是:请求失败,资源正在被其他程序使用中。

热心网友 时间:2023-09-28 16:51

声音创造不合格

热心网友 时间:2023-09-28 16:51

题目错了
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
李卓彬工作简历 林少明工作简历 广东工业职业技术学院怎么样 郑德涛任职简历 唐新桂个人简历 土地入股的定义 ups快递客服电话24小时 贷款记录在征信保留几年? 安徽徽商城有限公司公司简介 安徽省徽商集团新能源股份有限公司基本情况 2015上半年安徽省中小学教师资格报名条件具体是啥?有学历要求么? DirectGraphic Create Failed - 信息提示 设备创建失败,出现&quot;Device create failed&quot;怎么办?迫切希望得到帮助,谢谢~ 安徽省成人自考大专初中学历好报名吗? device create failed的问题 请问:安徽省公务员必须以最高学历报考吗?我本科学中文,硕士学思政,想以本科学历报考,可以吗? dcvice create failed是什么意思? 在安徽报考学历的话,可选择的专业有哪些 QQ三国出现 GameUI Create Failed 怎么办 请问安徽省公务员招录职位中要求本科的是指全日制本科学历吗?还有,专科可以考安徽省公务员吗? 删除文件,新建文件夹时出现File Create Failed 安徽省的自考本科文凭在公*中能报考有本科要求的职位吗 device create failed 是什么意思? 安徽省政法干警考试中学历要求专科的本科可以报吗 create process failed是怎么回事? 安徽省公务员考试学历要求 device create failed是什么意思 安徽公务员要求什么学历?最低什么学历?国税和地税要求什么学历?同等学历行吗? 电脑大型游戏玩不起,出现Device create failed怎么办? 安徽大专学历可以考初中教师资格证吗 彩虹岛在登录时出现 device create failed 咋办? 要详细!有用! 好办法再加100分!!!!!!!! 在安徽的中专学历能否报考吗? 我开彩虹岛的时候出现Device create failed... 怎么办 安徽省人事考试网怎么查学历 Devic create failed是什么意思啊~~ 虚拟机Vm运行游戏出现 renderer device create failed 求大神如何解决 createFromBuffer failed怎么办 createRenderThread failed to connect 是什么意思 一启动游戏就显示:[CWHDX Graphicwindow:Greate]Directgraphic create failed 为什么大家选择使用吸尘器 梦见狗咬自己的孩子? 我们为什么需要一个吸尘器 梦见我儿子被狗咬了,什么意思? 梦见自己小孩被别人家的狗咬了? 工厂为什么要用工业吸尘器? 什么漫画软件可以免费看漫画,我现在用的快看,还有别的吗⊙▽⊙ 做梦见我小儿子被狗咬了,我把狗打死了,我和婆婆吵架,这是好事还是坏事? 看漫画软件大家都是用的哪个APP? 免费看漫画用什么软件最好?