Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/console/src/audio/AudioStream.cc @ 1438

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

removed some other (potential) bugs or dangerous code lines

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