Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 2702 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
RevLine 
[1505]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 */
[1784]28
[1505]29#include "AudioStream.h"
[1747]30#include "util/Debug.h"
[1505]31
[2171]32namespace orxonox
[1505]33{
[1784]34    AudioStream::AudioStream(std::string path)
35    {
36        this->path = path;
37        loaded = false;
38    }
[1505]39
[1784]40    void AudioStream::open()
41    {
42        int result;
[1505]43
[1784]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        }
[1505]50
[1784]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        }
[1505]57
[1784]58        loaded = true;
[1505]59
[1784]60        vorbisInfo = ov_info(&oggStream, -1);
61        vorbisComment = ov_comment(&oggStream, -1);
[1505]62
[1784]63        if (vorbisInfo->channels == 1)
64            format = AL_FORMAT_MONO16;
65        else
66            format = AL_FORMAT_STEREO16;
[1505]67
68
[1784]69        alGenBuffers(2, buffers);
70        check();
71        alGenSources(1, &source);
72        check();
[1505]73
[1784]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    }
[1505]80
81
82
[1784]83    void AudioStream::release()
84    {
85        alSourceStop(source);
86        empty();
87        alDeleteSources(1, &source);
88        check();
89        alDeleteBuffers(1, buffers);
90        check();
[1505]91
[1784]92        ov_clear(&oggStream);
93        loaded = false;
94    }
[1505]95
96
97
[1784]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;
[1505]112
[1784]113            for (int i = 0; i < vorbisComment->comments; i++)
114            {
115                COUT(3) << "   " << vorbisComment->user_comments[i] << std::endl;
116            }
[1505]117
[1784]118            COUT(3) << std::endl;
119        }
120    }
[1505]121
122
123
[1784]124    bool AudioStream::playback()
125    {
126        if (!loaded)
127        {
128            return false;
129        }
[1505]130
[1784]131        if (playing())
132            return true;
[1505]133
[1784]134        if (!stream(buffers[0]))
135            return false;
[1505]136
[1784]137        if (!stream(buffers[1]))
138            return false;
[1505]139
[1784]140        alSourceQueueBuffers(source, 2, buffers);
141        alSourcePlay(source);
[1505]142
[1784]143        return true;
144    }
[1505]145
146
147
148
[1784]149    bool AudioStream::playing()
150    {
151        if (!loaded)
152        {
153            return false;
154        }
[1505]155
[1784]156        ALenum state;
157        alGetSourcei(source, AL_SOURCE_STATE, &state);
158        return (state == AL_PLAYING);
159    }
[1505]160
161
162
163
[1784]164    bool AudioStream::update()
165    {
166        int processed;
167        bool active = true;
[1505]168
[1784]169        alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
[1505]170
[1784]171        while (processed--)
172        {
173            ALuint buffer;
[1505]174
[1784]175            alSourceUnqueueBuffers(source, 1, &buffer);
176            check();
[1505]177
[1784]178            active = stream(buffer);
[1505]179
[1784]180            alSourceQueueBuffers(source, 1, &buffer);
181            check();
182        }
[1505]183
[1784]184        if (active==false)
185        {
186            loaded = false;
187        }
188        return active;
189    }
[1505]190
191
192
193
[1784]194    bool AudioStream::stream(ALuint buffer)
195    {
196        char pcm[BUFFER_SIZE];
197        int  size = 0;
198        int  section;
199        int  result;
[1505]200
[1784]201        while (size < BUFFER_SIZE)
202        {
203            result = ov_read(&oggStream, pcm + size, BUFFER_SIZE - size, 0, 2, 1, &section);
[1505]204
[1784]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        }
[1505]213
[1784]214        if (size == 0)
215            return false;
[1505]216
[1784]217        alBufferData(buffer, format, pcm, size, vorbisInfo->rate);
218        check();
[1505]219
[1784]220        return true;
221    }
[1505]222
223
224
[1784]225    void AudioStream::empty()
226    {
227        int queued;
[1505]228
[1784]229        alGetSourcei(source, AL_BUFFERS_QUEUED, &queued);
[1505]230
[1784]231        while (queued--)
232        {
233            ALuint buffer;
[1505]234
[1784]235            alSourceUnqueueBuffers(source, 1, &buffer);
236            check();
237        }
238    }
[1505]239
240
241
242
[1784]243    void AudioStream::check()
244    {
245        int error = alGetError();
[1505]246
[1784]247        if (error != AL_NO_ERROR)
248            COUT(2) << "AudioStream: OpenAL error was raised." << std::endl;
249    }
[1505]250
251
252
[1784]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    }
[1505]271}
272
Note: See TracBrowser for help on using the repository browser.