Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/FICN/src/audio/AudioStream.cc @ 516

Last change on this file since 516 was 513, checked in by nicolasc, 17 years ago

added copyright notice
network still need to be done

File size: 5.7 KB
RevLine 
[513]1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *
4 *
5 *   License notice:
6 *
7 *   This program is free software; you can redistribute it and/or
8 *   modify it under the terms of the GNU General Public License
9 *   as published by the Free Software Foundation; either version 2
10 *   of the License, or (at your option) any later version.
11 *
12 *   This program is distributed in the hope that it will be useful,
13 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 *   GNU General Public License for more details.
16 *
17 *   You should have received a copy of the GNU General Public License
18 *   along with this program; if not, write to the Free Software
19 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 *
21 *   Author:
22 *      ...
23 *   Co-authors:
24 *      ...
25 *
26 */
[410]27
[513]28
[410]29#include "AudioStream.h"
30
31namespace audio
[513]32{
33        AudioStream::AudioStream(std::string path)
34        {
35                this->path = path;
36                loaded = false;
37        }
[430]38
39        void AudioStream::open()
[410]40        {
[513]41            int result;
[424]42
[513]43
44            if(!(oggFile = fopen(path.c_str(), "rb")))
[423]45                        {
[513]46                orxonox::Error("Could not open Ogg file "+path);
[423]47                                return;
[513]48                        }
[423]49
[410]50            if((result = ov_open(oggFile, &oggStream, NULL, 0)) < 0)
51            {
[513]52        fclose(oggFile);
[423]53              orxonox::Error("Could not open Ogg stream. " + errorString(result));
[513]54                                return;
55            }
56
[423]57                        loaded = true;
[513]58
[410]59            vorbisInfo = ov_info(&oggStream, -1);
60            vorbisComment = ov_comment(&oggStream, -1);
[513]61
[410]62            if(vorbisInfo->channels == 1)
63                format = AL_FORMAT_MONO16;
64            else
65                format = AL_FORMAT_STEREO16;
[513]66
67
[410]68            alGenBuffers(2, buffers);
69            check();
70            alGenSources(1, &source);
71            check();
[513]72
[410]73            alSource3f(source, AL_POSITION,        0.0, 0.0, 0.0);
74            alSource3f(source, AL_VELOCITY,        0.0, 0.0, 0.0);
75            alSource3f(source, AL_DIRECTION,       0.0, 0.0, 0.0);
76            alSourcef (source, AL_ROLLOFF_FACTOR,  0.0          );
[423]77            alSourcei (source, AL_SOURCE_RELATIVE, AL_FALSE      );
[410]78        }
[513]79
80
81
82
[410]83        void AudioStream::release()
[513]84        {
[430]85
[410]86            alSourceStop(source);
87            empty();
88            alDeleteSources(1, &source);
89            check();
90            alDeleteBuffers(1, buffers);
91            check();
[513]92
93            ov_clear(&oggStream);
94                        loaded = false;
95
[410]96        }
[513]97
98
99
100
[410]101        void AudioStream::display()
[513]102        {
103                if (loaded)
[423]104                {
[419]105            std::cout
[410]106                << "version         " << vorbisInfo->version         << "\n"
107                << "channels        " << vorbisInfo->channels        << "\n"
108                << "rate (hz)       " << vorbisInfo->rate            << "\n"
109                << "bitrate upper   " << vorbisInfo->bitrate_upper   << "\n"
110                << "bitrate nominal " << vorbisInfo->bitrate_nominal << "\n"
111                << "bitrate lower   " << vorbisInfo->bitrate_lower   << "\n"
112                << "bitrate window  " << vorbisInfo->bitrate_window  << "\n"
113                << "\n"
114                << "vendor " << vorbisComment->vendor << "\n";
[513]115
[410]116            for(int i = 0; i < vorbisComment->comments; i++)
[419]117                std::cout << "   " << vorbisComment->user_comments[i] << "\n";
[513]118
119            std::cout << std::endl;
[423]120                }
[410]121        }
[513]122
123
124
125
[410]126        bool AudioStream::playback()
[513]127        {
128                if (!loaded)
129                {
130                        return false;
131                }
[423]132
[410]133            if(playing())
134                return true;
[513]135
[410]136            if(!stream(buffers[0]))
137                return false;
[513]138
[410]139            if(!stream(buffers[1]))
140                return false;
[513]141
[410]142            alSourceQueueBuffers(source, 2, buffers);
143            alSourcePlay(source);
[513]144
[410]145            return true;
146        }
[513]147
148
149
150
[410]151        bool AudioStream::playing()
[513]152        {
153                if (!loaded)
154                {
155                        return false;
156                }
[423]157
[410]158            ALenum state;
159            alGetSourcei(source, AL_SOURCE_STATE, &state);
160            return (state == AL_PLAYING);
161        }
[513]162
163
164
165
[410]166        bool AudioStream::update()
167        {
168            int processed;
169            bool active = true;
[513]170
[410]171            alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
[513]172
[410]173            while(processed--)
174            {
175                ALuint buffer;
[513]176
[410]177                alSourceUnqueueBuffers(source, 1, &buffer);
178                check();
[513]179
[410]180                active = stream(buffer);
[513]181
[410]182                alSourceQueueBuffers(source, 1, &buffer);
183                check();
184            }
[513]185
186                        if (active==false)
187                        {
188                                loaded = false;
[430]189                        }
[410]190            return active;
191        }
[513]192
193
194
195
[410]196        bool AudioStream::stream(ALuint buffer)
197        {
198            char pcm[BUFFER_SIZE];
199            int  size = 0;
200            int  section;
201            int  result;
[513]202
[410]203            while(size < BUFFER_SIZE)
204            {
205                result = ov_read(&oggStream, pcm + size, BUFFER_SIZE - size, 0, 2, 1, &section);
[513]206
[410]207                if(result > 0)
208                    size += result;
209                else
210                    if(result < 0)
[423]211                        orxonox::Error(errorString(result));
[410]212                    else
213                        break;
214            }
[513]215
[410]216            if(size == 0)
217                return false;
[513]218
[410]219            alBufferData(buffer, format, pcm, size, vorbisInfo->rate);
220            check();
[513]221
[410]222            return true;
223        }
[423]224
[513]225
226
[410]227        void AudioStream::empty()
228        {
229            int queued;
[513]230
[410]231            alGetSourcei(source, AL_BUFFERS_QUEUED, &queued);
[513]232
[410]233            while(queued--)
234            {
235                ALuint buffer;
[513]236
[410]237                alSourceUnqueueBuffers(source, 1, &buffer);
238                check();
239            }
240        }
[513]241
242
243
244
[410]245        void AudioStream::check()
246        {
247                int error = alGetError();
[513]248
[410]249                if(error != AL_NO_ERROR)
[423]250                        orxonox::Error("OpenAL error was raised.");
[410]251        }
[513]252
253
254
[410]255        std::string AudioStream::errorString(int code)
256        {
257            switch(code)
258            {
259                case OV_EREAD:
260                    return std::string("Read from media.");
261                case OV_ENOTVORBIS:
262                    return std::string("Not Vorbis data.");
263                case OV_EVERSION:
264                    return std::string("Vorbis version mismatch.");
265                case OV_EBADHEADER:
266                    return std::string("Invalid Vorbis header.");
267                case OV_EFAULT:
[419]268                    return std::string("Internal logic fault (bug or heap/stack corruption.");
[410]269                default:
270                    return std::string("Unknown Ogg error.");
271            }
272        }
[513]273}
274
Note: See TracBrowser for help on using the repository browser.