Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/openAL/src/lib/sound/sound_engine.cc @ 4203

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

orxonox/branches/openAL: better error-check

File size: 6.8 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   code has been taken from http://www.devmaster.net/articles.php?catID=6
16   The code has been applied to our needs, and many things have been changed.
17*/
18
19//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
20
21#include "sound_engine.h"
22
23#include "p_node.h"
24#include "list.h"
25#include "AL/alc.h"
26
27using namespace std;
28
29
30//////////////////
31/* SOUND-BUFFER */
32//////////////////
33/**
34   \brief Creates a Soundbuffer out of an inputfile
35   \param fileName The name of the File
36*/
37SoundBuffer::SoundBuffer(const char* fileName)
38{
39  SoundEngine::getInstance()->addBuffer(this);
40
41  ALenum format;
42  ALvoid* data;
43  ALsizei freq;
44 
45  ALenum result;
46
47  // generate a Buffer
48  alGenBuffers(1, &this->bufferID);
49  if ((result = alGetError()) != AL_NO_ERROR)
50    SoundEngine::PrintALErrorString(result);
51
52  // read in the wav data
53  alutLoadWAVFile((ALbyte*)fileName, &format, &data, &this->size, &freq, &this->loop);
54  if ((result = alGetError()) != AL_NO_ERROR)
55    SoundEngine::PrintALErrorString(result);
56 
57  // send the loaded wav data to the buffer
58  alBufferData(this->bufferID, format, data, this->size, freq);
59  if ((result = alGetError()) != AL_NO_ERROR)
60    SoundEngine::PrintALErrorString(result);
61
62  // remove the wav data (redundant)
63  alutUnloadWAV(format, data, this->size, freq);
64  if ((result = alGetError()) != AL_NO_ERROR)
65    SoundEngine::PrintALErrorString(result);
66}
67
68SoundBuffer::~SoundBuffer(void)
69{
70  SoundEngine::getInstance()->removeBuffer(this);
71  alDeleteBuffers(1, &this->bufferID);
72}
73
74//////////////////
75/* SOUND-SOURCE */
76//////////////////
77/**
78   \brief creates a SoundSource at position sourceNode with the SoundBuffer buffer
79*/
80SoundSource::SoundSource(SoundBuffer* buffer, PNode* sourceNode)
81{
82  ALenum result;
83
84  // adding the Source to the SourcesList of the SoundEngine
85  SoundEngine::getInstance()->addSource(this);
86
87  this->buffer = buffer;
88  this->sourceNode = sourceNode;
89
90  alGenSources(1, &this->sourceID);
91  if ((result = alGetError()) != AL_NO_ERROR)
92    SoundEngine::PrintALErrorString(result);
93  alSourcei (this->sourceID, AL_BUFFER,   this->buffer->getID());
94  alSourcef (this->sourceID, AL_PITCH,    1.0      );
95  alSourcef (this->sourceID, AL_GAIN,     1.0      );
96  alSourcei (sourceID, AL_LOOPING,  true     );
97}
98
99SoundSource::~SoundSource(void)
100{
101  SoundEngine::getInstance()->removeSource(this);
102  alDeleteSources(1, &this->sourceID);
103}
104
105
106void SoundSource::play()
107{
108  alSourcePlay(this->sourceID);
109}
110void SoundSource::stop()
111{
112  alSourceStop(this->sourceID);
113}
114void SoundSource::pause()
115{
116  alSourcePause(this->sourceID);
117}
118
119void SoundSource::setRolloffFactor(ALfloat rolloffFactor)
120{
121  alSourcef(this->sourceID, AL_ROLLOFF_FACTOR, rolloffFactor);
122}
123
124
125
126//////////////////
127/* SOUND-ENGINE */
128//////////////////
129/**
130   \brief standard constructor
131*/
132SoundEngine::SoundEngine () 
133{
134  this->setClassName ("SoundEngine");
135   
136   this->initAudio();
137
138   this->listener = NULL;
139   this->bufferList = new tList<SoundBuffer>;
140   this->sourceList = new tList<SoundSource>;
141}
142
143/**
144   \brief the singleton reference to this class
145*/
146SoundEngine* SoundEngine::singletonRef = NULL;
147
148/**
149   \returns a Pointer to this Class
150*/
151SoundEngine* SoundEngine::getInstance(void)
152{
153  if (!SoundEngine::singletonRef)
154    SoundEngine::singletonRef = new SoundEngine();
155  return SoundEngine::singletonRef;
156}
157
158/**
159   \brief standard deconstructor
160
161*/
162SoundEngine::~SoundEngine () 
163{
164  SoundEngine::singletonRef = NULL;
165
166}
167
168/**
169   \brief sets The listener (normaly the Camera)
170*/
171void SoundEngine::setListener(PNode* listener)
172{
173  this->listener = listener;
174}
175
176
177void SoundEngine::addBuffer(SoundBuffer* buffer)
178{
179  this->bufferList->add(buffer);
180}
181
182void SoundEngine::removeBuffer(SoundBuffer* buffer)
183{
184  this->bufferList->remove(buffer);
185}
186
187void SoundEngine::addSource(SoundSource* source)
188{
189  this->sourceList->add(source);
190}
191void SoundEngine::removeSource(SoundSource* source)
192{
193  this->sourceList->remove(source);
194}
195
196
197/**
198   \brief updates all The positions, Directions and Velocities of all Sounds
199*/
200void SoundEngine::update(void)
201{
202
203  // updating the Listeners Position
204  if (this->listener)
205    {
206      alListener3f(AL_POSITION,
207                   this->listener->getAbsCoor().x,
208                   this->listener->getAbsCoor().y,
209                   this->listener->getAbsCoor().z);
210      alListener3f(AL_VELOCITY,
211                   this->listener->getVelocity().x,
212                   this->listener->getVelocity().y,
213                   this->listener->getVelocity().z);
214      Vector absDirV = this->listener->getAbsDirV();
215      ALfloat orientation [6] = {1,0,0, absDirV.x, absDirV.y, absDirV.z};
216      alListenerfv(AL_ORIENTATION, orientation);
217    }
218  else
219    PRINTF(2)("no listener defined\n");
220
221  // updating all the Sources positions
222  tIterator<SoundSource>* iterator = this->sourceList->getIterator();
223  SoundSource* enumSource = iterator->nextElement();
224  while (enumSource)
225    {
226      alSource3f(enumSource->getID(), AL_POSITION,
227                 enumSource->getNode()->getAbsCoor().x,
228                 enumSource->getNode()->getAbsCoor().y,
229                 enumSource->getNode()->getAbsCoor().z);
230      alSource3f(enumSource->getID(), AL_VELOCITY,
231                 enumSource->getNode()->getVelocity().x,
232                 enumSource->getNode()->getVelocity().y,
233                 enumSource->getNode()->getVelocity().z);
234
235      enumSource = iterator->nextElement();
236    }
237  delete iterator;
238}
239
240/**
241   \brief initializes Audio in general
242*/
243bool SoundEngine::initAudio(void)
244{
245  alutInit(NULL, 0);
246  alGetError();
247
248  alDopplerFactor(SOUND_DOPPLER_FACTOR);
249  alDopplerVelocity(SOUND_DOPPLER_VELOCITY);
250}
251
252void SoundEngine::PrintALErrorString(ALenum err)
253{
254  switch(err)
255    {
256    case AL_NO_ERROR:
257      PRINTF(4)("AL_NO_ERROR\n");
258      break;
259     
260    case AL_INVALID_NAME:
261      PRINTF(2)("AL_INVALID_NAME\n");
262      break;
263
264    case AL_INVALID_ENUM:
265      PRINTF(2)("AL_INVALID_ENUM\n");
266      break;
267
268    case AL_INVALID_VALUE:
269      PRINTF(2)("AL_INVALID_VALUE\n");
270      break;
271
272    case AL_INVALID_OPERATION:
273      PRINTF(2)("AL_INVALID_OPERATION\n");
274      break;
275
276    case AL_OUT_OF_MEMORY:
277      PRINTF(2)("AL_OUT_OF_MEMORY\n");
278      break;
279    };
280}
281
282
283void SoundEngine::PrintALCErrorString(ALenum err)
284{
285  switch(err)
286    {
287    case ALC_NO_ERROR:
288      PRINTF(4)("AL_NO_ERROR\n");
289      break;
290
291    case ALC_INVALID_DEVICE:
292      PRINTF(2)("ALC_INVALID_DEVICE\n");
293      break;
294
295    case ALC_INVALID_CONTEXT:
296      PRINTF(2)("ALC_INVALID_CONTEXT\n");
297      break;
298
299    case ALC_INVALID_ENUM:
300      PRINTF(2)("ALC_INVALID_ENUM\n");
301      break;
302
303    case ALC_INVALID_VALUE:
304      PRINTF(2)("ALC_INVALID_VALUE\n");
305      break;
306
307    case ALC_OUT_OF_MEMORY:
308      PRINTF(2)("ALC_OUT_OF_MEMORY\n");
309      break;
310    };
311}
Note: See TracBrowser for help on using the repository browser.