zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Sound_Source.cpp
Go to the documentation of this file.
1 /* This file is part of the Zenipex Library (zenilib).
2  * Copyright (C) 2011 Mitchell Keith Bloch (bazald).
3  *
4  * zenilib is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * zenilib is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with zenilib. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include <zeni_audio.h>
19 
20 #include <algorithm>
21 #include <iostream>
22 #include <utility>
23 #include <vector>
24 #include <cmath>
25 
26 #ifndef DISABLE_AL
27 #define OV_EXCLUDE_STATIC_CALLBACKS
28 #include <vorbis/vorbisfile.h>
29 #undef OV_EXCLUDE_STATIC_CALLBACKS
30 #endif
31 
32 #include <Zeni/Define.h>
33 
34 #if defined(_DEBUG) && defined(_WINDOWS)
35 #define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
36 #define new DEBUG_NEW
37 #endif
38 
39 namespace Zeni {
40 
41  Sound_Source_HW::Sound_Source_HW(const ALuint &source)
42  :
43 #ifndef DISABLE_AL
44  m_source(source),
45 #endif
46 #ifdef ENABLE_SLES
47  fdPlayerObject(NULL),
48  fdPlayerPlay(NULL),
49  fdPlayerSeek(NULL),
50  fdPlayerMuteSolo(NULL),
51  fdPlayerVolume(NULL),
52 #endif
53  m_buffer(0)
54  {
55  Sound &sr = get_Sound();
56 
57 #ifdef ENABLE_SLES
58  if(Sound_Renderer_SLES * const sles = dynamic_cast<Sound_Renderer_SLES *>(&sr.get_Renderer())) {
59  // configure audio sink
60  loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, sles->get_outputMixObject()};
61  audioSnk = {&loc_outmix, NULL};
62  }
63 #endif
64 
65  init(sr.get_Hello_World_Buffer());
66  }
67 
68  Sound_Source_HW::Sound_Source_HW(const Sound_Buffer &buffer, const float &pitch, const float &gain,
69  const Point3f &position, const Vector3f &velocity, const bool &looping)
70  :
71 #ifndef DISABLE_AL
72  m_source(AL_NONE),
73 #endif
74 #ifdef ENABLE_SLES
75  fdPlayerObject(NULL),
76  fdPlayerPlay(NULL),
77  fdPlayerSeek(NULL),
78  fdPlayerMuteSolo(NULL),
79  fdPlayerVolume(NULL),
80 #endif
81  m_buffer(0)
82  {
83 #ifdef ENABLE_SLES
84  Sound &sr = get_Sound();
85 
86  if(Sound_Renderer_SLES * const sles = dynamic_cast<Sound_Renderer_SLES *>(&sr.get_Renderer())) {
87  // configure audio sink
88  loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, sles->get_outputMixObject()};
89  audioSnk = {&loc_outmix, NULL};
90  }
91 #endif
92 
93  init(buffer, pitch, gain, position, velocity, looping);
94  }
95 
96  Sound_Source_HW::~Sound_Source_HW() {
97  uninit();
98  }
99 
100  Sound_Source_HW * Sound_Source_HW::Try_Construct() {
101  ALuint source = AL_NONE;
102 #ifndef DISABLE_AL
103  if(dynamic_cast<Sound_Renderer_AL *>(&get_Sound().get_Renderer()) && Sound_Renderer_AL::alGenSources())
105 #endif
106 #ifdef ENABLE_SLES
107  if(dynamic_cast<Sound_Renderer_SLES *>(&get_Sound().get_Renderer()))
108  return new Sound_Source_HW(AL_NONE);
109 #endif
110  return source != AL_NONE ? new Sound_Source_HW(source) : 0;
111  }
112 
114 #if !defined(DISABLE_AL) || defined(ENABLE_SLES)
115  buffer
116 #endif
117  ) {
118 #ifndef DISABLE_AL
119  if(dynamic_cast<Sound_Renderer_AL *>(&get_Sound().get_Renderer())) {
120  m_buffer = &buffer;
121  Sound_Renderer_AL::alSourcei()(m_source, AL_BUFFER, ALint(buffer.get_id()));
122  }
123 #endif
124 #ifdef ENABLE_SLES
125  if(dynamic_cast<Sound_Renderer_SLES *>(&get_Sound().get_Renderer())) {
126  const float gain = get_gain();
127  const bool looping = is_looping();
128  uninit();
129  init(buffer, float(), gain, Point3f(), Vector3f(), looping);
130  }
131 #endif
132  }
133 
134  void Sound_Source_HW::set_pitch(const float &
135 #ifndef DISABLE_AL
136  pitch
137 #endif
138  ) {
139 #ifndef DISABLE_AL
140  Sound_Renderer_AL::alSourcef()(m_source, AL_PITCH, pitch);
141 #endif
142  }
143 
144  void Sound_Source_HW::set_gain(const float &
145 #if !defined(DISABLE_AL) || defined(ENABLE_SLES)
146  gain
147 #endif
148  ) {
149 #ifndef DISABLE_AL
150  if(dynamic_cast<Sound_Renderer_AL *>(&get_Sound().get_Renderer())) {
151  Sound_Renderer_AL::alSourcef()(m_source, AL_GAIN, gain);
152  }
153 #endif
154 #ifdef ENABLE_SLES
155  if(dynamic_cast<Sound_Renderer_SLES *>(&get_Sound().get_Renderer())) {
156  (*fdPlayerVolume)->SetVolumeLevel(fdPlayerVolume, SLmillibel(2000.0f * log10(std::max(1.0f, gain))));
157  }
158 #endif
159  }
160 
162 #ifndef DISABLE_AL
163  position
164 #endif
165  ) {
166 #ifndef DISABLE_AL
167  Sound_Renderer_AL::alSourcefv()(m_source, AL_POSITION, const_cast<ALfloat *>(reinterpret_cast<const ALfloat *>(&position)));
168 #endif
169  }
170 
172 #ifndef DISABLE_AL
173  velocity
174 #endif
175  ) {
176 #ifndef DISABLE_AL
177  Sound_Renderer_AL::alSourcefv()(m_source, AL_VELOCITY, const_cast<ALfloat *>(reinterpret_cast<const ALfloat *>(&velocity)));
178 #endif
179  }
180 
182 #if !defined(DISABLE_AL) || defined(ENABLE_SLES)
183  looping
184 #endif
185  ) {
186 #ifndef DISABLE_AL
187  if(dynamic_cast<Sound_Renderer_AL *>(&get_Sound().get_Renderer())) {
188  Sound_Renderer_AL::alSourcei()(m_source, AL_LOOPING, looping);
189  }
190 #endif
191 #ifdef ENABLE_SLES
192  if(dynamic_cast<Sound_Renderer_SLES *>(&get_Sound().get_Renderer())) {
193  (*fdPlayerSeek)->SetLoop(fdPlayerSeek, looping ? SL_BOOLEAN_TRUE : SL_BOOLEAN_FALSE, 0, SL_TIME_UNKNOWN);
194  }
195 #endif
196  }
197 
198  void Sound_Source_HW::set_time(const float &
199 #if !defined(DISABLE_AL) || defined(ENABLE_SLES)
200  time
201 #endif
202  ) {
203 #ifndef DISABLE_AL
204  if(dynamic_cast<Sound_Renderer_AL *>(&get_Sound().get_Renderer())) {
205  Sound_Renderer_AL::alSourcef()(m_source, AL_SEC_OFFSET, time);
206  }
207 #endif
208 #ifdef ENABLE_SLES
209  if(dynamic_cast<Sound_Renderer_SLES *>(&get_Sound().get_Renderer())) {
210  (*fdPlayerSeek)->SetPosition(fdPlayerSeek, SLmillisecond(1000.0f * time), SL_SEEKMODE_FAST);
211  }
212 #endif
213  }
214 
216 #ifndef DISABLE_AL
217  reference_distance
218 #endif
219  ) {
220 #ifndef DISABLE_AL
221  Sound_Renderer_AL::alSourcef()(m_source, AL_REFERENCE_DISTANCE, reference_distance);
222 #endif
223  }
224 
226 #ifndef DISABLE_AL
227  max_distance
228 #endif
229  ) {
230 #ifndef DISABLE_AL
231  Sound_Renderer_AL::alSourcef()(m_source, AL_MAX_DISTANCE, max_distance);
232 #endif
233  }
234 
235  void Sound_Source_HW::set_rolloff(const float &
236 #ifndef DISABLE_AL
237  rolloff
238 #endif
239  ) {
240 #ifndef DISABLE_AL
241  Sound_Renderer_AL::alSourcef()(m_source, AL_ROLLOFF_FACTOR, rolloff);
242 #endif
243  }
244 
246  assert(m_buffer);
247  return *m_buffer;
248  }
249 
251 #ifdef ENABLE_SLES
252  if(dynamic_cast<Sound_Renderer_SLES *>(&get_Sound().get_Renderer())) {
253  SLmillisecond duration;
254  (*fdPlayerPlay)->GetDuration(fdPlayerPlay, &duration);
255  if(duration != SL_TIME_UNKNOWN)
256  return duration * 0.001f;
257  }
258 #endif
259  return m_buffer->get_duration();
260  }
261 
263  float pitch = ZENI_DEFAULT_PITCH;
264 #ifndef DISABLE_AL
265  Sound_Renderer_AL::alGetSourcef()(m_source, AL_PITCH, &pitch);
266 #endif
267  return pitch;
268  }
269 
271  float gain = ZENI_DEFAULT_GAIN;
272 #ifndef DISABLE_AL
273  if(dynamic_cast<Sound_Renderer_AL *>(&get_Sound().get_Renderer())) {
274  Sound_Renderer_AL::alGetSourcef()(m_source, AL_GAIN, &gain);
275  }
276 #endif
277 #ifdef ENABLE_SLES
278  if(dynamic_cast<Sound_Renderer_SLES *>(&get_Sound().get_Renderer())) {
279  SLmillibel millibels;
280  if((*fdPlayerVolume)->GetVolumeLevel(fdPlayerVolume, &millibels) == SL_RESULT_SUCCESS)
281  gain = pow(10.0f, millibels / 2000.0f);
282  }
283 #endif
284  return gain;
285  }
286 
288  Point3f position;
289 #ifndef DISABLE_AL
290  Sound_Renderer_AL::alGetSourcefv()(m_source, AL_POSITION, reinterpret_cast<ALfloat *>(&position));
291 #endif
292  return position;
293  }
294 
296  Vector3f velocity;
297 #ifndef DISABLE_AL
298  Sound_Renderer_AL::alGetSourcefv()(m_source, AL_VELOCITY, reinterpret_cast<ALfloat *>(&velocity));
299 #endif
300  return velocity;
301  }
302 
304  ALint looping = AL_FALSE;
305 #ifndef DISABLE_AL
306  if(dynamic_cast<Sound_Renderer_AL *>(&get_Sound().get_Renderer())) {
307  Sound_Renderer_AL::alGetSourcei()(m_source, AL_LOOPING, &looping);
308  }
309 #endif
310 #ifdef ENABLE_SLES
311  if(dynamic_cast<Sound_Renderer_SLES *>(&get_Sound().get_Renderer())) {
312  SLboolean slooping;
313  SLmillisecond start, end;
314  if((*fdPlayerSeek)->GetLoop(fdPlayerSeek, &slooping, &start, &end) == SL_RESULT_SUCCESS)
315  return slooping != SL_BOOLEAN_FALSE;
316  }
317 #endif
318  return looping != AL_FALSE;
319  }
320 
322  float time = 0.0f;
323 #ifndef DISABLE_AL
324  if(dynamic_cast<Sound_Renderer_AL *>(&get_Sound().get_Renderer())) {
326  }
327 #endif
328 #ifdef ENABLE_SLES
329  if(dynamic_cast<Sound_Renderer_SLES *>(&get_Sound().get_Renderer())) {
330  SLmillisecond milliseconds;
331  if((*fdPlayerPlay)->GetPosition(fdPlayerPlay, &milliseconds) == SL_RESULT_SUCCESS)
332  time = milliseconds / 1000.0f;
333  }
334 #endif
335  return time;
336  }
337 
339  float reference_distance = ZENI_DEFAULT_REFERENCE_DISTANCE;
340 #ifndef DISABLE_AL
341  Sound_Renderer_AL::alGetSourcef()(m_source, AL_REFERENCE_DISTANCE, &reference_distance);
342 #endif
343  return reference_distance;
344  }
345 
347  float max_distance = ZENI_DEFAULT_MAX_SOUND_DISTANCE;
348 #ifndef DISABLE_AL
349  Sound_Renderer_AL::alGetSourcef()(m_source, AL_MAX_DISTANCE, &max_distance);
350 #endif
351  return max_distance;
352  }
353 
355  float rolloff = ZENI_DEFAULT_ROLLOFF;
356 #ifndef DISABLE_AL
357  Sound_Renderer_AL::alGetSourcef()(m_source, AL_ROLLOFF_FACTOR, &rolloff);
358 #endif
359  return rolloff;
360  }
361 
363 #ifndef DISABLE_AL
364  if(dynamic_cast<Sound_Renderer_AL *>(&get_Sound().get_Renderer())) {
366  }
367 #endif
368 #ifdef ENABLE_SLES
369  if(dynamic_cast<Sound_Renderer_SLES *>(&get_Sound().get_Renderer())) {
370  ZENI_LOGD("SLES play executing.");
371  (*fdPlayerPlay)->SetPlayState(fdPlayerPlay, SL_PLAYSTATE_PLAYING);
372  }
373 #endif
374  }
375 
377 #ifndef DISABLE_AL
378  if(dynamic_cast<Sound_Renderer_AL *>(&get_Sound().get_Renderer())) {
380  }
381 #endif
382 #ifdef ENABLE_SLES
383  if(dynamic_cast<Sound_Renderer_SLES *>(&get_Sound().get_Renderer())) {
384  (*fdPlayerPlay)->SetPlayState(fdPlayerPlay, SL_PLAYSTATE_PAUSED);
385  }
386 #endif
387  }
388 
390 #ifndef DISABLE_AL
391  if(dynamic_cast<Sound_Renderer_AL *>(&get_Sound().get_Renderer())) {
393  }
394 #endif
395 #ifdef ENABLE_SLES
396  if(dynamic_cast<Sound_Renderer_SLES *>(&get_Sound().get_Renderer())) {
397  (*fdPlayerPlay)->SetPlayState(fdPlayerPlay, SL_PLAYSTATE_STOPPED);
398  }
399 #endif
400  }
401 
403 #ifndef DISABLE_AL
404  if(dynamic_cast<Sound_Renderer_AL *>(&get_Sound().get_Renderer())) {
405  ALenum state = AL_STOPPED;
407  return state == AL_PLAYING ? PLAYING :
408  state == AL_PAUSED ? PAUSED :
409  STOPPED;
410  }
411 #endif
412 #ifdef ENABLE_SLES
413  if(dynamic_cast<Sound_Renderer_SLES *>(&get_Sound().get_Renderer())) {
414  SLuint32 state;
415  if((*fdPlayerPlay)->GetPlayState(fdPlayerPlay, &state) != SL_RESULT_SUCCESS)
416  return STOPPED;
417  return state == SL_PLAYSTATE_PLAYING ? PLAYING :
418  state == SL_PLAYSTATE_PAUSED ? PAUSED :
419  STOPPED;
420  }
421 #endif
422  return Sound_Source_HW::STATE();
423  }
424 
426  return get_state() == PLAYING;
427  }
428 
430  return get_state() == PAUSED;
431  }
432 
434  return get_state() == STOPPED;
435  }
436 
437  void Sound_Source_HW::init(const Sound_Buffer &buffer, const float &
438 #ifndef DISABLE_AL
439  pitch
440 #endif
441  , const float &
442 #if !defined(DISABLE_AL) || defined(ENABLE_SLES)
443  gain
444 #endif
445  , const Point3f &
446 #ifndef DISABLE_AL
447  position
448 #endif
449  , const Vector3f &
450 #ifndef DISABLE_AL
451  velocity
452 #endif
453  , const bool &
454 #if !defined(DISABLE_AL) || defined(ENABLE_SLES)
455  looping
456 #endif
457  )
458  {
459  m_buffer = &buffer;
460 
461  Sound &sr = get_Sound();
462 
463 #ifndef DISABLE_AL
464  if(dynamic_cast<Sound_Renderer_AL *>(&sr.get_Renderer())) {
467 
468  if(m_source == AL_NONE) {
469  Sound_Renderer_AL::alGenSources()(1, &m_source);
470 
471  if(m_source == AL_NONE) {
472  std::cerr << "OpenAL error: " << Sound_Renderer_AL::errorString() << std::endl;
474  }
475  }
476 
477  Sound_Renderer_AL::alSourcei()(m_source, AL_BUFFER, ALint(buffer.get_id()));
478  Sound_Renderer_AL::alSourcef()(m_source, AL_PITCH, pitch);
479  Sound_Renderer_AL::alSourcef()(m_source, AL_GAIN, gain);
480  Sound_Renderer_AL::alSourcefv()(m_source, AL_POSITION, const_cast<ALfloat *>(reinterpret_cast<const ALfloat *>(&position)));
481  Sound_Renderer_AL::alSourcefv()(m_source, AL_VELOCITY, const_cast<ALfloat *>(reinterpret_cast<const ALfloat *>(&velocity)));
482  Sound_Renderer_AL::alSourcei()(m_source, AL_LOOPING, looping);
483  }
484 #endif
485 #ifdef ENABLE_SLES
486  if(Sound_Renderer_SLES * const sles = dynamic_cast<Sound_Renderer_SLES *>(&sr.get_Renderer())) {
487  const SLInterfaceID ids[3] = {SL_IID_SEEK, SL_IID_MUTESOLO, SL_IID_VOLUME};
488  const SLboolean req[3] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
489 
490  // create audio player
491  if((*sles->get_engineEngine())->CreateAudioPlayer(sles->get_engineEngine(), &fdPlayerObject, &const_cast<SLDataSource &>(buffer.get_audioSrc()), &audioSnk, 3, ids, req) != SL_RESULT_SUCCESS ||
492  (*fdPlayerObject)->Realize(fdPlayerObject, SL_BOOLEAN_FALSE) != SL_RESULT_SUCCESS ||
493  (*fdPlayerObject)->GetInterface(fdPlayerObject, SL_IID_PLAY, &fdPlayerPlay) != SL_RESULT_SUCCESS ||
494  (*fdPlayerObject)->GetInterface(fdPlayerObject, SL_IID_SEEK, &fdPlayerSeek) != SL_RESULT_SUCCESS ||
495  (*fdPlayerObject)->GetInterface(fdPlayerObject, SL_IID_MUTESOLO, &fdPlayerMuteSolo) != SL_RESULT_SUCCESS ||
496  (*fdPlayerObject)->GetInterface(fdPlayerObject, SL_IID_VOLUME, &fdPlayerVolume) != SL_RESULT_SUCCESS ||
497  (*fdPlayerSeek)->SetLoop(fdPlayerSeek, looping ? SL_BOOLEAN_TRUE : SL_BOOLEAN_FALSE, 0, SL_TIME_UNKNOWN) != SL_RESULT_SUCCESS ||
498  (*fdPlayerVolume)->SetVolumeLevel(fdPlayerVolume, SLmillibel(2000.0f * log10(std::max(1.0f, gain)))) != SL_RESULT_SUCCESS)
499  {
500  throw Sound_Source_HW_Init_Failure();
501  }
502  }
503 #endif
504 
507  }
508 
509  void Sound_Source_HW::uninit() {
510  stop();
511 
512 #ifndef DISABLE_AL
513  if(m_source != AL_NONE)
514  Sound_Renderer_AL::alDeleteSources()(1, &m_source);
515 #endif
516 #ifdef ENABLE_SLES
517  // destroy file descriptor audio player object, and invalidate all associated interfaces
518  if (fdPlayerObject != NULL) {
519  (*fdPlayerObject)->Destroy(fdPlayerObject);
520  fdPlayerObject = NULL;
521  fdPlayerPlay = NULL;
522  fdPlayerSeek = NULL;
523  fdPlayerMuteSolo = NULL;
524  fdPlayerVolume = NULL;
525  }
526 #endif
527  }
528 
530  : m_hw(0),
531  m_priority(ZENI_DEFAULT_SOUND_PRIORITY),
532  m_buffer(&get_Sound().get_Hello_World_Buffer()),
533  m_duration(0.0f),
534  m_pitch(ZENI_DEFAULT_PITCH),
535  m_gain(ZENI_DEFAULT_GAIN),
536  m_looping(false),
537  m_reference_distance(ZENI_DEFAULT_REFERENCE_DISTANCE),
538  m_max_distance(ZENI_DEFAULT_MAX_SOUND_DISTANCE),
539  m_rolloff(ZENI_DEFAULT_ROLLOFF),
540  m_play_position(0.0f),
541  m_playing(false),
542  m_paused(false),
543  m_stopped(true),
544  m_remove_from_Pool_on_destruction(true)
545  {
546  get_Sound_Source_Pool().insert_Sound_Source(*this);
547  }
548 
550  const float &pitch,
551  const float &gain,
552  const Point3f &position,
553  const Vector3f &velocity,
554  const bool &looping)
555  : m_hw(0),
556  m_priority(ZENI_DEFAULT_SOUND_PRIORITY),
557  m_buffer(&buffer),
558  m_duration(0.0f),
559  m_pitch(pitch),
560  m_gain(gain),
561  m_position(position),
562  m_velocity(velocity),
563  m_looping(looping),
564  m_reference_distance(ZENI_DEFAULT_REFERENCE_DISTANCE),
565  m_max_distance(ZENI_DEFAULT_MAX_SOUND_DISTANCE),
566  m_rolloff(ZENI_DEFAULT_ROLLOFF),
567  m_play_position(0.0f),
568  m_playing(false),
569  m_paused(false),
570  m_stopped(true),
571  m_remove_from_Pool_on_destruction(true)
572  {
573  get_Sound_Source_Pool().insert_Sound_Source(*this);
574  }
575 
577  if(m_remove_from_Pool_on_destruction)
578  get_Sound_Source_Pool().remove_Sound_Source(*this);
579  }
580 
581  float Sound_Source::get_time() const {
582  if(m_playing) {
583  const float duration = get_duration();
584 
585  const Time_HQ current_time;
586  if(m_hw)
587  m_play_position = m_hw->get_time();
588  else {
589  float time_step = float(current_time.get_seconds_since(m_play_time));
590  m_play_position += time_step;
591  }
592  m_play_time = current_time;
593 
594  if(duration && m_play_position > duration) {
595  if(m_looping)
596  m_play_position = float(fmod(m_play_position, duration));
597  else {
598  m_playing = false;
599  m_stopped = true;
600 
601  m_play_position = 0.0f;
602  }
603  }
604  }
605  else if(m_hw)
606  m_play_position = m_hw->get_time();
607 
608  return m_play_position;
609  }
610 
611  float Sound_Source::calculate_gain(const Point3f &listener_position) const {
612  float distance = (listener_position - m_position).magnitude();
613 
614  // 'OpenAL 1.1 Specification.pdf' - '3.4.4. Linear Distance Clamped Model'
615  distance = std::max(distance, m_reference_distance);
616  distance = std::min(distance, m_max_distance);
617  return 1.0f - m_rolloff * (distance - m_reference_distance) /
618  (m_max_distance - m_reference_distance);
619  }
620 
621  void Sound_Source::assign(Sound_Source_HW &hw) {
622  m_hw = &hw;
623 
624  const float time = get_time();
625  const float duration = get_duration();
626 
627  hw.set_buffer(*m_buffer);
628  hw.set_pitch(m_pitch);
629  hw.set_gain(m_gain);
630  hw.set_position(m_position);
631  hw.set_velocity(m_velocity);
632  hw.set_looping(m_looping);
633  hw.set_time(time);
634  hw.set_reference_distance(m_reference_distance);
635  hw.set_max_distance(m_max_distance);
636  hw.set_rolloff(m_rolloff);
637 
638  if(m_playing && (!duration || time < duration))
639  hw.play();
640  }
641 
642  Sound_Source_HW * Sound_Source::unassign() {
643  Sound_Source_HW * ptr = m_hw;
644 
645  if(m_hw) {
646  update_state();
647 
648  m_hw->stop();
649 
650  m_hw = 0;
651  }
652 
653  return ptr;
654  }
655 
656  void Sound_Source::update_state() const {
657  if(m_hw)
658  update_state(m_hw->get_state());
659  }
660 
661  void Sound_Source::update_state(const Sound_Source_HW::STATE &state) const {
662  if(state == Sound_Source_HW::PLAYING) {
663  m_playing = true;
664  m_paused = m_stopped = false;
665 
666  m_play_time.update();
667 
668  get_time();
669  }
670  else if(state == Sound_Source_HW::PAUSED) {
671  get_time();
672 
673  m_paused = true;
674  m_playing = m_stopped = false;
675  }
676  else if(!m_paused && state == Sound_Source_HW::STOPPED) {
677  m_stopped = true;
678  m_playing = m_paused = false;
679 
680  get_time();
681  }
682  }
683 
684 }
685 
686 #include <Zeni/Undefine.h>
static alGetSourcefv_fcn alGetSourcefv()
float get_duration() const
Get the duration of the Sound_Buffer in seconds.
float get_pitch() const
Get the pitch.
const Sound_Buffer & get_buffer() const
Get the Sound_Buffer.
#define AL_NONE
Definition: al.h:80
#define AL_STOPPED
Definition: al.h:241
void set_buffer(const Sound_Buffer &buffer)
Set the Sound_Buffer to be played.
A Snapshot of the Timer_HQ.
Definition: Timer_HQ.h:79
#define NULL
Definition: ftobjs.h:61
Sound_Source_Pool & get_Sound_Source_Pool()
Get access to the singleton.
GLuint start
Definition: glew.h:1239
GLclampf f
Definition: glew.h:3390
void set_time(const float &time)
Set the current position in the Sound_Buffer, offset in seconds.
static alSourceStop_fcn alSourceStop()
void update()
Update to current Time.
Definition: Timer_HQ.hxx:47
#define ZENI_DEFAULT_PITCH
Definition: Define.h:54
static alDeleteSources_fcn alDeleteSources()
static alGetSourcei_fcn alGetSourcei()
void stop()
Stop the Sound_Source_HW. (Essentially the same as pause but resets the current time.)
#define AL_MAX_DISTANCE
Definition: al.h:309
static void init(struct bs2b *bs2b)
Definition: bs2b.c:46
int ALint
Definition: al.h:56
#define AL_FALSE
Definition: al.h:83
#define AL_SOURCE_STATE
Definition: al.h:235
static alSourcei_fcn alSourcei()
Sound_Renderer & get_Renderer()
Get the current Sound_Renderer.
Definition: Sound.hxx:30
const float & get_duration() const
Get the duration of the Sound_Buffer in seconds.
Definition: Sound_Buffer.h:102
void play()
Begin playing or unpause the Sound_Source_HW.
float get_time() const
Get the current position in the Sound_Buffer, offset in seconds.
#define assert(x)
Definition: SDL_malloc.c:1234
static alGetSourcef_fcn alGetSourcef()
void set_gain(const float &gain=ZENI_DEFAULT_GAIN)
Set the gain.
float ALfloat
Definition: al.h:68
void set_reference_distance(const float &reference_distance=ZENI_DEFAULT_REFERENCE_DISTANCE)
#define AL_PAUSED
Definition: al.h:240
#define ZENI_DEFAULT_GAIN
Definition: Define.h:55
void set_looping(const bool &looping)
Set whether the Sound_Buffer should loop back to the start once it is done playing.
#define AL_POSITION
Definition: al.h:144
static alSourcef_fcn alSourcef()
STATE get_state() const
Get PLAYING/PAUSED/STOPPED.
void set_velocity(const Vector3f &velocity)
Set the velocity of the Sound_Source_HW for the doppler effect.
A 3D Point represented with floats.
Definition: Coordinate.h:133
#define ZENI_DEFAULT_MAX_SOUND_DISTANCE
Definition: Define.h:57
Plays Sound Data.
Definition: Sound_Source.h:69
void set_max_distance(const float &max_distance=ZENI_DEFAULT_MAX_SOUND_DISTANCE)
Vector3f get_velocity() const
Get the velocity of the Sound_Buffer.
EGLContext EGLenum EGLClientBuffer buffer
Definition: eglext.h:87
Sound & get_Sound()
Get access to the singleton.
Definition: Sound.cpp:220
float get_rolloff() const
A Featureful 3-Space Vector Class.
Definition: Vector3f.h:58
#define AL_PLAYING
Definition: al.h:239
#define AL_ROLLOFF_FACTOR
Definition: al.h:286
void set_rolloff(const float &rolloff=ZENI_DEFAULT_ROLLOFF)
#define true
Definition: ftrandom.c:49
#define AL_LOOPING
Definition: al.h:173
#define AL_PITCH
Definition: al.h:128
const ALuint & get_id() const
Get the OpenAL id of the Sound_Buffer.
Definition: Sound_Buffer.h:97
GLsizei GLsizei GLfloat distance
Definition: glew.h:12423
#define ZENI_DEFAULT_REFERENCE_DISTANCE
Definition: Define.h:56
int ALenum
Definition: al.h:65
void ZENI_LOGD(const Zeni::String &str)
Definition: Android.h:50
unsigned int ALuint
Definition: al.h:59
#define AL_BUFFER
Definition: al.h:182
Stores Sound Data.
Definition: Sound_Buffer.h:83
float get_reference_distance() const
#define ZENI_DEFAULT_ROLLOFF
Definition: Define.h:58
float calculate_gain(const Point3f &listener_position) const
Get the actual volume gain, given gain+position+near_clamp+far_clamp+rolloff.
static alSourcefv_fcn alSourcefv()
float get_duration() const
Get the duration of the Sound_Buffer in seconds.
static alSourcePlay_fcn alSourcePlay()
float get_max_distance() const
bool is_looping() const
Check to see if the Sound_Buffer is set to loop back to the start once it is done playing...
#define AL_REFERENCE_DISTANCE
Definition: al.h:274
bool is_playing() const
Check to see if the Sound_Source_HW is playing.
The Sound Singleton.
Definition: Sound.h:53
void set_position(const Point3f &position)
Set the position of the Sound_Source_HW.
#define ZENI_DEFAULT_SOUND_PRIORITY
Definition: Define.h:59
GLuint * ids
Definition: gl2ext.h:1139
GLuint GLuint end
Definition: glew.h:1239
static alSourcePause_fcn alSourcePause()
bool is_stopped() const
Check to see if the Sound_Source_HW is stopped.
#define min(x, y)
Definition: os.h:75
#define AL_GAIN
Definition: al.h:196
bool is_paused() const
Check to see if the Sound_Source_HW is paused.
float get_gain() const
Get the gain.
#define AL_SEC_OFFSET
Definition: al.h:312
void pause()
Pause the Sound_Source_HW.
long double get_seconds_since(const Time_HQ &time) const
Get the number of seconds passed between &#39;time&#39; and this Time.
Definition: Timer_HQ.hxx:43
#define max(x, y)
Definition: os.h:79
static alGenSources_fcn alGenSources()
Point3f get_position() const
Get the position of the Sound_Buffer.
GLsizei GLsizei GLchar * source
Definition: gl2ext.h:994
void set_pitch(const float &pitch=ZENI_DEFAULT_PITCH)
Set the pitch.
#define AL_VELOCITY
Definition: al.h:163
#define false
Definition: ftrandom.c:50
float get_time() const
Get the current position in the Sound_Buffer, offset in seconds.