piping for local UI sounds

This commit is contained in:
Stephen Birarda 2014-11-07 10:08:09 -08:00
parent 3323ac11ff
commit f1a238a6c2
9 changed files with 40 additions and 23 deletions

View file

@ -416,6 +416,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
_trayIcon->show();
// set the local loopback interface for local sounds from audio scripts
AudioScriptingInterface::getInstance().setLocalLoopbackInterface(&_audio);
#ifdef HAVE_RTMIDI
// setup the MIDIManager
MIDIManager& midiManagerInstance = MIDIManager::getInstance();

View file

@ -1331,9 +1331,10 @@ void Audio::startDrumSound(float volume, float frequency, float duration, float
_drumSoundSample = 0;
}
void Audio::handleAudioByteArray(const QByteArray& audioByteArray) {
void Audio::handleAudioByteArray(const QByteArray& audioByteArray, const AudioInjectorOptions& injectorOptions) {
// TODO: either create a new audio device (up to the limit of the sound card or a hard limit)
// or send to the mixer and use delayed loopback
}
void Audio::renderToolBox(int x, int y, bool boxed) {

View file

@ -155,7 +155,7 @@ public slots:
void selectAudioFilterBassCut();
void selectAudioFilterSmiley();
virtual void handleAudioByteArray(const QByteArray& audioByteArray);
virtual void handleAudioByteArray(const QByteArray& audioByteArray, const AudioInjectorOptions& options);
void sendDownstreamAudioStatsPacket();

View file

@ -14,6 +14,8 @@
#include <QtCore/QObject>
#include "AudioInjectorOptions.h"
class AbstractAudioInterface : public QObject {
Q_OBJECT
public:
@ -22,7 +24,7 @@ public:
virtual void startCollisionSound(float magnitude, float frequency, float noise, float duration, bool flashScreen) = 0;
virtual void startDrumSound(float volume, float frequency, float duration, float decay) = 0;
public slots:
virtual void handleAudioByteArray(const QByteArray& audioByteArray) = 0;
virtual void handleAudioByteArray(const QByteArray& audioByteArray, const AudioInjectorOptions& options) = 0;
};
Q_DECLARE_METATYPE(AbstractAudioInterface*)

View file

@ -62,14 +62,6 @@ 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.getLoopbackAudioInterface()) {
// assume that localAudioInterface could be on a separate thread, use Qt::AutoConnection to handle properly
QMetaObject::invokeMethod(_options.getLoopbackAudioInterface(), "handleAudioByteArray",
Qt::AutoConnection,
Q_ARG(QByteArray, soundByteArray));
}
// setup the packet for injected audio
QByteArray injectAudioPacket = byteArrayWithPopulatedHeader(PacketTypeInjectAudio);
@ -86,7 +78,7 @@ void AudioInjector::injectAudio() {
packetStream << _options.isStereo();
// pack the flag for loopback
uchar loopbackFlag = (uchar) (!_options.getLoopbackAudioInterface());
uchar loopbackFlag = (uchar) true;
packetStream << loopbackFlag;
// pack the position for injected audio

View file

@ -18,8 +18,7 @@ AudioInjectorOptions::AudioInjectorOptions(QObject* parent) :
_loop(false),
_orientation(glm::vec3(0.0f, 0.0f, 0.0f)),
_isStereo(false),
_ignorePenumbra(false),
_loopbackAudioInterface(NULL)
_ignorePenumbra(false)
{
}
@ -30,7 +29,6 @@ AudioInjectorOptions::AudioInjectorOptions(const AudioInjectorOptions& other) {
_orientation = other._orientation;
_isStereo = other._isStereo;
_ignorePenumbra = other._ignorePenumbra;
_loopbackAudioInterface = other._loopbackAudioInterface;
}
void AudioInjectorOptions::operator=(const AudioInjectorOptions& other) {
@ -40,5 +38,4 @@ void AudioInjectorOptions::operator=(const AudioInjectorOptions& other) {
_orientation = other._orientation;
_isStereo = other._isStereo;
_ignorePenumbra = other._ignorePenumbra;
_loopbackAudioInterface = other._loopbackAudioInterface;
}

View file

@ -19,8 +19,6 @@
#include <RegisteredMetaTypes.h>
#include "AbstractAudioInterface.h"
class AudioInjectorOptions : public QObject {
Q_OBJECT
@ -53,9 +51,6 @@ public:
const bool ignorePenumbra() const {return _ignorePenumbra; }
void setIgnorePenumbra(bool ignorePenumbra) { _ignorePenumbra = ignorePenumbra; }
AbstractAudioInterface* getLoopbackAudioInterface() const { return _loopbackAudioInterface; }
void setLoopbackAudioInterface(AbstractAudioInterface* loopbackAudioInterface)
{ _loopbackAudioInterface = loopbackAudioInterface; }
private:
glm::vec3 _position;
float _volume;
@ -63,7 +58,8 @@ private:
glm::quat _orientation;
bool _isStereo;
bool _ignorePenumbra;
AbstractAudioInterface* _loopbackAudioInterface;
};
Q_DECLARE_METATYPE(AudioInjectorOptions)
#endif // hifi_AudioInjectorOptions_h

View file

@ -16,6 +16,12 @@ AudioScriptingInterface& AudioScriptingInterface::getInstance() {
return staticInstance;
}
AudioScriptingInterface::AudioScriptingInterface() :
_localLoopbackInterface(NULL)
{
qRegisterMetaType<AudioInjectorOptions>("AudioInjectorOptions");
}
void AudioScriptingInterface::stopAllInjectors() {
QList<QPointer<AudioInjector> >::iterator injector = _activeInjectors.begin();
while (injector != _activeInjectors.end()) {
@ -31,6 +37,18 @@ void AudioScriptingInterface::stopAllInjectors() {
}
}
void AudioScriptingInterface::playLocalSound(Sound* sound, const AudioInjectorOptions* injectorOptions) {
if (sound->isStereo()) {
const_cast<AudioInjectorOptions*>(injectorOptions)->setIsStereo(true);
}
// assume that localAudioInterface could be on a separate thread, use Qt::AutoConnection to handle properly
QMetaObject::invokeMethod(_localLoopbackInterface, "handleAudioByteArray",
Qt::AutoConnection,
Q_ARG(QByteArray, sound->getByteArray()),
Q_ARG(const AudioInjectorOptions&, *injectorOptions));
}
AudioInjector* AudioScriptingInterface::playSound(Sound* sound, const AudioInjectorOptions* injectorOptions) {
if (sound->isStereo()) {

View file

@ -14,9 +14,12 @@
#include <qpointer.h>
#include "AbstractAudioInterface.h"
#include "AudioInjector.h"
#include "Sound.h"
class AbstractAudioInterface;
const AudioInjectorOptions DEFAULT_INJECTOR_OPTIONS;
class AudioScriptingInterface : public QObject {
@ -25,19 +28,24 @@ public:
static AudioScriptingInterface& getInstance();
void stopAllInjectors();
void setLocalLoopbackInterface(AbstractAudioInterface* audioInterface) { _localLoopbackInterface = audioInterface; }
public slots:
static float getLoudness(AudioInjector* injector);
void playLocalSound(Sound *sound, const AudioInjectorOptions* injectorOptions = NULL);
AudioInjector* playSound(Sound* sound, const AudioInjectorOptions* injectorOptions = NULL);
void stopInjector(AudioInjector* injector);
bool isInjectorPlaying(AudioInjector* injector);
void injectorStopped();
private:
AudioScriptingInterface() {};
AudioScriptingInterface();
QList< QPointer<AudioInjector> > _activeInjectors;
AbstractAudioInterface* _localLoopbackInterface;
};