Revision: 7275
http://playerstage.svn.sourceforge.net/playerstage/?rev=7275&view=rev
Author: natepak
Date: 2009-01-16 04:32:09 +0000 (Fri, 16 Jan 2009)
Log Message:
-----------
Added audio_video directory
Modified Paths:
--------------
code/gazebo/trunk/server/SConscript
code/gazebo/trunk/server/rendering/UserCamera.cc
Added Paths:
-----------
code/gazebo/trunk/server/audio_video/
code/gazebo/trunk/server/audio_video/AudioDecoder.cc
code/gazebo/trunk/server/audio_video/AudioDecoder.hh
code/gazebo/trunk/server/audio_video/OpenAL.cc
code/gazebo/trunk/server/audio_video/OpenAL.hh
code/gazebo/trunk/server/audio_video/SConscript
Modified: code/gazebo/trunk/server/SConscript
===================================================================
--- code/gazebo/trunk/server/SConscript 2009-01-15 23:15:17 UTC (rev 7274)
+++ code/gazebo/trunk/server/SConscript 2009-01-16 04:32:09 UTC (rev 7275)
@@ -1,7 +1,7 @@
#Import variables
Import('env install_prefix sharedObjs headers')
-dirs = Split('physics rendering sensors controllers gui')# bindings')
+dirs = Split('physics rendering sensors controllers gui audio_video')#
bindings')
for subdir in dirs:
SConscript('%s/SConscript' % subdir)
Added: code/gazebo/trunk/server/audio_video/AudioDecoder.cc
===================================================================
--- code/gazebo/trunk/server/audio_video/AudioDecoder.cc
(rev 0)
+++ code/gazebo/trunk/server/audio_video/AudioDecoder.cc 2009-01-16
04:32:09 UTC (rev 7275)
@@ -0,0 +1,173 @@
+#include <stdlib.h>
+#include <string.h>
+
+#include "AudioDecoder.hh"
+
+bool AudioDecoder::initialized = false;
+
+////////////////////////////////////////////////////////////////////////////////
+/// Constructor
+AudioDecoder::AudioDecoder()
+{
+ this->formatCtx = NULL;
+ this->codecCtx = NULL;
+ this->codec = NULL;
+ this->audioStream = 0;
+
+ // Initialize the ffmpeg library only once
+ if (!initialized)
+ {
+ initialized = true;
+ avcodec_init();
+ avcodec_register_all();
+
+ // Register all formats and codecs
+ av_register_all();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Destructor
+AudioDecoder::~AudioDecoder()
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Decode and audio file
+int AudioDecoder::Decode(uint8_t **outBuffer, unsigned int *outBufferSize)
+{
+ AVPacket packet;
+ char tmpBuf[AVCODEC_MAX_AUDIO_FRAME_SIZE];
+ int tmpBufsize = 0;
+ int bytesDecoded = 0;
+ unsigned int maxBufferSize = 0;
+
+ if (this->codec == NULL)
+ {
+ printf("Set and audio file before decoding.\n");
+ return -1;
+ }
+
+ if (outBufferSize == NULL)
+ {
+ printf("outBufferSize is NULL!!\n");
+ return -1;
+ }
+
+ *outBufferSize = 0;
+
+ if (*outBuffer)
+ {
+ delete [] *outBuffer;
+ *outBuffer = NULL;
+ }
+
+ // Read the next frame of a stream
+ while (av_read_frame(this->formatCtx, &packet) >=0)
+ {
+ if (packet.stream_index == this->audioStream)
+ {
+ tmpBufsize = sizeof(tmpBuf);
+
+ // Decode the frame
+ bytesDecoded = avcodec_decode_audio2( this->codecCtx, (int16_t*)tmpBuf,
+ &tmpBufsize, packet.data, packet.size );
+
+ if (bytesDecoded < 0)
+ {
+ printf("Error decoding audio\n");
+ return -1;
+ }
+
+ if (tmpBufsize <= 0)
+ {
+ printf("No data yet\n");
+ return -1;
+ }
+
+ // Resize the audio buffer as necessary
+ if (*outBufferSize + tmpBufsize > maxBufferSize)
+ {
+ maxBufferSize += tmpBufsize * 10;
+ *outBuffer = (uint8_t*)realloc(*outBuffer,
+ maxBufferSize * sizeof(*outBuffer[0]) );
+ }
+
+ memcpy(*outBuffer + *outBufferSize, tmpBuf, tmpBufsize);
+ *outBufferSize += tmpBufsize;
+ }
+ }
+
+ av_free_packet(&packet);
+
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Get the sample rate from the latest decoded file
+int AudioDecoder::GetSampleRate()
+{
+ return this->codecCtx->sample_rate;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Helper function to read in an audio file
+int AudioDecoder::SetFile(const std::string &filename)
+{
+ unsigned int i;
+
+ // Open file
+ if (av_open_input_file(&this->formatCtx, filename.c_str(), NULL, 0, NULL) !=
0)
+ {
+ printf("Unable to open input file\n");
+ return -1;
+ }
+
+ // Retrieve some information
+ if (av_find_stream_info(this->formatCtx) < 0)
+ {
+ printf("Unable to find stream info\n");
+ return -1;
+ }
+
+ // Dump information about file onto standard error
+ //dump_format(formatCtx, 0, "dump.txt", false);
+
+ // Find audio stream;
+ this->audioStream = -1;
+ for (i=0; i < this->formatCtx->nb_streams; i++)
+ {
+ if (this->formatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO)
+ {
+ this->audioStream = i;
+ break;
+ }
+ }
+
+ if (this->audioStream == -1)
+ {
+ printf("Couldn't find audio stream\n");
+ return -1;
+ }
+
+ // Get the audio stream codec
+ this->codecCtx = this->formatCtx->streams[audioStream]->codec;
+
+ // Find a decoder
+ this->codec = avcodec_find_decoder(codecCtx->codec_id);
+
+ if (this->codec == NULL)
+ {
+ perror("couldn't find codec");
+ return -1;
+ }
+
+ if (this->codec->capabilities & CODEC_CAP_TRUNCATED)
+ this->codecCtx->flags |= CODEC_FLAG_TRUNCATED;
+
+ // Open codec
+ if (avcodec_open(this->codecCtx, this->codec) < 0)
+ perror("couldn't open codec");
+
+ return 0;
+}
Added: code/gazebo/trunk/server/audio_video/AudioDecoder.hh
===================================================================
--- code/gazebo/trunk/server/audio_video/AudioDecoder.hh
(rev 0)
+++ code/gazebo/trunk/server/audio_video/AudioDecoder.hh 2009-01-16
04:32:09 UTC (rev 7275)
@@ -0,0 +1,40 @@
+#ifndef AUDIODECODER_HH
+#define AUDIODECODER_HH
+
+extern "C" {
+#include <libavformat/avformat.h>
+#include <libavcodec/avcodec.h>
+}
+
+#include <string>
+
+class AudioDecoder
+{
+ /// \brief Constructor
+ public: AudioDecoder();
+
+ /// \brief Destructor
+ public: virtual ~AudioDecoder();
+
+ /// \brief Set the file to decode
+ public: int SetFile(const std::string &filename);
+
+ /// \brief Decode and audio file
+ public: int Decode(uint8_t **outBuffer, unsigned int *outBufferSize);
+
+ /// \brief Get the sample rate from the latest decoded file
+ public: int GetSampleRate();
+
+ private: AVFormatContext *formatCtx;
+ private: AVCodecContext *codecCtx;
+
+ // libavcodec audio codec
+ private: AVCodec *codec;
+
+ // Index of the audio stream
+ private: int audioStream;
+
+ private: static bool initialized;
+};
+
+#endif
Added: code/gazebo/trunk/server/audio_video/OpenAL.cc
===================================================================
--- code/gazebo/trunk/server/audio_video/OpenAL.cc
(rev 0)
+++ code/gazebo/trunk/server/audio_video/OpenAL.cc 2009-01-16 04:32:09 UTC
(rev 7275)
@@ -0,0 +1,396 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <iostream>
+
+#include <AL/alut.h>
+#include <AL/alc.h>
+
+#include "AudioDecoder.hh"
+#include "OpenAL.hh"
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+
+////////////////////////////////////////////////////////////////////////////////
+///// Constructor
+OpenAL::OpenAL()
+{
+ this->context = NULL;
+ this->audioDevice = NULL;
+
+ this->pos[0] = this->pos[1] = this->pos[2] = 0.0;
+ this->pos[0] = -10.0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Destructor
+OpenAL::~OpenAL()
+{
+ if (this->context && this->audioDevice)
+ {
+ this->context = alcGetCurrentContext();
+ this->audioDevice = alcGetContextsDevice(this->context);
+ alcMakeContextCurrent(NULL);
+ alcDestroyContext(this->context);
+ alcCloseDevice(this->audioDevice);
+ }
+
+ this->sources.clear();
+ this->buffers.clear();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Initialize
+int OpenAL::Init()
+{
+ // Open the default audio device
+ this->audioDevice = alcOpenDevice("ALSA Software on HDA Intel");
+ if (this->audioDevice == NULL)
+ {
+ printf("Unable to open audio device\n");
+ return -1;
+ }
+
+ this->context = alcCreateContext(this->audioDevice, NULL);
+
+ alcMakeContextCurrent(this->context);
+
+ //Clear error code
+ alGetError();
+
+ // TODO: put in function to set distance model
+ //alDistanceModel(AL_EXPONENT_DISTANCE);
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Create a sound source
+unsigned int OpenAL::CreateSource()
+{
+ unsigned int source;
+
+ //Create 1 source
+ alGenSources(1, &source);
+
+ this->sources.push_back(source);
+
+ return this->sources.size()-1;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Create an audio data buffer
+unsigned int OpenAL::CreateBuffer(const std::string &audioFile)
+{
+ unsigned int buffer;
+ uint8_t *dataBuffer = NULL;
+ unsigned int dataBufferSize;
+
+ // Create an audio decoder
+ AudioDecoder audioDecoder;
+
+ // Create and openAL audio buffer
+ alGenBuffers(1, &buffer);
+
+ // Store the openAL buffer
+ this->buffers.push_back(buffer);
+
+ // Set the audio file to decode
+ audioDecoder.SetFile(audioFile);
+ audioDecoder.Decode(&dataBuffer, &dataBufferSize);
+
+ // Fill the openAL data buffer
+ this->SetData(buffer, dataBuffer, dataBufferSize,
+ audioDecoder.GetSampleRate() );
+
+ if (dataBuffer)
+ delete [] dataBuffer;
+
+ return this->buffers.size()-1;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+/// Update all the sources and the listener
+void OpenAL::Update()
+{
+ //ALfloat pos[3];
+ ALfloat vel[3];
+
+ //for (int i=0; i< this->sourceCount; i++)
+ {
+
+ //alGetSourcefv(0, AL_VELOCITY, vel);
+ //alGetSourcefv(0, AL_POSITION, pos);
+
+ vel[0] = 0.1;
+ vel[1] = 0.0;
+ vel[2] = 0.0;
+
+ this->pos[0] += 0.01;
+ this->pos[1] = 0;
+ this->pos[2] = 0;
+
+ //printf("p[%f %f %f] v[%f %f %f]\n", pos[0], pos[1], pos[2], vel[0],
vel[1], vel[2]);
+ this->SetSourcePos(0, this->pos[0], this->pos[1], this->pos[2] );
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Set the data
+int OpenAL::SetData(unsigned int index, uint8_t *data, unsigned int dataSize,
unsigned int freq)
+{
+ // Clear the error buffer;
+ alGetError();
+
+ printf("Set Data Freq[%d] DataSize[%d]\n",freq, dataSize);
+
+ // Copy raw buffer into AL buffer 0
+ // AL_FORMAT_MONO8, AL_FORMAT_MONO16, AL_FORMAT_STEREO8,
+ // AL_FORMAT_STEREO16
+ alBufferData( this->buffers[0], AL_FORMAT_MONO16, data, dataSize, freq);
+
+ if ( alGetError() != AL_NO_ERROR)
+ {
+ printf("Unable to copy data into openAL buffer\n");
+
+ alDeleteBuffers(1, &this->buffers[index]);
+ return -1;
+ }
+
+
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// \brief Attach a buffer to a source
+int OpenAL::SetSourceBuffer(unsigned int sourceIndex, unsigned int bufferIndex)
+{
+ if (sourceIndex >= this->sources.size())
+ {
+ std::cerr << "Invalid source index\n";
+ return -1;
+ }
+
+ if (bufferIndex >= this->buffers.size())
+ {
+ std::cerr << "Invalid buffer index\n";
+ return -1;
+ }
+
+ // Buffer data must be set before calling this function
+
+ // Attach buffer to source
+ alSourcei(this->sources[sourceIndex], AL_BUFFER, this->buffers[bufferIndex]
);
+
+ if ((this->error = alGetError()) != AL_NO_ERROR)
+ {
+ std::cerr << "OpenAL SetSourceBuffer Error: [%d]\n" << this->error << "\n";
+ return -1;
+ }
+
+
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Play the source
+void OpenAL::Play( unsigned int index )
+{
+ // Play the source
+ alSourcePlay( this->sources[index] );
+
+
+ // Wait until finished
+ /*ALint state;
+ do
+ {
+ usleep(100000);
+ alGetSourcei(this->sources[index], AL_SOURCE_STATE, &state);
+ } while ( state == AL_PLAYING);
+ */
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Set the listener position
+int OpenAL::SetListenerPos( float x, float y, float z )
+{
+ // Clear error state
+ alGetError();
+
+ alListener3f(AL_POSITION, x, y, z);
+
+ if ((this->error = alGetError()) != AL_NO_ERROR)
+ {
+ std::cerr << "OpenAL SetListenerPos Error: [%d]\n" << this->error << "\n";
+ return -1;
+ }
+
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Set the listener velocity
+int OpenAL::SetListenerVel( float x, float y, float z )
+{
+ // Clear error state
+ alGetError();
+
+ alListener3f(AL_VELOCITY, x, y, z);
+ if ((this->error = alGetError()) != AL_NO_ERROR)
+ {
+ std::cerr << "OpenAL SetListenerVel Error: [%d]" << this->error << "\n";
+ return -1;
+ }
+
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Set the listener orientation
+int OpenAL::SetListenerOrient( float cx, float cy, float cz,
+ float ux, float uy, float uz )
+{
+ ALfloat orient[]={cx, cy, cz, ux, uy, uz};
+
+ // Clear error state
+ alGetError();
+
+ alListenerfv( AL_ORIENTATION, orient );
+
+ if ((this->error = alGetError()) != AL_NO_ERROR)
+ {
+ std::cerr << "OpenAL SetListenerOrientation Error: [%d]" << this->error <<
"\n";
+ return -1;
+ }
+
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Set the position of the source
+int OpenAL::SetSourcePos(unsigned int index, float x, float y, float z)
+{
+ ALfloat p[3] = {x, y, z};
+
+ if (index >= this->sources.size())
+ {
+ std::cerr << "Invalid source index[" << index <<" ]\n";
+ return -1;
+ }
+
+ // Clear error state
+ alGetError();
+
+ alSourcefv( this->sources[index], AL_POSITION, p);
+
+ if ((this->error = alGetError()) != AL_NO_ERROR)
+ {
+ std::cerr << "OpenAL::SetSourcePos Error: [%d]" << this->error << "\n";
+ return -1;
+ }
+
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Set the position of the source
+int OpenAL::SetSourceVel(unsigned int index, float x, float y, float z)
+{
+ ALfloat v[3] = {x, y, z};
+
+ if (index >= this->sources.size())
+ {
+ std::cerr << "Invalid source index[" << index <<" ]\n";
+ return -1;
+ }
+
+ // Clear error state
+ alGetError();
+
+ alSourcefv( this->sources[index], AL_VELOCITY, v);
+
+ if ((this->error = alGetError()) != AL_NO_ERROR)
+ {
+ std::cerr << "OpenAL::SetSourceVel Error: [%d]" << this->error << "\n";
+ return -1;
+ }
+
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Set the pitch of the source
+int OpenAL::SetSourcePitch(unsigned int index, float p)
+{
+ if (index >= this->sources.size())
+ {
+ std::cerr << "Invalid source index[" << index <<" ]\n";
+ return -1;
+ }
+
+ // clear error state
+ alGetError();
+
+ alSourcef(this->sources[index], AL_PITCH, p);
+
+ if ((this->error = alGetError()) != AL_NO_ERROR)
+ {
+ std::cerr << "OpenAL::SetSourcePitch Error: [%d]\n" << this->error;
+ return -1;
+ }
+
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Set the pitch of the source
+int OpenAL::SetSourceGain(unsigned int index, float g)
+{
+ if (index >= this->sources.size())
+ {
+ std::cerr << "Invalid source index[" << index <<" ]\n";
+ return -1;
+ }
+
+ // clear error state
+ alGetError();
+
+ alSourcef(this->sources[index], AL_GAIN, g);
+
+ if ((this->error = alGetError()) != AL_NO_ERROR)
+ {
+ std::cerr << "OpenAL::SetSourceGain Error: [%d]\n" << this->error;
+ return -1;
+ }
+
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Set whether the source loops the audio
+int OpenAL::SetSourceLoop(unsigned int index, bool state)
+{
+ if (index >= this->sources.size())
+ {
+ std::cerr << "Invalid source index[" << index <<" ]\n";
+ return -1;
+ }
+
+ // clear error state
+ alGetError();
+
+ // Set looping state
+ alSourcei(this->sources[index], AL_LOOPING, state);
+
+ if ((this->error = alGetError()) != AL_NO_ERROR)
+ {
+ std::cerr << "OpenAL::SetSourceLoop Error: [%d]\n" << this->error << "\n";
+ return -1;
+ }
+
+
+ return 0;
+}
Added: code/gazebo/trunk/server/audio_video/OpenAL.hh
===================================================================
--- code/gazebo/trunk/server/audio_video/OpenAL.hh
(rev 0)
+++ code/gazebo/trunk/server/audio_video/OpenAL.hh 2009-01-16 04:32:09 UTC
(rev 7275)
@@ -0,0 +1,81 @@
+#ifndef OPENAL_HH
+#define OPENAL_HH
+
+#include <AL/al.h>
+#include <AL/alc.h>
+#include <AL/alext.h>
+#include <stdint.h>
+
+#include <deque>
+
+
+class OpenAL
+{
+ /// \brief Constructor
+ public: OpenAL();
+
+ /// \brief Destructor
+ public: virtual ~OpenAL();
+
+ /// \brief Initialize
+ public: int Init();
+
+ /// \brief Update all the sources and the listener
+ public: void Update();
+
+ /// \brief Create a sound source
+ public: unsigned int CreateSource();
+
+ /// \brief Create an audio data buffer
+ public: unsigned int CreateBuffer(const std::string &audioFile);
+
+ /// \brief Set the data
+ public: int SetData(unsigned int index, uint8_t *data, unsigned int
dataSize, unsigned int freq);
+
+ /// \brief Attach a buffer to a source
+ public: int SetSourceBuffer(unsigned int sourceIndex, unsigned int
bufferIndex);
+
+ /// \brief Play a sound
+ public: void Play(unsigned int source);
+
+ /// \brief Set the listener position
+ public: int SetListenerPos( float x, float y, float z );
+
+ /// \brief Set the listener velocity
+ public: int SetListenerVel( float x, float y, float z );
+
+ /// \brief Set the listener orientation
+ public: int SetListenerOrient(float cx, float cy, float cz,
+ float ux, float uy, float uz);
+
+ /// \brief Set the position of the source
+ public: int SetSourcePos(unsigned int index, float x, float y, float z);
+
+ /// \brief Set the position of the source
+ public: int SetSourceVel(unsigned int index, float x, float y, float z);
+
+ /// \brief Set the pitch of the source
+ public: int SetSourcePitch(unsigned int index, float p);
+
+ /// \brief Set the pitch of the source
+ public: int SetSourceGain(unsigned int index, float g);
+
+ /// \brief Set whether the source loops the audio
+ public: int SetSourceLoop(unsigned int index, bool state);
+
+ private: ALCcontext *context;
+ private: ALCdevice *audioDevice;
+
+ // OpenAL error code
+ private: ALenum error;
+
+ // Audio sources.
+ private: std::deque<unsigned int> sources;
+
+ // Audio data buffers
+ private: std::deque<unsigned int> buffers;
+
+ private: ALfloat pos[3];
+};
+
+#endif
Added: code/gazebo/trunk/server/audio_video/SConscript
===================================================================
--- code/gazebo/trunk/server/audio_video/SConscript
(rev 0)
+++ code/gazebo/trunk/server/audio_video/SConscript 2009-01-16 04:32:09 UTC
(rev 7275)
@@ -0,0 +1,41 @@
+#Import variable
+Import('env sharedObjs headers')
+
+parseConfigs = [
+ 'pkg-config --cflags --libs libavformat',
+ 'pkg-config --cflags --libs libavcodec',
+ 'pkg-config --cflags --libs openal',
+ 'pkg-config --cflags --libs freealut'
+]
+
+myEnv = env.Clone()
+
+sources = ['AudioDecoder.cc',
+ 'OpenAL.cc'
+ ]
+
+headers.append(
+ ['server/audio_video/AudioDecoder.hh',
+ 'server/audio_video/OpenAL.hh',
+ ] )
+#
+# Parse all the pacakge configurations
+#
+if not myEnv.GetOption('clean'):
+ for cfg in parseConfigs:
+ print "Checking for ["+cfg+"]"
+ try:
+ myEnv.ParseConfig(cfg)
+ print " Success"
+ except OSError,e:
+ print "Unable to parse config ["+cfg+"]"
+ if cfg.find("OpenAL") >= 0:
+ print "OpenAL not found. 3D audio is disabled."
+ print " http://connect.creativelabs.com/"
+ Exit(1)
+ if cfg.find("avcodec") >= 0 or cfg.find("avformat") >= 0:
+ print "FFMpeg not found. Audio decoding disabled."
+ print " http://ffmpeg.mplayerhq.hu/"
+ Exit(1)
+
+myEnv.SharedLibrary('gazeboav', sources)
Modified: code/gazebo/trunk/server/rendering/UserCamera.cc
===================================================================
--- code/gazebo/trunk/server/rendering/UserCamera.cc 2009-01-15 23:15:17 UTC
(rev 7274)
+++ code/gazebo/trunk/server/rendering/UserCamera.cc 2009-01-16 04:32:09 UTC
(rev 7275)
@@ -65,7 +65,7 @@
{
OgreCamera::LoadCam(node);
- this->SetClipDist(0.1, 100);
+ this->SetClipDist(0.1, 50);
this->SetFOV( DTOR(60) );
}
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
This SF.net email is sponsored by:
SourcForge Community
SourceForge wants to tell your story.
http://p.sf.net/sfu/sf-spreadtheword
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit