Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/sound/sound_source.cc

Last change on this file was 10695, checked in by snellen, 17 years ago

changes on soundengine and mover by fabian landau

File size: 10.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
16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SOUND
17
18#include "sound_source.h"
19#include "sound_engine.h"
20
21#include "compiler.h"
22#include "debug.h"
23
24namespace OrxSound
25{
26  ObjectListDefinition(SoundSource);
27  /**
28  * @brief creates a SoundSource at position sourceNode with the SoundBuffer buffer
29  */
30  SoundSource::SoundSource(const PNode* sourceNode, const SoundBuffer& buffer)
31  {
32    this->registerObject(this, SoundSource::_objectList);
33    // adding the Source to the SourcesList of the SoundEngine
34    this->buffer = buffer;
35    this->sourceNode = sourceNode;
36    this->resident = false;
37
38    this->sourceID = 0;
39    this->bPlay = false;
40  }
41
42
43  /**
44  * @brief construct a SoundSource out of the another soundSource
45  * @param source the Source to create this source from.
46  *
47  * Copies the buffer from source to this Source.
48  * Acquires a new SourceID if source is Playing.
49  */
50  SoundSource::SoundSource(const SoundSource& source)
51  {
52    this->registerObject(this, SoundSource::_objectList);
53
54    // adding the Source to the SourcesList of the SoundEngine
55    this->buffer = source.buffer;
56    this->sourceNode = source.sourceNode;
57    this->resident = source.resident;
58
59    this->sourceID = 0;
60    if (source.bPlay == true)
61    {
62      this->bPlay = true;
63      SoundEngine::getInstance()->popALSource(this->sourceID);
64    }
65    else
66      this->bPlay = false;
67  }
68
69
70  /**
71  * @brief paste a copy of the source into this Source.
72  * @param source the SoundSource to paste into this one.
73  * @returns a Reference to this Source.
74  *
75  */
76  SoundSource& SoundSource::operator=(const SoundSource& source)
77  {
78    this->buffer = source.buffer;
79    this->sourceNode = sourceNode;
80    this->resident = source.resident;
81
82    if (source.bPlay)
83      this->play();
84    else
85      this->stop();
86
87    return *this;
88  }
89
90
91  /**
92  * @brief compares two Sources with each other.
93  * @param source the Source to compare against this One.
94  * Two Sources are the same, if the PNodes match, and the Sound Played are the same.
95  * The alSource must not match, because no two Sources can have the same alSource.
96  */
97  bool SoundSource::operator==(const SoundSource& source)
98  {
99    return (this->buffer == source.buffer &&
100            this->bPlay == source.bPlay &&
101            this->sourceNode == source.sourceNode);
102  }
103
104
105  /**
106  * @brief deletes a SoundSource
107  */
108  SoundSource::~SoundSource()
109  {
110    this->stop();
111    if (this->sourceID != 0)
112      SoundEngine::getInstance()->pushALSource(this->sourceID);
113  }
114
115
116  /**
117  * @brief Plays back a SoundSource
118  */
119  void SoundSource::play()
120  {
121    if (this->retrieveSource())
122    {
123      if (this->bPlay)
124        alSourceStop(this->sourceID);
125
126      alSourcei (this->sourceID, AL_BUFFER, this->buffer.getID());
127      alSourcei (this->sourceID, AL_LOOPING,  AL_FALSE);
128//      alSourcef (this->sourceID, AL_ROLLOFF_FACTOR, 0.0);
129      alSourcef (this->sourceID, AL_GAIN, SoundEngine::getInstance()->getEffectsVolume());
130      alSourcePlay(this->sourceID);
131
132      if (DEBUG_LEVEL >= 3)
133        SoundEngine::checkError("Play Source", __LINE__);
134      this->bPlay = true;
135    }
136  }
137
138
139  /**
140  * @brief Plays back buffer on this Source
141  * @param buffer the buffer to play back on this Source
142  */
143  void SoundSource::play(const SoundBuffer& buffer)
144  {
145    if (!this->retrieveSource())
146    {
147      PRINTF(3)("No more Free sources (You might consider raising the Source-Count).\n");
148      return;
149    }
150
151    alSourceStop(this->sourceID);
152    alSourcei (this->sourceID, AL_BUFFER, buffer.getID());
153    alSourcei (this->sourceID, AL_LOOPING,  AL_FALSE);
154//    alSourcef (this->sourceID, AL_ROLLOFF_FACTOR, 0.0);
155    alSourcef (this->sourceID, AL_GAIN, SoundEngine::getInstance()->getEffectsVolume());
156
157    alSourcePlay(this->sourceID);
158
159    if (unlikely(this->buffer.getID() != 0))
160      alSourcei (this->sourceID, AL_BUFFER, this->buffer.getID());
161    this->bPlay = true;
162
163    if (DEBUG_LEVEL >= 3)
164      SoundEngine::checkError("Play Source", __LINE__);
165  }
166
167
168  /**
169   * @brief Plays back buffer on this Source with gain
170   * @param buffer the buffer to play back on this Source
171   * @param gain the gain of the sound buffer
172   * @param rolloff the rolloff of the sound buffer
173  */
174  void SoundSource::play(const SoundBuffer& buffer, float gain, float rolloff)
175  {
176    if (!this->retrieveSource())
177    {
178      PRINTF(3)("No more Free sources (You might consider raising the Source-Count).\n");
179      return;
180    }
181
182    alSourceStop(this->sourceID);
183    alSourcei (this->sourceID, AL_BUFFER, buffer.getID());
184    alSourcei (this->sourceID, AL_LOOPING,  AL_FALSE);
185    alSourcef (this->sourceID, AL_ROLLOFF_FACTOR, rolloff);
186    alSourcef (this->sourceID, AL_GAIN, gain);
187
188    alSourcePlay(this->sourceID);
189
190    if (unlikely(this->buffer.getID() != 0))
191      alSourcei (this->sourceID, AL_BUFFER, this->buffer.getID());
192    this->bPlay = true;
193
194    if (DEBUG_LEVEL >= 3)
195      SoundEngine::checkError("Play Source", __LINE__);
196  }
197
198  /**
199   * @brief Plays back buffer on this Source with gain, rolloff and looping possibility
200   * @param buffer the buffer to play back on this Source
201   * @param gain the gain of the sound buffer
202   * @param rolloff the rolloff of the sound buffer
203   * @param loop if true, sound gets looped
204   */
205  void SoundSource::play(const SoundBuffer& buffer, float gain, float rolloff, bool loop)
206  {
207    if (!this->retrieveSource())
208    {
209      PRINTF(3)("No more Free sources (You might consider raising the Source-Count).\n");
210      return;
211    }
212
213    alSourceStop(this->sourceID);
214    alSourcei (this->sourceID, AL_BUFFER, buffer.getID());
215
216    if (loop)
217      alSourcei (this->sourceID, AL_LOOPING,  AL_TRUE);
218    else
219      alSourcei (this->sourceID, AL_LOOPING,  AL_FALSE);
220
221    alSourcef (this->sourceID, AL_GAIN, gain);
222    alSourcef (this->sourceID, AL_ROLLOFF_FACTOR, rolloff);
223
224    alSourcePlay(this->sourceID);
225
226    if (unlikely(this->buffer.getID() != 0))
227      alSourcei (this->sourceID, AL_BUFFER, this->buffer.getID());
228    this->bPlay = true;
229
230    if (DEBUG_LEVEL >= 3)
231      SoundEngine::checkError("Play Source", __LINE__);
232  }
233
234  /**
235   * @brief Plays back buffer on this Source with looping possibility
236   * @param buffer the buffer to play back on this Source
237   * @param loop if true, sound gets looped
238   */
239  void SoundSource::play(const SoundBuffer& buffer, bool loop)
240  {
241    if (!this->retrieveSource())
242    {
243      PRINTF(3)("No more Free sources (You might consider raising the Source-Count).\n");
244      return;
245    }
246
247    alSourceStop(this->sourceID);
248    alSourcei (this->sourceID, AL_BUFFER, buffer.getID());
249
250    if (loop)
251      alSourcei (this->sourceID, AL_LOOPING,  AL_TRUE);
252    else
253      alSourcei (this->sourceID, AL_LOOPING,  AL_FALSE);
254
255    alSourcef (this->sourceID, AL_GAIN, SoundEngine::getInstance()->getEffectsVolume());
256
257    alSourcePlay(this->sourceID);
258
259    if (unlikely(this->buffer.getID() != 0))
260      alSourcei (this->sourceID, AL_BUFFER, this->buffer.getID());
261    this->bPlay = true;
262
263    if (DEBUG_LEVEL >= 3)
264      SoundEngine::checkError("Play Source", __LINE__);
265  }
266 
267  /**
268   * @brief Changes the volume of an (active) buffer
269   * @param buffer the buffer to play back on this Source
270   * @param gain the new gain value
271   */
272  void SoundSource::gain(const SoundBuffer& buffer, float gain)
273  {
274    // alSourcei (this->sourceID, AL_BUFFER, buffer->getID());
275    alSourcef (this->sourceID, AL_GAIN, gain);
276  }
277
278  /**
279   * @brief Stops playback of a SoundSource
280   */
281  void SoundSource::stop()
282  {
283    this->bPlay = false;
284    if (this->sourceID != 0)
285    {
286      this->bPlay = false;
287      if (this->sourceID != 0)
288      {
289        alSourceStop(this->sourceID);
290        if (DEBUG_LEVEL >= 3)
291          SoundEngine::checkError("StopSource", __LINE__);
292        alSourcei(this->sourceID, AL_BUFFER, 0);
293        if (!this->resident)
294          SoundEngine::getInstance()->pushALSource(this->sourceID);
295        this->sourceID = 0;
296      }
297    }
298  }
299
300  /**
301  * @brief Pauses Playback of a SoundSource
302  */
303  void SoundSource::pause()
304  {
305    alSourcePause(this->sourceID);
306    if (DEBUG_LEVEL >= 3)
307      SoundEngine::checkError("Pause Source", __LINE__);
308  }
309
310
311  /**
312  * @brief Rewinds Playback of a SoundSource
313  */
314  void SoundSource::rewind()
315  {
316    alSourceRewind(this->sourceID);
317
318    if (DEBUG_LEVEL >= 3)
319      SoundEngine::checkError("Rewind Source", __LINE__);
320  }
321
322
323  /**
324  * @brief sets the RolloffFactor of the Sound emitted from the SoundSource
325  * @param rolloffFactor The Factor described
326  *
327  * this tells openAL how fast the Sounds decay outward from the Source
328  */
329  void SoundSource::setRolloffFactor(ALfloat rolloffFactor)
330  {
331    alSourcef(this->sourceID, AL_ROLLOFF_FACTOR, rolloffFactor);
332
333    if (DEBUG_LEVEL >= 3)
334      SoundEngine::checkError("Set Source Rolloff-factor", __LINE__);
335  }
336
337
338  /**
339  * @brief sets the Positional this Source should be attached to.
340  * @param sourceNode the Source this is attached to.
341  * If sourceNode == NULL then the Source will be centered, and Audio will be played on all channels.
342  */
343  void SoundSource::setSourceNode(const PNode* sourceNode)
344  {
345    this->sourceNode = sourceNode;
346  }
347
348  /**
349  * @brief retrieve a Source.
350  */
351  bool SoundSource::retrieveSource()
352  {
353    if (this->sourceID != 0)
354      return true;
355    else
356    {
357      SoundEngine::getInstance()->popALSource(this->sourceID);
358      if (this->sourceID != 0)
359      {
360        if (unlikely(this->sourceNode == NULL))
361          resetSource(this->sourceID);
362        return true;
363      }
364    }
365    return false;
366  }
367
368
369  /**
370  * @brief reset an alSource to its default Values.
371  */
372  void SoundSource::resetSource(ALuint sourceID)
373  {
374    alSource3f(sourceID, AL_POSITION,        0.0, 0.0, 0.0);
375    alSource3f(sourceID, AL_VELOCITY,        0.0, 0.0, 0.0);
376    alSource3f(sourceID, AL_DIRECTION,       0.0, 0.0, 0.0);
377    alSourcef (sourceID, AL_ROLLOFF_FACTOR,  0.0          );
378    //alSourcei (sourceID, AL_SOURCE_RELATIVE, AL_TRUE      );
379    alSourcef (sourceID, AL_GAIN,            SoundEngine::getInstance()->getEffectsVolume());
380  }
381
382
383  /**
384  * @brief Fades in a Source over a time period
385  * @param duration time perios to fade in
386  */
387  void SoundSource::fadein(const SoundBuffer& buffer, ALfloat duration)
388  {
389    //if (this->buffer && this->retrieveSource())
390    //{
391
392    for (ALfloat n = 0.0; n < 1.0; n+=.01)
393    {
394      alSourcef(this->sourceID, AL_GAIN, n);
395      // sleep(1);
396    }
397
398    //  alSourcePlay(this->sourceID);
399
400    //  if (DEBUG_LEVEL >= 3)
401    //    SoundEngine::checkError("Loop Source", __LINE__);
402    //  this->bPlay = true;
403    //}
404
405  }
406
407
408}
Note: See TracBrowser for help on using the repository browser.