24 #define openal_audio_debug(x) \
25 audio_debug("OpenALAudioSound \""<<get_name() \
28 #define openal_audio_debug(x) ((void)0)
50 _positional(positional),
52 _max_dist(1000000000.0f),
53 _drop_off_factor(1.0f),
59 _basename(movie->get_filename().get_basename()),
60 _active(manager->get_active()),
72 if (!require_sound_data()) {
77 _length = _sd->_length;
79 if (_sd->_channels != 1) {
80 audio_warning(
"stereo sound " << movie->
get_filename() <<
" will not be spatialized");
83 release_sound_data(
false);
99 void OpenALAudioSound::
108 if (has_sound_data()) {
109 release_sound_data(
true);
111 _manager->release_sound(
this);
122 if (!is_valid())
return;
124 PN_stdfloat px,py,pz,vx,vy,vz;
133 if (!require_sound_data()) {
138 _manager->starting_sound(
this);
143 _manager->make_current();
149 alSourcei(_source,AL_SOURCE_RELATIVE,_positional?AL_FALSE:AL_TRUE);
150 al_audio_errcheck(
"alSourcei(_source,AL_SOURCE_RELATIVE)");
162 _playing_loops = _loop_count;
163 if (_playing_loops == 0) {
164 _playing_loops = 1000000000;
166 _loops_completed = 0;
168 double play_rate = _play_rate * _manager->get_play_rate();
169 audio_debug(
"playing. Rate=" << play_rate);
170 alSourcef(_source, AL_PITCH, play_rate);
171 _playing_rate = play_rate;
174 push_fresh_buffers();
175 alSourcef(_source, AL_SEC_OFFSET, _start_time);
176 _stream_queued[0]._time_offset = _start_time;
177 restart_stalled_audio();
179 audio_debug(
"Play: stream tell = " << _sd->_stream->tell() <<
" seeking " << _start_time);
180 if (_sd->_stream->tell() != _start_time) {
181 _sd->_stream->seek(_start_time);
183 push_fresh_buffers();
184 restart_stalled_audio();
187 set_calibrated_clock(rtc, _start_time, 1.0);
188 _current_time = _start_time;
199 if (!is_valid())
return;
202 _manager->make_current();
204 nassertv(has_sound_data());
207 alSourceStop(_source);
208 al_audio_errcheck(
"stopping a source");
209 alSourcei(_source, AL_BUFFER, 0);
210 al_audio_errcheck(
"clear source buffers");
211 for (
int i=0; i<((int)(_stream_queued.size())); i++) {
212 ALuint buffer = _stream_queued[i]._buffer;
213 if (buffer != _sd->_sample) {
214 _manager->delete_buffer(buffer);
217 _stream_queued.resize(0);
222 _manager->stopping_sound(
this);
223 release_sound_data(
false);
229 void OpenALAudioSound::
233 if (!is_valid())
return;
236 _current_time = _length;
237 if (!_finished_event.empty()) {
238 throw_event(_finished_event);
248 set_loop_count((loop)?0:1);
256 return (_loop_count == 0);
262 void OpenALAudioSound::
263 set_loop_count(
unsigned long loop_count) {
266 if (!is_valid())
return;
268 if (loop_count >= 1000000000) {
271 _loop_count=loop_count;
289 void OpenALAudioSound::
290 restart_stalled_audio() {
294 if (!is_valid())
return;
295 nassertv(is_playing());
297 if (_stream_queued.size() == 0) {
302 alGetSourcei(_source, AL_SOURCE_STATE, &
status);
303 if (
status != AL_PLAYING) {
304 alSourcePlay(_source);
311 void OpenALAudioSound::
312 queue_buffer(ALuint buffer,
int samples,
int loop_index,
double time_offset) {
315 nassertv(is_playing());
319 alSourceQueueBuffers(_source,1,&buffer);
320 ALenum err = alGetError();
321 if (err != AL_NO_ERROR) {
322 audio_error(
"could not load sample buffer into the queue");
327 buf._buffer = buffer;
328 buf._samples = samples;
329 buf._loop_index = loop_index;
330 buf._time_offset = time_offset;
331 _stream_queued.push_back(buf);
337 ALuint OpenALAudioSound::
338 make_buffer(
int samples,
int channels,
int rate,
unsigned char *data) {
341 nassertr(is_playing(), 0);
346 alGenBuffers(1, &buffer);
347 if (alGetError() != AL_NO_ERROR) {
348 audio_error(
"could not allocate an OpenAL buffer object");
355 (channels>1) ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16,
356 data, samples * channels * 2, rate);
357 int err = alGetError();
358 if (err != AL_NO_ERROR) {
359 audio_error(
"could not fill OpenAL buffer object with data");
371 int OpenALAudioSound::
372 read_stream_data(
int bytelen,
unsigned char *buffer) {
375 nassertr(has_sound_data(), 0);
378 double length = cursor->length();
379 int channels = cursor->audio_channels();
380 int rate = cursor->audio_rate();
381 int space = bytelen / (channels * 2);
384 while (space && (_loops_completed < _playing_loops)) {
385 double t = cursor->tell();
386 double remain =
length - t;
390 int samples = (int)(remain * rate);
392 _loops_completed += 1;
396 if (_sd->_stream->ready() == 0) {
397 if (_sd->_stream->aborted()) {
398 _loops_completed = _playing_loops;
402 if (samples > space) {
405 if (samples > _sd->_stream->ready()) {
406 samples = _sd->_stream->ready();
410 audio_debug(
"Streaming " << cursor->get_source()->get_name() <<
" at " << t <<
" hash " << hval);
413 buffer += (samples * channels * 2);
424 void OpenALAudioSound::
425 correct_calibrated_clock(
double rtc,
double t) {
428 nassertv(is_playing());
430 double cc = (rtc - _calibrated_clock_base) * _calibrated_clock_scale;
432 _calibrated_clock_decavg = (_calibrated_clock_decavg * 0.95) + (diff * 0.05);
434 set_calibrated_clock(rtc, t, 1.0);
435 _calibrated_clock_decavg = 0.0;
438 if ((_calibrated_clock_decavg > 0.01) && (diff > 0.01)) {
441 if ((_calibrated_clock_decavg < -0.01) && (diff < -0.01)) {
444 if ((_calibrated_clock_decavg < -0.05) && (diff < -0.05)) {
447 if ((_calibrated_clock_decavg < -0.15) && (diff < -0.15)) {
450 set_calibrated_clock(rtc, cc, scale);
452 cc = (rtc - _calibrated_clock_base) * _calibrated_clock_scale;
458 void OpenALAudioSound::
459 pull_used_buffers() {
462 if (!is_valid())
return;
463 nassertv(is_playing());
464 nassertv(has_sound_data());
466 while (_stream_queued.size()) {
468 ALint num_buffers = 0;
469 alGetSourcei(_source, AL_BUFFERS_PROCESSED, &num_buffers);
470 if (num_buffers <= 0) {
473 alSourceUnqueueBuffers(_source, 1, &buffer);
474 int err = alGetError();
475 if (err == AL_NO_ERROR) {
476 if (_stream_queued[0]._buffer != buffer) {
481 bool found_culprit =
false;
482 for (
auto it = _stream_queued.begin(); it != _stream_queued.end(); ++it) {
483 if (it->_buffer == buffer) {
485 _stream_queued.erase(it);
486 found_culprit =
true;
490 if (!found_culprit) {
491 audio_error(
"corruption in stream queue");
496 _stream_queued.pop_front();
497 if (_stream_queued.size()) {
498 double al = _stream_queued[0]._time_offset + _stream_queued[0]._loop_index * _length;
500 correct_calibrated_clock(rtc, al);
502 if (buffer != _sd->_sample) {
503 _manager->delete_buffer(buffer);
516 void OpenALAudioSound::
517 push_fresh_buffers() {
519 static unsigned char data[65536];
521 if (!is_valid())
return;
522 nassertv(is_playing());
523 nassertv(has_sound_data());
526 while ((_loops_completed < _playing_loops) &&
527 (_stream_queued.size() < 100)) {
528 queue_buffer(_sd->_sample, 0,_loops_completed, 0.0);
529 _loops_completed += 1;
533 int channels = cursor->audio_channels();
534 int rate = cursor->audio_rate();
537 for (
size_t i = 0; i < _stream_queued.size(); i++) {
538 fill += _stream_queued[i]._samples;
541 while ((_loops_completed < _playing_loops) &&
542 (fill < (
int)(audio_buffering_seconds * rate * channels))) {
543 int loop_index = _loops_completed;
544 double time_offset = cursor->tell();
545 int samples = read_stream_data(65536, data);
549 ALuint buffer = make_buffer(samples, channels, rate, data);
550 if (!is_valid() || !buffer)
return;
551 queue_buffer(buffer, samples, loop_index, time_offset);
552 if (!is_valid())
return;
577 return _current_time;
583 void OpenALAudioSound::
584 cache_time(
double rtc) {
587 nassertv(is_playing());
589 double t=get_calibrated_clock(rtc);
590 double max = _length * _playing_loops;
592 _current_time = _length;
594 _current_time = fmod(t, _length);
607 volume*=_manager->get_volume();
608 _manager->make_current();
610 alSourcef(_source,AL_GAIN,volume);
611 al_audio_errcheck(
"alSourcef(_source,AL_GAIN)");
628 audio_debug(
"OpenALAudioSound::set_balance() not implemented");
637 audio_debug(
"OpenALAudioSound::get_balance() not implemented");
649 _play_rate = play_rate;
651 alSourcef(_source, AL_PITCH, play_rate);
658 PN_stdfloat OpenALAudioSound::
659 get_play_rate()
const {
682 set_3d_attributes(PN_stdfloat px, PN_stdfloat py, PN_stdfloat pz, PN_stdfloat vx, PN_stdfloat vy, PN_stdfloat vz) {
693 _manager->make_current();
696 alSourcefv(_source,AL_POSITION,_location);
697 al_audio_errcheck(
"alSourcefv(_source,AL_POSITION)");
698 alSourcefv(_source,AL_VELOCITY,_velocity);
699 al_audio_errcheck(
"alSourcefv(_source,AL_VELOCITY)");
708 get_3d_attributes(PN_stdfloat *px, PN_stdfloat *py, PN_stdfloat *pz, PN_stdfloat *vx, PN_stdfloat *vy, PN_stdfloat *vz) {
729 _manager->make_current();
732 alSourcef(_source,AL_REFERENCE_DISTANCE,_min_dist);
733 al_audio_errcheck(
"alSourcefv(_source,AL_REFERENCE_DISTANCE)");
754 _manager->make_current();
757 alSourcef(_source,AL_MAX_DISTANCE,_max_dist);
758 al_audio_errcheck(
"alSourcefv(_source,AL_MAX_DISTANCE)");
776 _drop_off_factor = factor;
779 _manager->make_current();
782 alSourcef(_source,AL_ROLLOFF_FACTOR,_drop_off_factor*_manager->audio_3d_get_drop_off_factor());
783 al_audio_errcheck(
"alSourcefv(_source,AL_ROLLOFF_FACTOR)");
792 return _drop_off_factor;
804 if (!is_valid())
return;
806 if (_active!=active) {
810 if (_paused && _loop_count==0) {
819 if (_loop_count==0) {
840 void OpenALAudioSound::
841 set_finished_event(
const std::string& event) {
842 _finished_event = event;
848 const std::string& OpenALAudioSound::
849 get_finished_event()
const {
850 return _finished_event;
870 return AudioSound::READY;
872 if ((_loops_completed >= _playing_loops)&&(_stream_queued.size()==0)) {
873 return AudioSound::READY;
875 return AudioSound::PLAYING;