0

I am receiving a system error code x05 error_access_denied when I try to use the WaitForSingleObjectEx function to signal that an Xaudio2 source voice has finished processing all of the data in its buffer.

I want to use this as an event handler to know when to submit another buffer of audio data to the source voice, so it can continue playing until my stop() function/method is called.

How should the WaitForSingleObjectEx function be propely implemented so that I do not receive the error_access_denied system error code?

This is for a Windows Phone 8 C++/CX Windows Runtime Component...

TestTone.h file:

#pragma once

#include <client.h>  /* ComPtr */
#include <winnt.h>   /* HRESULT */
#include <xaudio2.h> /* IXAudio2 */
#include <ppltasks.h>  /* task .then */
#include "XAudio2VoiceBufferCallback.h"

namespace PhoneDirect3DXamlAppComponent
{
    public ref class TestTone sealed
    {
    public:
        void Initialize();
        void Play();
        void Stop();
    private:
        Microsoft::WRL::ComPtr<IXAudio2> pXAudio2;
        IXAudio2MasteringVoice *pMasteringVoice;
        IXAudio2SourceVoice * pSourceVoice;
        byte soundData[2*44100];
        XAUDIO2_BUFFER buffer;
        WAVEFORMATEX waveformat;
        VoiceCallback *vcb;
        void CreateSourceVoice();
        void FillSoundArrayWithData();
        void getSourceVoiceCallbacks(VoiceCallback *vcb,IXAudio2SourceVoice *pSourceVoice,XAUDIO2_BUFFER *buffer);
    };
}

TestTone.cpp file:

// TestTone.cpp
#include "pch.h"
#include "TestTone.h"
#include "XAudio2VoiceBufferCallback.h"
#include <client.h>  /* ComPtr */
#include <winnt.h>   /* HRESULT */
#include <XAudio2.h> /* IXAudio2 */
#include <ppltasks.h>  /* task .then */
#include <math.h> /* sine */

#define PI 3.14159265

using namespace PhoneDirect3DXamlAppComponent;
using namespace concurrency;  // tasks

void TestTone::Initialize()
{
    XAudio2Create(&pXAudio2,0,XAUDIO2_DEFAULT_PROCESSOR);
    pXAudio2->CreateMasteringVoice(&pMasteringVoice);
    vcb = new VoiceCallback();
    CreateSourceVoice();
    buffer.AudioBytes = 2 * 44100;
    buffer.pAudioData = soundData;
    buffer.PlayBegin = 0;
    buffer.PlayLength = 44100;
}

void TestTone::Play()
{
    pSourceVoice->Start();
    FillSoundArrayWithData();
    buffer.pAudioData = soundData;
    pSourceVoice->SubmitSourceBuffer(&buffer);
    getSourceVoiceCallbacks(vcb, pSourceVoice, &buffer);
}
void TestTone::Stop()
{
    pSourceVoice->Stop();
    CreateSourceVoice();
}
void TestTone::CreateSourceVoice()
{
    waveformat.wFormatTag = WAVE_FORMAT_PCM;
    waveformat.nChannels = 1;
    waveformat.nSamplesPerSec = 44100;
    waveformat.nAvgBytesPerSec = waveformat.nSamplesPerSec * waveformat.nChannels;
    waveformat.nBlockAlign = waveformat.nChannels;
    waveformat.wBitsPerSample = 8;
    waveformat.cbSize = 0;
    hrXAudio2Create = pXAudio2->CreateSourceVoice(&pSourceVoice,&waveformat,0,XAUDIO2_DEFAULT_FREQ_RATIO,vcb,NULL,NULL);
}
void TestTone::FillSoundArrayWithData()
{
    for (int index = 0, second = 0; second < 1; second++)
    {
        for (int sample = 0; sample < waveformat.nSamplesPerSec; sample++)
        {   
            soundData[index++] = 128+(127*sin((500*sample*PI)/(waveformat.nSamplesPerSec)));
        }
    }
}
void TestTone::getSourceVoiceCallbacks(VoiceCallback *vcb,IXAudio2SourceVoice *pSourceVoice,XAUDIO2_BUFFER *buffer)
{
    DWORD dw = NULL;
    dw = WaitForSingleObjectEx( vcb->hBufferEndEvent,0,//INFINITE,TRUE );
    DWORD err = NULL;
    err = GetLastError();
    while (WAIT_OBJECT_0 == (WaitForSingleObjectEx(vcb->hBufferEndEvent,INFINITE,TRUE)))
    {
        pSourceVoice->SubmitSourceBuffer(buffer);
    }
    return;
}

XAudio2VoiceBufferCallback.h file:

#pragma once

#include <client.h>  /* ComPtr */
#include <winnt.h>   /* HRESULT */
#include <xaudio2.h> /* IXAudio2 */

namespace PhoneDirect3DXamlAppComponent
{
    class VoiceCallback : public IXAudio2VoiceCallback
    {
        public:
            HANDLE hBufferEndEvent;
            VoiceCallback();//: hBufferEndEvent( CreateEventEx( NULL, FALSE, FALSE, NULL ) ){};
            ~VoiceCallback();//{ CloseHandle( hBufferEndEvent ); }

        //Called when the voice has just finished playing a contiguous audio stream.
        virtual void __stdcall OnStreamEnd(); //{ SetEvent( hBufferEndEvent ); }
        //Unused methods are stubs
        void __stdcall OnVoiceProcessingPassEnd();
        void __stdcall OnVoiceProcessingPassStart(UINT32 SamplesRequired);
        void __stdcall OnBufferEnd(void * pBufferContext);
        void __stdcall OnBufferStart(void * pBufferContext);
        void __stdcall OnLoopEnd(void * pBufferContext);
        void __stdcall OnVoiceError(void * pBufferContext, HRESULT Error);
    };
}

XAudio2VoiceBufferCallback.cpp file:

// XAudio2VoiceBufferCallback.cpp
#include "pch.h"
#include "XAudio2VoiceBufferCallback.h"
#include <client.h>  /* ComPtr */
#include <winnt.h>   /* HRESULT */
#include <XAudio2.h> /* IXAudio2 */

using namespace PhoneDirect3DXamlAppComponent;

VoiceCallback::VoiceCallback()//:hBufferEndEvent( CreateEventEx( NULL, FALSE, FALSE, NULL ) )
{
    hBufferEndEvent = (CreateEventEx(NULL,FALSE,FALSE,NULL));
}
VoiceCallback::~VoiceCallback()
{
    CloseHandle( hBufferEndEvent );
}
void VoiceCallback::OnStreamEnd()
{
     SetEvent( hBufferEndEvent );
}
void VoiceCallback::OnVoiceProcessingPassEnd() { }
void VoiceCallback::OnVoiceProcessingPassStart(UINT32 SamplesRequired) {    }
void VoiceCallback::OnBufferEnd(void * pBufferContext)    { }
void VoiceCallback::OnBufferStart(void * pBufferContext) {    }
void VoiceCallback::OnLoopEnd(void * pBufferContext) {    }
void VoiceCallback::OnVoiceError(void * pBufferContext, HRESULT Error) { }

0 Answers0