zenilib: zenilib/jni/external/zenilib/zeni_audio/Sound_Source.cpp Source File

zenilib 0.5.3.0

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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())
104 Sound_Renderer_AL::alGenSources()(1, &source);
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
113 void Sound_Source_HW::set_buffer(const Sound_Buffer &
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
161 void Sound_Source_HW::set_position(const Point3f &
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
171 void Sound_Source_HW::set_velocity(const Vector3f &
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
181 void Sound_Source_HW::set_looping(const bool &
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
215 void Sound_Source_HW::set_reference_distance(const float &
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
225 void Sound_Source_HW::set_max_distance(const float &
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
245 const Sound_Buffer & Sound_Source_HW::get_buffer() const {
246 assert(m_buffer);
247 return *m_buffer;
248 }
249
250 float Sound_Source_HW::get_duration() const {
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
262 float Sound_Source_HW::get_pitch() const {
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
270 float Sound_Source_HW::get_gain() const {
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
287 Point3f Sound_Source_HW::get_position() const {
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
295 Vector3f Sound_Source_HW::get_velocity() const {
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
303 bool Sound_Source_HW::is_looping() const {
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
321 float Sound_Source_HW::get_time() const {
322 float time = 0.0f;
323 #ifndef DISABLE_AL
324 if(dynamic_cast<Sound_Renderer_AL *>(&get_Sound().get_Renderer())) {
325 Sound_Renderer_AL::alGetSourcef()(m_source, AL_SEC_OFFSET, &time);
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
338 float Sound_Source_HW::get_reference_distance() const {
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
346 float Sound_Source_HW::get_max_distance() const {
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
354 float Sound_Source_HW::get_rolloff() const {
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
362 void Sound_Source_HW::play() {
363 #ifndef DISABLE_AL
364 if(dynamic_cast<Sound_Renderer_AL *>(&get_Sound().get_Renderer())) {
365 Sound_Renderer_AL::alSourcePlay()(m_source);
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
376 void Sound_Source_HW::pause() {
377 #ifndef DISABLE_AL
378 if(dynamic_cast<Sound_Renderer_AL *>(&get_Sound().get_Renderer())) {
379 Sound_Renderer_AL::alSourcePause()(m_source);
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
389 void Sound_Source_HW::stop() {
390 #ifndef DISABLE_AL
391 if(dynamic_cast<Sound_Renderer_AL *>(&get_Sound().get_Renderer())) {
392 Sound_Renderer_AL::alSourceStop()(m_source);
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
402 Sound_Source_HW::STATE Sound_Source_HW::get_state() const {
403 #ifndef DISABLE_AL
404 if(dynamic_cast<Sound_Renderer_AL *>(&get_Sound().get_Renderer())) {
405 ALenum state = AL_STOPPED;
406 Sound_Renderer_AL::alGetSourcei()(m_source, AL_SOURCE_STATE, &state);
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
425 bool Sound_Source_HW::is_playing() const {
426 return get_state() == PLAYING;
427 }
428
429 bool Sound_Source_HW::is_paused() const {
430 return get_state() == PAUSED;
431 }
432
433 bool Sound_Source_HW::is_stopped() const {
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())) {
465 if(!Sound_Renderer_AL::alGenSources())
466 throw Sound_Source_HW_Init_Failure();
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;
473 throw Sound_Source_HW_Init_Failure();
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
505 set_reference_distance();
506 set_max_distance();
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
529 Sound_Source::Sound_Source()
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
549 Sound_Source::Sound_Source(const Sound_Buffer &buffer,
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
576 Sound_Source::~Sound_Source() {
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>
Zeni::Sound_Renderer_AL::alGetSourcefv
static alGetSourcefv_fcn alGetSourcefv()
Definition: Sound_Renderer_AL.h:95
Zeni::Sound_Source_HW::get_duration
float get_duration() const
Get the duration of the Sound_Buffer in seconds.
Definition: Sound_Source.cpp:250
Zeni::Sound_Source_HW::get_pitch
float get_pitch() const
Get the pitch.
Definition: Sound_Source.cpp:262
Zeni::Sound_Source_HW::get_buffer
const Sound_Buffer & get_buffer() const
Get the Sound_Buffer.
Definition: Sound_Source.cpp:245
AL_NONE
#define AL_NONE
Definition: al.h:80
AL_STOPPED
#define AL_STOPPED
Definition: al.h:241
Zeni::Sound_Source_HW::set_buffer
void set_buffer(const Sound_Buffer &buffer)
Set the Sound_Buffer to be played.
Definition: Sound_Source.cpp:113
Zeni::Time_HQ
A Snapshot of the Timer_HQ.
Definition: Timer_HQ.h:79
NULL
#define NULL
Definition: ftobjs.h:61
Zeni::get_Sound_Source_Pool
Sound_Source_Pool & get_Sound_Source_Pool()
Get access to the singleton.
Definition: Sound_Source_Pool.cpp:347
start
GLuint start
Definition: glew.h:1239
f
GLclampf f
Definition: glew.h:3390
Zeni::Sound_Source_HW::set_time
void set_time(const float &time)
Set the current position in the Sound_Buffer, offset in seconds.
Definition: Sound_Source.cpp:198
Zeni::Sound_Renderer_AL::alSourceStop
static alSourceStop_fcn alSourceStop()
Definition: Sound_Renderer_AL.h:105
Zeni::Time_HQ::update
void update()
Update to current Time.
Definition: Timer_HQ.hxx:47
ZENI_DEFAULT_PITCH
#define ZENI_DEFAULT_PITCH
Definition: Define.h:54
Zeni::Sound_Renderer_AL::alDeleteSources
static alDeleteSources_fcn alDeleteSources()
Definition: Sound_Renderer_AL.h:89
Zeni::Sound_Renderer_AL::alGetSourcei
static alGetSourcei_fcn alGetSourcei()
Definition: Sound_Renderer_AL.h:96
Zeni::Sound_Source_HW::stop
void stop()
Stop the Sound_Source_HW. (Essentially the same as pause but resets the current time.)
Definition: Sound_Source.cpp:389
AL_MAX_DISTANCE
#define AL_MAX_DISTANCE
Definition: al.h:309
init
static void init(struct bs2b *bs2b)
Definition: bs2b.c:46
Zeni::Sound_Source_HW_Init_Failure
Definition: Sound_Source.h:233
ALint
int ALint
Definition: al.h:56
AL_FALSE
#define AL_FALSE
Definition: al.h:83
AL_SOURCE_STATE
#define AL_SOURCE_STATE
Definition: al.h:235
Zeni::Sound_Renderer_AL::alSourcei
static alSourcei_fcn alSourcei()
Definition: Sound_Renderer_AL.h:102
Zeni::Sound::get_Renderer
Sound_Renderer & get_Renderer()
Get the current Sound_Renderer.
Definition: Sound.hxx:30
Zeni::Sound_Source_HW::STATE
STATE
Definition: Sound_Source.h:87
Zeni::Sound_Buffer::get_duration
const float & get_duration() const
Get the duration of the Sound_Buffer in seconds.
Definition: Sound_Buffer.h:102
Zeni::Sound_Source_HW::play
void play()
Begin playing or unpause the Sound_Source_HW.
Definition: Sound_Source.cpp:362
Zeni::Sound_Source::get_time
float get_time() const
Get the current position in the Sound_Buffer, offset in seconds.
Definition: Sound_Source.cpp:581
Zeni::Sound_Source_HW::PAUSED
Definition: Sound_Source.h:87
assert
#define assert(x)
Definition: SDL_malloc.c:1234
Zeni::Sound_Renderer_AL::alGetSourcef
static alGetSourcef_fcn alGetSourcef()
Definition: Sound_Renderer_AL.h:94
Undefine.h
Zeni::Sound_Source_HW::set_gain
void set_gain(const float &gain=ZENI_DEFAULT_GAIN)
Set the gain.
Definition: Sound_Source.cpp:144
ALfloat
float ALfloat
Definition: al.h:68
Zeni::Sound_Source_HW::set_reference_distance
void set_reference_distance(const float &reference_distance=ZENI_DEFAULT_REFERENCE_DISTANCE)
Definition: Sound_Source.cpp:215
AL_PAUSED
#define AL_PAUSED
Definition: al.h:240
ZENI_DEFAULT_GAIN
#define ZENI_DEFAULT_GAIN
Definition: Define.h:55
Zeni::Sound_Source_HW::set_looping
void set_looping(const bool &looping)
Set whether the Sound_Buffer should loop back to the start once it is done playing.
Definition: Sound_Source.cpp:181
AL_POSITION
#define AL_POSITION
Definition: al.h:144
Zeni::Sound_Renderer_AL::alSourcef
static alSourcef_fcn alSourcef()
Definition: Sound_Renderer_AL.h:100
Zeni::Sound_Source_HW::get_state
STATE get_state() const
Get PLAYING/PAUSED/STOPPED.
Definition: Sound_Source.cpp:402
Zeni::Sound_Source_HW::set_velocity
void set_velocity(const Vector3f &velocity)
Set the velocity of the Sound_Source_HW for the doppler effect.
Definition: Sound_Source.cpp:171
Zeni::Point3f
A 3D Point represented with floats.
Definition: Coordinate.h:133
ZENI_DEFAULT_MAX_SOUND_DISTANCE
#define ZENI_DEFAULT_MAX_SOUND_DISTANCE
Definition: Define.h:57
Zeni::Sound_Source_HW
Plays Sound Data.
Definition: Sound_Source.h:69
Zeni::Sound_Source_HW::set_max_distance
void set_max_distance(const float &max_distance=ZENI_DEFAULT_MAX_SOUND_DISTANCE)
Definition: Sound_Source.cpp:225
Zeni::Sound_Source_HW::get_velocity
Vector3f get_velocity() const
Get the velocity of the Sound_Buffer.
Definition: Sound_Source.cpp:295
buffer
EGLContext EGLenum EGLClientBuffer buffer
Definition: eglext.h:87
Zeni::get_Sound
Sound & get_Sound()
Get access to the singleton.
Definition: Sound.cpp:220
Zeni::Sound_Source_HW::get_rolloff
float get_rolloff() const
Definition: Sound_Source.cpp:354
Zeni::Sound_Source::Sound_Source
Sound_Source()
Definition: Sound_Source.cpp:529
Zeni::Vector3f
A Featureful 3-Space Vector Class.
Definition: Vector3f.h:58
AL_PLAYING
#define AL_PLAYING
Definition: al.h:239
AL_ROLLOFF_FACTOR
#define AL_ROLLOFF_FACTOR
Definition: al.h:286
Zeni::Sound_Source_HW::set_rolloff
void set_rolloff(const float &rolloff=ZENI_DEFAULT_ROLLOFF)
Definition: Sound_Source.cpp:235
Define.h
true
#define true
Definition: ftrandom.c:49
AL_LOOPING
#define AL_LOOPING
Definition: al.h:173
AL_PITCH
#define AL_PITCH
Definition: al.h:128
Zeni::Sound_Buffer::get_id
const ALuint & get_id() const
Get the OpenAL id of the Sound_Buffer.
Definition: Sound_Buffer.h:97
distance
GLsizei GLsizei GLfloat distance
Definition: glew.h:12423
Zeni::Sound_Renderer_AL::errorString
static String errorString()
Definition: Sound_Renderer_AL.cpp:214
ZENI_DEFAULT_REFERENCE_DISTANCE
#define ZENI_DEFAULT_REFERENCE_DISTANCE
Definition: Define.h:56
ALenum
int ALenum
Definition: al.h:65
ZENI_LOGD
void ZENI_LOGD(const Zeni::String &str)
Definition: Android.h:50
ALuint
unsigned int ALuint
Definition: al.h:59
AL_BUFFER
#define AL_BUFFER
Definition: al.h:182
Zeni::Sound_Buffer
Stores Sound Data.
Definition: Sound_Buffer.h:83
Zeni::Sound_Source_HW::get_reference_distance
float get_reference_distance() const
Definition: Sound_Source.cpp:338
ZENI_DEFAULT_ROLLOFF
#define ZENI_DEFAULT_ROLLOFF
Definition: Define.h:58
Zeni::Sound_Source::calculate_gain
float calculate_gain(const Point3f &listener_position) const
Get the actual volume gain, given gain+position+near_clamp+far_clamp+rolloff.
Definition: Sound_Source.cpp:611
Zeni::Sound_Source::~Sound_Source
~Sound_Source()
Definition: Sound_Source.cpp:576
Zeni::Sound_Renderer_AL::alSourcefv
static alSourcefv_fcn alSourcefv()
Definition: Sound_Renderer_AL.h:101
Zeni::Sound_Source::get_duration
float get_duration() const
Get the duration of the Sound_Buffer in seconds.
Definition: Sound_Source.hxx:63
Zeni::Sound_Renderer_AL::alSourcePlay
static alSourcePlay_fcn alSourcePlay()
Definition: Sound_Renderer_AL.h:104
Zeni::Sound_Source_HW::get_max_distance
float get_max_distance() const
Definition: Sound_Source.cpp:346
Zeni::Sound_Source_HW::is_looping
bool is_looping() const
Check to see if the Sound_Buffer is set to loop back to the start once it is done playing...
Definition: Sound_Source.cpp:303
AL_REFERENCE_DISTANCE
#define AL_REFERENCE_DISTANCE
Definition: al.h:274
Zeni::Sound_Source_HW::STOPPED
Definition: Sound_Source.h:87
Zeni::Sound_Source_HW::PLAYING
Definition: Sound_Source.h:87
Zeni::Sound_Source_HW::is_playing
bool is_playing() const
Check to see if the Sound_Source_HW is playing.
Definition: Sound_Source.cpp:425
Zeni::Sound
The Sound Singleton.
Definition: Sound.h:53
Zeni::Sound_Source_HW::set_position
void set_position(const Point3f &position)
Set the position of the Sound_Source_HW.
Definition: Sound_Source.cpp:161
ZENI_DEFAULT_SOUND_PRIORITY
#define ZENI_DEFAULT_SOUND_PRIORITY
Definition: Define.h:59
ids
GLuint * ids
Definition: gl2ext.h:1139
end
GLuint GLuint end
Definition: glew.h:1239
Zeni::Sound_Renderer_AL::alSourcePause
static alSourcePause_fcn alSourcePause()
Definition: Sound_Renderer_AL.h:103
Zeni::Sound_Source_HW::is_stopped
bool is_stopped() const
Check to see if the Sound_Source_HW is stopped.
Definition: Sound_Source.cpp:433
min
#define min(x, y)
Definition: os.h:75
vorbisfile.h
AL_GAIN
#define AL_GAIN
Definition: al.h:196
Zeni::Sound_Source_HW::is_paused
bool is_paused() const
Check to see if the Sound_Source_HW is paused.
Definition: Sound_Source.cpp:429
Zeni::Sound_Source_HW::get_gain
float get_gain() const
Get the gain.
Definition: Sound_Source.cpp:270
AL_SEC_OFFSET
#define AL_SEC_OFFSET
Definition: al.h:312
Zeni::Sound_Source_HW::pause
void pause()
Pause the Sound_Source_HW.
Definition: Sound_Source.cpp:376
Zeni::Time_HQ::get_seconds_since
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
max
#define max(x, y)
Definition: os.h:79
Zeni::Sound_Renderer_AL::alGenSources
static alGenSources_fcn alGenSources()
Definition: Sound_Renderer_AL.h:97
Zeni::Sound_Source_HW::get_position
Point3f get_position() const
Get the position of the Sound_Buffer.
Definition: Sound_Source.cpp:287
source
GLsizei GLsizei GLchar * source
Definition: gl2ext.h:994
zeni_audio.h
Zeni::Sound_Source_HW::set_pitch
void set_pitch(const float &pitch=ZENI_DEFAULT_PITCH)
Set the pitch.
Definition: Sound_Source.cpp:134
AL_VELOCITY
#define AL_VELOCITY
Definition: al.h:163
false
#define false
Definition: ftrandom.c:50
Zeni::Sound_Source_HW::get_time
float get_time() const
Get the current position in the Sound_Buffer, offset in seconds.
Definition: Sound_Source.cpp:321