summaryrefslogtreecommitdiffstats
path: root/src/uscxml/plugins/invoker/audio
diff options
context:
space:
mode:
authorStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-08-13 10:07:32 (GMT)
committerStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-08-13 10:07:32 (GMT)
commit459f406eb2a36d393bd3a2b6aa3d63d86eb99c07 (patch)
tree35593bb978fee75bb7547f3d2c84a9039413fe1f /src/uscxml/plugins/invoker/audio
parentbeac3e74f703148085947d75da6fdaa9fd7472b4 (diff)
downloaduscxml-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.h4
-rw-r--r--src/uscxml/plugins/invoker/audio/LibSoundFile.cpp40
-rw-r--r--src/uscxml/plugins/invoker/audio/LibSoundFile.h4
-rw-r--r--src/uscxml/plugins/invoker/audio/OpenALInvoker.cpp77
-rw-r--r--src/uscxml/plugins/invoker/audio/OpenALInvoker.h12
-rw-r--r--src/uscxml/plugins/invoker/audio/OpenALPlayer.cpp16
-rw-r--r--src/uscxml/plugins/invoker/audio/PCMConverter.h2
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: