Tutorial Reproducir audio/música/sonido en C++ con Allegro 5

OP

YoshiFanGM

Gimmick Master
Colaborador
Mensajes
1.068
Calificaciones
499 3
Puntos
160
Ubicación
MTY
#1
Holas... Aquí comparto unos códigos de ejemplo para usar archivos de audio en C++, por medio de la biblioteca de programación "Allegro" (versión 5) para el desarrollo de videojuegos. Al final del tema pondré un enlace para descargar los programas pre-compilados con los códigos.

Para ver una guía de instalación y configuración de Allegro en Code Blocks (incluyendo tutoriales básicos para usar la librería) pueden mirar el tema de Programación de Juegos en C++ y Allegro, para Windows y Linux.


Debido a que Allegro puede manejar audio usando "samples" y "streams", he hecho dos ejemplos para cada uno, mostrando una forma de cargar archivos de audio por medio de ALLEGRO_SAMPLE y ALLEGRO_AUDIO_STREAM.

La principal diferencia, es que un ALLEGRO_SAMPLE carga todo el archivo en la memoria RAM, por lo que es mejor para efectos de sonido ligeros. Mientras que un ALLEGRO_AUDIO_STREAM reproduce el archivo haciendo streaming (sin necesidad de cargar todo el archivo en la memoria RAM) y es útil para poner una música de fondo o efectos de sonido más grandes.


Códigos

1. Usando ALLEGRO_SAMPLE

C++:
// Allegro
#include <allegro5/allegro.h>

// Funciones de audio
#include <allegro5/allegro_acodec.h>
#include <allegro5/allegro_audio.h>

// Funciones para mostrar diálogos (mensajes de texto)
#include <allegro5/allegro_native_dialog.h>


// Función para inicializar Allegro y los módulos
// Devuelve "false" si hubo un error
bool Inicializar_Allegro()
{
   // Allegro
   al_init();

   // Audio
   if (!al_install_audio())
   {  al_show_native_message_box(NULL, "Allegro", "Error"
                                 ,"Error al inicializar el audio!", NULL
                                 , ALLEGRO_MESSAGEBOX_ERROR);
      return false;
   }

   // Códecs
   if (!al_init_acodec_addon())
   {  al_show_native_message_box(NULL, "Allegro", "Error"
                                 ,"Error al inicializar los códecs!", NULL
                                 , ALLEGRO_MESSAGEBOX_ERROR);
      return false;
   }

   // Devolver "true" si no hubo error
   return true;
}



// Función main()
// Tenemos que poner los argumentos "argc" y "argv" para que se pueda cargar
// el archivo de audio desde la línea de comandos o arrastrándolo al programa.
int main(int argc, char **argv)
{
   // Punteros para el archivo de sonido y la ventana
   ALLEGRO_SAMPLE *samp;
   ALLEGRO_DISPLAY *ventana;


   if (!Inicializar_Allegro())
      return 0;


   // Crear la ventana
   ventana = al_create_display(640, 480);

   if (!ventana)
   {  al_show_native_message_box(NULL, "Allegro", "Error"
                                 ,"No se pudo crear una ventana", NULL
                                 , ALLEGRO_MESSAGEBOX_ERROR);
      return 0;
   }


   // Indicar la cantidad de sonidos que se pueden reproducir simultáneamente
   al_reserve_samples(1);

   // Cargar el archivo de audio de acuerdo al primer argumento del programa
   if (argc > 1)
   {  samp = al_load_sample(argv[1]);

      if (!samp)
      {  al_show_native_message_box(NULL, "Allegro", "Error"
                                    ,"No se pudo abrir el archivo", NULL
                                    , ALLEGRO_MESSAGEBOX_ERROR);
         return 0;
      }
   }
   else
   {  // Mostrar un mensaje de aviso si no se especificó un archivo de audio
      al_show_native_message_box(NULL, "Allegro", "Error"
                                 ,"Debes especificar un archivo de audio desde"
                                 " la línea de comandos o arrastrarlo.", NULL
                                 , ALLEGRO_MESSAGEBOX_ERROR);
      return 0;
   }

   // Reproducir el archivo de sonido
   al_play_sample(samp, 1.0, 0, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL);


   // Crear una lista de eventos para la ventana
   ALLEGRO_EVENT_QUEUE *eventos = al_create_event_queue();
   al_register_event_source(eventos, al_get_display_event_source(ventana));

   // Mantener abierto el programa hasta que la ventana se cierre
   while (1)
   {  ALLEGRO_EVENT ev;
      al_wait_for_event(eventos, &ev);

      if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
      {  break;
      }
   }


   // Liberar la memoria ocupada
   al_destroy_event_queue(eventos);
   al_destroy_display(ventana);
   al_destroy_sample(samp);


   return 0;
}
Resumen

1. Se declara un puntero del tipo "ALLEGRO_SAMPLE" adentro de main(), llamado "samp".
2. Se usa las funciones al_install_audio y al_init_acodec_addon antes de llamar a las otras funciones de audio.
3. Se usa la función al_reserve_samples para especificar la cantidad de sonidos que se pueden reproducir simultáneamente.
4. Se usa la función al_load_sample para cargar el archivo de audio, y el valor devuelto se almacena en el puntero "samp".
5. Se reproduce el sonido por medio de al_play_sample.
6. Se libera la memoria con al_destroy_sample.

2. Usando ALLEGRO_AUDIO_STREAM

C++:
// Allegro
#include <allegro5/allegro.h>

// Funciones de audio
#include <allegro5/allegro_acodec.h>
#include <allegro5/allegro_audio.h>

// Funciones para mostrar diálogos (mensajes de texto)
#include <allegro5/allegro_native_dialog.h>


// Función para inicializar Allegro y los módulos
// Devuelve 0 si hubo un error
bool Inicializar_Allegro()
{
   // Allegro
   al_init();

   // Audio
   if (!al_install_audio())
   {  al_show_native_message_box(NULL, "Allegro", "Error"
                                 ,"Error al inicializar el audio!", NULL
                                 , ALLEGRO_MESSAGEBOX_ERROR);
      return 0;
   }

   // Códecs
   if (!al_init_acodec_addon())
   {  al_show_native_message_box(NULL, "Allegro", "Error"
                                 ,"Error al inicializar los códecs!", NULL
                                 , ALLEGRO_MESSAGEBOX_ERROR);
      return 0;
   }

   // Devolver 1 si no hubo error
   return 1;
}



// Función main()
// Tenemos que poner los argumentos "argc" y "argv" para que se pueda cargar
// el archivo de audio desde la línea de comandos o arrastrándolo al programa.
int main(int argc, char **argv)
{
   // Punteros para el archivo de sonido y la ventana
   ALLEGRO_AUDIO_STREAM *stream;
   ALLEGRO_DISPLAY *ventana;


   if (!Inicializar_Allegro())
      return 0;


   // Crear la ventana
   ventana = al_create_display(640, 480);

   if (!ventana)
   {  al_show_native_message_box(NULL, "Allegro", "Error"
                                 ,"No se pudo crear una ventana", NULL
                                 , ALLEGRO_MESSAGEBOX_ERROR);
      return 0;
   }


   // Indicar la cantidad de sonidos que se pueden reproducir simultáneamente
   al_reserve_samples(1);


   // Cargar el archivo de audio de acuerdo al primer argumento del programa
   if (argc > 1)
   {  stream = al_load_audio_stream(argv[1], 2, 4096);

      if (!stream)
      {  al_show_native_message_box(NULL, "Allegro", "Error"
                                    ,"No se pudo abrir el archivo", NULL
                                    , ALLEGRO_MESSAGEBOX_ERROR);
         return 0;
      }
   }
   else
   {  // Mostrar un mensaje de aviso si no se especificó un archivo de audio
      al_show_native_message_box(NULL, "Allegro", "Error"
                                 ,"Debes especificar un archivo de audio desde"
                                 " la línea de comandos o arrastrarlo.", NULL
                                 , ALLEGRO_MESSAGEBOX_ERROR);
      return 0;
   }

   // Debemos juntar el stream con el "mixer" para poder escucharlo.
   al_attach_audio_stream_to_mixer(stream, al_get_default_mixer());


   // Crear una lista de eventos para la ventana
   ALLEGRO_EVENT_QUEUE *eventos = al_create_event_queue();
   al_register_event_source(eventos, al_get_display_event_source(ventana));

   // Mantener abierto el programa hasta que la ventana se cierre
   while (1)
   {  ALLEGRO_EVENT ev;
      al_wait_for_event(eventos, &ev);

      if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
      {  break;
      }
   }


   // Liberar la memoria ocupada
   al_destroy_event_queue(eventos);
   al_destroy_display(ventana);
   al_destroy_audio_stream(stream);


   return 0;
}
Resumen

1. Se declara un puntero del tipo "ALLEGRO_AUDIO_STREAM" adentro de main(), llamado "stream".
2. Se usa las funciones al_install_audio y al_init_acodec_addon antes de llamar a las otras funciones de audio.
3. Se usa la función al_reserve_samples para especificar la cantidad de sonidos que se pueden reproducir simultáneamente.
4. Se usa la función al_load_audio_stream para cargar y reproducir el archivo en modo streaming, y el valor devuelto se almacena en el puntero "stream".
5. Se adjunta el stream con la función al_attach_audio_stream_to_mixer para que se pueda escuchar.
6. Se libera la memoria con al_destroy_audio_stream.


Descarga de los programas



Para abrir un archivo de audio, se necesita arrastrar el archivo hacia el programa con el mouse, o se puede especificar en la línea de comandos:
Código:
Sample.exe "C:\archivo\de\audio.ogg"
Código:
Stream.exe "C:\archivo\de\audio.ogg"

Formatos compatibles:
  • .WAV
  • .FLAC
  • .OGG
 
Última edición:
Arriba Pie