[Anterior] Tabla De Contenido [Siguiente]

Usando la API de Simple DirectMedia Layer

Sonido

  • Abriendo el dispositivo de sonido

Necesitas tener una función de retrollamada que mezcle tus datos de sonido y lo coloque en el flujo de sonido. Tras esto, elije el formato de sonido que desees y la velocidad, y abre el dispositivo de sonido.

El sonido no empezará realmente a reproducirse hasta que no hagas una llamada a SDL_PauseAudio(0), permitiéndote realizar las demás inicializaciones de audio que necesite antes de que tu función de retrollamada se ejecute. Tras terminar de usar la salida de audio, deberías cerrarla usando la función SDL_CloseAudio().

Pista:
Si tu aplicación puede manejar diferentes formatos de audio, pasa un segundo puntero SDL_AudioSpec a la función SDL_OpenAudio() para obtener el formato real de sonido del hardware. Si dejas el segundo puntero como NULL, los datos de sonido serán convertidos al formato de sonido del hardware en tiempo de ejecución.
Ejemplo:
#include "SDL.h"
#include "SDL_audio.h"
{
    extern void mixaudio(void *unused, Uint8 *stream, int len);
    SDL_AudioSpec fmt;

    /* Establece sonido estéreo de 16 bits a 22Khz */
    fmt.freq = 22050;
    fmt.format = AUDIO_S16;
    fmt.channels = 2;
    fmt.samples = 512;  /* Un buen valor para juegos */
    fmt.callback = mixaudio;
    fmt.userdata = NULL;

    /* ¡Abre el dispositivo de sonido y comienza a
       reproducir sonidos! */
    if ( SDL_OpenAudio(&fmt, NULL) < 0 ) {
        fprintf(stderr, "¡No puedo abrir el sonido!: %s\n",
	        SDL_GetError());
        exit(1);
    }
    SDL_PauseAudio(0);

    ...

    SDL_CloseAudio();
}
  • Cargando y reproduciendo sonidos

SDL facilita para tu conveniencia, una rútina única para cargar sonido, SDL_LoadWAV(). Tra cargar tus sonidos, deberías convertirlos al formato de audio de salida usando SDL_ConvertAudio(), y así hacerlo disponible a tu función de mezcla.

Pista:
Las facilidades de sonido de SDL están diseñadas para un mezclador de sonido de software de bajo nivel. Una completa implementación de un mezclador de ejmplo está disponible bajo la licencia LGPL, y puede encontrarse en la sección de demos del archivo SDL.
Ejemplo:
#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;

    /* Busca una ranura de sonido vacía(o finalizada) */
    for ( index=0; index<NUM_SOUNDS; ++index ) {
        if ( sounds[index].dpos == sounds[index].dlen ) 
	{	
            break;
        }
    }
    if ( index == NUM_SOUNDS )
        return;

    /* Carga el archivo de sonido y lo convierte a
       estéreo 16 bits a 22kHz */
    if ( SDL_LoadWAV(file, &wave, &data, &dlen) == NULL ) 
    {
        fprintf(stderr, "No pude cargar %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);

    /* Pone los datos de audio en la ranura (comienza
       la reproducción inmediatemente) */
    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();
}

[Anterior] Tabla De Contenido [Siguiente]