[Précédente] Table Des Matières [Suivante]

Utiliser l'API Simple DirectMedia Layer

Son

  • Ouvrir le contexte de de périphérique audio

Vous devez avoir écrit une fonction de rappel qui mixte vos données audios et les placent dans le flux audio. Après ça, choisissez le format et le taux audio, et ouvrez le contexte de périphérique audio.

Le son ne sera pas joué tant que vous n'aurez pas appelé SDL_PauseAudio(0), vous permettant d'exécuter d'autres initialisations audio avant que votre fonction de rappel ne soit exécutée.Vous dévez refermer le contexte après son utilisation par SDL_CloseAudio().

Astuce:
Si votre application peut manipuler différents formats audio, passer un second pointeur SDL_AudioSpec à SDL_OpenAudio() afin de récupérer le format audio actuel du matériel. Si vous laissez ce second pointeur à NULL, les données audio seront converties au format audio du matériel à l'exécution.
Exemple:
#include "SDL.h"
#include "SDL_audio.h"
{
    extern void mixaudio(void *unused, Uint8 *stream, int len);
    SDL_AudioSpec fmt;

    /* Un son sereo de 16 bits à 22kHz */
    fmt.freq = 22050;
    fmt.format = AUDIO_S16;
    fmt.channels = 2;
    fmt.samples = 512;        /*Une bonne valeur pour les jeux */
    fmt.callback = mixaudio;
    fmt.userdata = NULL;

    /* Ouvre le contexte audio et joue le son */
    if ( SDL_OpenAudio(&fmt, NULL) < 0 ) {
        fprintf(stderr, "Impossible d'accéder à l'audio: %s\n", SDL_GetError());
        exit(1);
    }
    SDL_PauseAudio(0);

    ...

    SDL_CloseAudio();
}
  • Charger et jouer un son

SDL vous fournie une unique routine de chargement, SDL_LoadWAV(). Après avoir charger votre son, vous devez le convertir au bon format audio en utilisant SDL_ConvertAudio().

Astuce:
SDL est une API de bas niveau dans la gestion de l'audio. Un exemple complet d'une telle implémentation existe sous licence LGPL, et peut être trouvée dans les archives des démos SDL.
Example:
#define NUM_SOUNDS 2
struct sample {
    Uint8 *data;
    Uint32 dpos;
    Uint32 dlen;
} sounds[NUM_SOUNDS];

void mixaudio(void *unused, Uint8 *stream, int len)
{
    int i;
    Uint32 amount;

    for ( i=0; i<NUM_SOUNDS; ++i ) {
        amount = (sounds[i].dlen-sounds[i].dpos);
        if ( amount > len ) {
            amount = len;
        }
        SDL_MixAudio(stream, &sounds[i].data[sounds[i].dpos], amount, SDL_MIX_MAXVOLUME);
        sounds[i].dpos += amount;
    }
}

void PlaySound(char *file)
{
    int index;
    SDL_AudioSpec wave;
    Uint8 *data;
    Uint32 dlen;
    SDL_AudioCVT cvt;

    /* Look for an empty (or finished) sound slot */
    for ( index=0; index<NUM_SOUNDS; ++index ) {
        if ( sounds[index].dpos == sounds[index].dlen ) {
            break;
        }
    }
    if ( index == NUM_SOUNDS )
        return;

    /* Load the sound file and convert it to 16-bit stereo at 22kHz */
    if ( SDL_LoadWAV(file, &wave, &data, &dlen) == NULL ) {
        fprintf(stderr, "Couldn't load %s: %s\n", file, 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);

    /* Put the sound data in the slot (it starts playing immediately) */
    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();
}

[Précédente] Table Des Matières [Suivante]