Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: merged the std-branche back, it runs on windows and Linux

svn merge https://svn.orxonox.net/orxonox/branches/std . -r7202:HEAD

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