mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 20:33:09 +02:00
Initial script engine audio listener
This commit is contained in:
parent
2986352e7e
commit
803be053e9
5 changed files with 107 additions and 0 deletions
|
@ -448,6 +448,34 @@ void AudioClient::setAudioPaused(bool pause) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QUuid AudioClient::registerScriptListener() {
|
||||||
|
std::lock_guard<std::mutex> lock(_scriptListenersMutex);
|
||||||
|
QUuid listenerID = QUuid::createUuid();
|
||||||
|
while (_scriptListeners.contains(listenerID)) {
|
||||||
|
listenerID = QUuid::createUuid();
|
||||||
|
}
|
||||||
|
_scriptListeners.insert(listenerID, std::make_shared<ScriptAudioListener>());
|
||||||
|
return listenerID;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioClient::unregisterScriptListener(const QUuid& listener) {
|
||||||
|
std::lock_guard<std::mutex> lock(_scriptListenersMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray AudioClient::getPCMData(const QUuid& listenerID) {
|
||||||
|
std::shared_ptr<ScriptAudioListener> listener;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(_scriptListenersMutex);
|
||||||
|
if (_scriptListeners.contains(listenerID)) {
|
||||||
|
listener = _scriptListeners[listenerID];
|
||||||
|
} else {
|
||||||
|
qDebug() << "AudioClient::getPCMData: Script listener doesn't exist: " << listenerID;
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return listener->getData();
|
||||||
|
}
|
||||||
|
|
||||||
HifiAudioDeviceInfo getNamedAudioDeviceForMode(QAudio::Mode mode, const QString& deviceName, const QString& hmdName, bool isHmd=false) {
|
HifiAudioDeviceInfo getNamedAudioDeviceForMode(QAudio::Mode mode, const QString& deviceName, const QString& hmdName, bool isHmd=false) {
|
||||||
HifiAudioDeviceInfo result;
|
HifiAudioDeviceInfo result;
|
||||||
foreach (HifiAudioDeviceInfo audioDevice, getAvailableDevices(mode,hmdName)) {
|
foreach (HifiAudioDeviceInfo audioDevice, getAvailableDevices(mode,hmdName)) {
|
||||||
|
@ -2450,6 +2478,18 @@ qint64 AudioClient::AudioOutputIODevice::readData(char * data, qint64 maxSize) {
|
||||||
_audio->_audioFileWav.addRawAudioChunk(data, bytesWritten);
|
_audio->_audioFileWav.addRawAudioChunk(data, bytesWritten);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Send audio data to script engines.
|
||||||
|
// Hash table needs to be copied to avoid deadlocks and improve performance
|
||||||
|
QHash<QUuid, std::shared_ptr<ScriptAudioListener>> scriptListeners;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(_audio->_scriptListenersMutex);
|
||||||
|
scriptListeners = _audio->_scriptListeners;
|
||||||
|
}
|
||||||
|
QByteArray dataArray(data, bytesWritten);
|
||||||
|
for (auto listener : _audio->_scriptListeners) {
|
||||||
|
listener->putData(dataArray);
|
||||||
|
}
|
||||||
|
|
||||||
int bytesAudioOutputUnplayed = _audio->_audioOutput->bufferSize() - _audio->_audioOutput->bytesFree();
|
int bytesAudioOutputUnplayed = _audio->_audioOutput->bufferSize() - _audio->_audioOutput->bytesFree();
|
||||||
float msecsAudioOutputUnplayed = bytesAudioOutputUnplayed / (float)_audio->_outputFormat.bytesForDuration(USECS_PER_MSEC);
|
float msecsAudioOutputUnplayed = bytesAudioOutputUnplayed / (float)_audio->_outputFormat.bytesForDuration(USECS_PER_MSEC);
|
||||||
_audio->_stats.updateOutputMsUnplayed(msecsAudioOutputUnplayed);
|
_audio->_stats.updateOutputMsUnplayed(msecsAudioOutputUnplayed);
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
|
|
||||||
#include <plugins/CodecPlugin.h>
|
#include <plugins/CodecPlugin.h>
|
||||||
|
|
||||||
|
#include "AudioScriptingInterface.h"
|
||||||
#include "AudioIOStats.h"
|
#include "AudioIOStats.h"
|
||||||
#include "AudioFileWav.h"
|
#include "AudioFileWav.h"
|
||||||
#include "HifiAudioDeviceInfo.h"
|
#include "HifiAudioDeviceInfo.h"
|
||||||
|
@ -187,6 +188,10 @@ public:
|
||||||
|
|
||||||
AudioSolo& getAudioSolo() override { return _solo; }
|
AudioSolo& getAudioSolo() override { return _solo; }
|
||||||
|
|
||||||
|
QUuid registerScriptListener() override;
|
||||||
|
void unregisterScriptListener(const QUuid& listenerID) override;
|
||||||
|
QByteArray getPCMData(const QUuid& listener) override;
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
static QString getWinDeviceName(wchar_t* guid);
|
static QString getWinDeviceName(wchar_t* guid);
|
||||||
#endif
|
#endif
|
||||||
|
@ -535,6 +540,9 @@ private:
|
||||||
Mutex _checkPeakValuesMutex;
|
Mutex _checkPeakValuesMutex;
|
||||||
QTimer* _checkPeakValuesTimer { nullptr };
|
QTimer* _checkPeakValuesTimer { nullptr };
|
||||||
|
|
||||||
|
Mutex _scriptListenersMutex;
|
||||||
|
QHash<QUuid, std::shared_ptr<ScriptAudioListener>> _scriptListeners;
|
||||||
|
|
||||||
bool _isRecording { false };
|
bool _isRecording { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,10 @@ public:
|
||||||
|
|
||||||
virtual AudioSolo& getAudioSolo() = 0;
|
virtual AudioSolo& getAudioSolo() = 0;
|
||||||
|
|
||||||
|
virtual QUuid registerScriptListener() = 0;
|
||||||
|
virtual void unregisterScriptListener(const QUuid& listener) = 0;
|
||||||
|
virtual QByteArray getPCMData(const QUuid& listener) = 0;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
virtual bool shouldLoopbackInjectors() { return false; }
|
virtual bool shouldLoopbackInjectors() { return false; }
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,22 @@ void registerAudioMetaTypes(ScriptEngine* engine) {
|
||||||
scriptRegisterMetaType<SharedSoundPointer, soundSharedPointerToScriptValue, soundSharedPointerFromScriptValue>(engine);
|
scriptRegisterMetaType<SharedSoundPointer, soundSharedPointerToScriptValue, soundSharedPointerFromScriptValue>(engine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QByteArray ScriptAudioListener::getData() {
|
||||||
|
QByteArray result;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(_dataMutex);
|
||||||
|
while (!_data.empty()) {
|
||||||
|
result.append(_data.front());
|
||||||
|
_data.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptAudioListener::putData(const QByteArray &data) {
|
||||||
|
std::lock_guard<std::mutex> lock(_dataMutex);
|
||||||
|
_data.push(data);
|
||||||
|
}
|
||||||
|
|
||||||
void AudioScriptingInterface::setLocalAudioInterface(AbstractAudioInterface* audioInterface) {
|
void AudioScriptingInterface::setLocalAudioInterface(AbstractAudioInterface* audioInterface) {
|
||||||
if (_localAudioInterface) {
|
if (_localAudioInterface) {
|
||||||
|
@ -96,6 +112,28 @@ bool AudioScriptingInterface::isStereoInput() {
|
||||||
return stereoEnabled;
|
return stereoEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QUuid AudioScriptingInterface::registerScriptListener() {
|
||||||
|
if (_localAudioInterface) {
|
||||||
|
return _localAudioInterface->registerScriptListener();
|
||||||
|
} else {
|
||||||
|
return QUuid();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioScriptingInterface::unregisterScriptListener(const QUuid& listener) {
|
||||||
|
if (_localAudioInterface) {
|
||||||
|
_localAudioInterface->unregisterScriptListener(listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray AudioScriptingInterface::getPCMData(const QUuid& listener) {
|
||||||
|
if (_localAudioInterface) {
|
||||||
|
return _localAudioInterface->getPCMData(listener);
|
||||||
|
} else {
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool AudioScriptingInterface::getServerEcho() {
|
bool AudioScriptingInterface::getServerEcho() {
|
||||||
bool serverEchoEnabled = false;
|
bool serverEchoEnabled = false;
|
||||||
if (_localAudioInterface) {
|
if (_localAudioInterface) {
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
#ifndef hifi_AudioScriptingInterface_h
|
#ifndef hifi_AudioScriptingInterface_h
|
||||||
#define hifi_AudioScriptingInterface_h
|
#define hifi_AudioScriptingInterface_h
|
||||||
|
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
#include "AbstractAudioInterface.h"
|
#include "AbstractAudioInterface.h"
|
||||||
#include "AudioInjector.h"
|
#include "AudioInjector.h"
|
||||||
#include <DependencyManager.h>
|
#include <DependencyManager.h>
|
||||||
|
@ -25,6 +27,17 @@
|
||||||
class ScriptAudioInjector;
|
class ScriptAudioInjector;
|
||||||
class ScriptEngine;
|
class ScriptEngine;
|
||||||
|
|
||||||
|
class ScriptAudioListener {
|
||||||
|
//TODO: add total data size limit
|
||||||
|
//TODO: unregister on script engine destruction
|
||||||
|
public:
|
||||||
|
QByteArray getData();
|
||||||
|
void putData(const QByteArray &data);
|
||||||
|
private:
|
||||||
|
std::mutex _dataMutex;
|
||||||
|
std::queue<QByteArray> _data;
|
||||||
|
};
|
||||||
|
|
||||||
/// Provides the <code><a href="https://apidocs.overte.org/Audio.html">Audio</a></code> scripting API
|
/// Provides the <code><a href="https://apidocs.overte.org/Audio.html">Audio</a></code> scripting API
|
||||||
class AudioScriptingInterface : public QObject, public Dependency {
|
class AudioScriptingInterface : public QObject, public Dependency {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -224,6 +237,10 @@ protected:
|
||||||
*/
|
*/
|
||||||
Q_INVOKABLE bool isStereoInput();
|
Q_INVOKABLE bool isStereoInput();
|
||||||
|
|
||||||
|
Q_INVOKABLE QUuid registerScriptListener();
|
||||||
|
Q_INVOKABLE void unregisterScriptListener(const QUuid& listener);
|
||||||
|
Q_INVOKABLE QByteArray getPCMData(const QUuid& listener);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
/*@jsdoc
|
/*@jsdoc
|
||||||
|
|
Loading…
Reference in a new issue