diff options
author | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2013-08-13 10:07:32 (GMT) |
---|---|---|
committer | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2013-08-13 10:07:32 (GMT) |
commit | 459f406eb2a36d393bd3a2b6aa3d63d86eb99c07 (patch) | |
tree | 35593bb978fee75bb7547f3d2c84a9039413fe1f /src/uscxml/plugins/invoker/audio | |
parent | beac3e74f703148085947d75da6fdaa9fd7472b4 (diff) | |
download | uscxml-459f406eb2a36d393bd3a2b6aa3d63d86eb99c07.zip uscxml-459f406eb2a36d393bd3a2b6aa3d63d86eb99c07.tar.gz uscxml-459f406eb2a36d393bd3a2b6aa3d63d86eb99c07.tar.bz2 |
Started Java datamodel and fixed memory leaks
Diffstat (limited to 'src/uscxml/plugins/invoker/audio')
-rw-r--r-- | src/uscxml/plugins/invoker/audio/AudioToolbox.h | 4 | ||||
-rw-r--r-- | src/uscxml/plugins/invoker/audio/LibSoundFile.cpp | 40 | ||||
-rw-r--r-- | src/uscxml/plugins/invoker/audio/LibSoundFile.h | 4 | ||||
-rw-r--r-- | src/uscxml/plugins/invoker/audio/OpenALInvoker.cpp | 77 | ||||
-rw-r--r-- | src/uscxml/plugins/invoker/audio/OpenALInvoker.h | 12 | ||||
-rw-r--r-- | src/uscxml/plugins/invoker/audio/OpenALPlayer.cpp | 16 | ||||
-rw-r--r-- | src/uscxml/plugins/invoker/audio/PCMConverter.h | 2 |
7 files changed, 81 insertions, 74 deletions
diff --git a/src/uscxml/plugins/invoker/audio/AudioToolbox.h b/src/uscxml/plugins/invoker/audio/AudioToolbox.h index 3e04d8f..6ad7390 100644 --- a/src/uscxml/plugins/invoker/audio/AudioToolbox.h +++ b/src/uscxml/plugins/invoker/audio/AudioToolbox.h @@ -5,7 +5,7 @@ #include <AudioToolbox/AudioToolbox.h> namespace uscxml { - + class AudioToolbox : public PCMConverter { public: AudioToolbox(const std::string filename); @@ -20,7 +20,7 @@ protected: ExtAudioFileRef _afId; AudioStreamBasicDescription _outputFormat; AudioStreamBasicDescription _inputFormat; - + ALenum formatToALEnum(AudioStreamBasicDescription); bool alEnumToFormat(AudioStreamBasicDescription&, ALenum); }; diff --git a/src/uscxml/plugins/invoker/audio/LibSoundFile.cpp b/src/uscxml/plugins/invoker/audio/LibSoundFile.cpp index 1340140..26d3328 100644 --- a/src/uscxml/plugins/invoker/audio/LibSoundFile.cpp +++ b/src/uscxml/plugins/invoker/audio/LibSoundFile.cpp @@ -7,39 +7,39 @@ LibSoundFile::LibSoundFile(const std::string filename) : PCMConverter() { _handle = SndfileHandle(_filename, SFM_READ, SF_FORMAT_PCM_16, 1, 44100); _format.sampleRate = _handle.samplerate(); _format.alFormat = AL_FORMAT_MONO16; - + } LibSoundFile::~LibSoundFile() { - + } void LibSoundFile::seek(unsigned int pos) { - _handle.seek(pos, 0); + _handle.seek(pos, 0); } int LibSoundFile::read(char* buffer, unsigned int size) { - return _handle.readRaw(buffer, size); + return _handle.readRaw(buffer, size); } - + void LibSoundFile::setOutFormat(const PCMFormat& format) { _format = format; switch (_format.alFormat) { - case AL_FORMAT_MONO8: - _handle = SndfileHandle(_filename, SFM_READ, SF_FORMAT_PCM_S8, 1, _format.sampleRate); - break; - case AL_FORMAT_MONO16: - _handle = SndfileHandle(_filename, SFM_READ, SF_FORMAT_PCM_16, 1, _format.sampleRate); - break; - case AL_FORMAT_STEREO8: - _handle = SndfileHandle(_filename, SFM_READ, SF_FORMAT_PCM_S8, 2, _format.sampleRate); - break; - case AL_FORMAT_STEREO16: - _handle = SndfileHandle(_filename, SFM_READ, SF_FORMAT_PCM_16, 2, _format.sampleRate); - break; - - default: - break; + case AL_FORMAT_MONO8: + _handle = SndfileHandle(_filename, SFM_READ, SF_FORMAT_PCM_S8, 1, _format.sampleRate); + break; + case AL_FORMAT_MONO16: + _handle = SndfileHandle(_filename, SFM_READ, SF_FORMAT_PCM_16, 1, _format.sampleRate); + break; + case AL_FORMAT_STEREO8: + _handle = SndfileHandle(_filename, SFM_READ, SF_FORMAT_PCM_S8, 2, _format.sampleRate); + break; + case AL_FORMAT_STEREO16: + _handle = SndfileHandle(_filename, SFM_READ, SF_FORMAT_PCM_16, 2, _format.sampleRate); + break; + + default: + break; } } diff --git a/src/uscxml/plugins/invoker/audio/LibSoundFile.h b/src/uscxml/plugins/invoker/audio/LibSoundFile.h index 5491609..0d740f6 100644 --- a/src/uscxml/plugins/invoker/audio/LibSoundFile.h +++ b/src/uscxml/plugins/invoker/audio/LibSoundFile.h @@ -5,14 +5,14 @@ #include <sndfile.hh> namespace uscxml { - + class LibSoundFile : public PCMConverter { public: LibSoundFile(const std::string filename); virtual ~LibSoundFile(); void seek(unsigned int pos); int read(char* buffer, unsigned int size); - + virtual void setOutFormat(const PCMFormat& format); virtual PCMFormat getInFormat(); diff --git a/src/uscxml/plugins/invoker/audio/OpenALInvoker.cpp b/src/uscxml/plugins/invoker/audio/OpenALInvoker.cpp index cf9d15a..6b52c8c 100644 --- a/src/uscxml/plugins/invoker/audio/OpenALInvoker.cpp +++ b/src/uscxml/plugins/invoker/audio/OpenALInvoker.cpp @@ -1,6 +1,6 @@ -// see http://stackoverflow.com/questions/6563810/m-pi-works-with-math-h-but-not-with-cmath-in-visual-studio
-#define _USE_MATH_DEFINES
-#include <cmath>
+// see http://stackoverflow.com/questions/6563810/m-pi-works-with-math-h-but-not-with-cmath-in-visual-studio +#define _USE_MATH_DEFINES +#include <cmath> #include "OpenALInvoker.h" #include <uscxml/config.h> @@ -20,13 +20,12 @@ bool connect(pluma::Host& host) { return true; } #endif -
-// see http://stackoverflow.com/questions/1904635/warning-c4003-and-errors-c2589-and-c2059-on-x-stdnumeric-limitsintmax
+ +// see http://stackoverflow.com/questions/1904635/warning-c4003-and-errors-c2589-and-c2059-on-x-stdnumeric-limitsintmax #undef max OpenALInvoker::OpenALInvoker() { _isStarted = false; - _isRunning = false; _alContext = NULL; _alDevice = NULL; _thread = NULL; @@ -34,13 +33,14 @@ OpenALInvoker::OpenALInvoker() { OpenALInvoker::~OpenALInvoker() { if (_thread) { - _isRunning = false; + _isStarted = false; + _sourcesAvailable.notify_all(); _thread->join(); delete(_thread); } if (_alContext) { - alcCloseDevice(alcGetContextsDevice(_alContext)); - alcDestroyContext(_alContext); +// alcCloseDevice(alcGetContextsDevice(_alContext)); +// alcDestroyContext(_alContext); } }; @@ -57,15 +57,15 @@ Data OpenALInvoker::getDataModelVariables() { void OpenALInvoker::send(const SendRequest& req) { tthread::lock_guard<tthread::recursive_mutex> lock(_mutex); - + if (!_isStarted) start(); - + if (boost::iequals(req.name, "play")) { if (req.params.find("src") == req.params.end()) { LOG(ERROR) << "Sent event play with no src URL"; } - + URL srcURL = req.params.find("src")->second; if (!srcURL.toAbsolute(_interpreter->getBaseURI())) { LOG(ERROR) << "src URL " << req.params.find("src")->second << " is relative with no base URI set for interpreter"; @@ -87,12 +87,12 @@ void OpenALInvoker::send(const SendRequest& req) { _sources.erase(req.sendid); return; } - + // force mono format to ensure actual spatial audio PCMFormat format = _sources[req.sendid]->transform->getInFormat(); format.alFormat = AL_FORMAT_MONO16; _sources[req.sendid]->transform->setOutFormat(format); - + try { _sources[req.sendid]->player = new OpenALPlayer(_alContext, NULL, format.alFormat, format.sampleRate); } catch (std::exception ex) { @@ -108,10 +108,9 @@ void OpenALInvoker::send(const SendRequest& req) { returnErrorExecution(ex.what()); } - _sourcesAvailable.notify_all(); } - + if (boost::iequals(req.name, "move.source")) { std::string sourceId; if (req.params.find("source") == req.params.end()) { @@ -119,12 +118,12 @@ void OpenALInvoker::send(const SendRequest& req) { return; } sourceId = req.params.find("source")->second; - + if (_sources.find(sourceId) == _sources.end()) { LOG(WARNING) << "Given source '" << sourceId << "' not active or not existing"; return; } - + getPosFromParams(req.params, _sources[sourceId]->pos); try { _sources[sourceId]->player->setPosition(_sources[sourceId]->pos); @@ -145,12 +144,16 @@ void OpenALInvoker::fillBuffers(void* userdata) { // do nothing until we have at least one source int waitMs = std::numeric_limits<int>::max(); INST->_mutex.lock(); - while (INST->_sources.size() == 0) { + while (INST->_sources.size() == 0 && INST->_isStarted) { INST->_sourcesAvailable.wait(INST->_mutex); } + + if (!INST->_isStarted) + return; + // here we are with at least one source and a locked mutex assert(INST->_sources.size() > 0); - + std::map<std::string, OpenALSource*>::iterator srcIter = INST->_sources.begin(); while(srcIter != INST->_sources.end()) { OpenALSource* src = srcIter->second; @@ -195,7 +198,7 @@ void OpenALInvoker::fillBuffers(void* userdata) { } } } - + // there are unwritten samples in the buffer if (src->read != src->written) { try { @@ -211,15 +214,16 @@ void OpenALInvoker::fillBuffers(void* userdata) { assert(src->finished); } } - + waitMs = (wait < waitMs ? wait : waitMs); srcIter++; } - + // std::cout << "W" << waitMs << "."; - + INST->_mutex.unlock(); - tthread::this_thread::sleep_for(tthread::chrono::milliseconds(waitMs)); + if (waitMs < std::numeric_limits<int>::max()) + tthread::this_thread::sleep_for(tthread::chrono::milliseconds(waitMs)); } } @@ -233,14 +237,17 @@ void OpenALInvoker::invoke(const InvokeRequest& req) { if (_alDevice == NULL) { throw std::string("__FILE__ __LINE__ openal error opening device"); } - + // create new context with device _alContext = alcCreateContext (_alDevice, NULL); if (_alContext == NULL) { alcCloseDevice (_alDevice); throw std::string("openal error create context"); } - + + std::cout << boost::lexical_cast<std::string>(_alContext); + std::cout << boost::lexical_cast<std::string>(_alDevice); + // alcMakeContextCurrent(_alContext); // float listener[3] = {0,0,0}; // alListenerfv(AL_POSITION, listener); @@ -257,7 +264,7 @@ void OpenALInvoker::invoke(const InvokeRequest& req) { start(); } - + void OpenALInvoker::notifyOfEnd(OpenALSource* src) { Event ev; ev.name = "audio.end"; @@ -284,7 +291,7 @@ void OpenALInvoker::getPosFromParams(const std::multimap<std::string, std::strin } catch (boost::bad_lexical_cast& e) { LOG(ERROR) << "Cannot interpret x, y or z as float value in params: " << e.what(); } - + try { // right is an alias for x if (params.find("right") != params.end()) @@ -298,7 +305,7 @@ void OpenALInvoker::getPosFromParams(const std::multimap<std::string, std::strin } catch (boost::bad_lexical_cast& e) { LOG(ERROR) << "Cannot interpret right, height or front as float value in params: " << e.what(); } - + // do we have a position on a circle? try { if (params.find("circle") != params.end()) { @@ -307,24 +314,24 @@ void OpenALInvoker::getPosFromParams(const std::multimap<std::string, std::strin position[2] = -1 * sinf(rad); // z axis increases to front position[0] *= 150; position[2] *= 150; - + } } catch (boost::bad_lexical_cast& e) { LOG(ERROR) << "Cannot interpret circle as float value in params: " << e.what(); } - + // position[0] = position[0] / _maxPos[0]; // position[1] = position[1] / _maxPos[1]; // position[2] = position[2] / _maxPos[2]; // std::cout << _pos[0] << ":" << _pos[1] << ":" << _pos[2] << std::endl; - + } float OpenALInvoker::posToRadian(const std::string& pos) { - + std::string trimmedPos = boost::trim_copy(pos); float rad = 0; - + if (trimmedPos.size() > 3 && boost::iequals("deg", trimmedPos.substr(trimmedPos.length() - 3, 3))) { rad = boost::lexical_cast<float>(trimmedPos.substr(0, trimmedPos.size() - 3)); rad = fmodf(rad, 360); // into range [0-360] diff --git a/src/uscxml/plugins/invoker/audio/OpenALInvoker.h b/src/uscxml/plugins/invoker/audio/OpenALInvoker.h index c0ed842..086bfe8 100644 --- a/src/uscxml/plugins/invoker/audio/OpenALInvoker.h +++ b/src/uscxml/plugins/invoker/audio/OpenALInvoker.h @@ -24,7 +24,7 @@ class OpenALSource { public: OpenALSource(); ~OpenALSource(); - + OpenALPlayer* player; char buffer[ALPLAY_AUDIO_BUFFER_SIZE]; bool loop; @@ -35,7 +35,7 @@ public: URL file; PCMConverter* transform; }; - + class OpenALInvoker : public InvokerImpl { public: OpenALInvoker(); @@ -49,7 +49,7 @@ public: names.insert("http://uscxml.tk.informatik.tu-darmstadt.de/#openal"); return names; } - + virtual Data getDataModelVariables(); virtual void send(const SendRequest& req); virtual void cancel(const std::string sendId); @@ -59,20 +59,20 @@ protected: std::map<std::string, OpenALSource*> _sources; ALCcontext* _alContext; ALCdevice* _alDevice; - + tthread::recursive_mutex _mutex; tthread::thread* _thread; tthread::condition_variable _sourcesAvailable; bool _isStarted; bool _isRunning; - + static void fillBuffers(void* userdata); void start(); void notifyOfEnd(OpenALSource*); void notifyOfLoop(OpenALSource*); - + float posToRadian(const std::string& pos); void getPosFromParams(const std::multimap<std::string, std::string>& params, float* position); diff --git a/src/uscxml/plugins/invoker/audio/OpenALPlayer.cpp b/src/uscxml/plugins/invoker/audio/OpenALPlayer.cpp index 4266f79..a5f90b8 100644 --- a/src/uscxml/plugins/invoker/audio/OpenALPlayer.cpp +++ b/src/uscxml/plugins/invoker/audio/OpenALPlayer.cpp @@ -17,11 +17,11 @@ OpenALPlayer::OpenALPlayer(ALCcontext* context, OpenALPlayerCallback* audioCallb _nrBuffers = 0; _thread = NULL; _alId = 0; - + _position[0] = _position[1] = _position[2] = 0; _velocity[0] = _velocity[1] = _velocity[2] = 0; _direction[0] = _direction[1] = _direction[2] = 0; - + tthread::lock_guard<tthread::recursive_mutex> lock(_alMutex); if (context == NULL) { // this is in essence alutInit() from freealut. @@ -143,7 +143,7 @@ void OpenALPlayer::init() { // get available buffer ids tthread::lock_guard<tthread::recursive_mutex> lock(_alMutex); - + if (!alcMakeContextCurrent (_context)) { throw std::runtime_error("openal error make context current"); } @@ -153,7 +153,7 @@ void OpenALPlayer::init() { // get new source id from openAL alGenSources(1, &_alId); - + checkOpenALError(__LINE__); if (!alIsSource(_alId)) { throw std::runtime_error("openal source id not valid"); @@ -254,7 +254,7 @@ int OpenALPlayer::write(char* buffer, int size, int* repollAt, bool blocking) { if (!alcMakeContextCurrent (_context)) { throw std::runtime_error("openal error make context current"); } - + // try to enqueue the given buffer data for (;;) { // do we have an empty buffer in the OpenAL queue? @@ -264,7 +264,7 @@ int OpenALPlayer::write(char* buffer, int size, int* repollAt, bool blocking) { // if (!isPlaying()) // std::cout << "-"; - + if (processed > 0) { // std::cout << "P" << processed; ALuint bufferId = 0; @@ -308,7 +308,7 @@ int OpenALPlayer::write(char* buffer, int size, int* repollAt, bool blocking) { // there was a free buffer, repoll immediately to try to write more if (repollAt) *repollAt = 0; - + break; } else { // std::cout << "X"; @@ -330,7 +330,7 @@ int OpenALPlayer::write(char* buffer, int size, int* repollAt, bool blocking) { checkOpenALError(__LINE__); _isStarted = true; } - + return size; } diff --git a/src/uscxml/plugins/invoker/audio/PCMConverter.h b/src/uscxml/plugins/invoker/audio/PCMConverter.h index 6036af2..df367f8 100644 --- a/src/uscxml/plugins/invoker/audio/PCMConverter.h +++ b/src/uscxml/plugins/invoker/audio/PCMConverter.h @@ -18,7 +18,7 @@ public: virtual ~PCMConverter() {} virtual void seek(unsigned int pos) = 0; virtual int read(char* buffer, unsigned int size) = 0; - + virtual void setOutFormat(const PCMFormat& format) = 0; virtual PCMFormat getInFormat() = 0; protected: |