123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- #include <allegro5/allegro_audio.h>
- #include <allegro5/allegro_acodec.h>
- #include "sound.h"
- #include "mem.h"
- #include "store.h"
- struct Sound_;
- typedef struct Sound_ Sound;
- struct Music_;
- typedef struct Music_ Music;
- struct Audio_;
- typedef struct Audio_ Audio;
- /** Wraper structure around an allegro sample. */
- struct Sound_ {
- ALLEGRO_SAMPLE * handle;
- ALLEGRO_SAMPLE_ID id;
- };
- /** Wrapper structure around an allegro sound stream. */
- struct Music_ {
- ALLEGRO_AUDIO_STREAM * handle;
- };
- #define AUDIO_PLAYING_SAMPLES_MAX 64
- #define AUDIO_VOICES 8
- /**
- * Wraps around the Allegro sound system, and put severything in one handy
- * struct.
- */
- struct Audio_ {
- BOOL ok;
-
- ALLEGRO_MIXER * mixer;
- ALLEGRO_VOICE * voice;
-
- ALLEGRO_AUDIO_STREAM * stream;
- int stream_id;
-
- ALLEGRO_SAMPLE_ID playing[AUDIO_PLAYING_SAMPLES_MAX];
- int playing_id[AUDIO_PLAYING_SAMPLES_MAX];
- int playing_last;
- };
- /* The "global" audio state. */
- static Audio * audio_state;
- #ifndef SOUND_SAMPLES
- #define SOUND_SAMPLES 16
- #endif
- #define AUDIO_RATE 44100
- #define AUDIO_DEPTH ALLEGRO_AUDIO_DEPTH_INT16
- #define AUDIO_CHANNELS ALLEGRO_CHANNEL_CONF_2
- /* Call this when the use of audio is no longer needed. */
- BOOL audio_done() {
- if (!audio_state) {
- return FALSE;
- }
-
- al_stop_samples();
- if (audio_state->stream) {
- al_detach_audio_stream(audio_state->stream);
- }
- if (audio_state->mixer) {
- al_detach_mixer(audio_state->mixer);
- al_destroy_mixer(audio_state->mixer);
- }
- if (audio_state->voice) {
- al_destroy_voice(audio_state->voice);
- audio_state->voice = NULL;
- }
-
- mem_free(audio_state);
- al_uninstall_audio();
- return TRUE;
- }
- /** Call this to alloate space for the audio system. */
- Audio * audio_alloc(void) {
- return STRUCT_ALLOC(Audio);
- }
- int audio_playing_samples_max() {
- return AUDIO_PLAYING_SAMPLES_MAX;
- }
- /** Call this to start up the audio system. */
- BOOL audio_init() {
- int index;
-
- if(!al_install_audio()) return FALSE;
- if(!al_init_acodec_addon()) return FALSE;
-
- audio_state = audio_alloc();
- if (!audio_state) return FALSE;
-
- audio_state->mixer =
- al_create_mixer(AUDIO_RATE, AUDIO_DEPTH, AUDIO_CHANNELS);
- audio_state->voice =
- al_create_voice(AUDIO_RATE, AUDIO_DEPTH, AUDIO_CHANNELS);
- al_attach_mixer_to_voice(audio_state->mixer, audio_state->voice);
-
- al_set_default_mixer(audio_state->mixer);
- al_reserve_samples(SOUND_SAMPLES);
-
- audio_state->stream = NULL;
- audio_state->stream_id = -1;
-
- for (index = 0; index < AUDIO_PLAYING_SAMPLES_MAX; index++) {
- audio_state->playing_id[index] = -1;
- }
- audio_state->ok = TRUE;
- return TRUE;
- }
- /** Returns true if sound can be played, false if not. */
- BOOL audio_ok(void) {
- return audio_state && audio_state->ok;
- }
- #ifndef MUSIC_BUFFERS
- #define MUSIC_BUFFERS 2
- #endif
- #ifndef MUSIC_BUFSIZE
- #define MUSIC_BUFSIZE 2048
- #endif
- /* Set the music with the given index as the active usic.
- If the index is negative, sets no music as active. */
- BOOL audio_set_music(int store_id) {
- double length;
- ALLEGRO_AUDIO_STREAM * stream;
- if (!audio_ok()) return FALSE;
-
- if (store_id < 0) {
- if(audio_state->stream) {
- al_detach_audio_stream(audio_state->stream);
- }
- audio_state->stream = NULL;
- audio_state->stream_id = -1;
- return TRUE;
- }
- stream = store_get_audio_stream(store_id);
- if (!stream) {
- return FALSE;
- }
- audio_state->stream = stream;
-
- /* Automaticallly loop the music over it's whole length. */
- length = al_get_audio_stream_length_secs(audio_state->stream);
- if (length > 0.0) {
- al_set_audio_stream_loop_secs(audio_state->stream, 0.0, length);
- al_set_audio_stream_playmode(audio_state->stream, ALLEGRO_PLAYMODE_LOOP);
- }
-
- al_attach_audio_stream_to_mixer(audio_state->stream, audio_state->mixer);
- return TRUE;
- }
- BOOL audio_play_music() {
- if (!audio_ok()) return FALSE;
- if(!audio_state->stream) return FALSE;
- return al_set_audio_stream_playing(audio_state->stream, TRUE);
- }
- BOOL audio_stop_music() {
- if (!audio_ok()) return FALSE;
- if(!audio_state->stream) return FALSE;
- return al_set_audio_stream_playing(audio_state->stream, FALSE);
- }
- BOOL audio_music_playing_p() {
- if (!audio_ok()) return FALSE;
- if(!audio_state->stream) return FALSE;
- return al_get_audio_stream_playing(audio_state->stream);
- }
- int audio_playing_music_id() {
- if (!audio_ok()) return -1;
- if(!audio_state->stream) return -1;
- return audio_state->stream_id;
- }
- int audio_play_sound_ex
- (int store_id, float gain, float pan, float speed, BOOL loop) {
- int play_id;
- ALLEGRO_SAMPLE * sample;
- ALLEGRO_PLAYMODE mode =
- (loop ? ALLEGRO_PLAYMODE_LOOP : ALLEGRO_PLAYMODE_ONCE);
- if (!audio_ok()) return -2;
- sample = store_get_sample(store_id);
- if (!sample) return -1;
- play_id = audio_state->playing_last;
- audio_state->playing_last++;
- /* Work in ring buffer style. */
- if (audio_state->playing_last >= AUDIO_PLAYING_SAMPLES_MAX) {
- audio_state->playing_last = 0;
- }
- al_play_sample(sample, gain, pan, speed, mode,
- audio_state->playing + play_id);
- audio_state->playing_id[play_id] = store_id;
- return play_id;
- }
- void audio_stop_all_sounds() {
- al_stop_samples();
- /* reset ring buffer pointer */
- audio_state->playing_last = 0;
- }
- /** Plays the sound once only with default parameters. */
- int audio_play_sound(int sample_id) {
- return audio_play_sound_ex(sample_id, 1.0, 0.0, 1.0, FALSE);
- }
- /*
- Stops the sound with the given play id from playing. Doesn't work if
- the integer handle is stale, but thesoun sould have stopped by itself then.
- */
- BOOL audio_stop_sound(int play_id) {
- if (!audio_ok()) return FALSE;
- if (play_id < 0) return FALSE;
- if (play_id >= AUDIO_PLAYING_SAMPLES_MAX) return FALSE;
- al_stop_sample(audio_state->playing + play_id);
- return TRUE;
- }
|