我想加载一个* .wav文件,它是一个微软的wav/8bit pcm文件。我使用下面的代码加载数据:XAudio2和* .wav加载,HRESULT 0x88960001
class WavFile : public AudioSource, public LoadableObject
{
public:
WavFile(void)
: AudioSource()
, LoadableObject()
{ }
virtual concurrency::task<void> Load(Platform::String^ path)
{
buffer = nullptr;
BasicReaderWriter^ rw = ref new BasicReaderWriter();
return rw->ReadDataAsync(path).then([this, path](const Platform::Array<byte>^ arr){
DWORD chunkId = 0, fileSize = 0, chunkSize = 0, extra = 0;
ByteStream stream(arr);
stream.ReadData(&chunkId, sizeof(chunkId));
//chunkId = stream.ReadDWORD();
char test[4];
for(unsigned int i=0; i <4; i++)
test[i] = ((char *)&chunkId)[i];
if (chunkId != 'FFIR') throw ref new Platform::FailureException(L"Could not get RIFF chunk in file " + path + L", chunkId=" + chunkId.ToString());
fileSize = stream.ReadDWORD();
if (fileSize <= 16) throw ref new Platform::FailureException(L"Wave file size is too small; " + path);
extra = stream.ReadDWORD();
for(unsigned int i=0; i <4; i++)
test[i] = ((char *)&extra)[i];
if (extra != 'EVAW') throw ref new Platform::FailureException(L"Could not get WAVE chunk in file " + path + L", chunkId=" + chunkId.ToString());
bool formatChunk = false;
for(unsigned int i = 12; i < fileSize;)
{
stream.Seek(i, true);
chunkId = stream.ReadDWORD();
stream.Seek(i + 4, true);
chunkSize = stream.ReadDWORD();
if (chunkId = ' tmf')
{
stream.Seek(i + 8, true);
stream.ReadData(&waveFormat, sizeof(WAVEFORMATEX));
formatChunk = true;
break;
}
chunkSize += 8 + 1;
chunkSize &= 0xfffffffe;
stream.Seek(chunkSize, false);
i += chunkSize;
}
if (!formatChunk) throw ref new Platform::FailureException(L"Could not get fmt chunk in file " + path);
bool filledData = false;
for(unsigned int j=12; j < fileSize;)
{
stream.Seek(j, true);
chunkId = stream.ReadDWORD();
for(unsigned int i=0; i <4; i++)
test[i] = ((char *)&chunkId)[i];
stream.Seek(j + 4, true);
chunkSize = stream.ReadDWORD();
if (chunkId == 'atad')
{
byte *bufferData = new byte[chunkSize];
stream.Seek(j + 8, true);
stream.ReadData(bufferData, chunkSize);
buffer = ref new Platform::Array<byte>(bufferData, (unsigned int)chunkSize);
delete bufferData;
xbuffer.AudioBytes = chunkSize;
xbuffer.pAudioData = buffer->Data;
xbuffer.PlayBegin = 0;
xbuffer.PlayLength = 0;
filledData = true;
break;
}
chunkSize += 8 + 1;
chunkSize &= 0xfffffffe;
j += chunkSize;
}
if (!filledData) throw ref new Platform::FailureException(L"Could not find data chunk in file " + path);
});
}
};
它解析wav文件正确,这里是WAVEFORMATEX数据的样子:
{ wFormatTag=1, nChannels=2, nSamplesPerSec=22050, nAvgBytesPerSec=44100, nBlockAlign=2, wBitsPerSample=8, cbSize=24932 }
当我打电话instance->CreateSourceVoice(&voice, wave->GetWaveFormat(), 0, XAUDIO2_DEFAULT_FREQ_RATIO, reinterpret_cast<IXAudio2VoiceCallback*>(&voiceIn[id]->callbacks))
,我得到HRESULT = 0x88960001,其中instance
是类型IXAudio2*
,我将它包含在类中静态共享并使用我的类构造函数/析构函数初始化/销毁的类中:
AudioManager::AudioManager(void)
{
instance_count++;
if (instance == nullptr)
{
DX::ThrowIfFailed(XAudio2Create(&instance, 0));
}
}
AudioManager::~AudioManager(void)
{
/* Remove all the voices that were added in this audio manager */
instance_count--;
if (instance_count == 0)
{
HaltAudio();
instance->Release();
instance = nullptr;
}
}
我已经在多个地方看过这个HRESULT是某种Windows 8的bug,一年多来还没有被修复。我不能接受这是一个持续的错误,更倾向于认为这是我的代码的问题。你可以看看my full implemention for XAudio2 in this gist。
这就是XAUDIO2_E_INVALID_CALL,它不像你传递的参数值。 – 2013-03-01 02:06:01
啊,所以我并没有首先创造一个母音,这显然需要到位。我很惊讶没有更好的HRESULT值来描述这种情况。 – OzBarry 2013-03-01 14:34:56