Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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