Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

merged console branch into network branch

after several heavy troubles it compiles, but there is still a bug I couldn't fix: orxonox crashes as soon as one presses a key after opening the console… maybe someone else sees the problem?

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++)
[1446]119            {
[677]120                COUT(3) << "   " << vorbisComment->user_comments[i] << std::endl;
[1446]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.