Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/lib/sound/ogg_player.cc @ 4985

Last change on this file since 4985 was 4985, checked in by bensch, 19 years ago

orxonox/trunk: loading some stuff from ths sound-engine

File size: 6.0 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11### File Specific:
12   main-programmer: Benjamin Grauer
13   co-programmer: ...
14
15
16   -------------------------------------------------------------------
17   The source of this file comes stright from http://www.devmaster.net
18   Thanks a lot for the nice work, and the easy portability to our Project.
19*/
20
21#include "ogg_player.h"
22
23#include "sound_engine.h"
24
25#include "debug.h"
26
27
28/**
29 * initializes an Ogg-player from a file
30 * @param fileName the file to load
31 */
32OggPlayer::OggPlayer(const char* fileName)
33{
34  this->setClassID(CL_SOUND_OGG_PLAYER, "OggPlayer");
35  if (fileName != NULL)
36  {
37    this->open(fileName);
38    this->setName(fileName);
39  }
40}
41
42/**
43 * opens a file for playback
44 * @param fileName the file to open
45 */
46void OggPlayer::open(const char* fileName)
47{
48    int result;
49
50    if(!(oggFile = fopen(fileName, "rb")))
51        PRINTF(2)("Could not open Ogg file.");
52
53    if((result = ov_open(oggFile, &oggStream, NULL, 0)) < 0)
54    {
55        fclose(oggFile);
56
57        PRINTF(2)("Could not open Ogg stream. %s", errorString(result));
58    }
59
60    vorbisInfo = ov_info(&oggStream, -1);
61    vorbisComment = ov_comment(&oggStream, -1);
62
63    if(vorbisInfo->channels == 1)
64        format = AL_FORMAT_MONO16;
65    else
66        format = AL_FORMAT_STEREO16;
67
68
69    alGenBuffers(2, buffers);
70    check();
71    alGenSources(1, &source);
72    check();
73
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          );
78    alSourcei (source, AL_SOURCE_RELATIVE, AL_TRUE      );
79    alSourcef (source, AL_GAIN,            SoundEngine::getInstance()->getMusicVolume());
80}
81
82/**
83 * releases a stream
84 */
85void OggPlayer::release()
86{
87    alSourceStop(source);
88    empty();
89    alDeleteSources(1, &source);
90    check();
91    alDeleteBuffers(1, buffers);
92    check();
93
94    ov_clear(&oggStream);
95}
96
97/**
98 * displays some info about the ogg-file
99 */
100void OggPlayer::display()
101{
102    cout
103        << "version         " << vorbisInfo->version         << "\n"
104        << "channels        " << vorbisInfo->channels        << "\n"
105        << "rate (hz)       " << vorbisInfo->rate            << "\n"
106        << "bitrate upper   " << vorbisInfo->bitrate_upper   << "\n"
107        << "bitrate nominal " << vorbisInfo->bitrate_nominal << "\n"
108        << "bitrate lower   " << vorbisInfo->bitrate_lower   << "\n"
109        << "bitrate window  " << vorbisInfo->bitrate_window  << "\n"
110        << "\n"
111        << "vendor " << vorbisComment->vendor << "\n";
112
113    for(int i = 0; i < vorbisComment->comments; i++)
114        cout << "   " << vorbisComment->user_comments[i] << "\n";
115
116    cout << endl;
117}
118
119
120/**
121 * plays back the sound
122 * @return true if running, false otherwise
123 */
124bool OggPlayer::playback()
125{
126    if(playing())
127        return true;
128
129    if(!stream(buffers[0]))
130        return false;
131
132    if(!stream(buffers[1]))
133        return false;
134
135    alSourceQueueBuffers(source, 2, buffers);
136    alSourcePlay(source);
137
138    return true;
139}
140
141/**
142 *
143 * @returns true if the file is playing
144 */
145bool OggPlayer::playing()
146{
147    ALenum state;
148
149    alGetSourcei(source, AL_SOURCE_STATE, &state);
150
151    return (state == AL_PLAYING);
152}
153
154/**
155 * updates the stream, this has to be done every few parts of a second, for sound-consistency
156 * @returns true, if the Sound is playing flawlessly
157 */
158bool OggPlayer::update()
159{
160    int processed;
161    bool active = true;
162
163    alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
164
165    while(processed--)
166    {
167        ALuint buffer;
168
169        alSourceUnqueueBuffers(source, 1, &buffer);
170        check();
171
172        active = stream(buffer);
173
174        alSourceQueueBuffers(source, 1, &buffer);
175        check();
176    }
177
178    return active;
179}
180
181/**
182 * gets a new Stream from buffer
183 * @param buffer the buffer to get the stream from
184 * @return true, if everything worked as planed
185 */
186bool OggPlayer::stream(ALuint buffer)
187{
188    char pcm[BUFFER_SIZE];
189    int  size = 0;
190    int  section;
191    int  result;
192
193    while(size < BUFFER_SIZE)
194    {
195        result = ov_read(&oggStream, pcm + size, BUFFER_SIZE - size, 0, 2, 1, &section);
196
197        if(result > 0)
198            size += result;
199        else
200            if(result < 0)
201                throw errorString(result);
202            else
203                break;
204    }
205
206    if(size == 0)
207        return false;
208
209    alBufferData(buffer, format, pcm, size, vorbisInfo->rate);
210    check();
211
212    return true;
213}
214
215
216/**
217 * empties the buffers
218 */
219void OggPlayer::empty()
220{
221    int queued;
222
223    alGetSourcei(source, AL_BUFFERS_QUEUED, &queued);
224
225    while(queued--)
226    {
227        ALuint buffer;
228
229        alSourceUnqueueBuffers(source, 1, &buffer);
230        check();
231    }
232}
233
234/**
235 * checks for errors
236 */
237void OggPlayer::check()
238{
239        int error = alGetError();
240
241        if(error != AL_NO_ERROR)
242                PRINTF(2)("OpenAL error was raised.");
243}
244
245/**
246 * returns errors
247 * @param code the error-code
248 * @return the error as a String
249 */
250const char* OggPlayer::errorString(int code)
251{
252     switch(code)
253     {
254       case OV_EREAD:
255         return ("Read from media.");
256       case OV_ENOTVORBIS:
257         return ("Not Vorbis data.");
258       case OV_EVERSION:
259         return ("Vorbis version mismatch.");
260       case OV_EBADHEADER:
261         return ("Invalid Vorbis header.");
262       case OV_EFAULT:
263         return ("Internal logic fault (bug or heap/stack corruption.");
264       default:
265         return ("Unknown Ogg error.");
266     }
267}
Note: See TracBrowser for help on using the repository browser.