XAudio2

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Benutzeravatar
exploid
Establishment
Beiträge: 146
Registriert: 21.08.2005, 18:33

XAudio2

Beitrag von exploid »

Hallo liebe ZFX Community :)

Seit zwei Tagen versuche ich eine Windows Sound Datei vom Typ wav abzuspielen. Der Sound ist hörbar doch ended er in undefinierbares Gerausche und dann stürzt das Programm ab. Fehlertyp: Speicherzugriffsverletzung d.h. XAudio2 greift bzw. schreibt auf nicht referenzierten Speicher. Aus dem Web hab ich folgende Codefragmente gefunden und wie folgt "umgecoded":

Die Klasse die die Sounds verwaltet (Prototyp in Entwicklung)

Code: Alles auswählen

/**
 * Class definition for a DI input device, implementing the
 * interface InputDevice
 */
class DS : public SoundDevice {
	public:
		DS(HINSTANCE hInst);
		~DS(void);
				
		// initialize the stuff
		HRESULT Init(HWND hWnd);

		// interface functions
		void	Release(void);
		bool    IsRunning(void) { return m_bRunning; }

		HRESULT LoadSound(const char*, UINT*);
		
		void    PlaySound(void);

	private:		
		IXAudio2* m_pEngine;
		IXAudio2SourceVoice* m_pSource;
		IXAudio2MasteringVoice* m_pMaster;

         	WAVEFORMATEX m_wf;
		XAUDIO2_BUFFER m_xa;
		BYTE* m_pWaveData;

        // write to log file
		void Log(char *, ...);

}; // class DS
/*----------------------------------------------------------------*/
XAudio2 Gerät bereit machen:

Code: Alles auswählen

HRESULT DS::Init(HWND hWnd) {
	HRESULT hr=_FAIL;

	//must call this for COM
	CoInitializeEx( NULL, COINIT_MULTITHREADED );

	//create the engine
	if( hr = FAILED( XAudio2Create( &m_pEngine ) ) )
	{
		CoUninitialize();
		return _FAIL;
	}

	//create the mastering voice
	if( hr = FAILED( m_pEngine->CreateMasteringVoice( &m_pMaster ) ) )
	{
		m_pEngine->Release();
		CoUninitialize();
		return _FAIL;
	}

  
	m_bRunning = true;
	Log("initialized (online and ready)");
	return _OK;
}
/*----------------------------------------------------------------*/
Sound Datei vom Typ wav laden

Code: Alles auswählen

HRESULT DS::LoadSound(const char* szFile, UINT* puiID) {
	HRESULT hr=_FAIL;

	if(szFile == NULL)
		return _FAIL;

	std::ifstream inFile(szFile, std::ios::binary | std::ios::in);
	if(inFile.bad())
		return _FAIL;
		
	DWORD dwChunkId = 0, dwFileSize = 0, dwChunkSize = 0, dwExtra = 0;

	//look for 'RIFF' chunk identifier
	inFile.seekg(0, std::ios::beg);
	inFile.read(reinterpret_cast<char*>(&dwChunkId), sizeof(dwChunkId));
	if(dwChunkId != 'FFIR')
	{
		inFile.close();
		return _FAIL;
	}
	inFile.seekg(4, std::ios::beg); //get file size
	inFile.read(reinterpret_cast<char*>(&dwFileSize), sizeof(dwFileSize));
	if(dwFileSize <= 16)
	{
		inFile.close();
		return _FAIL;
	}
	inFile.seekg(8, std::ios::beg); //get file format
	inFile.read(reinterpret_cast<char*>(&dwExtra), sizeof(dwExtra));
	if(dwExtra != 'EVAW')
	{
		inFile.close();
		return _FAIL;
	}

	//look for 'fmt ' chunk id
	bool bFilledFormat = false;
	for(unsigned int i = 12; i < dwFileSize; )
	{
		inFile.seekg(i, std::ios::beg);
		inFile.read(reinterpret_cast<char*>(&dwChunkId), sizeof(dwChunkId));
		inFile.seekg(i + 4, std::ios::beg);
		inFile.read(reinterpret_cast<char*>(&dwChunkSize), sizeof(dwChunkSize));
		if(dwChunkId == ' tmf')
		{
			//I don't know what I was thinking with the following code, but I
			//never did solve it back 6 months, and didn't touch it since; oh well... :S

			//switch(dwChunkSize)
			//{
			//case sizeof(WAVEFORMATEX):
			//	{
			//		inFile.seekg(i + 8, std::ios::beg);
			//		inFile.read(reinterpret_cast<char*>(&m_wf), sizeof(m_wf));
			//	}
			//	break;
			//case sizeof(WAVEFORMATEXTENSIBLE):
			//	{
			//		WAVEFORMATEXTENSIBLE wfe;
			//		inFile.seekg(i + 8, std::ios::beg);
			//		inFile.read(reinterpret_cast<char*>(&wfe), sizeof(wfe));
			//		m_wf = wfe.Format;
			//	}
			//	break;
			//default:
			//	inFile.close();
			//	return;
			//}
			inFile.seekg(i + 8, std::ios::beg);
			inFile.read(reinterpret_cast<char*>(&m_wf), sizeof(m_wf));
			bFilledFormat = true;
			break;
		}
		dwChunkSize += 8; //add offsets of the chunk id, and chunk size data entries
		dwChunkSize += 1;
		dwChunkSize &= 0xfffffffe; //guarantees WORD padding alignment
		i += dwChunkSize;
	}
	if(!bFilledFormat)
	{
		inFile.close();
		return _FAIL;
	}
		//look for 'data' chunk id
	bool bFilledData = false;
	for(unsigned int i = 12; i < dwFileSize; )
	{
		inFile.seekg(i, std::ios::beg);
		inFile.read(reinterpret_cast<char*>(&dwChunkId), sizeof(dwChunkId));
		inFile.seekg(i + 4, std::ios::beg);
		inFile.read(reinterpret_cast<char*>(&dwChunkSize), sizeof(dwChunkSize));
		if(dwChunkId == 'atad')
		{
			m_pWaveData = new BYTE[dwChunkSize];
			inFile.seekg(i + 8, std::ios::beg);
			inFile.read(reinterpret_cast<char*>(m_pWaveData), dwChunkSize);
			m_xa.AudioBytes = dwChunkSize;
			m_xa.pAudioData = m_pWaveData;
			m_xa.PlayBegin = 0;
			m_xa.PlayLength = 0;
			bFilledData = true;
			break;
		}
		dwChunkSize += 8; //add offsets of the chunk id, and chunk size data entries
		dwChunkSize += 1;
		dwChunkSize &= 0xfffffffe; //guarantees WORD padding alignment
		i += dwChunkSize;
	}
	if(!bFilledData)
	{
		inFile.close();
		return _FAIL;
	}
	inFile.close();

	
	return hr;
}
/*----------------------------------------------------------------*/
Abspielen des Sounds über

Code: Alles auswählen

void DS::PlaySound(void){
	
	//create the source voice, based on loaded wave format
	if( FAILED( m_pEngine->CreateSourceVoice( &m_pSource, &m_wf ) ) )
	{
		m_pEngine->Release();
		CoUninitialize();
	}
	
	//play the sound
	m_pSource->SubmitSourceBuffer( &m_xa );
	
	//start consuming audio in the source voice
	m_pSource->Start();
}
/*----------------------------------------------------------------*/
Diese Funktionen befinden sich in einer dll und werden von "aussen" aufgerufen mit folgenden Befehlen

Code: Alles auswählen

	// create a sound object
	g_pSound = new Sound(g_hInst); 
	// create an sound device object
	if (FAILED( g_pSound->CreateDevice() )) return E_FAIL;
	// get a pointer on that device
	g_pSoundDevice = g_pSound->GetDevice();
	if(g_pSoundDevice == NULL) return E_FAIL;
	// init sound device
	if (FAILED( g_pSoundDevice->Init(g_hWnd))) {
		fprintf(pLog, "error: Init() failed in ProgramStartup()\n");
		return E_FAIL;
	}


	hr = g_pSoundDevice->LoadSound("wav.wav", &uitest);
	g_pSoundDevice->PlaySoundW();
Ich vermute den Fehler in der Ladefunktion die den XAUDIO2_BUFFER nicht richtig füllt. Vielleicht hat jemand hier damit mehr Erfahrung und könnte Tipps geben :).
Zuletzt geändert von exploid am 07.02.2013, 11:35, insgesamt 1-mal geändert.
All your base are belong to us! Justice
Youka
Beiträge: 28
Registriert: 20.04.2011, 18:24
Wohnort: Darmstadt

Re: XAudio2

Beitrag von Youka »

Code: Alles auswählen

if(dwChunkId != 'FFIR')
...
if(dwExtra != 'EVAW')
...
Gerade mal grob überflogen. Du möchtest öfters die 4 Byte der DWORDs mit const char Zeigern vergleichen? Stringvergleich geht anders ;)

Ausserdem würde ich dir das Durchlesen des Getting started von den MSDN Dokumentationen empfehlen.
Benutzeravatar
exploid
Establishment
Beiträge: 146
Registriert: 21.08.2005, 18:33

Re: XAudio2

Beitrag von exploid »

Hallo Youka

Also diese Laderoutine hab ich aus dem Web und nicht selbst gecoded aber soweit ich die Stellen verstehe die du beschreibst werden dort Konstanten verglichen. Es sind die "Chunk-Schlüsselwörter" des wav Formats. 'FFIR' ist eine Zahl nämlich 0x46464952 und die wird verglichen mit einem DWORD das zuvor aus der Datei gelesen wurde dwChunkId.

Vielleicht hast du Recht und ich sollte wirklich die Dokumentation lesen. :) => rtfm

Danke für deine Antwort.
All your base are belong to us! Justice
Benutzeravatar
exploid
Establishment
Beiträge: 146
Registriert: 21.08.2005, 18:33

Re: XAudio2

Beitrag von exploid »

Hallo

Nachdem ich folgendes Projekt compilert hab funktioniert der Code. Zeigt den folgenden Code aber nicht eurem Informatik Professor oder ihr lauft Gefahr, dass er ihn euch links und rechts um die Ohren schlägt. :) Die Dateien sind dem Web entnommen.

Code: Alles auswählen

//wave.h
//by Jay Tennant 3/4/12
//Wave helper class, to load simple wave files
//win32developer.com
//this code provided free, as in public domain; score!

#ifndef WAVE_H
#define WAVE_H

#include <windows.h>
#include <xaudio2.h>
#include <fstream>

class Wave
{
private:
	WAVEFORMATEX m_wf;
	XAUDIO2_BUFFER m_xa;
	BYTE* m_waveData;
public:
	Wave(const char* szFile = NULL) : m_waveData(NULL) {
		ZeroMemory(&m_wf, sizeof(m_wf));
		ZeroMemory(&m_xa, sizeof(m_xa));

		load(szFile);
	}
	Wave(const Wave& c) : m_waveData(NULL) {
		m_wf = c.m_wf;
		m_xa = c.m_xa;
		if(c.m_waveData)
		{
			m_waveData = new BYTE[m_xa.AudioBytes];
			memcpy( m_waveData, c.m_waveData, m_xa.AudioBytes );
			m_xa.pAudioData = m_waveData;
		}
	}
	~Wave() {
		if(m_waveData)
			delete [] m_waveData;
		m_waveData = NULL;
	}

	const XAUDIO2_BUFFER* xaBuffer() const {return &m_xa;}
	const WAVEFORMATEX* wf() const {return &m_wf;}
	bool load(const char* szFile) {
		if(szFile == NULL)
			return false;

		std::ifstream inFile(szFile, std::ios::binary | std::ios::in);
		if(inFile.bad())
			return false;
		
		DWORD dwChunkId = 0, dwFileSize = 0, dwChunkSize = 0, dwExtra = 0;

		//look for 'RIFF' chunk identifier
		inFile.seekg(0, std::ios::beg);
		inFile.read(reinterpret_cast<char*>(&dwChunkId), sizeof(dwChunkId));
		if(dwChunkId != 'FFIR')
		{
			inFile.close();
			return false;
		}
		inFile.seekg(4, std::ios::beg); //get file size
		inFile.read(reinterpret_cast<char*>(&dwFileSize), sizeof(dwFileSize));
		if(dwFileSize <= 16)
		{
			inFile.close();
			return false;
		}
		inFile.seekg(8, std::ios::beg); //get file format
		inFile.read(reinterpret_cast<char*>(&dwExtra), sizeof(dwExtra));
		if(dwExtra != 'EVAW')
		{
			inFile.close();
			return false;
		}

		//look for 'fmt ' chunk id
		bool bFilledFormat = false;
		for(unsigned int i = 12; i < dwFileSize; )
		{
			inFile.seekg(i, std::ios::beg);
			inFile.read(reinterpret_cast<char*>(&dwChunkId), sizeof(dwChunkId));
			inFile.seekg(i + 4, std::ios::beg);
			inFile.read(reinterpret_cast<char*>(&dwChunkSize), sizeof(dwChunkSize));
			if(dwChunkId == ' tmf')
			{
				//I don't know what I was thinking with the following code, but I
				//never did solve it back 6 months, and didn't touch it since; oh well... :S

				//switch(dwChunkSize)
				//{
				//case sizeof(WAVEFORMATEX):
				//	{
				//		inFile.seekg(i + 8, std::ios::beg);
				//		inFile.read(reinterpret_cast<char*>(&m_wf), sizeof(m_wf));
				//	}
				//	break;
				//case sizeof(WAVEFORMATEXTENSIBLE):
				//	{
				//		WAVEFORMATEXTENSIBLE wfe;
				//		inFile.seekg(i + 8, std::ios::beg);
				//		inFile.read(reinterpret_cast<char*>(&wfe), sizeof(wfe));
				//		m_wf = wfe.Format;
				//	}
				//	break;
				//default:
				//	inFile.close();
				//	return;
				//}
				inFile.seekg(i + 8, std::ios::beg);
				inFile.read(reinterpret_cast<char*>(&m_wf), sizeof(m_wf));
				bFilledFormat = true;
				break;
			}
			dwChunkSize += 8; //add offsets of the chunk id, and chunk size data entries
			dwChunkSize += 1;
			dwChunkSize &= 0xfffffffe; //guarantees WORD padding alignment
			i += dwChunkSize;
		}
		if(!bFilledFormat)
		{
			inFile.close();
			return false;
		}

		//look for 'data' chunk id
		bool bFilledData = false;
		for(unsigned int i = 12; i < dwFileSize; )
		{
			inFile.seekg(i, std::ios::beg);
			inFile.read(reinterpret_cast<char*>(&dwChunkId), sizeof(dwChunkId));
			inFile.seekg(i + 4, std::ios::beg);
			inFile.read(reinterpret_cast<char*>(&dwChunkSize), sizeof(dwChunkSize));
			if(dwChunkId == 'atad')
			{
				m_waveData = new BYTE[dwChunkSize];
				inFile.seekg(i + 8, std::ios::beg);
				inFile.read(reinterpret_cast<char*>(m_waveData), dwChunkSize);
				m_xa.AudioBytes = dwChunkSize;
				m_xa.pAudioData = m_waveData;
				m_xa.PlayBegin = 0;
				m_xa.PlayLength = 0;
				bFilledData = true;
				break;
			}
			dwChunkSize += 8; //add offsets of the chunk id, and chunk size data entries
			dwChunkSize += 1;
			dwChunkSize &= 0xfffffffe; //guarantees WORD padding alignment
			i += dwChunkSize;
		}
		if(!bFilledData)
		{
			inFile.close();
			return false;
		}

		inFile.close();
		return true;
	}
};

#endif

Code: Alles auswählen

//by Jay Tennant 3/4/12
//A Brief Look at XAudio2: Playing a Sound
//win32developer.com
//this code provided free, as in public domain; score!

#include <windows.h>
#include <xaudio2.h>
#include "wave.h"

IXAudio2* g_engine;
IXAudio2SourceVoice* g_source;
IXAudio2MasteringVoice* g_master;

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
	//must call this for COM
	CoInitializeEx( NULL, COINIT_MULTITHREADED );

	//create the engine
	if( FAILED( XAudio2Create( &g_engine ) ) )
	{
		CoUninitialize();
		return -1;
	}

	//create the mastering voice
	if( FAILED( g_engine->CreateMasteringVoice( &g_master ) ) )
	{
		g_engine->Release();
		CoUninitialize();
		return -2;
	}

	//helper class to load wave files; trust me, this makes it MUCH easier
	Wave buffer;

	//load a wave file
	if( !buffer.load( "wav.wav" ) )
	{
		g_engine->Release();
		CoUninitialize();
		return -3;
	}

	//create the source voice, based on loaded wave format
	if( FAILED( g_engine->CreateSourceVoice( &g_source, buffer.wf() ) ) )
	{
		g_engine->Release();
		CoUninitialize();
		return -4;
	}

	//start consuming audio in the source voice
	g_source->Start();

	//simple message loop
	while( MessageBox( 0, TEXT("Do you want to play the sound?"), TEXT("ABLAX: PAS"), MB_YESNO ) == IDYES )
	{
		//play the sound
		g_source->SubmitSourceBuffer( buffer.xaBuffer() );
	}

	//release the engine, NOT the voices!
	g_engine->Release();

	//again, for COM
	CoUninitialize();

	return 0;
}
Um XAudio2 zu verstehen ist es hinreichend.

Update 09.02.13 00:35
Der Vollständigkeit und zur Pflege des Forums:

Das Projekt hab ich folgend nun weiter gemacht und poste dieses um jemanden der hier nach XAudio2 Tipps sucht zu helfen:

Die Wave Helferklasse:

Code: Alles auswählen

//Wave.h
//by Jay Tennant 3/4/12
//Wave helper class, to load simple wave files
//win32developer.com
//this code provided free, as in public domain; score!

#ifndef WAVE_H
#define WAVE_H

#include <windows.h>
#include <xaudio2.h>
#include <fstream>

class Wave
{
	public:
		Wave();
		Wave(const char* szFile);
		Wave(const Wave& c);
		~Wave();

		const XAUDIO2_BUFFER* xaBuffer() const {return &m_xa;}
		const WAVEFORMATEX* wf() const {return &m_wf;}
		bool load(const char* szFile);

	private:
		WAVEFORMATEX m_wf;
		XAUDIO2_BUFFER m_xa;
		BYTE* m_waveData;
};

#endif
Die dazugehörige .cpp Datei:

Code: Alles auswählen

// Wave.cpp
#include "Wave.h"

Wave::Wave() {
	m_waveData=NULL;
	ZeroMemory(&m_wf, sizeof(m_wf));
	ZeroMemory(&m_xa, sizeof(m_xa));
}
/**************************************************************/

Wave::Wave(const char* szFile) {
	ZeroMemory(&m_wf, sizeof(m_wf));
	ZeroMemory(&m_xa, sizeof(m_xa));
	load(szFile);
}
/**************************************************************/

Wave::Wave(const Wave& c) {
	m_waveData=NULL;
	m_wf = c.m_wf;
	m_xa = c.m_xa;
	if(c.m_waveData)
	{
		m_waveData = new BYTE[m_xa.AudioBytes];
		memcpy( m_waveData, c.m_waveData, m_xa.AudioBytes );
		m_xa.pAudioData = m_waveData;
	}
}
/**************************************************************/

Wave::~Wave() {
	if(m_waveData)
		delete [] m_waveData;
	m_waveData = NULL;
}
/**************************************************************/

bool Wave::load(const char* szFile) {
	if(szFile == NULL)
		return false;

	std::ifstream inFile(szFile, std::ios::binary | std::ios::in);
	if(inFile.bad())
		return false;
	
	DWORD dwChunkId = 0, dwFileSize = 0, dwChunkSize = 0, dwExtra = 0;

	//look for 'RIFF' chunk identifier
	inFile.seekg(0, std::ios::beg);
	inFile.read(reinterpret_cast<char*>(&dwChunkId), sizeof(dwChunkId));
	if(dwChunkId != 'FFIR')
	{
		inFile.close();
		return false;
	}
	inFile.seekg(4, std::ios::beg); //get file size
	inFile.read(reinterpret_cast<char*>(&dwFileSize), sizeof(dwFileSize));
	if(dwFileSize <= 16)
	{
		inFile.close();
		return false;
	}
	inFile.seekg(8, std::ios::beg); //get file format
	inFile.read(reinterpret_cast<char*>(&dwExtra), sizeof(dwExtra));
	if(dwExtra != 'EVAW')
	{
		inFile.close();
		return false;
	}

	//look for 'fmt ' chunk id
	bool bFilledFormat = false;
	for(unsigned int i = 12; i < dwFileSize; )
	{
		inFile.seekg(i, std::ios::beg);
		inFile.read(reinterpret_cast<char*>(&dwChunkId), sizeof(dwChunkId));
		inFile.seekg(i + 4, std::ios::beg);
		inFile.read(reinterpret_cast<char*>(&dwChunkSize), sizeof(dwChunkSize));
		if(dwChunkId == ' tmf')
		{
			//I don't know what I was thinking with the following code, but I
			//never did solve it back 6 months, and didn't touch it since; oh well... :S
			//switch(dwChunkSize)
			//{
			//case sizeof(WAVEFORMATEX):
			//	{
			//		inFile.seekg(i + 8, std::ios::beg);
			//		inFile.read(reinterpret_cast<char*>(&m_wf), sizeof(m_wf));
			//	}
			//	break;
			//case sizeof(WAVEFORMATEXTENSIBLE):
			//	{
			//		WAVEFORMATEXTENSIBLE wfe;
			//		inFile.seekg(i + 8, std::ios::beg);
			//		inFile.read(reinterpret_cast<char*>(&wfe), sizeof(wfe));
			//		m_wf = wfe.Format;
			//	}
			//	break;
			//default:
			//	inFile.close();
			//	return;
			//}
			inFile.seekg(i + 8, std::ios::beg);
			inFile.read(reinterpret_cast<char*>(&m_wf), sizeof(m_wf));
			bFilledFormat = true;
			break;
		}
		dwChunkSize += 8; //add offsets of the chunk id, and chunk size data entries
		dwChunkSize += 1;
		dwChunkSize &= 0xfffffffe; //guarantees WORD padding alignment
		i += dwChunkSize;
	}
	if(!bFilledFormat)
	{
		inFile.close();
		return false;
	}
	//look for 'data' chunk id
	bool bFilledData = false;
	for(unsigned int i = 12; i < dwFileSize; )
	{
		inFile.seekg(i, std::ios::beg);
		inFile.read(reinterpret_cast<char*>(&dwChunkId), sizeof(dwChunkId));
		inFile.seekg(i + 4, std::ios::beg);
		inFile.read(reinterpret_cast<char*>(&dwChunkSize), sizeof(dwChunkSize));
		if(dwChunkId == 'atad')
		{
			m_waveData = new BYTE[dwChunkSize];
			inFile.seekg(i + 8, std::ios::beg);
			inFile.read(reinterpret_cast<char*>(m_waveData), dwChunkSize);
			m_xa.AudioBytes = dwChunkSize;
			m_xa.pAudioData = m_waveData;
			m_xa.PlayBegin = 0;
			m_xa.PlayLength = 0;
			bFilledData = true;
			break;
		}
		dwChunkSize += 8; //add offsets of the chunk id, and chunk size data entries
		dwChunkSize += 1;
		dwChunkSize &= 0xfffffffe; //guarantees WORD padding alignment
		i += dwChunkSize;
	}
	if(!bFilledData)
	{
		inFile.close();
		return false;
	}
		inFile.close();
	return true;
}
/**************************************************************/
Die Sound Klasse die alle Sounds verwalten wird:

Code: Alles auswählen

/**
 * Class definition for a DS sound device, implementing the
 * interface InputDevice
 */
class DS : public SoundDevice {
	public:
		DS(HINSTANCE hInst);
		~DS(void);
				
		// initialize the stuff
		HRESULT Init(HWND hWnd);

		// interface functions
		void	Release(void);
		bool    IsRunning(void) { return m_bRunning; }

		HRESULT LoadSound(const char*, UINT*);
		
		void    PlaySound(UINT nID, bool);

	private:		
		IXAudio2* m_pEngine;
		IXAudio2SourceVoice* m_pSource;
		IXAudio2MasteringVoice* m_pMaster;
		 	

		//helper class to load wave files
		Wave CSbuffer;

        // write to log file
		void Log(char *, ...);

}; // class DS
/*----------------------------------------------------------------*/
Die drei Funktionen zum Erstellen des XAudio2 Devices und zum Abspielen einer Wav Datei

Code: Alles auswählen

HRESULT DS::Init(HWND hWnd) {
	HRESULT hr=_FAIL;

	//must call this for COM
	CoInitializeEx( NULL, COINIT_MULTITHREADED );

	//create the engine
	if( hr = FAILED( XAudio2Create( &m_pEngine ) ) )
	{
		CoUninitialize();
		return _FAIL;
	}

	//create the mastering voice
	if( hr = FAILED( m_pEngine->CreateMasteringVoice( &m_pMaster ) ) )
	{
		m_pEngine->Release();
		CoUninitialize();
		return _FAIL;
	}

  
	m_bRunning = true;
	Log("initialized (online and ready)");
	return _OK;
}
/*----------------------------------------------------------------*/



HRESULT DS::LoadSound(const char* szFile, UINT* puiID) {
	HRESULT hr=_FAIL;
	//load a wave file
	if( !CSbuffer.load( szFile ) )
	{
		m_pEngine->Release();
		CoUninitialize();
		return _FAIL;
	}
	return _OK;
}
/*----------------------------------------------------------------*/

void DS::PlaySound(UINT nID, bool){
	// Die Zerstörung der Stimme ist notwendig weil XAudio2 sonst
        // alles in eine Schlange hängt und nacheinander abspielt
	if(m_pSource) {
		m_pSource->DestroyVoice();
                m_pSource=NULL;
        }
	//create the source voice, based on loaded wave format
	if( FAILED( m_pEngine->CreateSourceVoice( &m_pSource, CSbuffer.wf() ) ) )
	{
		m_pEngine->Release();
		CoUninitialize();
		
	}
	//play the sound
	m_pSource->SubmitSourceBuffer( CSbuffer.xaBuffer() );
	//start consuming audio in the source voice
	m_pSource->Start();	
		
}
/*----------------------------------------------------------------*/
All your base are belong to us! Justice
Antworten