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();
}
/*----------------------------------------------------------------*/