* Example program for the Allegro library.
*
* Demonstrate 'simple' audio interface.
*/
#define ALLEGRO_UNSTABLE
#include <math.h>
#include <stdio.h>
#include "allegro5/allegro.h"
#include "allegro5/allegro_font.h"
#include "allegro5/allegro_audio.h"
#include "allegro5/allegro_acodec.h"
#include "common.c"
#define RESERVED_SAMPLES 16
#define MAX_SAMPLE_DATA 10
const char *default_files[] = {NULL, "data/welcome.wav",
"data/haiku/fire_0.ogg", "data/haiku/fire_1.ogg",
"data/haiku/fire_2.ogg", "data/haiku/fire_3.ogg",
"data/haiku/fire_4.ogg", "data/haiku/fire_5.ogg",
"data/haiku/fire_6.ogg", "data/haiku/fire_7.ogg",
};
int main(int argc, const char *argv[])
{
ALLEGRO_SAMPLE *sample_data[MAX_SAMPLE_DATA] = {NULL};
ALLEGRO_DISPLAY *display = NULL;
ALLEGRO_EVENT_QUEUE *event_queue;
ALLEGRO_EVENT event;
ALLEGRO_SAMPLE_ID sample_id;
bool sample_id_valid = false;
ALLEGRO_TIMER* timer;
ALLEGRO_FONT* font;
ALLEGRO_AUDIO_STREAM *music = NULL;
int i;
bool panning = false;
if (!al_init()) {
abort_example("Could not init Allegro.\n");
}
if (!al_init_font_addon()) {
abort_example("Could not init the font addon.\n");
}
open_log();
if (argc < 2) {
log_printf("This example can be run from the command line.\nUsage: %s {audio_files}\n", argv[0]);
argv = default_files;
argc = 10;
}
argc--;
argv++;
al_install_keyboard();
display = al_create_display(640, 480);
if (!display) {
abort_example("Could not create display\n");
}
font = al_create_builtin_font();
timer = al_create_timer(1/60.0);
al_start_timer(timer);
event_queue = al_create_event_queue();
al_register_event_source(event_queue, al_get_keyboard_event_source());
al_register_event_source(event_queue, al_get_display_event_source(display));
al_register_event_source(event_queue, al_get_timer_event_source(timer));
al_init_acodec_addon();
Restart:
if (!al_install_audio()) {
abort_example("Could not init sound!\n");
}
if (!al_reserve_samples(RESERVED_SAMPLES)) {
abort_example("Could not set up voice and mixer.\n");
}
memset(sample_data, 0, sizeof(sample_data));
for (i = 0; i < argc && i < MAX_SAMPLE_DATA; i++) {
const char *filename = argv[i];
sample_data[i] = al_load_sample(argv[i]);
if (!sample_data[i]) {
log_printf("Could not load sample from '%s'!\n", filename);
continue;
}
}
log_printf(
"Press digits to play sounds.\n"
"Space to stop sounds.\n"
"Add Alt to play sounds repeatedly.\n"
"'p' to pan the last played sound.\n"
"Escape to quit.\n");
while (true) {
al_wait_for_event(event_queue, &event);
if (event.type == ALLEGRO_EVENT_KEY_CHAR) {
if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) {
break;
}
if (event.keyboard.unichar == ' ') {
log_printf("Stopping all sounds\n");
al_stop_samples();
if (music) {
al_set_audio_stream_playing(music, false);
}
}
if (event.keyboard.keycode >= ALLEGRO_KEY_0 && event.keyboard.keycode <= ALLEGRO_KEY_9) {
bool loop = event.keyboard.modifiers & ALLEGRO_KEYMOD_ALT;
bool bidir = event.keyboard.modifiers & ALLEGRO_KEYMOD_CTRL;
bool reversed = event.keyboard.modifiers & ALLEGRO_KEYMOD_SHIFT;
i = (event.keyboard.keycode - ALLEGRO_KEY_0 + 9) % 10;
if (sample_data[i]) {
ALLEGRO_SAMPLE_ID new_sample_id;
ALLEGRO_PLAYMODE playmode;
const char* playmode_str;
if (loop) {
playmode = ALLEGRO_PLAYMODE_LOOP;
playmode_str = "on a loop";
}
else if (bidir) {
playmode = ALLEGRO_PLAYMODE_BIDIR;
playmode_str = "on a bidirectional loop";
}
else {
playmode = ALLEGRO_PLAYMODE_ONCE;
playmode_str = "once";
}
bool ret = al_play_sample(sample_data[i], 1.0, 0.0, 1.0,
playmode, &new_sample_id);
if (reversed) {
ALLEGRO_SAMPLE_INSTANCE* inst = al_lock_sample_id(&new_sample_id);
al_set_sample_instance_position(inst, al_get_sample_instance_length(inst) - 1);
al_set_sample_instance_speed(inst, -1);
al_unlock_sample_id(&new_sample_id);
}
if (ret) {
log_printf("Playing %d %s\n", i, playmode_str);
}
else {
log_printf(
"al_play_sample_data failed, perhaps too many sounds\n");
}
if (!panning) {
if (ret) {
sample_id = new_sample_id;
sample_id_valid = true;
}
}
}
}
if (event.keyboard.unichar == 'p') {
if (sample_id_valid) {
panning = !panning;
if (panning) {
log_printf("Panning\n");
}
else {
log_printf("Not panning\n");
}
}
}
if (event.keyboard.unichar == 'm') {
music = al_play_audio_stream("../demos/cosmic_protector/data/sfx/title_music.ogg");
}
* For debugging race conditions on shutting down the audio.
*/
if (event.keyboard.unichar == 'r') {
for (i = 0; i < argc && i < MAX_SAMPLE_DATA; i++) {
if (sample_data[i])
al_destroy_sample(sample_data[i]);
}
al_uninstall_audio();
goto Restart;
}
}
else if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
break;
}
else if (event.type == ALLEGRO_EVENT_TIMER) {
int y = 12;
int dy = 12;
if (panning && sample_id_valid) {
ALLEGRO_SAMPLE_INSTANCE* instance = al_lock_sample_id(&sample_id);
if (instance) {
al_set_sample_instance_pan(instance, sin(al_get_time()));
}
al_unlock_sample_id(&sample_id);
}
al_clear_to_color(al_map_rgb_f(0., 0., 0.));
al_draw_text(font, al_map_rgb_f(1., 0.5, 0.5), 12, y,
ALLEGRO_ALIGN_LEFT, "CONTROLS");
y += dy;
al_draw_text(font, al_map_rgb_f(1., 0.5, 0.5), 12, y,
ALLEGRO_ALIGN_LEFT, "1-9 - play the sounds");
y += dy;
al_draw_text(font, al_map_rgb_f(1., 0.5, 0.5), 12, y,
ALLEGRO_ALIGN_LEFT, "SPACE - stop all sounds");
y += dy;
al_draw_text(font, al_map_rgb_f(1., 0.5, 0.5), 12, y,
ALLEGRO_ALIGN_LEFT, "Ctrl 1-9 - play sounds with bidirectional looping");
y += dy;
al_draw_text(font, al_map_rgb_f(1., 0.5, 0.5), 12, y,
ALLEGRO_ALIGN_LEFT, "Alt 1-9 - play sounds with regular looping");
y += dy;
al_draw_text(font, al_map_rgb_f(1., 0.5, 0.5), 12, y,
ALLEGRO_ALIGN_LEFT, "Shift 1-9 - play sounds reversed");
y += dy;
al_draw_text(font, al_map_rgb_f(1., 0.5, 0.5), 12, y,
ALLEGRO_ALIGN_LEFT, "p - pan the last played sound");
y += dy;
al_draw_text(font, al_map_rgb_f(1., 0.5, 0.5), 12, y,
ALLEGRO_ALIGN_LEFT, "m - play music");
y += 2 * dy;
al_draw_text(font, al_map_rgb_f(0.5, 1., 0.5), 12, y,
ALLEGRO_ALIGN_LEFT, "SOUNDS");
y += dy;
for (i = 0; i < argc && i < MAX_SAMPLE_DATA; i++) {
al_draw_textf(font, al_map_rgb_f(0.5, 1., 0.5), 12, y,
ALLEGRO_ALIGN_LEFT, "%d - %s", i + 1, argv[i]);
y += dy;
}
al_flip_display();
}
}
for (i = 0; i < argc && i < MAX_SAMPLE_DATA; i++) {
if (sample_data[i])
al_destroy_sample(sample_data[i]);
}
al_uninstall_audio();
al_destroy_display(display);
close_log(true);
return 0;
}