Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 2352 was 2171, checked in by landauf, 16 years ago

merged revisions 2111-2170 from objecthierarchy branch back to trunk.

  • Property svn:eol-style set to native
File size: 6.4 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
29#include "AudioStream.h"
30#include "util/Debug.h"
31
32namespace orxonox
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        oggFile = fopen(path.c_str(), "rb");
45        if (!oggFile)
46        {
47            COUT(2) << "AudioStream: Could not open Ogg file " << path << std::endl;
48            return;
49        }
50
51        if ((result = ov_open(oggFile, &oggStream, NULL, 0)) < 0)
52        {
53            fclose(oggFile);
54            COUT(2) << "AudioStream: Could not open Ogg stream. " << errorString(result) << std::endl;
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    void AudioStream::release()
84    {
85        alSourceStop(source);
86        empty();
87        alDeleteSources(1, &source);
88        check();
89        alDeleteBuffers(1, buffers);
90        check();
91
92        ov_clear(&oggStream);
93        loaded = false;
94    }
95
96
97
98    void AudioStream::display()
99    {
100        if (loaded)
101        {
102            COUT(3)
103                << "version         " << vorbisInfo->version         << std::endl
104                << "channels        " << vorbisInfo->channels        << std::endl
105                << "rate (hz)       " << vorbisInfo->rate            << std::endl
106                << "bitrate upper   " << vorbisInfo->bitrate_upper   << std::endl
107                << "bitrate nominal " << vorbisInfo->bitrate_nominal << std::endl
108                << "bitrate lower   " << vorbisInfo->bitrate_lower   << std::endl
109                << "bitrate window  " << vorbisInfo->bitrate_window  << std::endl
110                << std::endl
111                << "vendor " << vorbisComment->vendor << std::endl;
112
113            for (int i = 0; i < vorbisComment->comments; i++)
114            {
115                COUT(3) << "   " << vorbisComment->user_comments[i] << std::endl;
116            }
117
118            COUT(3) << std::endl;
119        }
120    }
121
122
123
124    bool AudioStream::playback()
125    {
126        if (!loaded)
127        {
128            return false;
129        }
130
131        if (playing())
132            return true;
133
134        if (!stream(buffers[0]))
135            return false;
136
137        if (!stream(buffers[1]))
138            return false;
139
140        alSourceQueueBuffers(source, 2, buffers);
141        alSourcePlay(source);
142
143        return true;
144    }
145
146
147
148
149    bool AudioStream::playing()
150    {
151        if (!loaded)
152        {
153            return false;
154        }
155
156        ALenum state;
157        alGetSourcei(source, AL_SOURCE_STATE, &state);
158        return (state == AL_PLAYING);
159    }
160
161
162
163
164    bool AudioStream::update()
165    {
166        int processed;
167        bool active = true;
168
169        alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
170
171        while (processed--)
172        {
173            ALuint buffer;
174
175            alSourceUnqueueBuffers(source, 1, &buffer);
176            check();
177
178            active = stream(buffer);
179
180            alSourceQueueBuffers(source, 1, &buffer);
181            check();
182        }
183
184        if (active==false)
185        {
186            loaded = false;
187        }
188        return active;
189    }
190
191
192
193
194    bool AudioStream::stream(ALuint buffer)
195    {
196        char pcm[BUFFER_SIZE];
197        int  size = 0;
198        int  section;
199        int  result;
200
201        while (size < BUFFER_SIZE)
202        {
203            result = ov_read(&oggStream, pcm + size, BUFFER_SIZE - size, 0, 2, 1, &section);
204
205            if (result > 0)
206                size += result;
207            else
208                if (result < 0)
209                    COUT(2) << "AudioStream: " << errorString(result) << std::endl;
210                else
211                    break;
212        }
213
214        if (size == 0)
215            return false;
216
217        alBufferData(buffer, format, pcm, size, vorbisInfo->rate);
218        check();
219
220        return true;
221    }
222
223
224
225    void AudioStream::empty()
226    {
227        int queued;
228
229        alGetSourcei(source, AL_BUFFERS_QUEUED, &queued);
230
231        while (queued--)
232        {
233            ALuint buffer;
234
235            alSourceUnqueueBuffers(source, 1, &buffer);
236            check();
237        }
238    }
239
240
241
242
243    void AudioStream::check()
244    {
245        int error = alGetError();
246
247        if (error != AL_NO_ERROR)
248            COUT(2) << "AudioStream: OpenAL error was raised." << std::endl;
249    }
250
251
252
253    std::string AudioStream::errorString(int code)
254    {
255        switch (code)
256        {
257            case OV_EREAD:
258                return std::string("Read from media.");
259            case OV_ENOTVORBIS:
260                return std::string("Not Vorbis data.");
261            case OV_EVERSION:
262                return std::string("Vorbis version mismatch.");
263            case OV_EBADHEADER:
264                return std::string("Invalid Vorbis header.");
265            case OV_EFAULT:
266                return std::string("Internal logic fault (bug or heap/stack corruption.");
267            default:
268                return std::string("Unknown Ogg error.");
269        }
270    }
271}
272
Note: See TracBrowser for help on using the repository browser.