Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 410 was 410, checked in by nicolape, 18 years ago

Added ogg streamer class

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