Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core/src/audio/AudioStream.cc @ 870

Last change on this file since 870 was 790, checked in by nicolasc, 17 years ago

merged FICN back into trunk
awaiting release.

File size: 5.8 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *
4 *
5 *   License notice:
6 *
7 *   This program is free software; you can redistribute it and/or
8 *   modify it under the terms of the GNU General Public License
9 *   as published by the Free Software Foundation; either version 2
10 *   of the License, or (at your option) any later version.
11 *
12 *   This program is distributed in the hope that it will be useful,
13 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 *   GNU General Public License for more details.
16 *
17 *   You should have received a copy of the GNU General Public License
18 *   along with this program; if not, write to the Free Software
19 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 *
21 *   Author:
22 *      ...
23 *   Co-authors:
24 *      ...
25 *
26 */
27
28#include <string>
29
30#include "AudioStream.h"
31#include "../orxonox/core/Debug.h"
32
33namespace audio
34{
35  AudioStream::AudioStream(std::string path)
36        {
37                this->path = path;
38                loaded = false;
39        }
40
41        void AudioStream::open()
42        {
43            int result;
44
45
46            if(!(oggFile = fopen(path.c_str(), "rb")))
47                        {
48                orxonox::Error("Could not open Ogg file "+path);
49                                return;
50                        }
51
52            if((result = ov_open(oggFile, &oggStream, NULL, 0)) < 0)
53            {
54        fclose(oggFile);
55              orxonox::Error("Could not open Ogg stream. " + errorString(result));
56                                return;
57            }
58
59                        loaded = true;
60
61            vorbisInfo = ov_info(&oggStream, -1);
62            vorbisComment = ov_comment(&oggStream, -1);
63
64            if(vorbisInfo->channels == 1)
65                format = AL_FORMAT_MONO16;
66            else
67                format = AL_FORMAT_STEREO16;
68
69
70            alGenBuffers(2, buffers);
71            check();
72            alGenSources(1, &source);
73            check();
74
75            alSource3f(source, AL_POSITION,        0.0, 0.0, 0.0);
76            alSource3f(source, AL_VELOCITY,        0.0, 0.0, 0.0);
77            alSource3f(source, AL_DIRECTION,       0.0, 0.0, 0.0);
78            alSourcef (source, AL_ROLLOFF_FACTOR,  0.0          );
79            alSourcei (source, AL_SOURCE_RELATIVE, AL_FALSE      );
80        }
81
82
83
84
85        void AudioStream::release()
86        {
87
88            alSourceStop(source);
89            empty();
90            alDeleteSources(1, &source);
91            check();
92            alDeleteBuffers(1, buffers);
93            check();
94
95            ov_clear(&oggStream);
96                        loaded = false;
97
98        }
99
100
101
102
103        void AudioStream::display()
104        {
105                if (loaded)
106                {
107            COUT(3)
108                << "version         " << vorbisInfo->version         << std::endl
109                << "channels        " << vorbisInfo->channels        << std::endl
110                << "rate (hz)       " << vorbisInfo->rate            << std::endl
111                << "bitrate upper   " << vorbisInfo->bitrate_upper   << std::endl
112                << "bitrate nominal " << vorbisInfo->bitrate_nominal << std::endl
113                << "bitrate lower   " << vorbisInfo->bitrate_lower   << std::endl
114                << "bitrate window  " << vorbisInfo->bitrate_window  << std::endl
115                << std::endl
116                << "vendor " << vorbisComment->vendor << std::endl;
117
118            for(int i = 0; i < vorbisComment->comments; i++)
119                COUT(3) << "   " << vorbisComment->user_comments[i] << std::endl;
120
121            COUT(3) << std::endl;
122                }
123        }
124
125
126
127
128        bool AudioStream::playback()
129        {
130                if (!loaded)
131                {
132                        return false;
133                }
134
135            if(playing())
136                return true;
137
138            if(!stream(buffers[0]))
139                return false;
140
141            if(!stream(buffers[1]))
142                return false;
143
144            alSourceQueueBuffers(source, 2, buffers);
145            alSourcePlay(source);
146
147            return true;
148        }
149
150
151
152
153        bool AudioStream::playing()
154        {
155                if (!loaded)
156                {
157                        return false;
158                }
159
160            ALenum state;
161            alGetSourcei(source, AL_SOURCE_STATE, &state);
162            return (state == AL_PLAYING);
163        }
164
165
166
167
168        bool AudioStream::update()
169        {
170            int processed;
171            bool active = true;
172
173            alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
174
175            while(processed--)
176            {
177                ALuint buffer;
178
179                alSourceUnqueueBuffers(source, 1, &buffer);
180                check();
181
182                active = stream(buffer);
183
184                alSourceQueueBuffers(source, 1, &buffer);
185                check();
186            }
187
188                        if (active==false)
189                        {
190                                loaded = false;
191                        }
192            return active;
193        }
194
195
196
197
198        bool AudioStream::stream(ALuint buffer)
199        {
200            char pcm[BUFFER_SIZE];
201            int  size = 0;
202            int  section;
203            int  result;
204
205            while(size < BUFFER_SIZE)
206            {
207                result = ov_read(&oggStream, pcm + size, BUFFER_SIZE - size, 0, 2, 1, &section);
208
209                if(result > 0)
210                    size += result;
211                else
212                    if(result < 0)
213                        orxonox::Error(errorString(result));
214                    else
215                        break;
216            }
217
218            if(size == 0)
219                return false;
220
221            alBufferData(buffer, format, pcm, size, vorbisInfo->rate);
222            check();
223
224            return true;
225        }
226
227
228
229        void AudioStream::empty()
230        {
231            int queued;
232
233            alGetSourcei(source, AL_BUFFERS_QUEUED, &queued);
234
235            while(queued--)
236            {
237                ALuint buffer;
238
239                alSourceUnqueueBuffers(source, 1, &buffer);
240                check();
241            }
242        }
243
244
245
246
247        void AudioStream::check()
248        {
249                int error = alGetError();
250
251                if(error != AL_NO_ERROR)
252                        orxonox::Error("OpenAL error was raised.");
253        }
254
255
256
257        std::string AudioStream::errorString(int code)
258        {
259            switch(code)
260            {
261                case OV_EREAD:
262                    return std::string("Read from media.");
263                case OV_ENOTVORBIS:
264                    return std::string("Not Vorbis data.");
265                case OV_EVERSION:
266                    return std::string("Vorbis version mismatch.");
267                case OV_EBADHEADER:
268                    return std::string("Invalid Vorbis header.");
269                case OV_EFAULT:
270                    return std::string("Internal logic fault (bug or heap/stack corruption.");
271                default:
272                    return std::string("Unknown Ogg error.");
273            }
274        }
275}
276
Note: See TracBrowser for help on using the repository browser.