Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/spaceshipcontrol/src/lib/sound/ogg_player.cc @ 5969

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

orxonox/trunk: compile (but not link) on mac

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