mirror of
https://github.com/overte-org/overte.git
synced 2025-04-19 13:43:49 +02:00
add AudioInjector class to pull samples from URL and inject
This commit is contained in:
parent
9c39bcba4c
commit
eac3b6be65
7 changed files with 118 additions and 37 deletions
|
@ -458,9 +458,31 @@ void Audio::addReceivedAudioToBuffer(const QByteArray& audioByteArray) {
|
|||
int16_t ringBufferSamples[NETWORK_BUFFER_LENGTH_SAMPLES_STEREO];
|
||||
_ringBuffer.readSamples(ringBufferSamples, NETWORK_BUFFER_LENGTH_SAMPLES_STEREO);
|
||||
|
||||
// add the next NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL from each QByteArray
|
||||
// in our _localInjectionByteArrays QVector to the _localInjectedSamples
|
||||
|
||||
// add to the output samples whatever is in the _localAudioOutput byte array
|
||||
// that lets this user hear sound effects and loopback (if enabled)
|
||||
|
||||
for (int b = 0; b < _localInjectionByteArrays.size(); b++) {
|
||||
QByteArray audioByteArray = _localInjectionByteArrays.at(b);
|
||||
|
||||
int16_t* byteArraySamples = (int16_t*) audioByteArray.data();
|
||||
|
||||
for (int i = 0; i < NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL; i++) {
|
||||
_localInjectedSamples[i] = glm::clamp(_localInjectedSamples[i] + byteArraySamples[i],
|
||||
MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE);
|
||||
}
|
||||
|
||||
// pull out the bytes we just read for outputs
|
||||
audioByteArray.remove(0, NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL);
|
||||
|
||||
if (audioByteArray.size() == 0) {
|
||||
// if there isn't anything left to inject from this byte array, remove it from the vector
|
||||
_localInjectionByteArrays.remove(b);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL; i++) {
|
||||
ringBufferSamples[i * 2] = glm::clamp(ringBufferSamples[i * 2] + _localInjectedSamples[i],
|
||||
MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE);
|
||||
|
@ -696,6 +718,11 @@ void Audio::startDrumSound(float volume, float frequency, float duration, float
|
|||
_drumSoundSample = 0;
|
||||
}
|
||||
|
||||
void Audio::handleAudioByteArray(const QByteArray& audioByteArray) {
|
||||
// add this byte array to our QVector
|
||||
_localInjectionByteArrays.append(audioByteArray);
|
||||
}
|
||||
|
||||
void Audio::renderToolIcon(int screenHeight) {
|
||||
|
||||
_iconBounds = QRect(ICON_LEFT, screenHeight - BOTTOM_PADDING, ICON_SIZE, ICON_SIZE);
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "InterfaceConfig.h"
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QVector>
|
||||
#include <QtMultimedia/QAudioFormat>
|
||||
|
||||
#include <AbstractAudioInterface.h>
|
||||
|
@ -31,7 +32,7 @@ class QAudioInput;
|
|||
class QAudioOutput;
|
||||
class QIODevice;
|
||||
|
||||
class Audio : public QObject, public AbstractAudioInterface {
|
||||
class Audio : public AbstractAudioInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
// setup for audio I/O
|
||||
|
@ -51,7 +52,7 @@ public:
|
|||
|
||||
virtual void startCollisionSound(float magnitude, float frequency, float noise, float duration, bool flashScreen);
|
||||
virtual void startDrumSound(float volume, float frequency, float duration, float decay);
|
||||
|
||||
|
||||
float getCollisionSoundMagnitude() { return _collisionSoundMagnitude; }
|
||||
|
||||
bool getCollisionFlashesScreen() { return _collisionFlashesScreen; }
|
||||
|
@ -65,14 +66,17 @@ public slots:
|
|||
void handleAudioInput();
|
||||
void reset();
|
||||
|
||||
virtual void handleAudioByteArray(const QByteArray& audioByteArray);
|
||||
|
||||
private:
|
||||
QByteArray firstInputFrame;
|
||||
QAudioInput* _audioInput;
|
||||
QAudioFormat _desiredInputFormat;
|
||||
QAudioFormat _inputFormat;
|
||||
QIODevice* _inputDevice;
|
||||
int16_t _localInjectedSamples[NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL];
|
||||
int _numInputCallbackBytes;
|
||||
int16_t _localInjectedSamples[NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL];
|
||||
QVector<QByteArray> _localInjectionByteArrays;
|
||||
QAudioOutput* _audioOutput;
|
||||
QAudioFormat _desiredOutputFormat;
|
||||
QAudioFormat _outputFormat;
|
||||
|
|
|
@ -10,10 +10,13 @@
|
|||
#ifndef __hifi__AbstractAudioInterface__
|
||||
#define __hifi__AbstractAudioInterface__
|
||||
|
||||
class AbstractAudioInterface {
|
||||
class AbstractAudioInterface : public QObject {
|
||||
Q_OBJECT
|
||||
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;
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__AbstractAudioInterface__) */
|
|
@ -1,15 +0,0 @@
|
|||
//
|
||||
// AudioInjectionManager.cpp
|
||||
// hifi
|
||||
//
|
||||
// Created by Stephen Birarda on 12/17/2013.
|
||||
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include "AudioInjectionManager.h"
|
||||
|
||||
AudioInjectionManager::AudioInjectionManager(QObject* parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
//
|
||||
// AudioInjectionManager.h
|
||||
// hifi
|
||||
//
|
||||
// Created by Stephen Birarda on 12/17/2013.
|
||||
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef __hifi__AudioInjectionManager__
|
||||
#define __hifi__AudioInjectionManager__
|
||||
|
||||
#include <QtCore/QObject>
|
||||
|
||||
class AudioInjectionManager : public QObject {
|
||||
AudioInjectionManager(QObject* parent = 0);
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__AudioInjectionManager__) */
|
49
libraries/audio/src/AudioInjector.cpp
Normal file
49
libraries/audio/src/AudioInjector.cpp
Normal file
|
@ -0,0 +1,49 @@
|
|||
//
|
||||
// AudioInjector.cpp
|
||||
// hifi
|
||||
//
|
||||
// Created by Stephen Birarda on 12/19/2013.
|
||||
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include <QtNetwork/QNetworkAccessManager>
|
||||
#include <QtNetwork/QNetworkReply>
|
||||
#include <QtNetwork/QNetworkRequest>
|
||||
|
||||
#include "AbstractAudioInterface.h"
|
||||
|
||||
#include "AudioInjector.h"
|
||||
|
||||
AudioInjector::AudioInjector(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
|
||||
|
||||
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
|
||||
connect(manager, SIGNAL(finished(QNetworkReply*)),
|
||||
this, SLOT(replyFinished(QNetworkReply*)));
|
||||
|
||||
manager->get(QNetworkRequest(sampleURL));
|
||||
}
|
||||
|
||||
void AudioInjector::replyFinished(QNetworkReply* reply) {
|
||||
// replace our samples array with the downloaded data
|
||||
_sampleByteArray = reply->readAll();
|
||||
}
|
||||
|
||||
void AudioInjector::injectViaThread(AbstractAudioInterface* localAudioInterface) {
|
||||
// make sure we actually have samples downloaded to inject
|
||||
if (_sampleByteArray.size()) {
|
||||
// give our sample byte array to the local audio interface, if we have it, so it can be handled locally
|
||||
if (localAudioInterface) {
|
||||
// assume that localAudioInterface could be on a separate thread
|
||||
QMetaObject::invokeMethod(localAudioInterface, "handleAudioByteArray",
|
||||
Qt::QueuedConnection,
|
||||
Q_ARG(QByteArray, _sampleByteArray));
|
||||
|
||||
}
|
||||
|
||||
// setup a new thread we can use for the injection
|
||||
}
|
||||
}
|
31
libraries/audio/src/AudioInjector.h
Normal file
31
libraries/audio/src/AudioInjector.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
//
|
||||
// AudioInjector.h
|
||||
// hifi
|
||||
//
|
||||
// Created by Stephen Birarda on 12/19/2013.
|
||||
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef __hifi__AudioInjector__
|
||||
#define __hifi__AudioInjector__
|
||||
|
||||
#include <QtCore/QObject>
|
||||
|
||||
class AbstractAudioInterface;
|
||||
class QNetworkReply;
|
||||
|
||||
class AudioInjector : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
AudioInjector(const QUrl& sampleURL, QObject* parent = 0);
|
||||
~AudioInjector();
|
||||
|
||||
void injectViaThread(AbstractAudioInterface* localAudioInterface = NULL);
|
||||
|
||||
private:
|
||||
QByteArray _sampleByteArray;
|
||||
private slots:
|
||||
void replyFinished(QNetworkReply* reply);
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__AudioInjector__) */
|
Loading…
Reference in a new issue