Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/audio/AudioStream.cc @ 1049

Last change on this file since 1049 was 1039, checked in by rgrieder, 17 years ago
  • train riding doesn't have to be boring
  • added some license notes
  • removed certain header dependencies in audio
  • changed order of header file inclusion in orxonox and audio (coding style guide will be updated)
File size: 5.9 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 *      Nicolas Perrenoud <nicolape@ee.ethz.ch>
23 *   Co-authors:
24 *      ...
25 *
26 */
27#include "AudioStream.h"
28
29#include "core/Debug.h"
30#include "core/Error.h"
31
32namespace audio
33{
34  AudioStream::AudioStream(std::string path)
35        {
36                this->path = path;
37                loaded = false;
38        }
39
40        void AudioStream::open()
41        {
42            int result;
43
44
45            if(!(oggFile = fopen(path.c_str(), "rb")))
46                        {
47                orxonox::Error("Could not open Ogg file "+path);
48                                return;
49                        }
50
51            if((result = ov_open(oggFile, &oggStream, NULL, 0)) < 0)
52            {
53        fclose(oggFile);
54              orxonox::Error("Could not open Ogg stream. " + errorString(result));
55                                return;
56            }
57
58                        loaded = true;
59
60            vorbisInfo = ov_info(&oggStream, -1);
61            vorbisComment = ov_comment(&oggStream, -1);
62
63            if(vorbisInfo->channels == 1)
64                format = AL_FORMAT_MONO16;
65            else
66                format = AL_FORMAT_STEREO16;
67
68
69            alGenBuffers(2, buffers);
70            check();
71            alGenSources(1, &source);
72            check();
73
74            alSource3f(source, AL_POSITION,        0.0, 0.0, 0.0);
75            alSource3f(source, AL_VELOCITY,        0.0, 0.0, 0.0);
76            alSource3f(source, AL_DIRECTION,       0.0, 0.0, 0.0);
77            alSourcef (source, AL_ROLLOFF_FACTOR,  0.0          );
78            alSourcei (source, AL_SOURCE_RELATIVE, AL_FALSE      );
79        }
80
81
82
83
84        void AudioStream::release()
85        {
86
87            alSourceStop(source);
88            empty();
89            alDeleteSources(1, &source);
90            check();
91            alDeleteBuffers(1, buffers);
92            check();
93
94            ov_clear(&oggStream);
95                        loaded = false;
96
97        }
98
99
100
101
102        void AudioStream::display()
103        {
104                if (loaded)
105                {
106            COUT(3)
107                << "version         " << vorbisInfo->version         << std::endl
108                << "channels        " << vorbisInfo->channels        << std::endl
109                << "rate (hz)       " << vorbisInfo->rate            << std::endl
110                << "bitrate upper   " << vorbisInfo->bitrate_upper   << std::endl
111                << "bitrate nominal " << vorbisInfo->bitrate_nominal << std::endl
112                << "bitrate lower   " << vorbisInfo->bitrate_lower   << std::endl
113                << "bitrate window  " << vorbisInfo->bitrate_window  << std::endl
114                << std::endl
115                << "vendor " << vorbisComment->vendor << std::endl;
116
117            for(int i = 0; i < vorbisComment->comments; i++)
118                COUT(3) << "   " << vorbisComment->user_comments[i] << std::endl;
119
120            COUT(3) << std::endl;
121                }
122        }
123
124
125
126
127        bool AudioStream::playback()
128        {
129                if (!loaded)
130                {
131                        return false;
132                }
133
134            if(playing())
135                return true;
136
137            if(!stream(buffers[0]))
138                return false;
139
140            if(!stream(buffers[1]))
141                return false;
142
143            alSourceQueueBuffers(source, 2, buffers);
144            alSourcePlay(source);
145
146            return true;
147        }
148
149
150
151
152        bool AudioStream::playing()
153        {
154                if (!loaded)
155                {
156                        return false;
157                }
158
159            ALenum state;
160            alGetSourcei(source, AL_SOURCE_STATE, &state);
161            return (state == AL_PLAYING);
162        }
163
164
165
166
167        bool AudioStream::update()
168        {
169            int processed;
170            bool active = true;
171
172            alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
173
174            while(processed--)
175            {
176                ALuint buffer;
177
178                alSourceUnqueueBuffers(source, 1, &buffer);
179                check();
180
181                active = stream(buffer);
182
183                alSourceQueueBuffers(source, 1, &buffer);
184                check();
185            }
186
187                        if (active==false)
188                        {
189                                loaded = false;
190                        }
191            return active;
192        }
193
194
195
196
197        bool AudioStream::stream(ALuint buffer)
198        {
199            char pcm[BUFFER_SIZE];
200            int  size = 0;
201            int  section;
202            int  result;
203
204            while(size < BUFFER_SIZE)
205            {
206                result = ov_read(&oggStream, pcm + size, BUFFER_SIZE - size, 0, 2, 1, &section);
207
208                if(result > 0)
209                    size += result;
210                else
211                    if(result < 0)
212                        orxonox::Error(errorString(result));
213                    else
214                        break;
215            }
216
217            if(size == 0)
218                return false;
219
220            alBufferData(buffer, format, pcm, size, vorbisInfo->rate);
221            check();
222
223            return true;
224        }
225
226
227
228        void AudioStream::empty()
229        {
230            int queued;
231
232            alGetSourcei(source, AL_BUFFERS_QUEUED, &queued);
233
234            while(queued--)
235            {
236                ALuint buffer;
237
238                alSourceUnqueueBuffers(source, 1, &buffer);
239                check();
240            }
241        }
242
243
244
245
246        void AudioStream::check()
247        {
248                int error = alGetError();
249
250                if(error != AL_NO_ERROR)
251                        orxonox::Error("OpenAL error was raised.");
252        }
253
254
255
256        std::string AudioStream::errorString(int code)
257        {
258            switch(code)
259            {
260                case OV_EREAD:
261                    return std::string("Read from media.");
262                case OV_ENOTVORBIS:
263                    return std::string("Not Vorbis data.");
264                case OV_EVERSION:
265                    return std::string("Vorbis version mismatch.");
266                case OV_EBADHEADER:
267                    return std::string("Invalid Vorbis header.");
268                case OV_EFAULT:
269                    return std::string("Internal logic fault (bug or heap/stack corruption.");
270                default:
271                    return std::string("Unknown Ogg error.");
272            }
273        }
274}
275
Note: See TracBrowser for help on using the repository browser.