Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/FICN/src/audio/AudioStream.cc @ 430

Last change on this file since 430 was 430, checked in by nicolape, 16 years ago

We now have a background sound playlist

File size: 5.0 KB
Line 
1
2#include "AudioStream.h"
3
4namespace audio
5{
6        AudioStream::AudioStream(std::string path)
7        {
8                this->path = path;
9                loaded = false;
10        }       
11
12        void AudioStream::open()
13        {
14            int result;
15
16           
17            if(!(oggFile = fopen(path.c_str(), "rb")))
18                        {
19                orxonox::Error("Could not open Ogg file "+path);
20                                return;
21                        }
22
23            if((result = ov_open(oggFile, &oggStream, NULL, 0)) < 0)
24            {
25        fclose(oggFile);               
26              orxonox::Error("Could not open Ogg stream. " + errorString(result));
27                                return;
28            }
29
30                        loaded = true;
31       
32            vorbisInfo = ov_info(&oggStream, -1);
33            vorbisComment = ov_comment(&oggStream, -1);
34       
35            if(vorbisInfo->channels == 1)
36                format = AL_FORMAT_MONO16;
37            else
38                format = AL_FORMAT_STEREO16;
39               
40               
41            alGenBuffers(2, buffers);
42            check();
43            alGenSources(1, &source);
44            check();
45           
46            alSource3f(source, AL_POSITION,        0.0, 0.0, 0.0);
47            alSource3f(source, AL_VELOCITY,        0.0, 0.0, 0.0);
48            alSource3f(source, AL_DIRECTION,       0.0, 0.0, 0.0);
49            alSourcef (source, AL_ROLLOFF_FACTOR,  0.0          );
50            alSourcei (source, AL_SOURCE_RELATIVE, AL_FALSE      );
51        }
52       
53       
54       
55       
56        void AudioStream::release()
57        {
58
59            alSourceStop(source);
60            empty();
61            alDeleteSources(1, &source);
62            check();
63            alDeleteBuffers(1, buffers);
64            check();
65       
66            ov_clear(&oggStream);
67                        loaded = false;
68               
69        }
70       
71       
72       
73       
74        void AudioStream::display()
75        {
76                if (loaded)
77                {
78            std::cout
79                << "version         " << vorbisInfo->version         << "\n"
80                << "channels        " << vorbisInfo->channels        << "\n"
81                << "rate (hz)       " << vorbisInfo->rate            << "\n"
82                << "bitrate upper   " << vorbisInfo->bitrate_upper   << "\n"
83                << "bitrate nominal " << vorbisInfo->bitrate_nominal << "\n"
84                << "bitrate lower   " << vorbisInfo->bitrate_lower   << "\n"
85                << "bitrate window  " << vorbisInfo->bitrate_window  << "\n"
86                << "\n"
87                << "vendor " << vorbisComment->vendor << "\n";
88               
89            for(int i = 0; i < vorbisComment->comments; i++)
90                std::cout << "   " << vorbisComment->user_comments[i] << "\n";
91               
92            std::cout << std::endl;     
93                }
94        }
95       
96       
97       
98       
99        bool AudioStream::playback()
100        {
101                if (!loaded)
102                {
103                        return false;
104                }
105
106            if(playing())
107                return true;
108               
109            if(!stream(buffers[0]))
110                return false;
111               
112            if(!stream(buffers[1]))
113                return false;
114           
115            alSourceQueueBuffers(source, 2, buffers);
116            alSourcePlay(source);
117           
118            return true;
119        }
120       
121       
122       
123       
124        bool AudioStream::playing()
125        {
126                if (!loaded)
127                {
128                        return false;
129                }
130
131            ALenum state;
132            alGetSourcei(source, AL_SOURCE_STATE, &state);
133            return (state == AL_PLAYING);
134        }
135       
136       
137       
138       
139        bool AudioStream::update()
140        {
141            int processed;
142            bool active = true;
143       
144            alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
145       
146            while(processed--)
147            {
148                ALuint buffer;
149               
150                alSourceUnqueueBuffers(source, 1, &buffer);
151                check();
152       
153                active = stream(buffer);
154       
155                alSourceQueueBuffers(source, 1, &buffer);
156                check();
157            }
158       
159                        if (active==false)
160                        {
161                                loaded = false;
162                        }
163            return active;
164        }
165       
166       
167       
168       
169        bool AudioStream::stream(ALuint buffer)
170        {
171            char pcm[BUFFER_SIZE];
172            int  size = 0;
173            int  section;
174            int  result;
175       
176            while(size < BUFFER_SIZE)
177            {
178                result = ov_read(&oggStream, pcm + size, BUFFER_SIZE - size, 0, 2, 1, &section);
179           
180                if(result > 0)
181                    size += result;
182                else
183                    if(result < 0)
184                        orxonox::Error(errorString(result));
185                    else
186                        break;
187            }
188           
189            if(size == 0)
190                return false;
191               
192            alBufferData(buffer, format, pcm, size, vorbisInfo->rate);
193            check();
194           
195            return true;
196        }
197       
198       
199
200        void AudioStream::empty()
201        {
202            int queued;
203           
204            alGetSourcei(source, AL_BUFFERS_QUEUED, &queued);
205           
206            while(queued--)
207            {
208                ALuint buffer;
209           
210                alSourceUnqueueBuffers(source, 1, &buffer);
211                check();
212            }
213        }
214       
215       
216       
217       
218        void AudioStream::check()
219        {
220                int error = alGetError();
221       
222                if(error != AL_NO_ERROR)
223                        orxonox::Error("OpenAL error was raised.");
224        }
225       
226       
227       
228        std::string AudioStream::errorString(int code)
229        {
230            switch(code)
231            {
232                case OV_EREAD:
233                    return std::string("Read from media.");
234                case OV_ENOTVORBIS:
235                    return std::string("Not Vorbis data.");
236                case OV_EVERSION:
237                    return std::string("Vorbis version mismatch.");
238                case OV_EBADHEADER:
239                    return std::string("Invalid Vorbis header.");
240                case OV_EFAULT:
241                    return std::string("Internal logic fault (bug or heap/stack corruption.");
242                default:
243                    return std::string("Unknown Ogg error.");
244            }
245        }
246}
247
Note: See TracBrowser for help on using the repository browser.