Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 6476 was 6476, checked in by erwin, 14 years ago

Tried to hack ths sound streaming part in… sound doesn't work at all now.

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