| | 323 | #if USE_SDL |
| | 324 | |
| | 325 | #include "SDL.h" |
| | 326 | |
| | 327 | class SDLAudioSink : public osg::AudioSink |
| | 328 | { |
| | 329 | public: |
| | 330 | |
| | 331 | SDLAudioSink(osg::AudioStream* audioStream): |
| | 332 | _playing(false), |
| | 333 | _audioStream(audioStream) {} |
| | 334 | |
| | 335 | ~SDLAudioSink() |
| | 336 | { |
| | 337 | if (_playing) |
| | 338 | { |
| | 339 | |
| | 340 | SDL_PauseAudio(1); |
| | 341 | SDL_CloseAudio(); |
| | 342 | |
| | 343 | osg::notify(osg::NOTICE)<<"~SDLAudioSink() destructor, but still playing"<<std::endl; |
| | 344 | } |
| | 345 | } |
| | 346 | |
| | 347 | virtual void startPlaying() |
| | 348 | { |
| | 349 | _playing = true; |
| | 350 | osg::notify(osg::NOTICE)<<"SDLAudioSink()::startPlaying()"<<std::endl; |
| | 351 | |
| | 352 | osg::notify(osg::NOTICE)<<" audioFrequency()="<<_audioStream->audioFrequency()<<std::endl; |
| | 353 | osg::notify(osg::NOTICE)<<" audioNbChannels()="<<_audioStream->audioNbChannels()<<std::endl; |
| | 354 | osg::notify(osg::NOTICE)<<" audioSampleFormat()="<<_audioStream->audioSampleFormat()<<std::endl; |
| | 355 | |
| | 356 | SDL_AudioSpec specs = { 0 }; |
| | 357 | SDL_AudioSpec wanted_specs = { 0 }; |
| | 358 | |
| | 359 | wanted_specs.freq = _audioStream->audioFrequency(); |
| | 360 | wanted_specs.format = AUDIO_S16SYS; |
| | 361 | wanted_specs.channels = _audioStream->audioNbChannels(); |
| | 362 | wanted_specs.silence = 0; |
| | 363 | wanted_specs.samples = 1024; |
| | 364 | wanted_specs.callback = soundReadCallback; |
| | 365 | wanted_specs.userdata = this; |
| | 366 | |
| | 367 | if (SDL_OpenAudio(&wanted_specs, &specs) < 0) |
| | 368 | throw "SDL_OpenAudio() failed (" + std::string(SDL_GetError()) + ")"; |
| | 369 | |
| | 370 | SDL_PauseAudio(0); |
| | 371 | |
| | 372 | } |
| | 373 | virtual bool playing() const { return _playing; } |
| | 374 | |
| | 375 | static void soundReadCallback(void * user_data, uint8_t * data, int datalen); |
| | 376 | |
| | 377 | bool _playing; |
| | 378 | osg::observer_ptr<osg::AudioStream> _audioStream; |
| | 379 | }; |
| | 380 | |
| | 381 | |
| | 382 | void SDLAudioSink::soundReadCallback(void * const user_data, Uint8 * const data, const int datalen) |
| | 383 | { |
| | 384 | SDLAudioSink * sink = reinterpret_cast<SDLAudioSink*>(user_data); |
| | 385 | osg::ref_ptr<osg::AudioStream> as = sink->_audioStream.get(); |
| | 386 | if (as.valid()) |
| | 387 | { |
| | 388 | as->consumeAudioBuffer(data, datalen); |
| | 389 | } |
| | 390 | } |
| | 391 | |
| | 392 | #endif |
| | 393 | |