handle cleanup of local injection, volume

This commit is contained in:
Stephen Birarda 2014-11-11 15:12:11 -08:00
parent 83529c1fed
commit 0e30c65e60
7 changed files with 60 additions and 25 deletions

View file

@ -39,6 +39,7 @@ var ORB_SHIFT = { x: 0, y: -1.4, z: -0.8};
var HELMET_ATTACHMENT_URL = HIFI_PUBLIC_BUCKET + "models/attachments/IronManMaskOnly.fbx"
var droneSound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Lobby/drone.raw")
var currentDrone;
function reticlePosition() {
var RETICLE_DISTANCE = 1;
@ -90,7 +91,7 @@ function drawLobby() {
MyAvatar.attach(HELMET_ATTACHMENT_URL, "Neck", {x: 0, y: 0, z: 0}, Quat.fromPitchYawRollDegrees(0, 0, 0), 1.15);
// start the drone sound
Audio.playSound(droneSound, { stereo: true, localOnly: true });
currentDrone = Audio.playSound(droneSound, { stereo: true, localOnly: true });
}
}
@ -121,6 +122,9 @@ function cleanupLobby() {
Overlays.deleteOverlay(orbShell);
Overlays.deleteOverlay(reticle);
currentDrone.stop();
currentDrone = null;
panelWall = false;
orbShell = false;
reticle = false;

View file

@ -453,23 +453,22 @@ Application::~Application() {
// ask the datagram processing thread to quit and wait until it is done
_nodeThread->quit();
_nodeThread->wait();
// kill any audio injectors that are still around
AudioScriptingInterface::getInstance().stopAllInjectors();
// stop the audio process
QMetaObject::invokeMethod(&_audio, "stop");
// ask the audio thread to quit and wait until it is done
_audio.thread()->quit();
_audio.thread()->wait();
// kill any audio injectors that are still around
AudioScriptingInterface::getInstance().stopAllInjectors();
_octreeProcessor.terminate();
_voxelHideShowThread.terminate();
_voxelEditSender.terminate();
_entityEditSender.terminate();
VoxelTreeElement::removeDeleteHook(&_voxels); // we don't need to do this processing on shutdown
Menu::getInstance()->deleteLater();

View file

@ -32,19 +32,21 @@
#include <QtMultimedia/QAudioOutput>
#include <QSvgRenderer>
#include <glm/glm.hpp>
#include <AudioInjector.h>
#include <NodeList.h>
#include <PacketHeaders.h>
#include <SharedUtil.h>
#include <StDev.h>
#include <UUID.h>
#include <glm/glm.hpp>
#include "Audio.h"
#include "Menu.h"
#include "Util.h"
#include "PositionalAudioStream.h"
#include "Audio.h"
static const float AUDIO_CALLBACK_MSECS = (float) NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL / (float)SAMPLE_RATE * 1000.0;
static const int NUMBER_OF_NOISE_SAMPLE_FRAMES = 300;
@ -1334,17 +1336,33 @@ void Audio::startDrumSound(float volume, float frequency, float duration, float
_drumSoundSample = 0;
}
QIODevice* Audio::newLocalOutputDevice(bool isStereo, int numBytes, QObject* injector) {
QIODevice* Audio::newLocalOutputDevice(bool isStereo, qreal volume, int numBytes, AudioInjector* injector) {
QAudioFormat localFormat = _desiredOutputFormat;
localFormat.setChannelCount(isStereo ? 2 : 1);
QAudioOutput* localOutput = new QAudioOutput(getNamedAudioDeviceForMode(QAudio::AudioOutput, _outputAudioDeviceName),
localFormat, this);
localOutput->setBufferSize(numBytes);
localOutput->setVolume(volume);
// add this to our list of local injected outputs, we will need to clean it up when the injector says it is done
_injectedOutputInterfaces.insert(injector, localOutput);
connect(injector, &AudioInjector::finished, this, &Audio::cleanupLocalOutputInterface);
return localOutput->start();
}
void Audio::cleanupLocalOutputInterface() {
QAudioOutput* outputInterface = _injectedOutputInterfaces.value(sender());
if (outputInterface) {
qDebug() << "Stopping a QAudioOutput interface since injector" << sender() << "is finished";
outputInterface->stop();
outputInterface->deleteLater();
}
}
void Audio::renderToolBox(int x, int y, bool boxed) {
glEnable(GL_TEXTURE_2D);

View file

@ -155,7 +155,7 @@ public slots:
void selectAudioFilterBassCut();
void selectAudioFilterSmiley();
virtual QIODevice* newLocalOutputDevice(bool isStereo, int numBytes, QObject* injector);
virtual QIODevice* newLocalOutputDevice(bool isStereo, qreal volume, int numBytes, AudioInjector* injector);
void sendDownstreamAudioStatsPacket();
@ -180,11 +180,11 @@ signals:
void processInboundAudio(unsigned int sampleTime, const QByteArray& samples, const QAudioFormat& format);
void processLocalAudio(unsigned int sampleTime, const QByteArray& samples, const QAudioFormat& format);
private slots:
void cleanupLocalOutputInterface();
private:
void outputFormatChanged();
private:
QByteArray firstInputFrame;
QAudioInput* _audioInput;
QAudioFormat _desiredInputFormat;
@ -365,6 +365,8 @@ private:
AudioOutputIODevice _audioOutputIODevice;
WeakRecorderPointer _recorder;
QHash<QObject*, QAudioOutput*> _injectedOutputInterfaces;
};

View file

@ -17,6 +17,8 @@
#include "AudioInjectorOptions.h"
class AudioInjector;
class AbstractAudioInterface : public QObject {
Q_OBJECT
public:
@ -25,7 +27,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 QIODevice* newLocalOutputDevice(bool isStereo, int numBytes, QObject* injector) = 0;
virtual QIODevice* newLocalOutputDevice(bool isStereo, qreal volume, int numBytes, AudioInjector* injector) = 0;
};
Q_DECLARE_METATYPE(AbstractAudioInterface*)

View file

@ -36,7 +36,8 @@ AudioInjector::AudioInjector(QObject* parent) :
_shouldStop(false),
_loudness(0.0f),
_isFinished(false),
_currentSendPosition(0)
_currentSendPosition(0),
_localDevice(NULL)
{
}
@ -67,22 +68,21 @@ void AudioInjector::injectAudio() {
}
void AudioInjector::injectLocally() {
if (_localAudioInterface) {
QIODevice* localBuffer = NULL;
if (_localAudioInterface) {
const QByteArray& soundByteArray = _sound->getByteArray();
if (soundByteArray.size() > 0) {
QMetaObject::invokeMethod(_localAudioInterface, "newLocalOutputDevice", Qt::BlockingQueuedConnection,
Q_RETURN_ARG(QIODevice*, localBuffer),
Q_RETURN_ARG(QIODevice*, _localDevice),
Q_ARG(bool, _options.stereo),
Q_ARG(qreal, _options.volume),
Q_ARG(int, soundByteArray.size()),
Q_ARG(QObject*, this));
Q_ARG(AudioInjector*, this));
if (localBuffer) {
if (_localDevice) {
// immediately write the byte array to the local device
qDebug() << "Writing" << localBuffer->write(soundByteArray) << "bytes to local audio device";
qDebug() << "Writing" << soundByteArray.size() << "bytes to local audio device";
_localDevice->write(soundByteArray);
} else {
qDebug() << "AudioInjector::injectLocally did not get a valid QIODevice from _localAudioInterface";
}
@ -220,3 +220,13 @@ void AudioInjector::injectToMixer() {
_isFinished = true;
emit finished();
}
void AudioInjector::stop() {
_shouldStop = true;
if (_localDevice) {
// we're only a local injector, so we can say we are finished and the AbstractAudioInterface should clean us up
_isFinished = true;
emit finished();
}
}

View file

@ -35,7 +35,7 @@ public:
void setLocalAudioInterface(AbstractAudioInterface* localAudioInterface) { _localAudioInterface = localAudioInterface; }
public slots:
void injectAudio();
void stop() { _shouldStop = true; }
void stop();
void setOptions(AudioInjectorOptions& options);
void setCurrentSendPosition(int currentSendPosition) { _currentSendPosition = currentSendPosition; }
float getLoudness();
@ -53,7 +53,7 @@ private:
bool _isFinished;
int _currentSendPosition;
AbstractAudioInterface* _localAudioInterface;
QIODevice* _localDevice;
};
Q_DECLARE_METATYPE(AudioInjector*)