Sounds mit DirectX abspielen

Aus Spieleprogrammierer-Wiki
Wechseln zu: Navigation, Suche

Inhaltsverzeichnis

1.Voreinstellungen

1.DirectX SDK herunterladen.

2.Die Includes <dsound.h> und <mmsystem.h> einfügen.

3.Die libs "winmm.lib","dsound.lib","dxguid" einfügen

(das könnt ihr sowohl in den Eigenschaften des Projekts einstellen, sowohl auch mit #pragma comment(lib,"...") einfügen)

4.Eine Klasse erstellen ( am Besten mit einer header- und einer cpp Datei. ) ( Ich nenne sie 'AUdio' )

2.Initalisierung von DirectSound
Als erstes fügen wir zu unserer Klasse die Funktion
 bool DSoundInit(HWND hWnd);
hinzu.

Als nächstes müssen wir diese Funktion beschreiben:

bool AUdio::DSoundInit(HWND hwnd)
{
	if (DirectSoundCreate(NULL, &lpDirectSound, NULL) != DS_OK)
	{
		return (false);
	}

	if (lpDirectSound->SetCooperativeLevel(hwnd, DSSCL_NORMAL) != DS_OK)
	{
		return (false);
	}

	return (true);
}

Wie sie sehen können sind zwei Variablen hinzgekommen, die wir noch nicht definiert haben. Das müssen wir noch in unserer Klassen machen:

LPDIRECTSOUND lpDirectSound;
	LPDIRECTSOUNDBUFFER dsbSound;

Als erstes wird der Sound erstellt, und es wird abgefragt, ob es erfolgreich war, dewegen auch bool. Wenn es fehlgeschlagen ist dann wird falsch zurückgegeben, so auch bei der zeiten Abfrage. Wenn es erfolgreich war, wird true zurückgegeben.

3.Laden von DirectSound
Als erstes ergänzen wir die Klasse um die Funktion
bool LoadWave(char *filename);
.

Auch dar wird ein Wert vom Typen bool zurückgegeben. Da dieser Teil komplizierter wird, erkläre ich nicht die einzelnen Schritte:

bool AUdio::LoadWave(char *filename)
{
	HMMIO wavefile;
	wavefile = mmioOpen(filename, 0, MMIO_READ | MMIO_ALLOCBUF);

	if (wavefile == NULL)
	{
		return (false);
	}

	MMCKINFO parent;
	memset(&parent, 0, sizeof(MMCKINFO));
	parent.fccType = mmioFOURCC('W', 'A', 'V', 'E');
	mmioDescend(wavefile, &parent, 0, MMIO_FINDRIFF);

	MMCKINFO child;
	memset(&child, 0, sizeof(MMCKINFO));
	child.fccType = mmioFOURCC('f', 'm', 't', ' ');
	mmioDescend(wavefile, &child, &parent, 0);

	WAVEFORMATEX wavefmt;
	mmioRead(wavefile, (char*)&wavefmt, sizeof(wavefmt));

	if (wavefmt.wFormatTag != WAVE_FORMAT_PCM)
	{
		return (false);
	}

	mmioAscend(wavefile, &child, 0);
	child.ckid = mmioFOURCC('d', 'a', 't', 'a');
	mmioDescend(wavefile, &child, &parent, MMIO_FINDCHUNK);



	DSBUFFERDESC bufdesc;
	memset(&bufdesc, 0, sizeof(DSBUFFERDESC));
	bufdesc.dwSize = sizeof(DSBUFFERDESC);

	bufdesc.dwFlags = 0;
	bufdesc.dwBufferBytes = child.cksize;
	bufdesc.lpwfxFormat = &wavefmt;

	if ((lpDirectSound->CreateSoundBuffer(&bufdesc, &dsbSound, NULL)) != DS_OK)
	{
		return (false);
	}



	void *write1 = 0, *write2 = 0;
	unsigned long length1, length2;
	dsbSound->Lock(0, child.cksize, &write1, &length1, &write2, &length2, 0);
	if (write1 > 0)
		mmioRead(wavefile, (char*)write1, length1);
	if (write2 > 0)
		mmioRead(wavefile, (char*)write2, length2);
	dsbSound->Unlock(write1, length1, write2, length2);

	mmioClose(wavefile, 0);

	return (true);
}

Wenn es erfolgreich ist wird true zurückgegeben wenn nicht, dann false.

4.Abspielen von DirectSound
Als erstes müssen wir unsere Klasse um
void PlayWave();
erweitern.

Diese Funktion ist sehr kurz und gibt keinen Wert zurück, da die gültigkeit in den vorigen Funktionen abgefragt wird. Nun schauen wir uns die Funktion an:

void AUdio::PlayWave()
{
	dsbSound->SetCurrentPosition(0);
	dsbSound->Play(0, 0, 0);
}

Die Aktuelle Position von dsbSound wird auf Null gesetzt, und der Sound dsbSound wird abgespielt.

5.Stoppen von DirectSound

Falls man nicht mehr möchte, dass der Sound abgespielt wird, wird er gestoppt.

Als erstes ergänzen wir unsere Klasse um
void StopWave()

Auch diese hat keinen Rückgabewert, da sie vom Typ void ist. Der code sieht folgendermaßen aus:

void AUdio::StopWave()
{
	dsbSound->Stop();
}
6.Den Sound wieder freigeben

Am Ende des Programms sollte es wieder freigegeben werden.

Dazu ergänzen wir zunächst unsere Klasse um
void ReleaseDSound()
.

Die Funktion ist folgendermaßen aufgebaut:

void AUdio::ReleaseDSound()
{
	if (dsbSound != NULL)
	{
		dsbSound->Release();
		dsbSound = NULL;
	}

	if (lpDirectSound != NULL)
	{
		lpDirectSound->Release();
		lpDirectSound = NULL;
	}
}

Zunächst wird abgefragt, ob der Sound überhaupt existiert, wenn ja wird er wieder freigegeben.

7.Den Sound benutzen

Nach dem erstellen des Windows Fensters sollte der Sound zunächst initialisiert werden und dann geladen werden:

AUdio Sound;

if(Sound.DSoundInit(hWnd) == false)
{
      //Fehlerbehandlung
}
if(Sound.LoadWave("sound.wav") == false)
{
      //Fehlerbehandlung
}

Die Variable "Sound" sollte global definiert werden, damit man sie auch in anderen Funktionen, als in der Main Funktion benutzt werden kann. Jetzt kann man z.B.: Abfragen, ob die Taste 1 gedrückt wurde, wenn ja dann:

Sound.PlayWave();

Wenn z.B.: Die Taste 2 gedrückt wird soll der Sound aufhören abzuspielen:

Sound.StopWave();

Falls das Programm geschlossen wird muss der Speicherplatz wieder freigegeben werden:

Sound.ReleaseDSound();

Nun sollte der Sound abspielbar sein. Grüße lcp9

Meine Werkzeuge
Namensräume
Varianten
Aktionen
Navigation
Werkzeuge