Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/sound4/src/orxonox/sound/SoundStreamer.cc @ 6435

Last change on this file since 6435 was 6435, checked in by rgrieder, 14 years ago

Moved getALErrorString function from SoundManager.h to newly created SoundPrereqs.h file.
Also moved forward declarations to that file (from OrxonoxPrereqs.h).

File size: 4.4 KB
Line 
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 *      Erwin 'vaiursch' Herrsche
24 *   Co-authors:
25 *
26 */
27#include "SoundStreamer.h"
28
29#include <al.h>
30#include <vorbis/vorbisfile.h>
31#include "SoundManager.h"
32
33namespace orxonox
34{
35    // vorbis callbacks
36    size_t readVorbis(void* ptr, size_t size, size_t nmemb, void* datasource);
37    int seekVorbis(void* datasource, ogg_int64_t offset, int whence);
38    long tellVorbis(void* datasource);
39
40    void orxonox::SoundStreamer::operator()(ALuint audioSource, DataStreamPtr dataStream)
41    {
42        // Open file with custom streaming
43        ov_callbacks vorbisCallbacks;
44        vorbisCallbacks.read_func  = &readVorbis;
45        vorbisCallbacks.seek_func  = &seekVorbis;
46        vorbisCallbacks.tell_func  = &tellVorbis;
47        vorbisCallbacks.close_func = NULL;
48
49        OggVorbis_File vf;
50        int ret = ov_open_callbacks(dataStream.get(), &vf, NULL, 0, vorbisCallbacks);
51        if (ret < 0)
52        {
53            COUT(2) << "Sound: libvorbisfile: File does not seem to be an Ogg Vorbis bitstream" << std::endl;
54            ov_clear(&vf);
55            return;
56        }
57        vorbis_info* vorbisInfo;
58        vorbisInfo = ov_info(&vf, -1);
59        ALenum format;
60        if (vorbisInfo->channels == 1)
61            format = AL_FORMAT_MONO16;
62        else
63            format = AL_FORMAT_STEREO16;
64
65        char inbuffer[256*1024];
66        ALuint initbuffers[4];
67        alGenBuffers(4, initbuffers);
68        int current_section;
69
70        for(int i = 0; i < 4; i++)
71        {
72            long ret = ov_read(&vf, inbuffer, sizeof(inbuffer), 0, 2, 1, &current_section);
73            if (ret == 0)
74            {
75                return;
76            }
77            else if (ret < 0)
78            {
79                COUT(2) << "Sound: libvorbisfile: error reading the file" << std::endl;
80                ov_clear(&vf);
81                return;
82            }
83
84            alBufferData(initbuffers[i], format, &inbuffer, ret, vorbisInfo->rate);
85        }
86        alSourceQueueBuffers(audioSource, 4, initbuffers);
87
88        while(true) // Stream forever, control through thread control
89        {
90            int processed;
91            alGetSourcei(audioSource, AL_BUFFERS_PROCESSED, &processed);
92            if (ALint error = alGetError())
93            COUT(2) << "Sound Warning: Couldn't get number of processed buffers: " << getALErrorString(error) << std::endl;
94
95            if(processed > 0)
96            {
97                ALuint* buffers = new ALuint[processed];
98                alSourceUnqueueBuffers(audioSource, processed, buffers);
99                if (ALint error = alGetError())
100                    COUT(2) << "Sound Warning: Couldn't unqueue buffers: " << getALErrorString(error) << std::endl;
101
102                for(int i = 0; i < processed; i++)
103                {
104                    long ret = ov_read(&vf, inbuffer, sizeof(inbuffer), 0, 2, 1, &current_section);
105                    if (ret == 0)
106                    {
107                        return;
108                    }
109                    else if (ret < 0)
110                    {
111                        COUT(2) << "Sound: libvorbisfile: error reading the file" << std::endl;
112                        ov_clear(&vf);
113                        return;
114                    }
115
116                    alBufferData(buffers[i], format, &inbuffer, ret, vorbisInfo->rate);
117                }
118
119                alSourceQueueBuffers(audioSource, processed, buffers);
120                if (ALint error = alGetError())
121                    COUT(2) << "Sound Warning: Couldn't queue buffers: " << getALErrorString(error) << std::endl;
122            }
123        }
124    }
125}
Note: See TracBrowser for help on using the repository browser.