Added SDL audio support for reading from ffmpeg movies

This commit is contained in:
Robert Osfield 2009-03-03 17:37:48 +00:00
parent 325fe37a6a
commit b678c8ca85
2 changed files with 66 additions and 8 deletions

View File

@ -1,9 +1,16 @@
# INCLUDE_DIRECTORIES( ${OPENAL_INCLUDE_DIR} )
# SET(TARGET_EXTERNAL_LIBRARIES ${OPENAL_LIBRARY} alut)
IF (SDL_FOUND)
SET(TARGET_EXTERNAL_LIBRARIES ${SDL_LIBRARY} )
INCLUDE_DIRECTORIES(${SDL_INCLUDE_DIR} )
ADD_DEFINITIONS(-DUSE_SDL)
ENDIF(SDL_FOUND)
SET(TARGET_SRC osgmovie.cpp )
SET(TARGET_ADDED_LIBRARIES osgGA )
# SET(TARGET_EXTERNAL_LIBRARIES ${OPENAL_LIBRARY} alut)
#### end var setup ###
SETUP_EXAMPLE(osgmovie)

View File

@ -320,30 +320,79 @@ osg::Geometry* myCreateTexturedQuadGeometry(const osg::Vec3& pos,float width,flo
}
}
class CustomAudioSink : public osg::AudioSink
#if USE_SDL
#include "SDL.h"
class SDLAudioSink : public osg::AudioSink
{
public:
CustomAudioSink(osg::AudioStream* audioStream):
SDLAudioSink(osg::AudioStream* audioStream):
_playing(false),
_audioStream(audioStream) {}
~SDLAudioSink()
{
if (_playing)
{
SDL_PauseAudio(1);
SDL_CloseAudio();
osg::notify(osg::NOTICE)<<"~SDLAudioSink() destructor, but still playing"<<std::endl;
}
}
virtual void startPlaying()
{
_playing = true;
osg::notify(osg::NOTICE)<<"CustomAudioSink()::startPlaying()"<<std::endl;
osg::notify(osg::NOTICE)<<"SDLAudioSink()::startPlaying()"<<std::endl;
osg::notify(osg::NOTICE)<<" audioFrequency()="<<_audioStream->audioFrequency()<<std::endl;
osg::notify(osg::NOTICE)<<" audioNbChannels()="<<_audioStream->audioNbChannels()<<std::endl;
osg::notify(osg::NOTICE)<<" audioSampleFormat()="<<_audioStream->audioSampleFormat()<<std::endl;
SDL_AudioSpec specs = { 0 };
SDL_AudioSpec wanted_specs = { 0 };
wanted_specs.freq = _audioStream->audioFrequency();
wanted_specs.format = AUDIO_S16SYS;
wanted_specs.channels = _audioStream->audioNbChannels();
wanted_specs.silence = 0;
wanted_specs.samples = 1024;
wanted_specs.callback = soundReadCallback;
wanted_specs.userdata = this;
if (SDL_OpenAudio(&wanted_specs, &specs) < 0)
throw "SDL_OpenAudio() failed (" + std::string(SDL_GetError()) + ")";
SDL_PauseAudio(0);
}
virtual bool playing() const { return _playing; }
static void soundReadCallback(void * user_data, uint8_t * data, int datalen);
bool _playing;
osg::observer_ptr<osg::AudioStream> _audioStream;
};
void SDLAudioSink::soundReadCallback(void * const user_data, Uint8 * const data, const int datalen)
{
osg::notify(osg::NOTICE)<<"SDLAudioSink::soundReadCallback"<<std::endl;
SDLAudioSink * sink = reinterpret_cast<SDLAudioSink*>(user_data);
osg::ref_ptr<osg::AudioStream> as = sink->_audioStream.get();
if (as.valid())
{
as->consumeAudioBuffer(data, datalen);
}
}
#endif
int main(int argc, char** argv)
{
// use an ArgumentParser object to manage the program arguments.
@ -450,8 +499,8 @@ int main(int argc, char** argv)
bool xyPlane = fullscreen;
bool useOpenALAudio = false;
while(arguments.read("--OpenAL")) { useOpenALAudio = true; }
bool useAudioSink = false;
while(arguments.read("--audio")) { useAudioSink = true; }
for(int i=1;i<arguments.argc();++i)
{
@ -462,11 +511,13 @@ int main(int argc, char** argv)
if (imagestream)
{
osg::ImageStream::AudioStreams& audioStreams = imagestream->getAudioStreams();
if (useOpenALAudio && !audioStreams.empty())
if (useAudioSink && !audioStreams.empty())
{
osg::AudioStream* audioStream = audioStreams[0].get();
osg::notify(osg::NOTICE)<<"AudioStream read ["<<audioStream->getName()<<"]"<<std::endl;
audioStream->setAudioSink(new CustomAudioSink(audioStream));
#if USE_SDL
audioStream->setAudioSink(new SDLAudioSink(audioStream));
#endif
}