mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-03 22:45:33 +02:00
add AudioInjectorLocalBuffer for more control
This commit is contained in:
parent
0e30c65e60
commit
a5a02b5f8a
8 changed files with 136 additions and 31 deletions
|
@ -38,7 +38,8 @@ var panelsCenterShift = Vec3.subtract(panelsCenter, orbCenter);
|
|||
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 droneSound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Lobby/latin.raw")
|
||||
var currentDrone;
|
||||
|
||||
function reticlePosition() {
|
||||
|
|
|
@ -1336,21 +1336,25 @@ void Audio::startDrumSound(float volume, float frequency, float duration, float
|
|||
_drumSoundSample = 0;
|
||||
}
|
||||
|
||||
QIODevice* Audio::newLocalOutputDevice(bool isStereo, qreal volume, int numBytes, AudioInjector* injector) {
|
||||
QAudioFormat localFormat = _desiredOutputFormat;
|
||||
localFormat.setChannelCount(isStereo ? 2 : 1);
|
||||
bool Audio::outputLocalInjector(bool isStereo, qreal volume, AudioInjector* injector) {
|
||||
if (injector->getLocalBuffer()) {
|
||||
QAudioFormat localFormat = _desiredOutputFormat;
|
||||
localFormat.setChannelCount(isStereo ? 2 : 1);
|
||||
|
||||
QAudioOutput* localOutput = new QAudioOutput(getNamedAudioDeviceForMode(QAudio::AudioOutput, _outputAudioDeviceName),
|
||||
localFormat, this);
|
||||
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);
|
||||
|
||||
localOutput->start(injector->getLocalBuffer());
|
||||
return localOutput->state() == QAudio::ActiveState;
|
||||
}
|
||||
|
||||
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();
|
||||
return false;
|
||||
}
|
||||
|
||||
void Audio::cleanupLocalOutputInterface() {
|
||||
|
|
|
@ -155,7 +155,7 @@ public slots:
|
|||
void selectAudioFilterBassCut();
|
||||
void selectAudioFilterSmiley();
|
||||
|
||||
virtual QIODevice* newLocalOutputDevice(bool isStereo, qreal volume, int numBytes, AudioInjector* injector);
|
||||
virtual bool outputLocalInjector(bool isStereo, qreal volume, AudioInjector* injector);
|
||||
|
||||
void sendDownstreamAudioStatsPacket();
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "AudioInjectorOptions.h"
|
||||
|
||||
class AudioInjector;
|
||||
class AudioInjectorLocalBuffer;
|
||||
|
||||
class AbstractAudioInterface : public QObject {
|
||||
Q_OBJECT
|
||||
|
@ -27,7 +28,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, qreal volume, int numBytes, AudioInjector* injector) = 0;
|
||||
virtual bool outputLocalInjector(bool isStereo, qreal volume, AudioInjector* injector) = 0;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(AbstractAudioInterface*)
|
||||
|
|
|
@ -37,7 +37,7 @@ AudioInjector::AudioInjector(QObject* parent) :
|
|||
_loudness(0.0f),
|
||||
_isFinished(false),
|
||||
_currentSendPosition(0),
|
||||
_localDevice(NULL)
|
||||
_localBuffer(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -47,10 +47,17 @@ AudioInjector::AudioInjector(Sound* sound, const AudioInjectorOptions& injectorO
|
|||
_shouldStop(false),
|
||||
_loudness(0.0f),
|
||||
_isFinished(false),
|
||||
_currentSendPosition(0)
|
||||
_currentSendPosition(0),
|
||||
_localBuffer(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
AudioInjector::~AudioInjector() {
|
||||
if (_localBuffer) {
|
||||
_localBuffer->stop();
|
||||
}
|
||||
}
|
||||
|
||||
void AudioInjector::setOptions(AudioInjectorOptions& options) {
|
||||
_options = options;
|
||||
}
|
||||
|
@ -72,19 +79,25 @@ void AudioInjector::injectLocally() {
|
|||
const QByteArray& soundByteArray = _sound->getByteArray();
|
||||
|
||||
if (soundByteArray.size() > 0) {
|
||||
QMetaObject::invokeMethod(_localAudioInterface, "newLocalOutputDevice", Qt::BlockingQueuedConnection,
|
||||
Q_RETURN_ARG(QIODevice*, _localDevice),
|
||||
bool successfulOutput = false;
|
||||
|
||||
_localBuffer = new AudioInjectorLocalBuffer(_sound->getByteArray(), this);
|
||||
_localBuffer->open(QIODevice::ReadOnly);
|
||||
_localBuffer->setIsLooping(_options.loop);
|
||||
|
||||
qDebug() << "Passing off AudioInjectorLocatBuffer to localAudioInterface";
|
||||
|
||||
QMetaObject::invokeMethod(_localAudioInterface, "outputLocalInjector",
|
||||
Qt::BlockingQueuedConnection,
|
||||
Q_RETURN_ARG(bool, successfulOutput),
|
||||
Q_ARG(bool, _options.stereo),
|
||||
Q_ARG(qreal, _options.volume),
|
||||
Q_ARG(int, soundByteArray.size()),
|
||||
Q_ARG(AudioInjector*, this));
|
||||
|
||||
if (_localDevice) {
|
||||
// immediately write the byte array to the local 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";
|
||||
|
||||
|
||||
if (!successfulOutput) {
|
||||
qDebug() << "AudioInjector::injectLocally could not output locally via _localAudioInterface";
|
||||
}
|
||||
} else {
|
||||
qDebug() << "AudioInjector::injectLocally called without any data in Sound QByteArray";
|
||||
|
@ -224,8 +237,11 @@ void AudioInjector::injectToMixer() {
|
|||
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
|
||||
if (_localBuffer) {
|
||||
// we're only a local injector, so we can say we are finished right away too
|
||||
|
||||
_localBuffer->stop();
|
||||
|
||||
_isFinished = true;
|
||||
emit finished();
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <glm/glm.hpp>
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
|
||||
#include "AudioInjectorLocalBuffer.h"
|
||||
#include "AudioInjectorOptions.h"
|
||||
#include "Sound.h"
|
||||
|
||||
|
@ -28,10 +29,14 @@ class AudioInjector : public QObject {
|
|||
public:
|
||||
AudioInjector(QObject* parent);
|
||||
AudioInjector(Sound* sound, const AudioInjectorOptions& injectorOptions);
|
||||
~AudioInjector();
|
||||
|
||||
bool isFinished() const { return _isFinished; }
|
||||
int getCurrentSendPosition() const { return _currentSendPosition; }
|
||||
|
||||
AudioInjectorLocalBuffer* getLocalBuffer() const { return _localBuffer; }
|
||||
bool isLocalOnly() const { return _options.localOnly; }
|
||||
|
||||
void setLocalAudioInterface(AbstractAudioInterface* localAudioInterface) { _localAudioInterface = localAudioInterface; }
|
||||
public slots:
|
||||
void injectAudio();
|
||||
|
@ -53,7 +58,7 @@ private:
|
|||
bool _isFinished;
|
||||
int _currentSendPosition;
|
||||
AbstractAudioInterface* _localAudioInterface;
|
||||
QIODevice* _localDevice;
|
||||
AudioInjectorLocalBuffer* _localBuffer;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(AudioInjector*)
|
||||
|
|
43
libraries/audio/src/AudioInjectorLocalBuffer.cpp
Normal file
43
libraries/audio/src/AudioInjectorLocalBuffer.cpp
Normal file
|
@ -0,0 +1,43 @@
|
|||
//
|
||||
// AudioInjectorLocalBuffer.cpp
|
||||
// libraries/audio/src
|
||||
//
|
||||
// Created by Stephen Birarda on 2014-11-11.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "AudioInjectorLocalBuffer.h"
|
||||
|
||||
AudioInjectorLocalBuffer::AudioInjectorLocalBuffer(const QByteArray& rawAudioArray, QObject* parent) :
|
||||
QIODevice(parent),
|
||||
_rawAudioArray(rawAudioArray),
|
||||
_isLooping(false),
|
||||
_isStopped(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void AudioInjectorLocalBuffer::stop() {
|
||||
_isStopped = true;
|
||||
QIODevice::close();
|
||||
}
|
||||
|
||||
qint64 AudioInjectorLocalBuffer::readData(char* data, qint64 maxSize) {
|
||||
if (!_isStopped) {
|
||||
int bytesToEnd = _rawAudioArray.size() - pos();
|
||||
|
||||
int bytesToRead = maxSize;
|
||||
|
||||
if (maxSize > bytesToEnd) {
|
||||
bytesToRead = bytesToEnd;
|
||||
}
|
||||
|
||||
memcpy(data, _rawAudioArray.data() + pos(), bytesToRead);
|
||||
return bytesToRead;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
35
libraries/audio/src/AudioInjectorLocalBuffer.h
Normal file
35
libraries/audio/src/AudioInjectorLocalBuffer.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
//
|
||||
// AudioInjectorLocalBuffer.h
|
||||
// libraries/audio/src
|
||||
//
|
||||
// Created by Stephen Birarda on 2014-11-11.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_AudioInjectorLocalBuffer_h
|
||||
#define hifi_AudioInjectorLocalBuffer_h
|
||||
|
||||
#include <QtCore/qiodevice.h>
|
||||
|
||||
class AudioInjectorLocalBuffer : public QIODevice {
|
||||
Q_OBJECT
|
||||
public:
|
||||
AudioInjectorLocalBuffer(const QByteArray& rawAudioArray, QObject* parent);
|
||||
|
||||
void stop();
|
||||
|
||||
qint64 readData(char* data, qint64 maxSize);
|
||||
qint64 writeData(const char* data, qint64 maxSize) { return 0; }
|
||||
|
||||
void setIsLooping(bool isLooping) { _isLooping = isLooping; }
|
||||
|
||||
private:
|
||||
QByteArray _rawAudioArray;
|
||||
bool _isLooping;
|
||||
bool _isStopped;
|
||||
};
|
||||
|
||||
#endif // hifi_AudioInjectorLocalBuffer_h
|
Loading…
Reference in a new issue