diff options
author | Stefan Radomski <github@mintwerk.de> | 2016-05-12 13:12:33 (GMT) |
---|---|---|
committer | Stefan Radomski <github@mintwerk.de> | 2016-05-12 13:12:33 (GMT) |
commit | b62e7979600feee23dc7cdb61042a8fc7673122b (patch) | |
tree | f7351372f37979dd2d048e0b68a16a4cd3b2aadb /src/uscxml/plugins/invoker/audio | |
parent | 1b11b310be61e51b3ac5ebb83f7c8a33aef3d6e8 (diff) | |
download | uscxml-b62e7979600feee23dc7cdb61042a8fc7673122b.zip uscxml-b62e7979600feee23dc7cdb61042a8fc7673122b.tar.gz uscxml-b62e7979600feee23dc7cdb61042a8fc7673122b.tar.bz2 |
Major Refactoring v2.0
Diffstat (limited to 'src/uscxml/plugins/invoker/audio')
-rw-r--r-- | src/uscxml/plugins/invoker/audio/AudioToolbox.h | 51 | ||||
-rw-r--r-- | src/uscxml/plugins/invoker/audio/AudioToolbox.mm | 185 | ||||
-rw-r--r-- | src/uscxml/plugins/invoker/audio/LibSoundFile.cpp | 69 | ||||
-rw-r--r-- | src/uscxml/plugins/invoker/audio/LibSoundFile.h | 46 | ||||
-rw-r--r-- | src/uscxml/plugins/invoker/audio/OpenALInvoker.cpp | 421 | ||||
-rw-r--r-- | src/uscxml/plugins/invoker/audio/OpenALInvoker.h | 111 | ||||
-rw-r--r-- | src/uscxml/plugins/invoker/audio/OpenALPlayer.cpp | 541 | ||||
-rw-r--r-- | src/uscxml/plugins/invoker/audio/OpenALPlayer.h | 125 | ||||
-rw-r--r-- | src/uscxml/plugins/invoker/audio/PCMConverter.h | 49 |
9 files changed, 0 insertions, 1598 deletions
diff --git a/src/uscxml/plugins/invoker/audio/AudioToolbox.h b/src/uscxml/plugins/invoker/audio/AudioToolbox.h deleted file mode 100644 index 5834f34..0000000 --- a/src/uscxml/plugins/invoker/audio/AudioToolbox.h +++ /dev/null @@ -1,51 +0,0 @@ -/** - * @file - * @author 2012-2013 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) - * @copyright Simplified BSD - * - * @cond - * This program is free software: you can redistribute it and/or modify - * it under the terms of the FreeBSD license as published by the FreeBSD - * project. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of the FreeBSD license along with this - * program. If not, see <http://www.opensource.org/licenses/bsd-license>. - * @endcond - */ - -#ifndef AUDIOTOOLBOX_H_GX4SW17C -#define AUDIOTOOLBOX_H_GX4SW17C - -#include "PCMConverter.h" -#include <AudioToolbox/AudioToolbox.h> - -namespace uscxml { - -class AudioToolbox : public PCMConverter { -public: - AudioToolbox(const std::string filename); - virtual ~AudioToolbox(); - virtual void seek(unsigned int pos); - virtual int read(char* buffer, unsigned int size); - - virtual void setOutFormat(const PCMFormat& format); - virtual PCMFormat getInFormat(); - -protected: - ExtAudioFileRef _afId; - AudioStreamBasicDescription _outputFormat; - AudioStreamBasicDescription _inputFormat; - - ALenum formatToALEnum(AudioStreamBasicDescription); - bool alEnumToFormat(AudioStreamBasicDescription&, ALenum); -}; - -} - -#endif /* end of include guard: AUDIOTOOLBOX_H_GX4SW17C */ - - diff --git a/src/uscxml/plugins/invoker/audio/AudioToolbox.mm b/src/uscxml/plugins/invoker/audio/AudioToolbox.mm deleted file mode 100644 index ef99063..0000000 --- a/src/uscxml/plugins/invoker/audio/AudioToolbox.mm +++ /dev/null @@ -1,185 +0,0 @@ -/** - * @file - * @author 2012-2013 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) - * @copyright Simplified BSD - * - * @cond - * This program is free software: you can redistribute it and/or modify - * it under the terms of the FreeBSD license as published by the FreeBSD - * project. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of the FreeBSD license along with this - * program. If not, see <http://www.opensource.org/licenses/bsd-license>. - * @endcond - */ - -#include "AudioToolbox.h" -#include <glog/logging.h> - -#import <Foundation/Foundation.h> -#import <Foundation/NSURL.h> - -#ifdef __has_feature -# if __has_feature(objc_arc) -# define(HAS_AUTORELEASE_POOL) -# endif -#endif - -namespace uscxml { - -AudioToolbox::AudioToolbox(const std::string filename) { -#if HAS_AUTORELEASE_POOL - @autoreleasepool { -#else - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; -#endif - _afId = 0; - NSString* filePath = [NSString stringWithCString:filename.c_str() encoding:NSASCIIStringEncoding]; - NSURL* afUrl = [NSURL fileURLWithPath:filePath]; - - OSStatus result = noErr; - - result = ExtAudioFileOpenURL((CFURLRef)afUrl, &_afId); - - if (result != noErr) { - LOG(WARNING) << "Cannot open audio file " << filename; - return; - } - UInt32 thePropertySize = sizeof(_inputFormat); - result = ExtAudioFileGetProperty(_afId, kExtAudioFileProperty_FileDataFormat, &thePropertySize, &_inputFormat); - if (result != noErr) { - LOG(WARNING) << "Cannot determine input format of " << filename; - return; - } - - // output format is input format - memcpy(&_outputFormat, &_inputFormat, sizeof(_inputFormat)); - - // except for things that make no sense for open al - _outputFormat.mFormatID = kAudioFormatLinearPCM; - _outputFormat.mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger; - - ALenum bestFormat = formatToALEnum(_outputFormat); - alEnumToFormat(_outputFormat, bestFormat); - - result = ExtAudioFileSetProperty(_afId, kExtAudioFileProperty_ClientDataFormat, sizeof(_outputFormat), &_outputFormat); - - if (result != noErr) { - LOG(WARNING) << "Cannot set audio format file " << filename; - return; - } - -#if HAS_AUTORELEASE_POOL - } -#else - [pool drain]; -#endif -} - -AudioToolbox::~AudioToolbox() { - if (_afId) - ExtAudioFileDispose(_afId); //close the file -} - -void AudioToolbox::seek(unsigned int pos) { - ExtAudioFileSeek(_afId, pos); -} - -int AudioToolbox::read(char* buffer, unsigned int size) { - UInt32 read = size / _outputFormat.mBytesPerFrame; - OSStatus result = noErr; - - SInt64 theFileLengthInFrames = 0; - UInt32 thePropertySize = sizeof(theFileLengthInFrames); - result = ExtAudioFileGetProperty(_afId, kExtAudioFileProperty_FileLengthFrames, &thePropertySize, &theFileLengthInFrames); - - read = (theFileLengthInFrames < read ? theFileLengthInFrames : read); - - AudioBufferList dataBuffer; - dataBuffer.mNumberBuffers = 1; - dataBuffer.mBuffers[0].mDataByteSize = size; - dataBuffer.mBuffers[0].mNumberChannels = _outputFormat.mChannelsPerFrame; - dataBuffer.mBuffers[0].mData = buffer; - - result = ExtAudioFileRead(_afId, &read, &dataBuffer); - if (result != noErr) { - LOG(WARNING) << "Cannot read data"; - return 0; - } - - return read * _outputFormat.mBytesPerFrame; -} - -ALenum AudioToolbox::formatToALEnum(AudioStreamBasicDescription asbd) { - if (asbd.mBitsPerChannel < 16) { - if (asbd.mChannelsPerFrame == 1) { - return AL_FORMAT_MONO8; - } else { - return AL_FORMAT_STEREO8; - } - } else { - if (asbd.mChannelsPerFrame == 1) { - return AL_FORMAT_MONO16; - } else { - return AL_FORMAT_STEREO16; - } - } -} - -bool AudioToolbox::alEnumToFormat(AudioStreamBasicDescription& asbd, ALenum format) { - switch (format) { - case AL_FORMAT_MONO8: - asbd.mBitsPerChannel = 8; - asbd.mBytesPerFrame = 1; - asbd.mBytesPerPacket = 1; - asbd.mChannelsPerFrame = 1; - break; - case AL_FORMAT_MONO16: - asbd.mBitsPerChannel = 16; - asbd.mBytesPerFrame = 2; - asbd.mBytesPerPacket = 2; - asbd.mChannelsPerFrame = 1; - break; - case AL_FORMAT_STEREO8: - asbd.mBitsPerChannel = 8; - asbd.mBytesPerFrame = 2; - asbd.mBytesPerPacket = 2; - asbd.mChannelsPerFrame = 2; - break; - case AL_FORMAT_STEREO16: - asbd.mBitsPerChannel = 16; - asbd.mBytesPerFrame = 4; - asbd.mBytesPerPacket = 4; - asbd.mChannelsPerFrame = 2; - break; - default: - break; - } - return true; -} - -void AudioToolbox::setOutFormat(const PCMFormat& format) { - - alEnumToFormat(_outputFormat, format.alFormat); - _outputFormat.mSampleRate = format.sampleRate; - - OSStatus result = ExtAudioFileSetProperty(_afId, kExtAudioFileProperty_ClientDataFormat, sizeof(_outputFormat), &_outputFormat); - if (result != noErr) { - LOG(WARNING) << "Cannot set audio format"; - return; - } - -} - -PCMFormat AudioToolbox::getInFormat() { - PCMFormat format; - format.sampleRate = _inputFormat.mSampleRate; - format.alFormat = formatToALEnum(_inputFormat); - return format; -} - -}
\ No newline at end of file diff --git a/src/uscxml/plugins/invoker/audio/LibSoundFile.cpp b/src/uscxml/plugins/invoker/audio/LibSoundFile.cpp deleted file mode 100644 index b881e41..0000000 --- a/src/uscxml/plugins/invoker/audio/LibSoundFile.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/** - * @file - * @author 2012-2013 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) - * @copyright Simplified BSD - * - * @cond - * This program is free software: you can redistribute it and/or modify - * it under the terms of the FreeBSD license as published by the FreeBSD - * project. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of the FreeBSD license along with this - * program. If not, see <http://www.opensource.org/licenses/bsd-license>. - * @endcond - */ - -#include "LibSoundFile.h" - -namespace uscxml { - -LibSoundFile::LibSoundFile(const std::string filename) : PCMConverter() { - _filename = filename; - _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); -} - -int LibSoundFile::read(char* buffer, unsigned int 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; - } -} - -PCMFormat LibSoundFile::getInFormat() { - return _format; -} - -}
\ No newline at end of file diff --git a/src/uscxml/plugins/invoker/audio/LibSoundFile.h b/src/uscxml/plugins/invoker/audio/LibSoundFile.h deleted file mode 100644 index 0e0b304..0000000 --- a/src/uscxml/plugins/invoker/audio/LibSoundFile.h +++ /dev/null @@ -1,46 +0,0 @@ -/** - * @file - * @author 2012-2013 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) - * @copyright Simplified BSD - * - * @cond - * This program is free software: you can redistribute it and/or modify - * it under the terms of the FreeBSD license as published by the FreeBSD - * project. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of the FreeBSD license along with this - * program. If not, see <http://www.opensource.org/licenses/bsd-license>. - * @endcond - */ - -#ifndef LIBSOUNDFILE_H_Q97OEKGG -#define LIBSOUNDFILE_H_Q97OEKGG - -#include "PCMConverter.h" -#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(); - -protected: - std::string _filename; - SndfileHandle _handle; - PCMFormat _format; -}; - -} - -#endif /* end of include guard: LIBSOUNDFILE_H_Q97OEKGG */ diff --git a/src/uscxml/plugins/invoker/audio/OpenALInvoker.cpp b/src/uscxml/plugins/invoker/audio/OpenALInvoker.cpp deleted file mode 100644 index e813f2f..0000000 --- a/src/uscxml/plugins/invoker/audio/OpenALInvoker.cpp +++ /dev/null @@ -1,421 +0,0 @@ -/** - * @file - * @author 2012-2013 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) - * @copyright Simplified BSD - * - * @cond - * This program is free software: you can redistribute it and/or modify - * it under the terms of the FreeBSD license as published by the FreeBSD - * project. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of the FreeBSD license along with this - * program. If not, see <http://www.opensource.org/licenses/bsd-license>. - * @endcond - */ - -// 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 <boost/algorithm/string.hpp> - -#include "OpenALInvoker.h" -#include <uscxml/config.h> -#include <glog/logging.h> -#include <limits.h> - -#ifdef BUILD_AS_PLUGINS -#include <Pluma/Connector.hpp> -#endif - -namespace uscxml { - -#ifdef BUILD_AS_PLUGINS -PLUMA_CONNECTOR -bool pluginConnect(pluma::Host& host) { - host.add( new OpenALInvokerProvider() ); - return true; -} -#endif - -// see http://stackoverflow.com/questions/1904635/warning-c4003-and-errors-c2589-and-c2059-on-x-stdnumeric-limitsintmax -#undef max - -OpenALInvoker::OpenALInvoker() { - _isStarted = false; - _alContext = NULL; - _alDevice = NULL; - _thread = NULL; - _listenerPos[0] = _listenerPos[1] = _listenerPos[2] = 0; - _listenerVel[0] = _listenerVel[1] = _listenerVel[2] = 0; - _maxPos[0] = _maxPos[1] = _maxPos[2] = 1; - - _listenerOrient[0] = _listenerOrient[1] = _listenerOrient[3] = _listenerOrient[5] = 0; - _listenerOrient[2] = _listenerOrient[4] = 1.0; -} - -OpenALInvoker::~OpenALInvoker() { - if (_thread) { - _isStarted = false; - _sourcesAvailable.notify_all(); - _thread->join(); - delete(_thread); - } - if (_alContext) { -// alcCloseDevice(alcGetContextsDevice(_alContext)); -// alcDestroyContext(_alContext); - } -}; - -boost::shared_ptr<InvokerImpl> OpenALInvoker::create(InterpreterImpl* interpreter) { - boost::shared_ptr<OpenALInvoker> invoker = boost::shared_ptr<OpenALInvoker>(new OpenALInvoker()); - invoker->_interpreter = interpreter; - return invoker; -} - -Data OpenALInvoker::getDataModelVariables() { - Data data; - return data; -} - -void OpenALInvoker::send(const SendRequest& req) { - tthread::lock_guard<tthread::recursive_mutex> lock(_mutex); - - if (!_isStarted) - start(); - - if (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.atom; - if (!srcURL.toAbsolute(_interpreter->getBaseURL(req.elem))) { - LOG(ERROR) << "src URL " << req.params.find("src")->second << " is relative with no base URI set for interpreter"; - return; - } - - _sources[req.sendid] = new OpenALSource(); - _sources[req.sendid]->loop = req.params.find("loop") != req.params.end() && iequals(req.params.find("loop")->second.atom, "true"); - _sources[req.sendid]->file = srcURL; -#ifdef LIBSNDFILE_FOUND - _sources[req.sendid]->transform = new LibSoundFile(srcURL.asLocalFile(".audio")); -#else -# ifdef AUDIOTOOLBOX_FOUND - _sources[req.sendid]->transform = new AudioToolbox(srcURL.asLocalFile(".audio")); -# endif -#endif - if (_sources[req.sendid]->transform == NULL) { - LOG(ERROR) << "No transcoder for input file known - install libsndfile or AudioToolbox"; - _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) { - returnErrorExecution(ex.what()); - return; - } - - getPosFromParams(req.params, _sources[req.sendid]->pos); - - _sources[req.sendid]->pos[0] -= _listenerPos[0]; - _sources[req.sendid]->pos[1] -= _listenerPos[1]; - _sources[req.sendid]->pos[2] -= _listenerPos[2]; - try { - _sources[req.sendid]->player->setPosition(_sources[req.sendid]->pos); - - } catch (std::exception ex) { - returnErrorExecution(ex.what()); - } - - _sourcesAvailable.notify_all(); - } - - if (iequals(req.name, "move.source")) { - std::string sourceId; - if (req.params.find("source") == req.params.end()) { - LOG(WARNING) << "Cannot move source with no source given in parameters"; - return; - } - sourceId = req.params.find("source")->second.atom; - - 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); - } catch (std::exception ex) { - returnErrorExecution(ex.what()); - } - } - - if (iequals(req.name, "move.listener")) { - getPosFromParams(req.params, _listenerPos); - - try { - alcMakeContextCurrent(_alContext); - alListenerfv(AL_POSITION, _listenerPos); - OpenALPlayer::checkOpenALError(__LINE__); - } catch (std::exception ex) { - returnErrorExecution(ex.what()); - } - } - -} - -void OpenALInvoker::start() { - _isStarted = true; - _thread = new tthread::thread(&OpenALInvoker::fillBuffers, this); -} - -void OpenALInvoker::fillBuffers(void* userdata) { - OpenALInvoker* INST = (OpenALInvoker*)userdata; - while(INST->_isStarted) { - // do nothing until we have at least one source - int waitMs = std::numeric_limits<int>::max(); - INST->_mutex.lock(); - 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; - int wait = std::numeric_limits<int>::max(); - - if (src->finished) { - // source has already finished playing, feed no more samples to it - try { - wait = src->player->isPlaying(); - if (wait == 0) { - // source stopped playing, delete it - INST->notifyOfEnd(src); - delete src; - INST->_sources.erase(srcIter++); - continue; - } else { - // source returned time when to repoll - assert(wait > 0); - } - } catch (std::exception ex) { - INST->returnErrorExecution(ex.what()); - delete src; - INST->_sources.erase(srcIter++); - continue; - } - } else { - // source still needs more samples or play existing buffer - if (src->written == src->read) { - // all read samples have been written, read some more - src->written = 0; - src->read = src->transform->read(src->buffer, ALPLAY_AUDIO_BUFFER_SIZE); - if (src->read < ALPLAY_AUDIO_BUFFER_SIZE) { - if (src->loop) { - INST->notifyOfLoop(src); - while (src->read < ALPLAY_AUDIO_BUFFER_SIZE) { - src->transform->seek(0); - src->read += src->transform->read(src->buffer + src->read, ALPLAY_AUDIO_BUFFER_SIZE - src->read); - } - } else { - src->finished = true; - memset(src->buffer + src->read, 0, ALPLAY_AUDIO_BUFFER_SIZE - src->read); - } - } - } - - // there are unwritten samples in the buffer - if (src->read != src->written) { - try { - int written = src->player->write(src->buffer, ALPLAY_AUDIO_BUFFER_SIZE, &wait); - if (written >=0 ) { - src->written += written; - } - } catch (std::exception ex) { - INST->returnErrorExecution(ex.what()); - src->finished = true; - } - } else { - assert(src->finished); - } - } - - waitMs = (wait < waitMs ? wait : waitMs); - srcIter++; - } - -// std::cout << "W" << waitMs << "."; - - INST->_mutex.unlock(); - if (waitMs < std::numeric_limits<int>::max()) - tthread::this_thread::sleep_for(tthread::chrono::milliseconds(waitMs)); - } -} - -void OpenALInvoker::cancel(const std::string sendId) { - tthread::lock_guard<tthread::recursive_mutex> lock(_mutex); - -} - -void OpenALInvoker::invoke(const InvokeRequest& req) { - _alDevice = alcOpenDevice(NULL); - if (_alDevice == NULL) { - throw std::string("__FILE__ __LINE__ openal error opening device"); - } - - std::multimap<std::string, Data>::const_iterator paramIter = req.params.begin(); - while(paramIter != req.params.end()) { - if (iequals(paramIter->first, "maxX")) - _maxPos[0] = strTo<float>(paramIter->second.atom); - if (iequals(paramIter->first, "maxY")) - _maxPos[1] = strTo<float>(paramIter->second.atom); - if (iequals(paramIter->first, "maxZ")) - _maxPos[2] = strTo<float>(paramIter->second.atom); - paramIter++; - } - - // 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); - - alcMakeContextCurrent(_alContext); - alListenerfv(AL_POSITION, _listenerPos); - alListenerfv(AL_VELOCITY, _listenerVel); - alListenerfv(AL_ORIENTATION, _listenerOrient); - - alListenerf(AL_GAIN, 0.5); - - start(); -} - -void OpenALInvoker::notifyOfEnd(OpenALSource* src) { - Event ev; - ev.name = "audio.end"; - ev.data.compound["file"] = src->file; - returnEvent(ev); -} - -void OpenALInvoker::notifyOfLoop(OpenALSource* src) { - Event ev; - ev.name = "audio.loop"; - ev.data.compound["file"] = src->file; - returnEvent(ev); -} - -void OpenALInvoker::getPosFromParams(const std::multimap<std::string, Data>& params, float* position) { - // vector explicitly given - try { - if (params.find("x") != params.end()) - position[0] = boost::lexical_cast<float>(params.find("x")->second); - if (params.find("y") != params.end()) - position[1] = boost::lexical_cast<float>(params.find("y")->second); - if (params.find("z") != params.end()) - position[2] = boost::lexical_cast<float>(params.find("z")->second); - } 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()) - position[0] = boost::lexical_cast<float>(params.find("right")->second); - // height is an alias for y - if (params.find("height") != params.end()) - position[1] = boost::lexical_cast<float>(params.find("height")->second); - // front is an alias for z - if (params.find("front") != params.end()) - position[2] = boost::lexical_cast<float>(params.find("front")->second); - } 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()) { - float rad = posToRadian(params.find("circle")->second); - position[0] = cosf(rad); - 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 << position[0] << ":" << position[1] << ":" << position[2] << std::endl; - -} - -float OpenALInvoker::posToRadian(const std::string& pos) { - - std::string trimmedPos = boost::trim_copy(pos); - float rad = 0; - - if (trimmedPos.size() > 3 && 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] - rad /= 180; // into range [0-2] - rad *= M_PI; // into range [0-2PI] - rad -= M_PI_2; // 0 to top; - rad *= -1; // make clockwise - rad += 2 * M_PI; // make positive - } else if (trimmedPos.size() > 3 && iequals("rad", trimmedPos.substr(trimmedPos.length() - 3, 3))) { - rad = boost::lexical_cast<float>(trimmedPos.substr(0, trimmedPos.size() - 3)); - rad = fmodf(rad, M_PI * 2); // into range [0-2*PI] - } else { - LOG(ERROR) << "Cannot make sense of position value " << trimmedPos << ": does not end in 'deg', 'rad'"; - } - return rad; -} - -OpenALSource::OpenALSource() { - pos[0] = pos[1] = pos[2] = 0; - player = NULL; - loop = false; - finished = false; - transform = NULL; - read = written = 0; - memset(buffer, 0, ALPLAY_AUDIO_BUFFER_SIZE); -} - -OpenALSource::~OpenALSource() { - if (player) - delete player; - if (transform) - delete transform; -} - -}
\ No newline at end of file diff --git a/src/uscxml/plugins/invoker/audio/OpenALInvoker.h b/src/uscxml/plugins/invoker/audio/OpenALInvoker.h deleted file mode 100644 index 98524ed..0000000 --- a/src/uscxml/plugins/invoker/audio/OpenALInvoker.h +++ /dev/null @@ -1,111 +0,0 @@ -/** - * @file - * @author 2012-2013 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) - * @copyright Simplified BSD - * - * @cond - * This program is free software: you can redistribute it and/or modify - * it under the terms of the FreeBSD license as published by the FreeBSD - * project. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of the FreeBSD license along with this - * program. If not, see <http://www.opensource.org/licenses/bsd-license>. - * @endcond - */ - -#ifndef OPENALINVOKER_H_W09J90F0 -#define OPENALINVOKER_H_W09J90F0 - -#include "uscxml/config.h" -#include <uscxml/Interpreter.h> -#include "OpenALPlayer.h" - -#include "PCMConverter.h" -#ifdef LIBSNDFILE_FOUND -# include "LibSoundFile.h" -#else -# ifdef AUDIOTOOLBOX_FOUND -# include "AudioToolbox.h" -# endif -#endif - -#ifdef BUILD_AS_PLUGINS -#include "uscxml/plugins/Plugins.h" -#endif - -namespace uscxml { - -class OpenALSource { -public: - OpenALSource(); - ~OpenALSource(); - - OpenALPlayer* player; - char buffer[ALPLAY_AUDIO_BUFFER_SIZE]; - bool loop; - bool finished; - int read; - int written; - ALfloat pos[3]; - URL file; - PCMConverter* transform; -}; - -class OpenALInvoker : public InvokerImpl { -public: - OpenALInvoker(); - virtual ~OpenALInvoker(); - virtual boost::shared_ptr<InvokerImpl> create(InterpreterImpl* interpreter); - - virtual std::list<std::string> getNames() { - std::list<std::string> names; - names.push_back("openal"); - names.push_back("spatial-audio"); - names.push_back("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); - virtual void invoke(const InvokeRequest& req); - -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; - ALfloat _listenerPos[3]; - ALfloat _listenerVel[3]; - ALfloat _listenerOrient[6]; - float _maxPos[3]; - - 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, Data>& params, float* position); - -}; - -#ifdef BUILD_AS_PLUGINS -PLUMA_INHERIT_PROVIDER(OpenALInvoker, InvokerImpl); -#endif - -} - - -#endif /* end of include guard: OPENALINVOKER_H_W09J90F0 */ diff --git a/src/uscxml/plugins/invoker/audio/OpenALPlayer.cpp b/src/uscxml/plugins/invoker/audio/OpenALPlayer.cpp deleted file mode 100644 index 3aaeddf..0000000 --- a/src/uscxml/plugins/invoker/audio/OpenALPlayer.cpp +++ /dev/null @@ -1,541 +0,0 @@ -/** - * @file - * @author 2012-2013 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) - * @copyright Simplified BSD - * - * @cond - * This program is free software: you can redistribute it and/or modify - * it under the terms of the FreeBSD license as published by the FreeBSD - * project. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of the FreeBSD license along with this - * program. If not, see <http://www.opensource.org/licenses/bsd-license>. - * @endcond - */ - -#include "OpenALPlayer.h" -#include <assert.h> -#include <stdexcept> - -tthread::recursive_mutex OpenALPlayer::_alMutex; - -/** -* Create a new OpenAL stream source -*/ -OpenALPlayer::OpenALPlayer(ALCcontext* context, OpenALPlayerCallback* audioCallback, ALenum format, ALsizei freq) { - - _isInitialized = false; - _audioCallback = audioCallback; - _freq = freq; - _format = format; - _bufferSize = 0; - _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. - - // use the current context if there is one - _context = alcGetCurrentContext(); - - if (_context == NULL) { -// std::cout << "\tnew context" << std::endl; - // create a new context if none was given and no is current - - // get default device - ALCdevice* device = alcOpenDevice(NULL); - if (device == NULL) { - throw std::runtime_error("__FILE__ __LINE__ openal error opening device"); - } - - // create new context with device - _context = alcCreateContext (device, NULL); - if (_context == NULL) { - alcCloseDevice (device); - throw std::runtime_error("openal error create context"); - } - - // make context current - if (!alcMakeContextCurrent (_context)) { - alcDestroyContext (_context); - alcCloseDevice (device); - throw std::runtime_error("openal error make context current"); - } - } else { -// std::cout << "\texisting context" << std::endl; - } - } else { -// std::cout << "\tgiven context" << std::endl; - _context = context; - } -} - -OpenALPlayer::~OpenALPlayer() { - tthread::lock_guard<tthread::recursive_mutex> lock(_alMutex); - if (isPlaying()) { - alSourceStop(_alId); - } - if (_thread) { - stop(); - _thread->join(); - delete(_thread); - } - - if (_isInitialized) { - alDeleteSources(1, &_alId); - if (alIsSource(_alId)) { - throw std::runtime_error("openal source id still valid"); - } - for (size_t i = 0; i < _nrBuffers; i++) { - assert(alIsBuffer(_bufferIds[i])); - free(_buffers[i]); - } - alDeleteBuffers(_nrBuffers, _bufferIds); - for (size_t i = 0; i < _nrBuffers; i++) { -// assert(!alIsBuffer(_bufferIds[i])); - } - free(_buffers); - free(_bufferIds); - } - // clear errors and begone - alGetError(); - -} - -/** -* Allocate; data and set defaults -*/ -void OpenALPlayer::init() { - _userData = NULL; - _pitch = 0; - _gain = 0; - _referenceDistance = 1.0; - _isLooping = false; - - // no one set a buffer size yet - if (_bufferSize <= 0) - _bufferSize = ALPLAY_AUDIO_BUFFER_SIZE; - - // no one set the number of buffers yet - if (_nrBuffers <= 0) - _nrBuffers = ALPLAY_NR_AUDIO_BUFFERS; - - _isInitialized = true; - - _buffers = (char**)malloc(_nrBuffers * sizeof(char*)); - _bufferIds = (ALuint*)malloc(_nrBuffers * sizeof(ALuint)); - for (size_t i = 0; i < _nrBuffers; i++) { - _buffers[i] = 0; //(char*)malloc(_bufferSize); - } - - // there are other formats as well and this will have to be extended - int bytesPerSample = 2; - switch(_format) { - case AL_FORMAT_MONO8: - case AL_FORMAT_STEREO8: - bytesPerSample = 1; - break; - - case AL_FORMAT_MONO16: - case AL_FORMAT_STEREO16: - bytesPerSample = 2; - break; - } - - // how many ms audio is in one buffer? - _msForBuffer = (int)(((float)_bufferSize / (float)bytesPerSample) / ((float)_freq / 1000.0f)); - _initialSleep = (_msForBuffer - (int)(0.6 * _msForBuffer)) * _nrBuffers; - _bufferSleep = _msForBuffer - (int)(0.4 * _msForBuffer); - _repollSleep = _msForBuffer - (int)(0.7 * _msForBuffer); - -// std::cout << _msForBuffer << "ms in one buffer" << std::endl; - - // get available buffer ids - tthread::lock_guard<tthread::recursive_mutex> lock(_alMutex); - - if (!alcMakeContextCurrent (_context)) { - throw std::runtime_error("openal error make context current"); - } - - alGenBuffers(_nrBuffers, _bufferIds); - checkOpenALError(__LINE__); - - // get new source id from openAL - alGenSources(1, &_alId); - - checkOpenALError(__LINE__); - if (!alIsSource(_alId)) { - throw std::runtime_error("openal source id not valid"); - } - - // set our position and various flags to meaningful defaults - alSourcei (_alId, AL_SOURCE_RELATIVE, AL_TRUE); - checkOpenALError(__LINE__); - alSourcei(_alId, AL_LOOPING, AL_FALSE); - checkOpenALError(__LINE__); - alSourcefv(_alId, AL_POSITION, _position); - checkOpenALError(__LINE__); -// alSourcef(_alId,AL_REFERENCE_DISTANCE, 5.0f); -// checkOpenALError(__LINE__); - alDistanceModel(AL_LINEAR_DISTANCE); - checkOpenALError(__LINE__); - alSourcefv(_alId, AL_VELOCITY, _velocity); - checkOpenALError(__LINE__); - alSourcefv(_alId, AL_DIRECTION, _direction); - checkOpenALError(__LINE__); -// alSourcef (_alId, AL_ROLLOFF_FACTOR, 1.0); -// checkOpenALError(__LINE__); -// alSourcef(_alId,AL_REFERENCE_DISTANCE, 5.0f); -// checkOpenALError(__LINE__); -// float listener[] = { 0.0, 0.0, 0.0 }; -// alListenerfv(AL_POSITION, listener); -// checkOpenALError(__LINE__); -} - -/** -* Start the sound source. -* -* This will trigger continuous calls top the audio callback. -*/ -void OpenALPlayer::start() { - if (!_isInitialized) - init(); - - if (_audioCallback == NULL) - throw std::runtime_error("cannot start without an audio callback"); - - _isStarted = true; - - // prime the buffers with some initial data and register for buffer ids - tthread::lock_guard<tthread::recursive_mutex> lock(_alMutex); - for (ALuint i = 0; i < (unsigned int)_nrBuffers; i++) { - _buffers[i] = (char*)malloc(_bufferSize); - _audioCallback->getSamples(_buffers[i], _bufferSize, this); - alBufferData(_bufferIds[i], _format, _buffers[i], _bufferSize, _freq); - checkOpenALError(__LINE__); - } - // enqueue all buffers - alSourceQueueBuffers(_alId, _nrBuffers, _bufferIds); - checkOpenALError(__LINE__); - - // start thread - if (_audioCallback != NULL) { - _thread = new tthread::thread(&OpenALPlayer::updateBuffersWrapper, this); - } - - // tell openAL to start rendering the buffers - alSourcePlay(_alId); - checkOpenALError(__LINE__); -} - -// find bufferId in _bufferIds to get bufferIndex into _buffers - messy -int OpenALPlayer::bufferIndex(int bufferId) { - int bufferIndex = 0; - for (; bufferIndex < _nrBuffers; bufferIndex++) { - if (_bufferIds[bufferIndex] == (unsigned int)bufferId) - break; - } - if (bufferIndex >= _nrBuffers) - throw std::runtime_error("could not find dequeued bufferId in ids"); - return bufferIndex; -} - -/** -* Write a buffer (blocking). -* -* This allows for a pushing model, whereas the callback allows for a polling model. -*/ -int OpenALPlayer::write(char* buffer, int size, int* repollAt, bool blocking) { - tthread::lock_guard<tthread::recursive_mutex> lock(_alMutex); - - if (!_isInitialized) - init(); - - if (_audioCallback != NULL) { - throw std::runtime_error("you cannot use the write interface with an audio callback"); - } - - if (size != _bufferSize) { - throw std::runtime_error("buffersize does not match"); - } - - 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? - int processed; - alGetSourcei(_alId, AL_BUFFERS_PROCESSED, &processed); - checkOpenALError(__LINE__); - -// if (!isPlaying()) -// std::cout << "-"; - - if (processed > 0) { -// std::cout << "P" << processed; - ALuint bufferId = 0; - alSourceUnqueueBuffers(_alId, 1, &bufferId); - checkOpenALError(__LINE__); - - int bufferIdx = bufferIndex(bufferId); - - // fill the buffer with the given data - memcpy(_buffers[bufferIdx], buffer, _bufferSize); - alBufferData(bufferId, _format, _buffers[bufferIdx], _bufferSize, _freq); - checkOpenALError(__LINE__); - - // enqueue - alSourceQueueBuffers(_alId, 1, &bufferId); - checkOpenALError(__LINE__); - - // some buffers were processed - if (repollAt) - *repollAt = _repollSleep; - break; - - } else { - // no buffer processed - is there an uninitialized buffer left? - int nextBuffer = 0; - for(; nextBuffer < _nrBuffers; nextBuffer++) { - if (_buffers[nextBuffer] == 0) { - break; - } - } - if (nextBuffer < _nrBuffers) { -// std::cout << "N"; - _buffers[nextBuffer] = (char*)malloc(_bufferSize); - memcpy(_buffers[nextBuffer], buffer, _bufferSize); - - alBufferData(_bufferIds[nextBuffer], _format, _buffers[nextBuffer], _bufferSize, _freq); - checkOpenALError(__LINE__); - - alSourceQueueBuffers(_alId, 1, &_bufferIds[nextBuffer]); - checkOpenALError(__LINE__); - // there was a free buffer, repoll immediately to try to write more - if (repollAt) - *repollAt = 0; - - break; - } else { -// std::cout << "X"; - // no processed, no new buffer, wait until we processed one - if (blocking) { - tthread::this_thread::sleep_for(tthread::chrono::milliseconds(_repollSleep)); - } else { - if (repollAt) - *repollAt = _repollSleep; - return -1; - } - } - } - } - - // we have at least one buffer queued, start playing - if (!_isStarted || !isPlaying()) { - alSourcePlay(_alId); - checkOpenALError(__LINE__); - _isStarted = true; - } - - return size; -} - - -/** -* Dequeue, refill and re-enqueue buffers. -*/ -void OpenALPlayer::updateBuffers() { - int processed; -// int queued; - -// std::cout << "Initial sleep: " << initialSleep << "ms" << std::endl; -// std::cout << "Buffer sleep: " << bufferSleep << "ms" << std::endl; -// std::cout << "Repoll sleep: " << repollSleep << "ms" << std::endl; - tthread::this_thread::sleep_for(tthread::chrono::milliseconds(_bufferSleep * _initialSleep)); - - - while(_isStarted) { - - // how many buffers have been rendered already? - tthread::lock_guard<tthread::recursive_mutex> lock(_alMutex); - alGetSourcei(_alId, AL_BUFFERS_PROCESSED, &processed); - checkOpenALError(__LINE__); - //std::cout << processed << std::flush; - - if (processed == 0) { - // avoid busy wait by sleeping - tthread::this_thread::sleep_for(tthread::chrono::milliseconds(_bufferSleep * _initialSleep)); - } else { - // dequeue buffers and get ids - // see http://stackoverflow.com/questions/1900665/c-compiler-differences-vs2008-and-g - ALuint bufferIds[ALPLAY_NR_AUDIO_BUFFERS]; - alSourceUnqueueBuffers(_alId, processed, bufferIds); - checkOpenALError(__LINE__); - - for (size_t id = 0; id < processed; id++) { - int bufferIdx = bufferIndex(bufferIds[id]); - - // refill the buffer with data from the callback - _audioCallback->getSamples(_buffers[bufferIdx], _bufferSize, this); - alBufferData(bufferIds[id], _format, _buffers[bufferIdx], _bufferSize, _freq); - checkOpenALError(__LINE__); - - } - // re-enqueue - alSourceQueueBuffers(_alId, processed, bufferIds); - checkOpenALError(__LINE__); - - // restart if we are not running anymore - if (!isPlaying()) { - alSourcePlay(_alId); - checkOpenALError(__LINE__); - } - - // sleep a bit less than the duration of one buffer - tthread::this_thread::sleep_for(tthread::chrono::milliseconds(_bufferSleep * processed)); - } - } -} - -/** -* TODO -*/ -void OpenALPlayer::stop() { - _isStarted = false; - _thread->join(); -} - -void OpenALPlayer::checkOpenALError(int line) { - int error = alGetError(); - if(error != AL_NO_ERROR) { - std::stringstream out; - out << "OpenALError:" << line << ":"; - - switch (error) { - case AL_INVALID_NAME: - out << "OpenAL invalid name."; - break; - case AL_INVALID_ENUM: - out << "OpenAL invalid enum."; - break; - case AL_INVALID_VALUE: - out << "OpenAL invalid value."; - break; - case AL_INVALID_OPERATION: - out << "OpenAL invalid operation."; - break; - case AL_OUT_OF_MEMORY: - out << "OpenAL out of memory."; - break; - - default: - out << "OpenAL unknown error."; - break; - } - throw std::runtime_error(out.str()); - } -} - -unsigned int OpenALPlayer::isPlaying() { - ALint val; - alGetSourcei(_alId, AL_SOURCE_STATE, &val); - if(val != AL_PLAYING) - return 0; - return _repollSleep; -} - -void OpenALPlayer::updateBuffersWrapper(void *obj) { - try { - reinterpret_cast<OpenALPlayer *>(obj)->updateBuffers(); - } catch(std::runtime_error& error) { -// std::cout << "Terminating Thread: " << error << std::endl; - } catch(...) { -// std::cout << "Terminating Thread! " << std::endl; - } -} - -void OpenALPlayer::setNrBuffers(int nrBuffers) { - if (_nrBuffers > 0) - throw std::runtime_error("cannot modify number of buffers"); - _nrBuffers = nrBuffers; -} - -int OpenALPlayer::getNrBuffers() { - return _nrBuffers; -} - -/** -* Set position of sound source in coordinate system -*/ -void OpenALPlayer::setPosition(ALfloat position[]) { - memcpy(&_position, position, 3 * sizeof(ALfloat)); -// std::cout << _position[0] << ", " << _position[1] << ", " << _position[2] << std::endl; - if (_isInitialized) - alSourcefv(_alId, AL_POSITION, _position); -} - -ALfloat* OpenALPlayer::getPosition() { - return _position; -} - -/** -* Set velocity of sound source in coordinate system -*/ -void OpenALPlayer::setVelocity(ALfloat velocity[]) { - memcpy(&_velocity, velocity, 3 * sizeof(ALfloat)); - if (_isInitialized) - alSourcefv(_alId, AL_VELOCITY, _velocity); -} - -ALfloat* OpenALPlayer::getVelocity() { - return _velocity; -} - -/** -* Set direction of sound source in coordinate system -*/ -void OpenALPlayer::setDirection(ALfloat direction[]) { - memcpy(&_direction, direction, 3 * sizeof(ALfloat)); - if (_isInitialized) - alSourcefv(_alId, AL_DIRECTION, _direction); -} - -ALfloat* OpenALPlayer::getDirection() { - return _direction; -} - -void OpenALPlayer::setBufferSize(int bufferSize) { - if (_bufferSize > 0) - throw std::runtime_error("cannot modify buffersize"); - _bufferSize = bufferSize; -} - -int OpenALPlayer::getBufferSize() { - return _bufferSize; -} - -OpenALPlayerCallback* OpenALPlayer::getCallback() { - return _audioCallback; -} -void OpenALPlayer::setCallback(OpenALPlayerCallback* callback) { - _audioCallback = callback; -} - -void* OpenALPlayer::getUserData() { - return _userData; -} -void OpenALPlayer::setUserData(void* userData) { - _userData = userData; -} diff --git a/src/uscxml/plugins/invoker/audio/OpenALPlayer.h b/src/uscxml/plugins/invoker/audio/OpenALPlayer.h deleted file mode 100644 index db883a0..0000000 --- a/src/uscxml/plugins/invoker/audio/OpenALPlayer.h +++ /dev/null @@ -1,125 +0,0 @@ -/** - * @file - * @author 2012-2013 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) - * @copyright Simplified BSD - * - * @cond - * This program is free software: you can redistribute it and/or modify - * it under the terms of the FreeBSD license as published by the FreeBSD - * project. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of the FreeBSD license along with this - * program. If not, see <http://www.opensource.org/licenses/bsd-license>. - * @endcond - */ - -#ifndef OPENALPLAYER_H_3PORVJDU -#define OPENALPLAYER_H_3PORVJDU - -#include <iostream> -#include <string.h> -#include <stdlib.h> -#include <sstream> -#include <uscxml/concurrency/tinythread.h> - -#include <al.h> -#include <alc.h> - -// sometimes the stream drops if this is less than 5000 bytes -#define ALPLAY_NR_AUDIO_BUFFERS 3 -#define ALPLAY_AUDIO_BUFFER_SIZE 2048 -//#define ALPLAYER_FORMAT_MONO16 0x1101 - -class OpenALPlayer; - -class OpenALPlayerCallback { -public: - virtual ~OpenALPlayerCallback() {} - /* - * Returning an OpenALPlayerCallback is a hack to be able to provide a typemap for SWIG. - * We cannot use SWIG directors with byte arrays otherwise. Posted to swig-ML already. - */ - virtual OpenALPlayerCallback* getSamples(char* buffer, int size, OpenALPlayer* player) = 0; -}; - -class OpenALPlayer { -private: - ALCcontext* _context; - - ALuint _alId; - ALfloat _position[3]; - ALfloat _velocity[3]; - ALfloat _direction[3]; - ALfloat _pitch; - ALfloat _gain; - ALfloat _referenceDistance; - ALboolean _isLooping; - - // OpenAL is not really thread safe - static tthread::recursive_mutex _alMutex; - - ALenum _format; - ALsizei _freq; - int _msForBuffer; - int _initialSleep; - int _bufferSleep; - int _repollSleep; - - int _bufferSize; - int _nrBuffers; - ALuint* _bufferIds; - char** _buffers; - OpenALPlayerCallback* _audioCallback; - void* _userData; - - tthread::thread* _thread; - bool _isStarted; - bool _isInitialized; - - void updateBuffers(); - void init(); - - // static wrapper as an entry point for pthreads - static void updateBuffersWrapper(void *obj); - - // get the index in _buffers for a buffer ID - int inline bufferIndex(int bufferId); - -public: - OpenALPlayer(ALCcontext*, OpenALPlayerCallback*, ALenum, ALsizei); - virtual ~OpenALPlayer(); - - unsigned int isPlaying(); - static void checkOpenALError(int line); - - ALfloat* getPosition(); - void setPosition(ALfloat[3]); - ALfloat* getVelocity(); - void setVelocity(ALfloat[3]); - ALfloat* getDirection(); - void setDirection(ALfloat[3]); - - void setBufferSize(int bufferSize); - int getBufferSize(); - void setNrBuffers(int nrBuffers); - int getNrBuffers(); - - // callback interface for pull - OpenALPlayerCallback* getCallback(); - void setCallback(OpenALPlayerCallback* callback); - - // stream interface for push - int write(char* buffer, int size, int* repollAt, bool blocking = false); - - void* getUserData(); - void setUserData(void* userData); - - void start(); - void stop(); -}; - -#endif /* end of include guard: OPENALPLAYER_H_3PORVJDU */ diff --git a/src/uscxml/plugins/invoker/audio/PCMConverter.h b/src/uscxml/plugins/invoker/audio/PCMConverter.h deleted file mode 100644 index 1984600..0000000 --- a/src/uscxml/plugins/invoker/audio/PCMConverter.h +++ /dev/null @@ -1,49 +0,0 @@ -/** - * @file - * @author 2012-2013 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) - * @copyright Simplified BSD - * - * @cond - * This program is free software: you can redistribute it and/or modify - * it under the terms of the FreeBSD license as published by the FreeBSD - * project. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of the FreeBSD license along with this - * program. If not, see <http://www.opensource.org/licenses/bsd-license>. - * @endcond - */ - -#ifndef PCMCONVERTER_H_97Z8U7PA -#define PCMCONVERTER_H_97Z8U7PA - -#include <string> -#include <al.h> -#include <alc.h> - -namespace uscxml { - -struct PCMFormat { - ALenum alFormat; - unsigned int sampleRate; -}; - -class PCMConverter { -public: - PCMConverter(const std::string filename) {} - 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: - PCMConverter() {} -}; - -} - -#endif /* end of include guard: PCMCONVERTER_H_97Z8U7PA */ |