Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: moved iostrem.

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