[Zurück]
Inhaltsverzeichnis
[Weiter]
Verwendung der "Simple DirectMedia Layer"-API
Audio
Es muß eine Callback-Funktion geschrieben werden,
die die Audiodaten mischt und in den Audio-Strom schreibt.
Danach kann das Audio-Format und die Abtastrate ausgewählt
und das Audio-Gerät geöffnet werden.
Der Sound wird erst gespielt, wenn SDL_PauseAudio(0) aufgerufen
wird. So kann initialisiert werden, bevor das Callback angesprungen
wird. Nach dem Ende der Audio-Ausgabe sollte SDL_CloseAudio()
aufgerufen werden.
|
Tip:
Wenn ein Programm verschiedene Audioformate unterstützt,
sollte man einen zweiten Parameter an SDL_AudioSpec() übergeben,
um das Audioformat der Hardware abzufragen. Ist dieser Parameter NULL,
werden die Audiodaten ggf. in das Format der Hardware umgewandelt. |
Beispiel:
#include "SDL.h"
#include "SDL_audio.h"
{
extern void mixeAudio(void *nichtVerwendet, Uint8 *stream, int laenge);
SDL_AudioSpec format;
/* Format: 16 Bit, stereo, 22 KHz */
format.freq = 22050;
format.format = AUDIO_S16;
format.channels = 2;
format.samples = 512; /* ein guter Wert für Spiele */
format.callback = mixeAudio;
format.userdata = NULL;
/* das Audio-Gerät öffnen und das Abspielen beginnen */
if ( SDL_OpenAudio(&format, NULL) < 0 ) {
fprintf(stderr, "Audio-Gerät konnte nicht geöffnet werden: %s\n", SDL_GetError());
exit(1);
}
SDL_PauseAudio(0);
...
SDL_CloseAudio();
}
|
- Audio laden und abspielen
SDL stellt eine Funktion zum Einladen und Abspielen von
Audio zur Verfügung: SDL_LoadWAV(). Nach dem Laden sollten die
Audiodaten mit SDL_ConvertAudio() konvertiert und der eigenen
Mixer-Funktion zur Verfügung gestellt werden.
|
Tip:
Die Audio-Möglichkeiten von SDL sind für einen einfachen Audio-Mixer
gedacht. Ein Beispiel-Mixer unter der LGPL findet sich im
SDL-Demoarchiv. |
Beispiel:
#define NUM_SOUNDS 2
struct sample {
Uint8 *data;
Uint32 dpos;
Uint32 dlen;
} sounds[NUM_SOUNDS];
void mixeAudio(void *nichtVerwendet, Uint8 *stream, int laenge)
{
int i;
Uint32 menge;
for ( i=0; i<NUM_SOUNDS; ++i ) {
menge = (sounds[i].dlen-sounds[i].dpos);
if ( menge > laenge ) {
menge = laenge;
}
SDL_MixAudio(stream, &sounds[i].data[sounds[i].dpos], menge, SDL_MIX_MAXVOLUME);
sounds[i].dpos += menge;
}
}
void spieleAudio(char *datei)
{
int index;
SDL_AudioSpec wave;
Uint8 *data;
Uint32 dlen;
SDL_AudioCVT cvt;
/* einen leeren Audio-Slot suchen */
for ( index=0; index<NUM_SOUNDS; ++index ) {
if ( sounds[index].dpos == sounds[index].dlen ) {
break;
}
}
if ( index == NUM_SOUNDS )
return;
/* Audio-Datei laden und nach 16 Bit und 22KHz wandeln */
if ( SDL_LoadWAV(datei, &wave, &data, &dlen) == NULL ) {
fprintf(stderr, "Konnte '%s' nicht laden: %s\n", datei, SDL_GetError());
return;
}
SDL_BuildAudioCVT(&cvt, wave.format, wave.channels, wave.freq,
AUDIO_S16, 2, 22050);
cvt.buf = malloc(dlen*cvt.len_mult);
memcpy(cvt.buf, data, dlen);
cvt.len = dlen;
SDL_ConvertAudio(&cvt);
SDL_FreeWAV(data);
/* die Audiodaten in den Slot schreiben (Abspielen startet sofort) */
if ( sounds[index].data ) {
free(sounds[index].data);
}
SDL_LockAudio();
sounds[index].data = cvt.buf;
sounds[index].dlen = cvt.len_cvt;
sounds[index].dpos = 0;
SDL_UnlockAudio();
}
|
[Zurück]
Inhaltsverzeichnis
[Weiter]
|