【问题标题】:XAudio2 and *.wav loading, HRESULT 0x88960001XAudio2 和 *.wav 加载,HRESULT 0x88960001
【发布时间】:2013-02-28 22:20:33
【问题描述】:

我正在尝试加载一个 *.wav 文件,它是一个 microsoft wav/8bit pcm 文件。我正在使用以下代码来加载数据:

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-&gt;CreateSourceVoice( &amp;voice, wave-&gt;GetWaveFormat(), 0, XAUDIO2_DEFAULT_FREQ_RATIO, reinterpret_cast&lt;IXAudio2VoiceCallback*&gt;( &amp;voiceIn[id]-&gt;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 错误,一年多没有修复。我不能接受这是一个持续存在的错误,更倾向于认为这是我的代码的问题。您可以查看my full implemention for XAudio2 in this gist

【问题讨论】:

  • 那是 XAUDIO2_E_INVALID_CALL,它不喜欢你传递的参数值。
  • 啊,所以我没有先创建母带声音,这显然需要到位。我很惊讶没有更好的 HRESULT 值来描述这种情况。

标签: windows-8 windows-runtime xaudio2


【解决方案1】:

当将 XAudio2SourceVoice* 的 sendList 设置为 NULL 时,IXAudio2 接口必须至少已设置一个主控声音。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-03
    • 1970-01-01
    • 1970-01-01
    • 2011-07-29
    相关资源
    最近更新 更多