/* * Note: There are proper Allegro addons for OggVorbis now, such as alogg by * Vincent Penquerc'h (currently at http://lyrian.obnix.com/alogg/). * I leave this up to show who did it first ;-) --pw, 2002-08-20. */ /* vorbillegro.c * * Demonstration of using Ogg Vorbis in an Allegro program, or more * specifically, using vorbisfile with AUDIOSTREAM routines. This is * a demo rather than a proper library as I have no need for Vorbis * streaming in a game at the moment, and because vorbisfile is so * simple to program anyway. But if this is useful to you, I'd like * to hear about it. * * This file is based off vorbisfile_example.c in the Ogg Vorbis * source distribution, and so falls under the licence. The original * copyleft message takes up the next comment block. The LGPL itself * can be read somewhere on http://www.gnu.org/. * * Peter Wang , 17 November 2000. */ /* * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY * * THE GNU LESSER/LIBRARY PUBLIC LICENSE, WHICH IS INCLUDED WITH * * THIS SOURCE. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * * * * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2000 * * by Monty and the XIPHOPHORUS Company * * http://www.xiph.org/ * */ #include #include #include #include /* Loose variables. */ static FILE *fp; static OggVorbis_File vf; static int current_section; static AUDIOSTREAM *as; static int buffer_size; static int loaded; /* Audiostream output format. */ static const int samples = 64; static const int bits = 16; static const int stereo = TRUE; static const int freq = 44100; static const int volume = 255; static const int panning = 128; #ifdef ALLEGRO_BIG_ENDIAN static const int big_endian = 1; #else static const int big_endian = 0; #endif /* Ready a Vorbis file to be played. Return TRUE on success. */ int load_vorbis_stream (const char *filename) { if (!(fp = fopen (filename, "rb"))) return FALSE; if (ov_open (fp, &vf, NULL, 0) < 0) { fclose (fp); return FALSE; } /* XXX need to find stereocity and frequency of vorbis file */ as = play_audio_stream (samples, bits, stereo, freq, volume, panning); if (!as) { ov_clear (&vf); return FALSE; } buffer_size = samples * ((bits == 16) ? 2 : 1) * (stereo ? 2 : 1); current_section = 0; loaded = 1; return TRUE; } /* Free the file from memory. */ void unload_vorbis_stream (void) { if (loaded) { stop_audio_stream (as); ov_clear (&vf); loaded = 0; } } /* Decode and buffer a part of the stream. Return -1 if the music * stopped, zero if the playback buffer is full, or 1 if data was * successfully decoded and buffered. */ int poll_vorbis_stream (void) { void *buffer; long size, x; size = buffer_size; while (size > 0) { buffer = get_audio_stream_buffer (as); if (!buffer) return 0; x = ov_read (&vf, buffer, size, big_endian, ((bits == 16) ? 2 : 1), 0, ¤t_section); free_audio_stream_buffer (as); if (x == 0) return -1; else if (x < 0) return 0; size -= x; } return 1; } /* Testing program. */ int bg, fg; int start_allegro () { allegro_init (); install_timer (); install_keyboard (); reserve_voices (1, 0); if (install_sound (DIGI_AUTODETECT, MIDI_NONE, NULL) < 0) { allegro_message ("Error installing digital sound.\n"); return 1; } set_gfx_mode (GFX_SAFE, 320, 200, 0, 0); bg = makecol (255, 255, 255); fg = makecol (0, 0, 0); clear_to_color (screen, bg); text_mode (bg); return 0; } void sayf (const char *fmt, ...) { static int y = 0; char buf[512]; va_list ap; va_start (ap, fmt); uvsprintf (buf, fmt, ap); va_end (ap); if (y > SCREEN_H - text_height (font)) clear_to_color (screen, bg), y = 0; textout (screen, font, buf, 0, y, fg); y += text_height (font) + 1; } int main (int argc, char *argv[]) { int i; if (argc < 2) { allegro_message ("Pass a few Vorbis filenames on the command line.\n"); return 1; } if (start_allegro ()) return 1; sayf ("Welcome to Really Advanced Player 6091!"); sayf ("Press a key to skip to the next song."); for (i = 1; i < argc; i++) { if (!load_vorbis_stream (argv[i])) { sayf ("Error opening file `%s'.", argv[i]); continue; } sayf ("Playing file `%s'.", get_filename (argv[i])); while (!keypressed ()) { if (poll_vorbis_stream () < 0) break; yield_timeslice (); } clear_keybuf (); unload_vorbis_stream (); } sayf ("Done. Press any key to quit."); readkey (); return 0; } END_OF_MAIN (); /* vorbillegro.c ends here. */