Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/cpp11_v2/src/orxonox/sound/SoundStreamer.cc @ 10917

Last change on this file since 10917 was 10916, checked in by landauf, 10 years ago

use actual types instead of 'auto'. only exception is for complicated template types, e.g. when iterating over a map

  • Property svn:eol-style set to native
File size: 4.7 KB
RevLine 
[6354]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"
[6378]28
[6354]29#include <al.h>
30#include <vorbis/vorbisfile.h>
[6378]31#include "SoundManager.h"
[6354]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;
[10765]47        vorbisCallbacks.close_func = nullptr;
[6354]48
49        OggVorbis_File vf;
[10765]50        int ret = ov_open_callbacks(dataStream.get(), &vf, nullptr, 0, vorbisCallbacks);
[6354]51        if (ret < 0)
52        {
[8858]53            orxout(internal_error, context::sound) << "libvorbisfile: File does not seem to be an Ogg Vorbis bitstream" << endl;
[6354]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
[10916]70        for(ALuint& initbuffer : initbuffers)
[6354]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            {
[8858]79                orxout(internal_error, context::sound) << "libvorbisfile: error reading the file" << endl;
[6354]80                ov_clear(&vf);
81                return;
82            }
83
[10821]84            alBufferData(initbuffer, format, &inbuffer, ret, vorbisInfo->rate);
[6354]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())
[8858]93            orxout(internal_warning, context::sound) << "Couldn't get number of processed buffers: "
94                                                     << SoundManager::getALErrorString(error) << endl;
[6354]95
96            if(processed > 0)
97            {
98                ALuint* buffers = new ALuint[processed];
99                alSourceUnqueueBuffers(audioSource, processed, buffers);
100                if (ALint error = alGetError())
[8858]101                    orxout(internal_warning, context::sound) << "Couldn't unqueue buffers: "
102                                                             << SoundManager::getALErrorString(error) << endl;
[6354]103
104                for(int i = 0; i < processed; i++)
105                {
106                    long ret = ov_read(&vf, inbuffer, sizeof(inbuffer), 0, 2, 1, &current_section);
107                    if (ret == 0)
108                    {
109                        return;
110                    }
111                    else if (ret < 0)
112                    {
[8858]113                        orxout(internal_error, context::sound) << "libvorbisfile: error reading the file" << endl;
[6354]114                        ov_clear(&vf);
115                        return;
116                    }
117
118                    alBufferData(buffers[i], format, &inbuffer, ret, vorbisInfo->rate);
119                }
120
121                alSourceQueueBuffers(audioSource, processed, buffers);
122                if (ALint error = alGetError())
[8858]123                    orxout(internal_warning, context::sound) << "Couldn't queue buffers: "
124                                                             << SoundManager::getALErrorString(error) << endl;
[6354]125            }
126        }
127    }
[6393]128}
Note: See TracBrowser for help on using the repository browser.