HRESULT OmnidirectionalSound::Initialize()

in Shared/Audio/OmnidirectionalSound.cpp [86:154]


HRESULT OmnidirectionalSound::Initialize(SpeechSynthesisStream^ stream, UINT32 const& loopCount)
{
    auto hr = _audioStream.Initialize(stream);

    if (SUCCEEDED(hr))
    {
        _sourceType = SoundSourceType::Stream;
    }

    ComPtr<IXAPO> xapo;
    if (SUCCEEDED(hr))
    {
        // Passing in nullptr as the first arg for HrtfApoInit initializes the APO with defaults of
        // omnidirectional sound with natural distance decay behavior.
        // CreateHrtfApo will fail with E_NOTIMPL on unsupported platforms.
        hr = CreateHrtfApo(nullptr, &xapo);
    }

    if (SUCCEEDED(hr))
    {
        hr = xapo.As(&_hrtfParams);
    }

    // Set the default environment.
    if (SUCCEEDED(hr))
    {
        hr = _hrtfParams->SetEnvironment(_environment);
    }

    // Initialize an XAudio2 graph that hosts the HRTF xAPO.
    // The source voice is used to submit audio data and control playback.
    if (SUCCEEDED(hr))
    {
        hr = SetupXAudio2(_audioStream.GetFormat(), xapo.Get(), &_xaudio2, &_sourceVoice);
    }

    // Set the initial position.
    if (SUCCEEDED(hr))
    {
        auto hrtfPosition = HrtfPosition{ 0.f, 0.f, 0.f };
        hr = _hrtfParams->SetSourcePosition(&hrtfPosition);
    }

    // Submit audio data to the source voice.
    if (SUCCEEDED(hr))
    {
        XAUDIO2_BUFFER buffer{};
        buffer.AudioBytes = static_cast<UINT32>(_audioStream.GetSize());
        buffer.pAudioData = _audioStream.GetData();
        buffer.LoopCount = loopCount;
        hr = _sourceVoice->SubmitSourceBuffer(&buffer);

        const WAVEFORMATEX* format = _audioStream.GetFormat();
        unsigned int streamSize = static_cast<unsigned int>(_audioStream.GetSize());

        // compute audio length, in seconds
        unsigned int numSamples =
            streamSize * 8 /                            // number of bits
            format->wBitsPerSample;                     // bits per sample

        float numSeconds =
            static_cast<float>(numSamples) /            // number of samples
            static_cast<float>(format->nSamplesPerSec); // samples per second

        _duration = numSeconds;
    }

    return (_initStatus = hr);
}