view src/ljvorbis.c @ 0:c84446dfb3f5

initial add
author paulo@localhost
date Fri, 13 Mar 2009 00:39:12 -0700
parents
children
line source
1 /*
3 ljvorbis.c
4 Simple wrapper around vorbisfile for use with the Allegro library
5 copyright 2006 Damian Yerrick
6 based on vorbisfile example
7 copyright 1994-2004 Xiph.Org Foundation
8 licensed under a BSD style license set forth in COPYING-OGG.txt
10 */
12 #define ALLEGRO_USE_CONSOLE
13 #include <stdio.h>
14 #include "ljvorbis.h"
16 #define VORBIS_BYTEDEPTH 2 // number of bytes per sample; 2 means 16-bit
17 #define VORBIS_ENDIAN 0 // 0: x86/little; 2: ppc/big
18 #define VORBIS_SIGNED 0 // 0: unsigned; 1: signed; Allegro uses unsigned
20 LJVorbis *LJVorbis_open(const char *filename) {
21 LJVorbis *ogg = malloc(sizeof(LJVorbis));
22 if (!ogg) {
23 return NULL;
24 }
25 ogg->fp = fopen(filename, "rb");
26 if (!ogg->fp) {
27 free(ogg);
28 return NULL;
29 }
30 if (ov_open(ogg->fp, &(ogg->vf), NULL, 0) < 0) {
31 fclose(ogg->fp);
32 free(ogg);
33 return NULL;
34 }
35 vorbis_info *vi=ov_info(&(ogg->vf),-1);
36 ogg->rate = vi->rate;
37 ogg->channels = vi->channels;
38 ogg->length = ov_pcm_total(&(ogg->vf),-1);
39 ogg->loopPoint = 0;
40 ogg->voice = NULL;
41 ogg->paused = 0;
42 return ogg;
43 }
45 void LJVorbis_setLoop(LJVorbis *ogg, unsigned long int loopPoint) {
46 if (ogg) {
47 if (loopPoint < ogg->length) {
48 ogg->loopPoint = loopPoint;
49 } else {
50 ogg->loopPoint = 0;
51 }
52 }
53 }
55 int LJVorbis_start(LJVorbis *ogg, int bufferSize, int vol, int pan) {
56 if (ogg) {
58 // if restarting, stop first
59 if (ogg->voice) {
60 LJVorbis_stop(ogg);
61 }
62 ogg->voice = play_audio_stream(bufferSize,
63 8 * VORBIS_BYTEDEPTH,
64 ogg->channels > 1,
65 ogg->rate,
66 vol, pan);
67 ogg->bufferSize = bufferSize;
68 if (!ogg->voice) {
69 return -1;
70 }
71 ov_pcm_seek(&(ogg->vf), 0);
72 return 0;
73 }
74 return -1;
75 }
77 void LJVorbis_stop(LJVorbis *ogg) {
78 if (ogg && ogg->voice) {
79 stop_audio_stream(ogg->voice);
80 ogg->voice = NULL;
81 }
82 }
84 void LJVorbis_close(LJVorbis *ogg) {
85 if (ogg) {
86 LJVorbis_stop(ogg);
87 ov_clear(&(ogg->vf)); // finalize decoder and close the file
88 // thanks kesiev for reminding me that ov_clear closes the file itself
89 free(ogg);
90 }
91 }
93 void LJVorbis_pause(LJVorbis *ogg, int value) {
94 if (ogg && ogg->voice) {
95 int hwVoice = ogg->voice->voice;
96 voice_set_frequency(hwVoice, value ? 0 : ogg->rate);
97 ogg->paused = value ? 1 : 0;
98 }
99 }
101 int LJVorbis_poll(LJVorbis *ogg) {
102 if (!ogg || !ogg->voice) {
103 return -1;
104 }
105 char *buf = get_audio_stream_buffer(ogg->voice);
106 int eofReached = 0;
108 if (buf) {
109 // the number of bytes left in this buffer
110 long int bytesLeft = ogg->bufferSize * VORBIS_BYTEDEPTH * ogg->channels;
112 while (bytesLeft > 0) {
113 long ret=ov_read(&(ogg->vf),
114 buf,
115 bytesLeft,
116 VORBIS_ENDIAN,
117 VORBIS_BYTEDEPTH,
118 VORBIS_SIGNED,
119 &(ogg->bitstream));
120 if (ret == 0) {
121 // try to seek back to the beginning of the file
122 int pcmErr = ov_pcm_seek(&(ogg->vf), ogg->loopPoint);
123 if (pcmErr) {
124 /* EOF */
125 eofReached = 1;
126 bytesLeft = 0;
127 }
128 } else if (ret < 0) {
129 // Stream error. Just ignore it.
130 } else {
131 /* FIXME: handle sample rate changes, etc */
132 // advance forward in the buffer
133 buf += ret;
134 bytesLeft -= ret;
135 }
136 }
137 free_audio_stream_buffer(ogg->voice);
138 }
139 return eofReached;
140 }
142 #ifdef LJVORBIS_DEMO
143 int main(){
144 int eofReached = 0;
145 LJVorbis *ogg = LJVorbis_open("AM-3P.ogg");
147 if (!ogg) {
148 fprintf(stderr, "Could not open AM-3P.ogg.\n");
149 exit(1);
150 }
151 LJVorbis_setLoop(ogg, 650772);
153 if (allegro_init() < 0
154 || install_timer() < 0
155 || set_gfx_mode(GFX_SAFE, 320, 200, 0, 0) < 0
156 || install_keyboard() < 0
157 || install_sound(DIGI_AUTODETECT, MIDI_NONE, NULL) < 0) {
158 allegro_exit();
159 LJVorbis_close(ogg);
160 fprintf(stderr, "Could not start Allegro library: %s\n", allegro_error);
161 exit(1);
162 }
164 /* Throw the comments plus a few lines about the bitstream we're
165 decoding */
166 if (0)
167 {
168 char line1[80], line2[80];
170 usprintf(line1,"%d channels, %u Hz", ogg->channels, ogg->rate);
171 usprintf(line2,"length: %lu samples", ogg->length);
172 alert(line1, line2, "ready?",
173 "Play", 0, 13, 0);
174 }
176 if (LJVorbis_start(ogg, 1024, 192, 128) < 0) {
177 LJVorbis_close(ogg);
178 alert("Could not allocate voice",
179 "for playing audio.",
180 "",
181 "OK", 0, 13, 0);
182 exit(1);
183 }
185 while(!eofReached){
186 eofReached = LJVorbis_poll(ogg);
187 rest(16);
189 if (keypressed()) {
190 int scancode;
191 ureadkey(&scancode);
193 if (scancode == KEY_P) {
194 LJVorbis_pause(ogg, !ogg->paused);
195 } else if (scancode == KEY_ESC) {
196 eofReached = 1;
197 }
198 }
199 }
201 /* cleanup */
202 LJVorbis_close(ogg);
203 return(0);
204 }
205 END_OF_MAIN();
206 #endif