From 845176bbc697bb274773370b5eba4740195e3e74 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 2 Jan 2014 15:14:28 -0800 Subject: [PATCH 1/7] expose Sound to ScriptEngine --- libraries/audio/src/Sound.cpp | 4 +++- libraries/audio/src/Sound.h | 2 +- libraries/script-engine/src/ScriptEngine.cpp | 12 ++++++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/libraries/audio/src/Sound.cpp b/libraries/audio/src/Sound.cpp index 0362561fff..aef926bb10 100644 --- a/libraries/audio/src/Sound.cpp +++ b/libraries/audio/src/Sound.cpp @@ -12,7 +12,9 @@ #include "Sound.h" -Sound::Sound(const QUrl& sampleURL) { +Sound::Sound(const QUrl& sampleURL, QObject* parent) : + QObject(parent) +{ // assume we have a QApplication or QCoreApplication instance and use the // QNetworkAccess manager to grab the raw audio file at the given URL diff --git a/libraries/audio/src/Sound.h b/libraries/audio/src/Sound.h index e9a6e856ba..dea15674e0 100644 --- a/libraries/audio/src/Sound.h +++ b/libraries/audio/src/Sound.h @@ -16,7 +16,7 @@ class QNetworkReply; class Sound : public QObject { Q_OBJECT public: - Sound(const QUrl& sampleURL); + Sound(const QUrl& sampleURL, QObject* parent = 0); const QByteArray& getByteArray() { return _byteArray; } private: diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index eec0c22359..30eb046bf5 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -20,12 +20,20 @@ #include #include +#include + #include "ScriptEngine.h" int ScriptEngine::_scriptNumber = 1; VoxelsScriptingInterface ScriptEngine::_voxelsScriptingInterface; ParticlesScriptingInterface ScriptEngine::_particlesScriptingInterface; +static QScriptValue soundConstructor(QScriptContext* context, QScriptEngine* engine) { + QUrl soundURL = QUrl(context->argument(0).toString()); + QScriptValue soundScriptValue = engine->newQObject(new Sound(soundURL), QScriptEngine::ScriptOwnership); + + return soundScriptValue; +} ScriptEngine::ScriptEngine(const QString& scriptContents, bool wantMenuItems, const char* scriptMenuName, AbstractMenuInterface* menu, @@ -101,6 +109,10 @@ void ScriptEngine::run() { QScriptValue particleScripterValue = engine.newQObject(&_particlesScriptingInterface); engine.globalObject().setProperty("Particles", particleScripterValue); + QScriptValue soundConstructorValue = engine.newFunction(soundConstructor); + QScriptValue soundMetaObject = engine.newQMetaObject(&Sound::staticMetaObject, soundConstructorValue); + engine.globalObject().setProperty("Sound", soundMetaObject); + if (_controllerScriptingInterface) { QScriptValue controllerScripterValue = engine.newQObject(_controllerScriptingInterface); engine.globalObject().setProperty("Controller", controllerScripterValue); From 594bd58774694f00ec1af073e4a9c80269a47a51 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 2 Jan 2014 15:35:28 -0800 Subject: [PATCH 2/7] add AudioScriptingInterface to expose playSound to JS --- interface/src/avatar/Hand.cpp | 6 ++--- interface/src/avatar/Hand.h | 2 +- libraries/audio/src/AudioInjector.cpp | 18 ------------- libraries/audio/src/AudioInjector.h | 6 ++--- .../audio/src/AudioScriptingInterface.cpp | 25 +++++++++++++++++++ libraries/audio/src/AudioScriptingInterface.h | 20 +++++++++++++++ 6 files changed, 52 insertions(+), 25 deletions(-) create mode 100644 libraries/audio/src/AudioScriptingInterface.cpp create mode 100644 libraries/audio/src/AudioScriptingInterface.h diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 6b776f5cfa..deeef15965 100644 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -130,8 +130,8 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f injectorOptions.position = targetPosition; injectorOptions.shouldLoopback = false; injectorOptions.loopbackAudioInterface = app->getAudio(); - - AudioInjector::threadSound(&_catchSound, injectorOptions); + + AudioScriptingInterface::playSound(&_catchSound, injectorOptions); } } @@ -220,7 +220,7 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f injectorOptions.shouldLoopback = false; injectorOptions.loopbackAudioInterface = app->getAudio(); - AudioInjector::threadSound(&_throwSound, injectorOptions); + AudioScriptingInterface::playSound(&_throwSound, injectorOptions); } } diff --git a/interface/src/avatar/Hand.h b/interface/src/avatar/Hand.h index 88ca4a61e7..60d7dd26ac 100755 --- a/interface/src/avatar/Hand.h +++ b/interface/src/avatar/Hand.h @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include diff --git a/libraries/audio/src/AudioInjector.cpp b/libraries/audio/src/AudioInjector.cpp index 5ad4dc6f4d..863906034f 100644 --- a/libraries/audio/src/AudioInjector.cpp +++ b/libraries/audio/src/AudioInjector.cpp @@ -19,7 +19,6 @@ int abstractAudioPointerMeta = qRegisterMetaType("AbstractAudioInterface*"); AudioInjector::AudioInjector(Sound* sound, AudioInjectorOptions injectorOptions) : - _thread(NULL), _sound(sound), _volume(injectorOptions.volume), _shouldLoopback(injectorOptions.shouldLoopback), @@ -27,24 +26,7 @@ AudioInjector::AudioInjector(Sound* sound, AudioInjectorOptions injectorOptions) _orientation(injectorOptions.orientation), _loopbackAudioInterface(injectorOptions.loopbackAudioInterface) { - _thread = new QThread(); - // we want to live on our own thread - moveToThread(_thread); -} - -void AudioInjector::threadSound(Sound* sound, AudioInjectorOptions injectorOptions) { - AudioInjector* injector = new AudioInjector(sound, injectorOptions); - - // start injecting when the injector thread starts - connect(injector->_thread, SIGNAL(started()), injector, SLOT(injectAudio())); - - // connect the right slots and signals so that the AudioInjector is killed once the injection is complete - connect(injector, SIGNAL(finished()), injector, SLOT(deleteLater())); - connect(injector, SIGNAL(finished()), injector->_thread, SLOT(quit())); - connect(injector->_thread, SIGNAL(finished()), injector->_thread, SLOT(deleteLater())); - - injector->_thread->start(); } const uchar MAX_INJECTOR_VOLUME = 0xFF; diff --git a/libraries/audio/src/AudioInjector.h b/libraries/audio/src/AudioInjector.h index f2e7b3b498..8b6c9e622f 100644 --- a/libraries/audio/src/AudioInjector.h +++ b/libraries/audio/src/AudioInjector.h @@ -18,6 +18,7 @@ #include "Sound.h" class AbstractAudioInterface; +class AudioScriptingInterface; struct AudioInjectorOptions { AudioInjectorOptions() : position(glm::vec3(0.0f, 0.0f, 0.0f)), @@ -36,11 +37,10 @@ struct AudioInjectorOptions { class AudioInjector : public QObject { Q_OBJECT public: - static void threadSound(Sound* sound, AudioInjectorOptions injectorOptions = AudioInjectorOptions()); + friend AudioScriptingInterface; private: AudioInjector(Sound* sound, AudioInjectorOptions injectorOptions); - - QThread* _thread; + Sound* _sound; float _volume; uchar _shouldLoopback; diff --git a/libraries/audio/src/AudioScriptingInterface.cpp b/libraries/audio/src/AudioScriptingInterface.cpp new file mode 100644 index 0000000000..fa5cdcc354 --- /dev/null +++ b/libraries/audio/src/AudioScriptingInterface.cpp @@ -0,0 +1,25 @@ +// +// AudioScriptingInterface.cpp +// hifi +// +// Created by Stephen Birarda on 1/2/2014. +// Copyright (c) 2013 HighFidelity, Inc. All rights reserved. +// + +#include "AudioScriptingInterface.h" + +void AudioScriptingInterface::playSound(Sound* sound, AudioInjectorOptions injectorOptions) { + AudioInjector* injector = new AudioInjector(sound, injectorOptions); + + QThread* injectorThread = new QThread(); + + // start injecting when the injector thread starts + connect(injectorThread, SIGNAL(started()), injector, SLOT(injectAudio())); + + // connect the right slots and signals so that the AudioInjector is killed once the injection is complete + connect(injector, SIGNAL(finished()), injector, SLOT(deleteLater())); + connect(injector, SIGNAL(finished()), injectorThread, SLOT(quit())); + connect(injectorThread, SIGNAL(finished()), injectorThread, SLOT(deleteLater())); + + injectorThread->start(); +} \ No newline at end of file diff --git a/libraries/audio/src/AudioScriptingInterface.h b/libraries/audio/src/AudioScriptingInterface.h new file mode 100644 index 0000000000..b0f1078f32 --- /dev/null +++ b/libraries/audio/src/AudioScriptingInterface.h @@ -0,0 +1,20 @@ +// +// AudioScriptingInterface.h +// hifi +// +// Created by Stephen Birarda on 1/2/2014. +// Copyright (c) 2013 HighFidelity, Inc. All rights reserved. +// + +#ifndef __hifi__AudioScriptingInterface__ +#define __hifi__AudioScriptingInterface__ + +#include "AudioInjector.h" +#include "Sound.h" + +class AudioScriptingInterface : public QObject { +public slots: + static void playSound(Sound* sound, AudioInjectorOptions injectorOptions = AudioInjectorOptions()); + +}; +#endif /* defined(__hifi__AudioScriptingInterface__) */ From 443c94a88fa3671833bc64ecc95233f6e0031251 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 2 Jan 2014 17:15:46 -0800 Subject: [PATCH 3/7] repairs to AudioMixer and audio injection flow --- .../src/audio/AudioMixerClientData.cpp | 5 ++- interface/src/avatar/Hand.cpp | 4 +-- libraries/audio/src/AudioInjector.cpp | 24 ++++++-------- libraries/audio/src/AudioInjector.h | 21 ++---------- libraries/audio/src/AudioInjectorOptions.cpp | 28 ++++++++++++++++ libraries/audio/src/AudioInjectorOptions.h | 32 +++++++++++++++++++ libraries/audio/src/AudioRingBuffer.cpp | 2 -- .../audio/src/AudioScriptingInterface.cpp | 3 ++ libraries/audio/src/AudioScriptingInterface.h | 5 ++- .../audio/src/InjectedAudioRingBuffer.cpp | 2 -- .../audio/src/PositionalAudioRingBuffer.cpp | 4 +++ libraries/script-engine/src/ScriptEngine.cpp | 3 ++ libraries/script-engine/src/ScriptEngine.h | 3 ++ 13 files changed, 95 insertions(+), 41 deletions(-) create mode 100644 libraries/audio/src/AudioInjectorOptions.cpp create mode 100644 libraries/audio/src/AudioInjectorOptions.h diff --git a/assignment-client/src/audio/AudioMixerClientData.cpp b/assignment-client/src/audio/AudioMixerClientData.cpp index fa171f252d..011a14c38f 100644 --- a/assignment-client/src/audio/AudioMixerClientData.cpp +++ b/assignment-client/src/audio/AudioMixerClientData.cpp @@ -9,6 +9,8 @@ #include #include +#include + #include "InjectedAudioRingBuffer.h" #include "AudioMixerClientData.h" @@ -94,7 +96,8 @@ void AudioMixerClientData::pushBuffersAfterFrameSend() { audioBuffer->shiftReadPosition(NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL); audioBuffer->setWillBeAddedToMix(false); - } else if (audioBuffer->hasStarted() && audioBuffer->isStarved()) { + } else if (audioBuffer->getType() == PositionalAudioRingBuffer::Injector + && audioBuffer->hasStarted() && audioBuffer->isStarved()) { // this is an empty audio buffer that has starved, safe to delete delete audioBuffer; _ringBuffers.erase(_ringBuffers.begin() + i); diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index deeef15965..74602d037d 100644 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -127,7 +127,7 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f // use the threadSound static method to inject the catch sound // pass an AudioInjectorOptions struct to set position and disable loopback AudioInjectorOptions injectorOptions; - injectorOptions.position = targetPosition; + injectorOptions.position = newPosition; injectorOptions.shouldLoopback = false; injectorOptions.loopbackAudioInterface = app->getAudio(); @@ -216,7 +216,7 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f // use the threadSound static method to inject the throw sound // pass an AudioInjectorOptions struct to set position and disable loopback AudioInjectorOptions injectorOptions; - injectorOptions.position = targetPosition; + injectorOptions.position = ballPosition; injectorOptions.shouldLoopback = false; injectorOptions.loopbackAudioInterface = app->getAudio(); diff --git a/libraries/audio/src/AudioInjector.cpp b/libraries/audio/src/AudioInjector.cpp index 863906034f..7ea70fdc0b 100644 --- a/libraries/audio/src/AudioInjector.cpp +++ b/libraries/audio/src/AudioInjector.cpp @@ -20,11 +20,7 @@ int abstractAudioPointerMeta = qRegisterMetaType("Abstr AudioInjector::AudioInjector(Sound* sound, AudioInjectorOptions injectorOptions) : _sound(sound), - _volume(injectorOptions.volume), - _shouldLoopback(injectorOptions.shouldLoopback), - _position(injectorOptions.position), - _orientation(injectorOptions.orientation), - _loopbackAudioInterface(injectorOptions.loopbackAudioInterface) + _options(injectorOptions) { } @@ -38,9 +34,9 @@ void AudioInjector::injectAudio() { // make sure we actually have samples downloaded to inject if (soundByteArray.size()) { // give our sample byte array to the local audio interface, if we have it, so it can be handled locally - if (_loopbackAudioInterface) { + if (_options.loopbackAudioInterface) { // assume that localAudioInterface could be on a separate thread, use Qt::AutoConnection to handle properly - QMetaObject::invokeMethod(_loopbackAudioInterface, "handleAudioByteArray", + QMetaObject::invokeMethod(_options.loopbackAudioInterface, "handleAudioByteArray", Qt::AutoConnection, Q_ARG(QByteArray, soundByteArray)); @@ -67,16 +63,16 @@ void AudioInjector::injectAudio() { currentPacketPosition += rfcStreamUUID.size(); // pack the flag for loopback - memcpy(currentPacketPosition, &_shouldLoopback, sizeof(_shouldLoopback)); - currentPacketPosition += sizeof(_shouldLoopback); + memcpy(currentPacketPosition, &_options.shouldLoopback, sizeof(_options.shouldLoopback)); + currentPacketPosition += sizeof(_options.shouldLoopback); // pack the position for injected audio - memcpy(currentPacketPosition, &_position, sizeof(_position)); - currentPacketPosition += sizeof(_position); + memcpy(currentPacketPosition, &_options.position, sizeof(_options.position)); + currentPacketPosition += sizeof(_options.position); // pack our orientation for injected audio - memcpy(currentPacketPosition, &_orientation, sizeof(_orientation)); - currentPacketPosition += sizeof(_orientation); + memcpy(currentPacketPosition, &_options.orientation, sizeof(_options.orientation)); + currentPacketPosition += sizeof(_options.orientation); // pack zero for radius float radius = 0; @@ -84,7 +80,7 @@ void AudioInjector::injectAudio() { currentPacketPosition += sizeof(radius); // pack 255 for attenuation byte - uchar volume = MAX_INJECTOR_VOLUME * _volume; + uchar volume = MAX_INJECTOR_VOLUME * _options.volume; memcpy(currentPacketPosition, &volume, sizeof(volume)); currentPacketPosition += sizeof(volume); diff --git a/libraries/audio/src/AudioInjector.h b/libraries/audio/src/AudioInjector.h index 8b6c9e622f..657ae0ca20 100644 --- a/libraries/audio/src/AudioInjector.h +++ b/libraries/audio/src/AudioInjector.h @@ -15,25 +15,12 @@ #include #include +#include "AudioInjectorOptions.h" #include "Sound.h" class AbstractAudioInterface; class AudioScriptingInterface; -struct AudioInjectorOptions { - AudioInjectorOptions() : position(glm::vec3(0.0f, 0.0f, 0.0f)), - volume(1.0f), - orientation(glm::quat()), - shouldLoopback(true), - loopbackAudioInterface(NULL) {}; - - glm::vec3 position; - float volume; - const glm::quat orientation; - bool shouldLoopback; - AbstractAudioInterface* loopbackAudioInterface; -}; - class AudioInjector : public QObject { Q_OBJECT public: @@ -42,11 +29,7 @@ private: AudioInjector(Sound* sound, AudioInjectorOptions injectorOptions); Sound* _sound; - float _volume; - uchar _shouldLoopback; - glm::vec3 _position; - glm::quat _orientation; - AbstractAudioInterface* _loopbackAudioInterface; + AudioInjectorOptions _options; private slots: void injectAudio(); signals: diff --git a/libraries/audio/src/AudioInjectorOptions.cpp b/libraries/audio/src/AudioInjectorOptions.cpp new file mode 100644 index 0000000000..4d0c26a087 --- /dev/null +++ b/libraries/audio/src/AudioInjectorOptions.cpp @@ -0,0 +1,28 @@ +// +// AudioInjectorOptions.cpp +// hifi +// +// Created by Stephen Birarda on 1/2/2014. +// Copyright (c) 2013 HighFidelity, Inc. All rights reserved. +// + +#include "AudioInjectorOptions.h" + +AudioInjectorOptions::AudioInjectorOptions(QObject* parent) : + QObject(parent), + position(0.0f, 0.0f, 0.0f), + volume(1.0f), + orientation(glm::vec3(0.0f, 0.0f, 0.0f)), + shouldLoopback(true), + loopbackAudioInterface(NULL) +{ + +} + +AudioInjectorOptions::AudioInjectorOptions(const AudioInjectorOptions& other) { + position = other.position; + volume = other.volume; + orientation = other.orientation; + shouldLoopback = other.shouldLoopback; + loopbackAudioInterface = other.loopbackAudioInterface; +} \ No newline at end of file diff --git a/libraries/audio/src/AudioInjectorOptions.h b/libraries/audio/src/AudioInjectorOptions.h new file mode 100644 index 0000000000..6ff9ebc4cc --- /dev/null +++ b/libraries/audio/src/AudioInjectorOptions.h @@ -0,0 +1,32 @@ +// +// AudioInjectorOptions.h +// hifi +// +// Created by Stephen Birarda on 1/2/2014. +// Copyright (c) 2013 HighFidelity, Inc. All rights reserved. +// + +#ifndef __hifi__AudioInjectorOptions__ +#define __hifi__AudioInjectorOptions__ + +#include + +#include +#include + +#include "AbstractAudioInterface.h" + +class AudioInjectorOptions : public QObject { + Q_OBJECT +public: + AudioInjectorOptions(QObject* parent = 0); + AudioInjectorOptions(const AudioInjectorOptions& other); + + glm::vec3 position; + float volume; + glm::quat orientation; + bool shouldLoopback; + AbstractAudioInterface* loopbackAudioInterface; +}; + +#endif /* defined(__hifi__AudioInjectorOptions__) */ diff --git a/libraries/audio/src/AudioRingBuffer.cpp b/libraries/audio/src/AudioRingBuffer.cpp index 4c9b6ff3ab..50bf554eca 100644 --- a/libraries/audio/src/AudioRingBuffer.cpp +++ b/libraries/audio/src/AudioRingBuffer.cpp @@ -107,8 +107,6 @@ qint64 AudioRingBuffer::writeData(const char* data, qint64 maxSize) { _isStarved = true; } - _hasStarted = true; - if (_endOfLastWrite + samplesToCopy <= _buffer + _sampleCapacity) { memcpy(_endOfLastWrite, data, samplesToCopy * sizeof(int16_t)); } else { diff --git a/libraries/audio/src/AudioScriptingInterface.cpp b/libraries/audio/src/AudioScriptingInterface.cpp index fa5cdcc354..3a943914a4 100644 --- a/libraries/audio/src/AudioScriptingInterface.cpp +++ b/libraries/audio/src/AudioScriptingInterface.cpp @@ -6,9 +6,12 @@ // Copyright (c) 2013 HighFidelity, Inc. All rights reserved. // +#include + #include "AudioScriptingInterface.h" void AudioScriptingInterface::playSound(Sound* sound, AudioInjectorOptions injectorOptions) { + AudioInjector* injector = new AudioInjector(sound, injectorOptions); QThread* injectorThread = new QThread(); diff --git a/libraries/audio/src/AudioScriptingInterface.h b/libraries/audio/src/AudioScriptingInterface.h index b0f1078f32..a36a6dc61b 100644 --- a/libraries/audio/src/AudioScriptingInterface.h +++ b/libraries/audio/src/AudioScriptingInterface.h @@ -12,9 +12,12 @@ #include "AudioInjector.h" #include "Sound.h" +const AudioInjectorOptions DEFAULT_INJECTOR_OPTIONS; + class AudioScriptingInterface : public QObject { + Q_OBJECT public slots: - static void playSound(Sound* sound, AudioInjectorOptions injectorOptions = AudioInjectorOptions()); + static void playSound(Sound* sound, AudioInjectorOptions injectorOptions = DEFAULT_INJECTOR_OPTIONS); }; #endif /* defined(__hifi__AudioScriptingInterface__) */ diff --git a/libraries/audio/src/InjectedAudioRingBuffer.cpp b/libraries/audio/src/InjectedAudioRingBuffer.cpp index 3d4d8a1834..ae8574f3c9 100644 --- a/libraries/audio/src/InjectedAudioRingBuffer.cpp +++ b/libraries/audio/src/InjectedAudioRingBuffer.cpp @@ -48,8 +48,6 @@ int InjectedAudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes unsigned int attenuationByte = *(currentBuffer++); _attenuationRatio = attenuationByte / (float) MAX_INJECTOR_VOLUME; - qDebug() << "Copying" << numBytes - (currentBuffer - sourceBuffer) << "for injected ring buffer\n"; - currentBuffer += writeData((char*) currentBuffer, numBytes - (currentBuffer - sourceBuffer)); return currentBuffer - sourceBuffer; diff --git a/libraries/audio/src/PositionalAudioRingBuffer.cpp b/libraries/audio/src/PositionalAudioRingBuffer.cpp index 4be6b80265..7037eb2154 100644 --- a/libraries/audio/src/PositionalAudioRingBuffer.cpp +++ b/libraries/audio/src/PositionalAudioRingBuffer.cpp @@ -66,6 +66,10 @@ bool PositionalAudioRingBuffer::shouldBeAddedToMix(int numJitterBufferSamples) { } else { // good buffer, add this to the mix _isStarved = false; + + // since we've read data from ring buffer at least once - we've started + _hasStarted = true; + return true; } diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 30eb046bf5..485e7ffcce 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -113,6 +113,9 @@ void ScriptEngine::run() { QScriptValue soundMetaObject = engine.newQMetaObject(&Sound::staticMetaObject, soundConstructorValue); engine.globalObject().setProperty("Sound", soundMetaObject); + QScriptValue audioScriptingInterfaceValue = engine.newQObject(&_audioScriptingInterface); + engine.globalObject().setProperty("Audio", audioScriptingInterfaceValue); + if (_controllerScriptingInterface) { QScriptValue controllerScripterValue = engine.newQObject(_controllerScriptingInterface); engine.globalObject().setProperty("Controller", controllerScripterValue); diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index 44172de180..49ed913744 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -16,8 +16,10 @@ #include #include +#include #include #include + #include "AbstractControllerScriptingInterface.h" const QString NO_SCRIPT(""); @@ -61,6 +63,7 @@ private: static VoxelsScriptingInterface _voxelsScriptingInterface; static ParticlesScriptingInterface _particlesScriptingInterface; AbstractControllerScriptingInterface* _controllerScriptingInterface; + AudioScriptingInterface _audioScriptingInterface; bool _wantMenuItems; QString _scriptMenuName; AbstractMenuInterface* _menu; From f24eff33fe55eb89b4187e4c4dd72294841a2f83 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 3 Jan 2014 09:38:05 -0800 Subject: [PATCH 4/7] open up ASI playSound method to ScriptEngine --- interface/src/avatar/Hand.cpp | 16 +++++----- libraries/audio/src/AudioInjector.cpp | 21 ++++++------- libraries/audio/src/AudioInjector.h | 2 +- libraries/audio/src/AudioInjectorOptions.cpp | 20 ++++++------- libraries/audio/src/AudioInjectorOptions.h | 30 +++++++++++++++---- .../audio/src/AudioScriptingInterface.cpp | 4 +-- libraries/audio/src/AudioScriptingInterface.h | 2 +- libraries/script-engine/src/ScriptEngine.cpp | 6 ++++ libraries/shared/src/RegisteredMetaTypes.h | 1 + 9 files changed, 65 insertions(+), 37 deletions(-) diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 74602d037d..6bedfdba2a 100644 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -127,11 +127,11 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f // use the threadSound static method to inject the catch sound // pass an AudioInjectorOptions struct to set position and disable loopback AudioInjectorOptions injectorOptions; - injectorOptions.position = newPosition; - injectorOptions.shouldLoopback = false; - injectorOptions.loopbackAudioInterface = app->getAudio(); + injectorOptions.setPosition(newPosition); + injectorOptions.setShouldLoopback(false); + injectorOptions.setLoopbackAudioInterface(app->getAudio()); - AudioScriptingInterface::playSound(&_catchSound, injectorOptions); + AudioScriptingInterface::playSound(&_catchSound, &injectorOptions); } } @@ -216,11 +216,11 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f // use the threadSound static method to inject the throw sound // pass an AudioInjectorOptions struct to set position and disable loopback AudioInjectorOptions injectorOptions; - injectorOptions.position = ballPosition; - injectorOptions.shouldLoopback = false; - injectorOptions.loopbackAudioInterface = app->getAudio(); + injectorOptions.setPosition(ballPosition); + injectorOptions.setShouldLoopback(false); + injectorOptions.setLoopbackAudioInterface(app->getAudio()); - AudioScriptingInterface::playSound(&_throwSound, injectorOptions); + AudioScriptingInterface::playSound(&_throwSound, &injectorOptions); } } diff --git a/libraries/audio/src/AudioInjector.cpp b/libraries/audio/src/AudioInjector.cpp index 7ea70fdc0b..906702210a 100644 --- a/libraries/audio/src/AudioInjector.cpp +++ b/libraries/audio/src/AudioInjector.cpp @@ -18,7 +18,7 @@ int abstractAudioPointerMeta = qRegisterMetaType("AbstractAudioInterface*"); -AudioInjector::AudioInjector(Sound* sound, AudioInjectorOptions injectorOptions) : +AudioInjector::AudioInjector(Sound* sound, const AudioInjectorOptions& injectorOptions) : _sound(sound), _options(injectorOptions) { @@ -34,9 +34,9 @@ void AudioInjector::injectAudio() { // make sure we actually have samples downloaded to inject if (soundByteArray.size()) { // give our sample byte array to the local audio interface, if we have it, so it can be handled locally - if (_options.loopbackAudioInterface) { + if (_options.getLoopbackAudioInterface()) { // assume that localAudioInterface could be on a separate thread, use Qt::AutoConnection to handle properly - QMetaObject::invokeMethod(_options.loopbackAudioInterface, "handleAudioByteArray", + QMetaObject::invokeMethod(_options.getLoopbackAudioInterface(), "handleAudioByteArray", Qt::AutoConnection, Q_ARG(QByteArray, soundByteArray)); @@ -63,16 +63,17 @@ void AudioInjector::injectAudio() { currentPacketPosition += rfcStreamUUID.size(); // pack the flag for loopback - memcpy(currentPacketPosition, &_options.shouldLoopback, sizeof(_options.shouldLoopback)); - currentPacketPosition += sizeof(_options.shouldLoopback); + bool loopbackFlag = _options.shouldLoopback(); + memcpy(currentPacketPosition, &loopbackFlag, sizeof(loopbackFlag)); + currentPacketPosition += sizeof(loopbackFlag); // pack the position for injected audio - memcpy(currentPacketPosition, &_options.position, sizeof(_options.position)); - currentPacketPosition += sizeof(_options.position); + memcpy(currentPacketPosition, &_options.getPosition(), sizeof(_options.getPosition())); + currentPacketPosition += sizeof(_options.getPosition()); // pack our orientation for injected audio - memcpy(currentPacketPosition, &_options.orientation, sizeof(_options.orientation)); - currentPacketPosition += sizeof(_options.orientation); + memcpy(currentPacketPosition, &_options.getOrientation(), sizeof(_options.getOrientation())); + currentPacketPosition += sizeof(_options.getOrientation()); // pack zero for radius float radius = 0; @@ -80,7 +81,7 @@ void AudioInjector::injectAudio() { currentPacketPosition += sizeof(radius); // pack 255 for attenuation byte - uchar volume = MAX_INJECTOR_VOLUME * _options.volume; + uchar volume = MAX_INJECTOR_VOLUME * _options.getVolume(); memcpy(currentPacketPosition, &volume, sizeof(volume)); currentPacketPosition += sizeof(volume); diff --git a/libraries/audio/src/AudioInjector.h b/libraries/audio/src/AudioInjector.h index 657ae0ca20..48d80c01c7 100644 --- a/libraries/audio/src/AudioInjector.h +++ b/libraries/audio/src/AudioInjector.h @@ -26,7 +26,7 @@ class AudioInjector : public QObject { public: friend AudioScriptingInterface; private: - AudioInjector(Sound* sound, AudioInjectorOptions injectorOptions); + AudioInjector(Sound* sound, const AudioInjectorOptions& injectorOptions); Sound* _sound; AudioInjectorOptions _options; diff --git a/libraries/audio/src/AudioInjectorOptions.cpp b/libraries/audio/src/AudioInjectorOptions.cpp index 4d0c26a087..a24f13e800 100644 --- a/libraries/audio/src/AudioInjectorOptions.cpp +++ b/libraries/audio/src/AudioInjectorOptions.cpp @@ -10,19 +10,19 @@ AudioInjectorOptions::AudioInjectorOptions(QObject* parent) : QObject(parent), - position(0.0f, 0.0f, 0.0f), - volume(1.0f), - orientation(glm::vec3(0.0f, 0.0f, 0.0f)), - shouldLoopback(true), - loopbackAudioInterface(NULL) + _position(0.0f, 0.0f, 0.0f), + _volume(1.0f), + _orientation(glm::vec3(0.0f, 0.0f, 0.0f)), + _shouldLoopback(true), + _loopbackAudioInterface(NULL) { } AudioInjectorOptions::AudioInjectorOptions(const AudioInjectorOptions& other) { - position = other.position; - volume = other.volume; - orientation = other.orientation; - shouldLoopback = other.shouldLoopback; - loopbackAudioInterface = other.loopbackAudioInterface; + _position = other._position; + _volume = other._volume; + _orientation = other._orientation; + _shouldLoopback = other._shouldLoopback; + _loopbackAudioInterface = other._loopbackAudioInterface; } \ No newline at end of file diff --git a/libraries/audio/src/AudioInjectorOptions.h b/libraries/audio/src/AudioInjectorOptions.h index 6ff9ebc4cc..2792f0069c 100644 --- a/libraries/audio/src/AudioInjectorOptions.h +++ b/libraries/audio/src/AudioInjectorOptions.h @@ -14,19 +14,39 @@ #include #include +#include + #include "AbstractAudioInterface.h" class AudioInjectorOptions : public QObject { Q_OBJECT + + Q_PROPERTY(glm::vec3 position READ getPosition WRITE setPosition) public: AudioInjectorOptions(QObject* parent = 0); AudioInjectorOptions(const AudioInjectorOptions& other); - glm::vec3 position; - float volume; - glm::quat orientation; - bool shouldLoopback; - AbstractAudioInterface* loopbackAudioInterface; + const glm::vec3& getPosition() const { return _position; } + void setPosition(const glm::vec3& position) { _position = position; } + + float getVolume() const { return _volume; } + void setVolume(float volume) { _volume = volume; } + + const glm::quat& getOrientation() const { return _orientation; } + void setOrientation(const glm::quat& orientation) { _orientation = orientation; } + + bool shouldLoopback() const { return _shouldLoopback; } + void setShouldLoopback(bool shouldLoopback) { _shouldLoopback = shouldLoopback; } + + AbstractAudioInterface* getLoopbackAudioInterface() const { return _loopbackAudioInterface; } + void setLoopbackAudioInterface(AbstractAudioInterface* loopbackAudioInterface) + { _loopbackAudioInterface = loopbackAudioInterface; } +private: + glm::vec3 _position; + float _volume; + glm::quat _orientation; + bool _shouldLoopback; + AbstractAudioInterface* _loopbackAudioInterface; }; #endif /* defined(__hifi__AudioInjectorOptions__) */ diff --git a/libraries/audio/src/AudioScriptingInterface.cpp b/libraries/audio/src/AudioScriptingInterface.cpp index 3a943914a4..fba0828c77 100644 --- a/libraries/audio/src/AudioScriptingInterface.cpp +++ b/libraries/audio/src/AudioScriptingInterface.cpp @@ -10,9 +10,9 @@ #include "AudioScriptingInterface.h" -void AudioScriptingInterface::playSound(Sound* sound, AudioInjectorOptions injectorOptions) { +void AudioScriptingInterface::playSound(Sound* sound, const AudioInjectorOptions* injectorOptions) { - AudioInjector* injector = new AudioInjector(sound, injectorOptions); + AudioInjector* injector = new AudioInjector(sound, *injectorOptions); QThread* injectorThread = new QThread(); diff --git a/libraries/audio/src/AudioScriptingInterface.h b/libraries/audio/src/AudioScriptingInterface.h index a36a6dc61b..9202c5a014 100644 --- a/libraries/audio/src/AudioScriptingInterface.h +++ b/libraries/audio/src/AudioScriptingInterface.h @@ -17,7 +17,7 @@ const AudioInjectorOptions DEFAULT_INJECTOR_OPTIONS; class AudioScriptingInterface : public QObject { Q_OBJECT public slots: - static void playSound(Sound* sound, AudioInjectorOptions injectorOptions = DEFAULT_INJECTOR_OPTIONS); + static void playSound(Sound* sound, const AudioInjectorOptions* injectorOptions = NULL); }; #endif /* defined(__hifi__AudioScriptingInterface__) */ diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 485e7ffcce..64bcb93696 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -90,6 +90,8 @@ bool ScriptEngine::setScriptContents(const QString& scriptContents) { return true; } +Q_SCRIPT_DECLARE_QMETAOBJECT(AudioInjectorOptions, QObject*) + void ScriptEngine::run() { _isRunning = true; QScriptEngine engine; @@ -109,10 +111,14 @@ void ScriptEngine::run() { QScriptValue particleScripterValue = engine.newQObject(&_particlesScriptingInterface); engine.globalObject().setProperty("Particles", particleScripterValue); + QScriptValue soundConstructorValue = engine.newFunction(soundConstructor); QScriptValue soundMetaObject = engine.newQMetaObject(&Sound::staticMetaObject, soundConstructorValue); engine.globalObject().setProperty("Sound", soundMetaObject); + QScriptValue injectionOptionValue = engine.scriptValueFromQMetaObject(); + engine.globalObject().setProperty("AudioInjectionOptions", injectionOptionValue); + QScriptValue audioScriptingInterfaceValue = engine.newQObject(&_audioScriptingInterface); engine.globalObject().setProperty("Audio", audioScriptingInterfaceValue); diff --git a/libraries/shared/src/RegisteredMetaTypes.h b/libraries/shared/src/RegisteredMetaTypes.h index b5d3d80e2f..4d91a21be7 100644 --- a/libraries/shared/src/RegisteredMetaTypes.h +++ b/libraries/shared/src/RegisteredMetaTypes.h @@ -12,6 +12,7 @@ #define hifi_RegisteredMetaTypes_h #include + #include #include "SharedUtil.h" From 339ef93fc448d0ea00885e2fbde4aa4a62301b58 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 3 Jan 2014 09:41:01 -0800 Subject: [PATCH 5/7] remove no longer needed QDebug includes --- assignment-client/src/audio/AudioMixerClientData.cpp | 2 -- libraries/audio/src/AudioScriptingInterface.cpp | 2 -- 2 files changed, 4 deletions(-) diff --git a/assignment-client/src/audio/AudioMixerClientData.cpp b/assignment-client/src/audio/AudioMixerClientData.cpp index 011a14c38f..b876e5290d 100644 --- a/assignment-client/src/audio/AudioMixerClientData.cpp +++ b/assignment-client/src/audio/AudioMixerClientData.cpp @@ -9,8 +9,6 @@ #include #include -#include - #include "InjectedAudioRingBuffer.h" #include "AudioMixerClientData.h" diff --git a/libraries/audio/src/AudioScriptingInterface.cpp b/libraries/audio/src/AudioScriptingInterface.cpp index fba0828c77..8c08fe3d8b 100644 --- a/libraries/audio/src/AudioScriptingInterface.cpp +++ b/libraries/audio/src/AudioScriptingInterface.cpp @@ -6,8 +6,6 @@ // Copyright (c) 2013 HighFidelity, Inc. All rights reserved. // -#include - #include "AudioScriptingInterface.h" void AudioScriptingInterface::playSound(Sound* sound, const AudioInjectorOptions* injectorOptions) { From 2a422b84f22ade89228fde823173c0b4d13ec137 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 3 Jan 2014 09:49:32 -0800 Subject: [PATCH 6/7] fix broken build by removing ASI as friend to AI --- libraries/audio/src/AudioInjector.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/libraries/audio/src/AudioInjector.h b/libraries/audio/src/AudioInjector.h index 48d80c01c7..6b1f60e0f9 100644 --- a/libraries/audio/src/AudioInjector.h +++ b/libraries/audio/src/AudioInjector.h @@ -24,13 +24,11 @@ class AudioScriptingInterface; class AudioInjector : public QObject { Q_OBJECT public: - friend AudioScriptingInterface; -private: AudioInjector(Sound* sound, const AudioInjectorOptions& injectorOptions); - +private: Sound* _sound; AudioInjectorOptions _options; -private slots: +public slots: void injectAudio(); signals: void finished(); From 6f60a22c07a6011f0eb613dcfa989a7cd98f74e4 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 3 Jan 2014 09:50:13 -0800 Subject: [PATCH 7/7] fix copyright years --- libraries/audio/src/AudioInjector.cpp | 2 +- libraries/audio/src/AudioInjector.h | 2 +- libraries/audio/src/AudioInjectorOptions.cpp | 2 +- libraries/audio/src/AudioInjectorOptions.h | 2 +- libraries/audio/src/AudioScriptingInterface.cpp | 2 +- libraries/audio/src/AudioScriptingInterface.h | 2 +- libraries/audio/src/Sound.cpp | 2 +- libraries/audio/src/Sound.h | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libraries/audio/src/AudioInjector.cpp b/libraries/audio/src/AudioInjector.cpp index 906702210a..51b289c91d 100644 --- a/libraries/audio/src/AudioInjector.cpp +++ b/libraries/audio/src/AudioInjector.cpp @@ -3,7 +3,7 @@ // hifi // // Created by Stephen Birarda on 1/2/2014. -// Copyright (c) 2013 HighFidelity, Inc. All rights reserved. +// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. // #include diff --git a/libraries/audio/src/AudioInjector.h b/libraries/audio/src/AudioInjector.h index 6b1f60e0f9..1e09a2c3c2 100644 --- a/libraries/audio/src/AudioInjector.h +++ b/libraries/audio/src/AudioInjector.h @@ -3,7 +3,7 @@ // hifi // // Created by Stephen Birarda on 1/2/2014. -// Copyright (c) 2013 HighFidelity, Inc. All rights reserved. +// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. // #ifndef __hifi__AudioInjector__ diff --git a/libraries/audio/src/AudioInjectorOptions.cpp b/libraries/audio/src/AudioInjectorOptions.cpp index a24f13e800..17307890ce 100644 --- a/libraries/audio/src/AudioInjectorOptions.cpp +++ b/libraries/audio/src/AudioInjectorOptions.cpp @@ -3,7 +3,7 @@ // hifi // // Created by Stephen Birarda on 1/2/2014. -// Copyright (c) 2013 HighFidelity, Inc. All rights reserved. +// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. // #include "AudioInjectorOptions.h" diff --git a/libraries/audio/src/AudioInjectorOptions.h b/libraries/audio/src/AudioInjectorOptions.h index 2792f0069c..0f4fa39ef7 100644 --- a/libraries/audio/src/AudioInjectorOptions.h +++ b/libraries/audio/src/AudioInjectorOptions.h @@ -3,7 +3,7 @@ // hifi // // Created by Stephen Birarda on 1/2/2014. -// Copyright (c) 2013 HighFidelity, Inc. All rights reserved. +// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. // #ifndef __hifi__AudioInjectorOptions__ diff --git a/libraries/audio/src/AudioScriptingInterface.cpp b/libraries/audio/src/AudioScriptingInterface.cpp index 8c08fe3d8b..9df283e2ff 100644 --- a/libraries/audio/src/AudioScriptingInterface.cpp +++ b/libraries/audio/src/AudioScriptingInterface.cpp @@ -3,7 +3,7 @@ // hifi // // Created by Stephen Birarda on 1/2/2014. -// Copyright (c) 2013 HighFidelity, Inc. All rights reserved. +// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. // #include "AudioScriptingInterface.h" diff --git a/libraries/audio/src/AudioScriptingInterface.h b/libraries/audio/src/AudioScriptingInterface.h index 9202c5a014..bded426cbd 100644 --- a/libraries/audio/src/AudioScriptingInterface.h +++ b/libraries/audio/src/AudioScriptingInterface.h @@ -3,7 +3,7 @@ // hifi // // Created by Stephen Birarda on 1/2/2014. -// Copyright (c) 2013 HighFidelity, Inc. All rights reserved. +// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. // #ifndef __hifi__AudioScriptingInterface__ diff --git a/libraries/audio/src/Sound.cpp b/libraries/audio/src/Sound.cpp index aef926bb10..02f8aaef9c 100644 --- a/libraries/audio/src/Sound.cpp +++ b/libraries/audio/src/Sound.cpp @@ -3,7 +3,7 @@ // hifi // // Created by Stephen Birarda on 1/2/2014. -// Copyright (c) 2013 HighFidelity, Inc. All rights reserved. +// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. // #include diff --git a/libraries/audio/src/Sound.h b/libraries/audio/src/Sound.h index dea15674e0..82b59c8b49 100644 --- a/libraries/audio/src/Sound.h +++ b/libraries/audio/src/Sound.h @@ -3,7 +3,7 @@ // hifi // // Created by Stephen Birarda on 1/2/2014. -// Copyright (c) 2013 HighFidelity, Inc. All rights reserved. +// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. // #ifndef __hifi__Sound__