Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/network/src/audio/AudioStream.cc @ 1494

Last change on this file since 1494 was 1494, checked in by rgrieder, 16 years ago
  • set the svn:eol-style property to all files so, that where ever you check out, you'll get the right line endings (had to change every file with mixed endings to windows in order to set the property)
  • Property svn:eol-style set to native
File size: 5.7 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Nicolas Perrenoud <nicolape_at_ee.ethz.ch>
24 *   Co-authors:
25 *      ...
26 *
27 */
28#include "AudioStream.h"
29
30#include "core/Debug.h"
31#include "core/Error.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      oggFile = fopen(path.c_str(), "rb");
46            if(!oggFile)
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            {
120                COUT(3) << "   " << vorbisComment->user_comments[i] << std::endl;
121            }
122
123            COUT(3) << std::endl;
124                }
125        }
126
127
128
129
130        bool AudioStream::playback()
131        {
132                if (!loaded)
133                {
134                        return false;
135                }
136
137            if(playing())
138                return true;
139
140            if(!stream(buffers[0]))
141                return false;
142
143            if(!stream(buffers[1]))
144                return false;
145
146            alSourceQueueBuffers(source, 2, buffers);
147            alSourcePlay(source);
148
149            return true;
150        }
151
152
153
154
155        bool AudioStream::playing()
156        {
157                if (!loaded)
158                {
159                        return false;
160                }
161
162            ALenum state;
163            alGetSourcei(source, AL_SOURCE_STATE, &state);
164            return (state == AL_PLAYING);
165        }
166
167
168
169
170        bool AudioStream::update()
171        {
172            int processed;
173            bool active = true;
174
175            alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
176
177            while(processed--)
178            {
179                ALuint buffer;
180
181                alSourceUnqueueBuffers(source, 1, &buffer);
182                check();
183
184                active = stream(buffer);
185
186                alSourceQueueBuffers(source, 1, &buffer);
187                check();
188            }
189
190                        if (active==false)
191                        {
192                                loaded = false;
193                        }
194            return active;
195        }
196
197
198
199
200        bool AudioStream::stream(ALuint buffer)
201        {
202            char pcm[BUFFER_SIZE];
203            int  size = 0;
204            int  section;
205            int  result;
206
207            while(size < BUFFER_SIZE)
208            {
209                result = ov_read(&oggStream, pcm + size, BUFFER_SIZE - size, 0, 2, 1, &section);
210
211                if(result > 0)
212                    size += result;
213                else
214                    if(result < 0)
215                        orxonox::Error(errorString(result));
216                    else
217                        break;
218            }
219
220            if(size == 0)
221                return false;
222
223            alBufferData(buffer, format, pcm, size, vorbisInfo->rate);
224            check();
225
226            return true;
227        }
228
229
230
231        void AudioStream::empty()
232        {
233            int queued;
234
235            alGetSourcei(source, AL_BUFFERS_QUEUED, &queued);
236
237            while(queued--)
238            {
239                ALuint buffer;
240
241                alSourceUnqueueBuffers(source, 1, &buffer);
242                check();
243            }
244        }
245
246
247
248
249        void AudioStream::check()
250        {
251                int error = alGetError();
252
253                if(error != AL_NO_ERROR)
254                        orxonox::Error("OpenAL error was raised.");
255        }
256
257
258
259        std::string AudioStream::errorString(int code)
260        {
261            switch(code)
262            {
263                case OV_EREAD:
264                    return std::string("Read from media.");
265                case OV_ENOTVORBIS:
266                    return std::string("Not Vorbis data.");
267                case OV_EVERSION:
268                    return std::string("Vorbis version mismatch.");
269                case OV_EBADHEADER:
270                    return std::string("Invalid Vorbis header.");
271                case OV_EFAULT:
272                    return std::string("Internal logic fault (bug or heap/stack corruption.");
273                default:
274                    return std::string("Unknown Ogg error.");
275            }
276        }
277}
278
Note: See TracBrowser for help on using the repository browser.