mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 08:48:53 +02:00
intial removal of Audio to audio-client
This commit is contained in:
parent
57743f126f
commit
0eced09f1d
28 changed files with 1048 additions and 143 deletions
|
@ -10,9 +10,7 @@ setup_hifi_library(Gui Widgets)
|
||||||
|
|
||||||
include_glm()
|
include_glm()
|
||||||
|
|
||||||
set(REQUIRED_HIFI_LIBRARIES "shared" "networking")
|
link_hifi_libraries(shared networking audio-client)
|
||||||
|
|
||||||
link_hifi_libraries(${REQUIRED_HIFI_LIBRARIES})
|
|
||||||
include_dependency_includes()
|
include_dependency_includes()
|
||||||
|
|
||||||
set(ANDROID_SDK_ROOT $ENV{ANDROID_HOME})
|
set(ANDROID_SDK_ROOT $ENV{ANDROID_HOME})
|
||||||
|
|
|
@ -2,7 +2,7 @@ set(TARGET_NAME interface)
|
||||||
project(${TARGET_NAME})
|
project(${TARGET_NAME})
|
||||||
|
|
||||||
# set a default root dir for each of our optional externals if it was not passed
|
# set a default root dir for each of our optional externals if it was not passed
|
||||||
set(OPTIONAL_EXTERNALS "Faceshift" "LibOVR" "PrioVR" "Sixense" "LeapMotion" "RtMidi" "Qxmpp" "SDL2" "Gverb" "RSSDK")
|
set(OPTIONAL_EXTERNALS "Faceshift" "LibOVR" "PrioVR" "Sixense" "LeapMotion" "RtMidi" "Qxmpp" "SDL2" "RSSDK")
|
||||||
foreach(EXTERNAL ${OPTIONAL_EXTERNALS})
|
foreach(EXTERNAL ${OPTIONAL_EXTERNALS})
|
||||||
string(TOUPPER ${EXTERNAL} ${EXTERNAL}_UPPERCASE)
|
string(TOUPPER ${EXTERNAL} ${EXTERNAL}_UPPERCASE)
|
||||||
if (NOT ${${EXTERNAL}_UPPERCASE}_ROOT_DIR)
|
if (NOT ${${EXTERNAL}_UPPERCASE}_ROOT_DIR)
|
||||||
|
@ -14,10 +14,6 @@ endforeach()
|
||||||
find_package(Qt5LinguistTools REQUIRED)
|
find_package(Qt5LinguistTools REQUIRED)
|
||||||
find_package(Qt5LinguistToolsMacros)
|
find_package(Qt5LinguistToolsMacros)
|
||||||
|
|
||||||
|
|
||||||
# As Gverb is currently the only reverb library, it's required.
|
|
||||||
find_package(Gverb REQUIRED)
|
|
||||||
|
|
||||||
if (DEFINED ENV{JOB_ID})
|
if (DEFINED ENV{JOB_ID})
|
||||||
set(BUILD_SEQ $ENV{JOB_ID})
|
set(BUILD_SEQ $ENV{JOB_ID})
|
||||||
else ()
|
else ()
|
||||||
|
@ -108,7 +104,8 @@ endif()
|
||||||
add_executable(${TARGET_NAME} MACOSX_BUNDLE ${INTERFACE_SRCS} ${QM})
|
add_executable(${TARGET_NAME} MACOSX_BUNDLE ${INTERFACE_SRCS} ${QM})
|
||||||
|
|
||||||
# link required hifi libraries
|
# link required hifi libraries
|
||||||
link_hifi_libraries(shared octree environment gpu model fbx metavoxels networking entities avatars audio animation script-engine physics
|
link_hifi_libraries(shared octree environment gpu model fbx metavoxels networking entities avatars
|
||||||
|
audio audio-client animation script-engine physics
|
||||||
render-utils entities-renderer)
|
render-utils entities-renderer)
|
||||||
|
|
||||||
# find any optional and required libraries
|
# find any optional and required libraries
|
||||||
|
@ -173,13 +170,6 @@ if (QXMPP_FOUND AND NOT DISABLE_QXMPP AND WIN32)
|
||||||
add_definitions(-DQXMPP_STATIC)
|
add_definitions(-DQXMPP_STATIC)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if (GVERB_FOUND)
|
|
||||||
file(GLOB GVERB_SRCS ${GVERB_SRC_DIRS}/*.c)
|
|
||||||
include_directories(${GVERB_INCLUDE_DIRS})
|
|
||||||
add_library(gverb STATIC ${GVERB_SRCS})
|
|
||||||
target_link_libraries(${TARGET_NAME} gverb)
|
|
||||||
endif (GVERB_FOUND)
|
|
||||||
|
|
||||||
# include headers for interface and InterfaceConfig.
|
# include headers for interface and InterfaceConfig.
|
||||||
include_directories("${PROJECT_SOURCE_DIR}/src" "${PROJECT_BINARY_DIR}/includes")
|
include_directories("${PROJECT_SOURCE_DIR}/src" "${PROJECT_BINARY_DIR}/includes")
|
||||||
|
|
||||||
|
|
|
@ -162,7 +162,7 @@ bool setupEssentials(int& argc, char** argv) {
|
||||||
auto geometryCache = DependencyManager::set<GeometryCache>();
|
auto geometryCache = DependencyManager::set<GeometryCache>();
|
||||||
auto glowEffect = DependencyManager::set<GlowEffect>();
|
auto glowEffect = DependencyManager::set<GlowEffect>();
|
||||||
auto faceshift = DependencyManager::set<Faceshift>();
|
auto faceshift = DependencyManager::set<Faceshift>();
|
||||||
auto audio = DependencyManager::set<Audio>();
|
auto audio = DependencyManager::set<AudioClient>();
|
||||||
auto audioScope = DependencyManager::set<AudioScope>();
|
auto audioScope = DependencyManager::set<AudioScope>();
|
||||||
auto audioIOStatsRenderer = DependencyManager::set<AudioIOStatsRenderer>();
|
auto audioIOStatsRenderer = DependencyManager::set<AudioIOStatsRenderer>();
|
||||||
auto deferredLightingEffect = DependencyManager::set<DeferredLightingEffect>();
|
auto deferredLightingEffect = DependencyManager::set<DeferredLightingEffect>();
|
||||||
|
@ -278,9 +278,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
||||||
// put the audio processing on a separate thread
|
// put the audio processing on a separate thread
|
||||||
QThread* audioThread = new QThread(this);
|
QThread* audioThread = new QThread(this);
|
||||||
|
|
||||||
auto audioIO = DependencyManager::get<Audio>();
|
auto audioIO = DependencyManager::get<AudioClient>();
|
||||||
audioIO->moveToThread(audioThread);
|
audioIO->moveToThread(audioThread);
|
||||||
connect(audioThread, &QThread::started, audioIO.data(), &Audio::start);
|
connect(audioThread, &QThread::started, audioIO.data(), &AudioClient::start);
|
||||||
|
|
||||||
audioThread->start();
|
audioThread->start();
|
||||||
|
|
||||||
|
@ -476,7 +476,7 @@ Application::~Application() {
|
||||||
// kill any audio injectors that are still around
|
// kill any audio injectors that are still around
|
||||||
AudioScriptingInterface::getInstance().stopAllInjectors();
|
AudioScriptingInterface::getInstance().stopAllInjectors();
|
||||||
|
|
||||||
auto audioIO = DependencyManager::get<Audio>();
|
auto audioIO = DependencyManager::get<AudioClient>();
|
||||||
|
|
||||||
// stop the audio process
|
// stop the audio process
|
||||||
QMetaObject::invokeMethod(audioIO.data(), "stop", Qt::BlockingQueuedConnection);
|
QMetaObject::invokeMethod(audioIO.data(), "stop", Qt::BlockingQueuedConnection);
|
||||||
|
@ -2117,7 +2117,7 @@ void Application::update(float deltaTime) {
|
||||||
if (sinceLastNack > TOO_LONG_SINCE_LAST_SEND_DOWNSTREAM_AUDIO_STATS) {
|
if (sinceLastNack > TOO_LONG_SINCE_LAST_SEND_DOWNSTREAM_AUDIO_STATS) {
|
||||||
_lastSendDownstreamAudioStats = now;
|
_lastSendDownstreamAudioStats = now;
|
||||||
|
|
||||||
QMetaObject::invokeMethod(DependencyManager::get<Audio>().data(), "sendDownstreamAudioStatsPacket", Qt::QueuedConnection);
|
QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(), "sendDownstreamAudioStatsPacket", Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3113,7 +3113,7 @@ void Application::resetSensors() {
|
||||||
|
|
||||||
_myAvatar->reset();
|
_myAvatar->reset();
|
||||||
|
|
||||||
QMetaObject::invokeMethod(DependencyManager::get<Audio>().data(), "reset", Qt::QueuedConnection);
|
QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(), "reset", Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setShortcutsEnabled(QWidget* widget, bool enabled) {
|
static void setShortcutsEnabled(QWidget* widget, bool enabled) {
|
||||||
|
@ -3253,7 +3253,7 @@ void Application::nodeKilled(SharedNodePointer node) {
|
||||||
_entityEditSender.nodeKilled(node);
|
_entityEditSender.nodeKilled(node);
|
||||||
|
|
||||||
if (node->getType() == NodeType::AudioMixer) {
|
if (node->getType() == NodeType::AudioMixer) {
|
||||||
QMetaObject::invokeMethod(DependencyManager::get<Audio>().data(), "audioMixerKilled");
|
QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(), "audioMixerKilled");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->getType() == NodeType::EntityServer) {
|
if (node->getType() == NodeType::EntityServer) {
|
||||||
|
|
|
@ -54,15 +54,15 @@ void DatagramProcessor::processDatagrams() {
|
||||||
case PacketTypeMixedAudio:
|
case PacketTypeMixedAudio:
|
||||||
case PacketTypeSilentAudioFrame: {
|
case PacketTypeSilentAudioFrame: {
|
||||||
if (incomingType == PacketTypeAudioStreamStats) {
|
if (incomingType == PacketTypeAudioStreamStats) {
|
||||||
QMetaObject::invokeMethod(DependencyManager::get<Audio>().data(), "parseAudioStreamStatsPacket",
|
QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(), "parseAudioStreamStatsPacket",
|
||||||
Qt::QueuedConnection,
|
Qt::QueuedConnection,
|
||||||
Q_ARG(QByteArray, incomingPacket));
|
Q_ARG(QByteArray, incomingPacket));
|
||||||
} else if (incomingType == PacketTypeAudioEnvironment) {
|
} else if (incomingType == PacketTypeAudioEnvironment) {
|
||||||
QMetaObject::invokeMethod(DependencyManager::get<Audio>().data(), "parseAudioEnvironmentData",
|
QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(), "parseAudioEnvironmentData",
|
||||||
Qt::QueuedConnection,
|
Qt::QueuedConnection,
|
||||||
Q_ARG(QByteArray, incomingPacket));
|
Q_ARG(QByteArray, incomingPacket));
|
||||||
} else {
|
} else {
|
||||||
QMetaObject::invokeMethod(DependencyManager::get<Audio>().data(), "addReceivedAudioToStream",
|
QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(), "addReceivedAudioToStream",
|
||||||
Qt::QueuedConnection,
|
Qt::QueuedConnection,
|
||||||
Q_ARG(QByteArray, incomingPacket));
|
Q_ARG(QByteArray, incomingPacket));
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,7 @@ void DatagramProcessor::processDatagrams() {
|
||||||
}
|
}
|
||||||
case PacketTypeNoisyMute:
|
case PacketTypeNoisyMute:
|
||||||
case PacketTypeMuteEnvironment: {
|
case PacketTypeMuteEnvironment: {
|
||||||
bool mute = !DependencyManager::get<Audio>()->isMuted();
|
bool mute = !DependencyManager::get<AudioClient>()->isMuted();
|
||||||
|
|
||||||
if (incomingType == PacketTypeMuteEnvironment) {
|
if (incomingType == PacketTypeMuteEnvironment) {
|
||||||
glm::vec3 position;
|
glm::vec3 position;
|
||||||
|
@ -144,7 +144,7 @@ void DatagramProcessor::processDatagrams() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mute) {
|
if (mute) {
|
||||||
DependencyManager::get<Audio>()->toggleMute();
|
DependencyManager::get<AudioClient>()->toggleMute();
|
||||||
if (incomingType == PacketTypeMuteEnvironment) {
|
if (incomingType == PacketTypeMuteEnvironment) {
|
||||||
AudioScriptingInterface::getInstance().environmentMuted();
|
AudioScriptingInterface::getInstance().environmentMuted();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -490,7 +490,7 @@ Menu::Menu() :
|
||||||
addCheckableActionToQMenuAndActionHash(timingMenu, MenuOption::PipelineWarnings);
|
addCheckableActionToQMenuAndActionHash(timingMenu, MenuOption::PipelineWarnings);
|
||||||
addCheckableActionToQMenuAndActionHash(timingMenu, MenuOption::SuppressShortTimings);
|
addCheckableActionToQMenuAndActionHash(timingMenu, MenuOption::SuppressShortTimings);
|
||||||
|
|
||||||
auto audioIO = DependencyManager::get<Audio>();
|
auto audioIO = DependencyManager::get<AudioClient>();
|
||||||
QMenu* audioDebugMenu = developerMenu->addMenu("Audio");
|
QMenu* audioDebugMenu = developerMenu->addMenu("Audio");
|
||||||
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::AudioNoiseReduction,
|
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::AudioNoiseReduction,
|
||||||
0,
|
0,
|
||||||
|
@ -615,7 +615,7 @@ void Menu::loadSettings(QSettings* settings) {
|
||||||
_receivedAudioStreamSettings._windowSecondsForDesiredReduction = settings->value("windowSecondsForDesiredReduction", DEFAULT_WINDOW_SECONDS_FOR_DESIRED_REDUCTION).toInt();
|
_receivedAudioStreamSettings._windowSecondsForDesiredReduction = settings->value("windowSecondsForDesiredReduction", DEFAULT_WINDOW_SECONDS_FOR_DESIRED_REDUCTION).toInt();
|
||||||
_receivedAudioStreamSettings._repetitionWithFade = settings->value("repetitionWithFade", DEFAULT_REPETITION_WITH_FADE).toBool();
|
_receivedAudioStreamSettings._repetitionWithFade = settings->value("repetitionWithFade", DEFAULT_REPETITION_WITH_FADE).toBool();
|
||||||
|
|
||||||
auto audio = DependencyManager::get<Audio>();
|
auto audio = DependencyManager::get<AudioClient>();
|
||||||
audio->setOutputStarveDetectionEnabled(settings->value("audioOutputStarveDetectionEnabled", DEFAULT_AUDIO_OUTPUT_STARVE_DETECTION_ENABLED).toBool());
|
audio->setOutputStarveDetectionEnabled(settings->value("audioOutputStarveDetectionEnabled", DEFAULT_AUDIO_OUTPUT_STARVE_DETECTION_ENABLED).toBool());
|
||||||
audio->setOutputStarveDetectionThreshold(settings->value("audioOutputStarveDetectionThreshold", DEFAULT_AUDIO_OUTPUT_STARVE_DETECTION_THRESHOLD).toInt());
|
audio->setOutputStarveDetectionThreshold(settings->value("audioOutputStarveDetectionThreshold", DEFAULT_AUDIO_OUTPUT_STARVE_DETECTION_THRESHOLD).toInt());
|
||||||
audio->setOutputStarveDetectionPeriod(settings->value("audioOutputStarveDetectionPeriod", DEFAULT_AUDIO_OUTPUT_STARVE_DETECTION_PERIOD).toInt());
|
audio->setOutputStarveDetectionPeriod(settings->value("audioOutputStarveDetectionPeriod", DEFAULT_AUDIO_OUTPUT_STARVE_DETECTION_PERIOD).toInt());
|
||||||
|
@ -680,7 +680,7 @@ void Menu::saveSettings(QSettings* settings) {
|
||||||
settings->setValue("windowSecondsForDesiredReduction", _receivedAudioStreamSettings._windowSecondsForDesiredReduction);
|
settings->setValue("windowSecondsForDesiredReduction", _receivedAudioStreamSettings._windowSecondsForDesiredReduction);
|
||||||
settings->setValue("repetitionWithFade", _receivedAudioStreamSettings._repetitionWithFade);
|
settings->setValue("repetitionWithFade", _receivedAudioStreamSettings._repetitionWithFade);
|
||||||
|
|
||||||
auto audio = DependencyManager::get<Audio>();
|
auto audio = DependencyManager::get<AudioClient>();
|
||||||
settings->setValue("audioOutputStarveDetectionEnabled", audio->getOutputStarveDetectionEnabled());
|
settings->setValue("audioOutputStarveDetectionEnabled", audio->getOutputStarveDetectionEnabled());
|
||||||
settings->setValue("audioOutputStarveDetectionThreshold", audio->getOutputStarveDetectionThreshold());
|
settings->setValue("audioOutputStarveDetectionThreshold", audio->getOutputStarveDetectionThreshold());
|
||||||
settings->setValue("audioOutputStarveDetectionPeriod", audio->getOutputStarveDetectionPeriod());
|
settings->setValue("audioOutputStarveDetectionPeriod", audio->getOutputStarveDetectionPeriod());
|
||||||
|
@ -1297,7 +1297,7 @@ void Menu::toggleToolWindow() {
|
||||||
void Menu::audioMuteToggled() {
|
void Menu::audioMuteToggled() {
|
||||||
QAction *muteAction = _actionHash.value(MenuOption::MuteAudio);
|
QAction *muteAction = _actionHash.value(MenuOption::MuteAudio);
|
||||||
if (muteAction) {
|
if (muteAction) {
|
||||||
muteAction->setChecked(DependencyManager::get<Audio>()->isMuted());
|
muteAction->setChecked(DependencyManager::get<AudioClient>()->isMuted());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ AudioIOStatsRenderer::AudioIOStatsRenderer() :
|
||||||
_shouldShowInjectedStreams(false)
|
_shouldShowInjectedStreams(false)
|
||||||
{
|
{
|
||||||
// grab the stats object from the audio I/O singleton
|
// grab the stats object from the audio I/O singleton
|
||||||
_stats = &DependencyManager::get<Audio>()->getStats();
|
_stats = &DependencyManager::get<AudioClient>()->getStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
|
@ -41,14 +41,14 @@ AudioScope::AudioScope() :
|
||||||
_outputLeftID(DependencyManager::get<GeometryCache>()->allocateID()),
|
_outputLeftID(DependencyManager::get<GeometryCache>()->allocateID()),
|
||||||
_outputRightD(DependencyManager::get<GeometryCache>()->allocateID())
|
_outputRightD(DependencyManager::get<GeometryCache>()->allocateID())
|
||||||
{
|
{
|
||||||
auto audioIO = DependencyManager::get<Audio>();
|
auto audioIO = DependencyManager::get<AudioClient>();
|
||||||
connect(&audioIO->getReceivedAudioStream(), &MixedProcessedAudioStream::addedSilence,
|
connect(&audioIO->getReceivedAudioStream(), &MixedProcessedAudioStream::addedSilence,
|
||||||
this, &AudioScope::addStereoSilenceToScope);
|
this, &AudioScope::addStereoSilenceToScope);
|
||||||
connect(&audioIO->getReceivedAudioStream(), &MixedProcessedAudioStream::addedLastFrameRepeatedWithFade,
|
connect(&audioIO->getReceivedAudioStream(), &MixedProcessedAudioStream::addedLastFrameRepeatedWithFade,
|
||||||
this, &AudioScope::addLastFrameRepeatedWithFadeToScope);
|
this, &AudioScope::addLastFrameRepeatedWithFadeToScope);
|
||||||
connect(&audioIO->getReceivedAudioStream(), &MixedProcessedAudioStream::addedStereoSamples,
|
connect(&audioIO->getReceivedAudioStream(), &MixedProcessedAudioStream::addedStereoSamples,
|
||||||
this, &AudioScope::addStereoSamplesToScope);
|
this, &AudioScope::addStereoSamplesToScope);
|
||||||
connect(audioIO.data(), &Audio::inputReceived, this, &AudioScope::addInputToScope);
|
connect(audioIO.data(), &AudioClient::inputReceived, this, &AudioScope::addInputToScope);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioScope::toggle() {
|
void AudioScope::toggle() {
|
||||||
|
|
|
@ -29,7 +29,7 @@ AudioToolBox::AudioToolBox() :
|
||||||
|
|
||||||
bool AudioToolBox::mousePressEvent(int x, int y) {
|
bool AudioToolBox::mousePressEvent(int x, int y) {
|
||||||
if (_iconBounds.contains(x, y)) {
|
if (_iconBounds.contains(x, y)) {
|
||||||
DependencyManager::get<Audio>()->toggleMute();
|
DependencyManager::get<AudioClient>()->toggleMute();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -49,7 +49,7 @@ void AudioToolBox::render(int x, int y, bool boxed) {
|
||||||
_boxTextureId = glCanvas->bindTexture(QImage(PathUtils::resourcesPath() + "images/audio-box.svg"));
|
_boxTextureId = glCanvas->bindTexture(QImage(PathUtils::resourcesPath() + "images/audio-box.svg"));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto audioIO = DependencyManager::get<Audio>();
|
auto audioIO = DependencyManager::get<AudioClient>();
|
||||||
|
|
||||||
if (boxed) {
|
if (boxed) {
|
||||||
bool isClipping = ((audioIO->getTimeSinceLastClip() > 0.0f) && (audioIO->getTimeSinceLastClip() < 1.0f));
|
bool isClipping = ((audioIO->getTimeSinceLastClip() > 0.0f) && (audioIO->getTimeSinceLastClip() < 1.0f));
|
||||||
|
|
|
@ -146,7 +146,7 @@ void MyAvatar::update(float deltaTime) {
|
||||||
head->relaxLean(deltaTime);
|
head->relaxLean(deltaTime);
|
||||||
updateFromTrackers(deltaTime);
|
updateFromTrackers(deltaTime);
|
||||||
// Get audio loudness data from audio input device
|
// Get audio loudness data from audio input device
|
||||||
auto audio = DependencyManager::get<Audio>();
|
auto audio = DependencyManager::get<AudioClient>();
|
||||||
head->setAudioLoudness(audio->getLastInputLoudness());
|
head->setAudioLoudness(audio->getLastInputLoudness());
|
||||||
head->setAudioAverageLoudness(audio->getAudioAverageInputLoudness());
|
head->setAudioAverageLoudness(audio->getAudioAverageInputLoudness());
|
||||||
|
|
||||||
|
@ -490,7 +490,7 @@ void MyAvatar::startRecording() {
|
||||||
if (!_recorder) {
|
if (!_recorder) {
|
||||||
_recorder = RecorderPointer(new Recorder(this));
|
_recorder = RecorderPointer(new Recorder(this));
|
||||||
}
|
}
|
||||||
DependencyManager::get<Audio>()->setRecorder(_recorder);
|
DependencyManager::get<AudioClient>()->setRecorder(_recorder);
|
||||||
_recorder->startRecording();
|
_recorder->startRecording();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,13 +19,13 @@ AudioDeviceScriptingInterface* AudioDeviceScriptingInterface::getInstance() {
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioDeviceScriptingInterface::AudioDeviceScriptingInterface() {
|
AudioDeviceScriptingInterface::AudioDeviceScriptingInterface() {
|
||||||
connect(DependencyManager::get<Audio>().data(), &Audio::muteToggled,
|
connect(DependencyManager::get<AudioClient>().data(), &AudioClient::muteToggled,
|
||||||
this, &AudioDeviceScriptingInterface::muteToggled);
|
this, &AudioDeviceScriptingInterface::muteToggled);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioDeviceScriptingInterface::setInputDevice(const QString& deviceName) {
|
bool AudioDeviceScriptingInterface::setInputDevice(const QString& deviceName) {
|
||||||
bool result;
|
bool result;
|
||||||
QMetaObject::invokeMethod(DependencyManager::get<Audio>().data(), "switchInputToAudioDevice",
|
QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(), "switchInputToAudioDevice",
|
||||||
Qt::BlockingQueuedConnection,
|
Qt::BlockingQueuedConnection,
|
||||||
Q_RETURN_ARG(bool, result),
|
Q_RETURN_ARG(bool, result),
|
||||||
Q_ARG(const QString&, deviceName));
|
Q_ARG(const QString&, deviceName));
|
||||||
|
@ -35,7 +35,7 @@ bool AudioDeviceScriptingInterface::setInputDevice(const QString& deviceName) {
|
||||||
|
|
||||||
bool AudioDeviceScriptingInterface::setOutputDevice(const QString& deviceName) {
|
bool AudioDeviceScriptingInterface::setOutputDevice(const QString& deviceName) {
|
||||||
bool result;
|
bool result;
|
||||||
QMetaObject::invokeMethod(DependencyManager::get<Audio>().data(), "switchOutputToAudioDevice",
|
QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(), "switchOutputToAudioDevice",
|
||||||
Qt::BlockingQueuedConnection,
|
Qt::BlockingQueuedConnection,
|
||||||
Q_RETURN_ARG(bool, result),
|
Q_RETURN_ARG(bool, result),
|
||||||
Q_ARG(const QString&, deviceName));
|
Q_ARG(const QString&, deviceName));
|
||||||
|
@ -44,50 +44,50 @@ bool AudioDeviceScriptingInterface::setOutputDevice(const QString& deviceName) {
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AudioDeviceScriptingInterface::getInputDevice() {
|
QString AudioDeviceScriptingInterface::getInputDevice() {
|
||||||
return DependencyManager::get<Audio>()->getDeviceName(QAudio::AudioInput);
|
return DependencyManager::get<AudioClient>()->getDeviceName(QAudio::AudioInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AudioDeviceScriptingInterface::getOutputDevice() {
|
QString AudioDeviceScriptingInterface::getOutputDevice() {
|
||||||
return DependencyManager::get<Audio>()->getDeviceName(QAudio::AudioOutput);
|
return DependencyManager::get<AudioClient>()->getDeviceName(QAudio::AudioOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AudioDeviceScriptingInterface::getDefaultInputDevice() {
|
QString AudioDeviceScriptingInterface::getDefaultInputDevice() {
|
||||||
return DependencyManager::get<Audio>()->getDefaultDeviceName(QAudio::AudioInput);
|
return DependencyManager::get<AudioClient>()->getDefaultDeviceName(QAudio::AudioInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AudioDeviceScriptingInterface::getDefaultOutputDevice() {
|
QString AudioDeviceScriptingInterface::getDefaultOutputDevice() {
|
||||||
return DependencyManager::get<Audio>()->getDefaultDeviceName(QAudio::AudioOutput);
|
return DependencyManager::get<AudioClient>()->getDefaultDeviceName(QAudio::AudioOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<QString> AudioDeviceScriptingInterface::getInputDevices() {
|
QVector<QString> AudioDeviceScriptingInterface::getInputDevices() {
|
||||||
return DependencyManager::get<Audio>()->getDeviceNames(QAudio::AudioInput);
|
return DependencyManager::get<AudioClient>()->getDeviceNames(QAudio::AudioInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<QString> AudioDeviceScriptingInterface::getOutputDevices() {
|
QVector<QString> AudioDeviceScriptingInterface::getOutputDevices() {
|
||||||
return DependencyManager::get<Audio>()->getDeviceNames(QAudio::AudioOutput);
|
return DependencyManager::get<AudioClient>()->getDeviceNames(QAudio::AudioOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float AudioDeviceScriptingInterface::getInputVolume() {
|
float AudioDeviceScriptingInterface::getInputVolume() {
|
||||||
return DependencyManager::get<Audio>()->getInputVolume();
|
return DependencyManager::get<AudioClient>()->getInputVolume();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDeviceScriptingInterface::setInputVolume(float volume) {
|
void AudioDeviceScriptingInterface::setInputVolume(float volume) {
|
||||||
DependencyManager::get<Audio>()->setInputVolume(volume);
|
DependencyManager::get<AudioClient>()->setInputVolume(volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDeviceScriptingInterface::setReverb(bool reverb) {
|
void AudioDeviceScriptingInterface::setReverb(bool reverb) {
|
||||||
DependencyManager::get<Audio>()->setReverb(reverb);
|
DependencyManager::get<AudioClient>()->setReverb(reverb);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDeviceScriptingInterface::setReverbOptions(const AudioEffectOptions* options) {
|
void AudioDeviceScriptingInterface::setReverbOptions(const AudioEffectOptions* options) {
|
||||||
DependencyManager::get<Audio>()->setReverbOptions(options);
|
DependencyManager::get<AudioClient>()->setReverbOptions(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDeviceScriptingInterface::toggleMute() {
|
void AudioDeviceScriptingInterface::toggleMute() {
|
||||||
DependencyManager::get<Audio>()->toggleMute();
|
DependencyManager::get<AudioClient>()->toggleMute();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioDeviceScriptingInterface::getMuted() {
|
bool AudioDeviceScriptingInterface::getMuted() {
|
||||||
return DependencyManager::get<Audio>()->isMuted();
|
return DependencyManager::get<AudioClient>()->isMuted();
|
||||||
}
|
}
|
||||||
|
|
|
@ -787,7 +787,7 @@ void ApplicationOverlay::renderMagnifier(glm::vec2 magPos, float sizeMult, bool
|
||||||
|
|
||||||
void ApplicationOverlay::renderAudioMeter() {
|
void ApplicationOverlay::renderAudioMeter() {
|
||||||
auto glCanvas = DependencyManager::get<GLCanvas>();
|
auto glCanvas = DependencyManager::get<GLCanvas>();
|
||||||
auto audio = DependencyManager::get<Audio>();
|
auto audio = DependencyManager::get<AudioClient>();
|
||||||
|
|
||||||
// Audio VU Meter and Mute Icon
|
// Audio VU Meter and Mute Icon
|
||||||
const int MUTE_ICON_SIZE = 24;
|
const int MUTE_ICON_SIZE = 24;
|
||||||
|
|
|
@ -140,7 +140,7 @@ void PreferencesDialog::loadPreferences() {
|
||||||
ui.windowSecondsForDesiredReductionSpin->setValue(streamSettings._windowSecondsForDesiredReduction);
|
ui.windowSecondsForDesiredReductionSpin->setValue(streamSettings._windowSecondsForDesiredReduction);
|
||||||
ui.repetitionWithFadeCheckBox->setChecked(streamSettings._repetitionWithFade);
|
ui.repetitionWithFadeCheckBox->setChecked(streamSettings._repetitionWithFade);
|
||||||
|
|
||||||
auto audio = DependencyManager::get<Audio>();
|
auto audio = DependencyManager::get<AudioClient>();
|
||||||
ui.outputBufferSizeSpinner->setValue(audio->getOutputBufferSize());
|
ui.outputBufferSizeSpinner->setValue(audio->getOutputBufferSize());
|
||||||
|
|
||||||
ui.outputStarveDetectionCheckBox->setChecked(audio->getOutputStarveDetectionEnabled());
|
ui.outputStarveDetectionCheckBox->setChecked(audio->getOutputStarveDetectionEnabled());
|
||||||
|
@ -256,7 +256,7 @@ void PreferencesDialog::savePreferences() {
|
||||||
|
|
||||||
Menu::getInstance()->setReceivedAudioStreamSettings(streamSettings);
|
Menu::getInstance()->setReceivedAudioStreamSettings(streamSettings);
|
||||||
|
|
||||||
auto audio = DependencyManager::get<Audio>();
|
auto audio = DependencyManager::get<AudioClient>();
|
||||||
|
|
||||||
QMetaObject::invokeMethod(audio.data(), "setOutputBufferSize", Q_ARG(int, ui.outputBufferSizeSpinner->value()));
|
QMetaObject::invokeMethod(audio.data(), "setOutputBufferSize", Q_ARG(int, ui.outputBufferSizeSpinner->value()));
|
||||||
|
|
||||||
|
|
21
libraries/audio-client/CMakeLists.txt
Normal file
21
libraries/audio-client/CMakeLists.txt
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
set(TARGET_NAME audio-client)
|
||||||
|
|
||||||
|
# use setup_hifi_library macro to setup our project and link appropriate Qt modules
|
||||||
|
setup_hifi_library(Network)
|
||||||
|
|
||||||
|
link_hifi_libraries(audio)
|
||||||
|
|
||||||
|
# call macro to include our dependency includes and bubble them up via a property on our target
|
||||||
|
include_dependency_includes()
|
||||||
|
|
||||||
|
set(GVERB_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/external/gverb")
|
||||||
|
|
||||||
|
# As Gverb is currently the only reverb library, it's required.
|
||||||
|
find_package(Gverb REQUIRED)
|
||||||
|
|
||||||
|
if (GVERB_FOUND)
|
||||||
|
file(GLOB GVERB_SRCS ${GVERB_SRC_DIRS}/*.c)
|
||||||
|
include_directories(${GVERB_INCLUDE_DIRS})
|
||||||
|
add_library(gverb STATIC ${GVERB_SRCS})
|
||||||
|
target_link_libraries(${TARGET_NAME} gverb)
|
||||||
|
endif (GVERB_FOUND)
|
234
libraries/audio-client/external/gverb/include/gverb.h
vendored
Executable file
234
libraries/audio-client/external/gverb/include/gverb.h
vendored
Executable file
|
@ -0,0 +1,234 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (C) 1999 Juhana Sadeharju
|
||||||
|
kouhia at nic.funet.fi
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GVERB_H
|
||||||
|
#define GVERB_H
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "gverbdsp.h"
|
||||||
|
#include "gverb.h"
|
||||||
|
#include "ladspa-util.h"
|
||||||
|
|
||||||
|
#define FDNORDER 4
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int rate;
|
||||||
|
float inputbandwidth;
|
||||||
|
float taillevel;
|
||||||
|
float earlylevel;
|
||||||
|
ty_damper *inputdamper;
|
||||||
|
float maxroomsize;
|
||||||
|
float roomsize;
|
||||||
|
float revtime;
|
||||||
|
float maxdelay;
|
||||||
|
float largestdelay;
|
||||||
|
ty_fixeddelay **fdndels;
|
||||||
|
float *fdngains;
|
||||||
|
int *fdnlens;
|
||||||
|
ty_damper **fdndamps;
|
||||||
|
float fdndamping;
|
||||||
|
ty_diffuser **ldifs;
|
||||||
|
ty_diffuser **rdifs;
|
||||||
|
ty_fixeddelay *tapdelay;
|
||||||
|
int *taps;
|
||||||
|
float *tapgains;
|
||||||
|
float *d;
|
||||||
|
float *u;
|
||||||
|
float *f;
|
||||||
|
double alpha;
|
||||||
|
} ty_gverb;
|
||||||
|
|
||||||
|
|
||||||
|
ty_gverb *gverb_new(int, float, float, float, float, float, float, float, float);
|
||||||
|
void gverb_free(ty_gverb *);
|
||||||
|
void gverb_flush(ty_gverb *);
|
||||||
|
static void gverb_do(ty_gverb *, float, float *, float *);
|
||||||
|
static void gverb_set_roomsize(ty_gverb *, float);
|
||||||
|
static void gverb_set_revtime(ty_gverb *, float);
|
||||||
|
static void gverb_set_damping(ty_gverb *, float);
|
||||||
|
static void gverb_set_inputbandwidth(ty_gverb *, float);
|
||||||
|
static void gverb_set_earlylevel(ty_gverb *, float);
|
||||||
|
static void gverb_set_taillevel(ty_gverb *, float);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This FDN reverb can be made smoother by setting matrix elements at the
|
||||||
|
* diagonal and near of it to zero or nearly zero. By setting diagonals to zero
|
||||||
|
* means we remove the effect of the parallel comb structure from the
|
||||||
|
* reverberation. A comb generates uniform impulse stream to the reverberation
|
||||||
|
* impulse response, and thus it is not good. By setting near diagonal elements
|
||||||
|
* to zero means we remove delay sequences having consequtive delays of the
|
||||||
|
* similar lenths, when the delays are in sorted in length with respect to
|
||||||
|
* matrix element index. The matrix described here could be generated by
|
||||||
|
* differencing Rocchesso's circulant matrix at max diffuse value and at low
|
||||||
|
* diffuse value (approaching parallel combs).
|
||||||
|
*
|
||||||
|
* Example 1:
|
||||||
|
* Set a(k,k), for all k, equal to 0.
|
||||||
|
*
|
||||||
|
* Example 2:
|
||||||
|
* Set a(k,k), a(k,k-1) and a(k,k+1) equal to 0.
|
||||||
|
*
|
||||||
|
* Example 3: The transition to zero gains could be smooth as well.
|
||||||
|
* a(k,k-1) and a(k,k+1) could be 0.3, and a(k,k-2) and a(k,k+2) could
|
||||||
|
* be 0.5, say.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static __inline void gverb_fdnmatrix(float *a, float *b)
|
||||||
|
{
|
||||||
|
const float dl0 = a[0], dl1 = a[1], dl2 = a[2], dl3 = a[3];
|
||||||
|
|
||||||
|
b[0] = 0.5f*(+dl0 + dl1 - dl2 - dl3);
|
||||||
|
b[1] = 0.5f*(+dl0 - dl1 - dl2 + dl3);
|
||||||
|
b[2] = 0.5f*(-dl0 + dl1 - dl2 + dl3);
|
||||||
|
b[3] = 0.5f*(+dl0 + dl1 + dl2 + dl3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void gverb_do(ty_gverb *p, float x, float *yl, float *yr)
|
||||||
|
{
|
||||||
|
float z;
|
||||||
|
unsigned int i;
|
||||||
|
float lsum,rsum,sum,sign;
|
||||||
|
|
||||||
|
if ((x != x) || fabsf(x) > 100000.0f) {
|
||||||
|
x = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
z = damper_do(p->inputdamper, x);
|
||||||
|
|
||||||
|
z = diffuser_do(p->ldifs[0],z);
|
||||||
|
|
||||||
|
for(i = 0; i < FDNORDER; i++) {
|
||||||
|
p->u[i] = p->tapgains[i]*fixeddelay_read(p->tapdelay,p->taps[i]);
|
||||||
|
}
|
||||||
|
fixeddelay_write(p->tapdelay,z);
|
||||||
|
|
||||||
|
for(i = 0; i < FDNORDER; i++) {
|
||||||
|
p->d[i] = damper_do(p->fdndamps[i],
|
||||||
|
p->fdngains[i]*fixeddelay_read(p->fdndels[i],
|
||||||
|
p->fdnlens[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
sum = 0.0f;
|
||||||
|
sign = 1.0f;
|
||||||
|
for(i = 0; i < FDNORDER; i++) {
|
||||||
|
sum += sign*(p->taillevel*p->d[i] + p->earlylevel*p->u[i]);
|
||||||
|
sign = -sign;
|
||||||
|
}
|
||||||
|
sum += x*p->earlylevel;
|
||||||
|
lsum = sum;
|
||||||
|
rsum = sum;
|
||||||
|
|
||||||
|
gverb_fdnmatrix(p->d,p->f);
|
||||||
|
|
||||||
|
for(i = 0; i < FDNORDER; i++) {
|
||||||
|
fixeddelay_write(p->fdndels[i],p->u[i]+p->f[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
lsum = diffuser_do(p->ldifs[1],lsum);
|
||||||
|
lsum = diffuser_do(p->ldifs[2],lsum);
|
||||||
|
lsum = diffuser_do(p->ldifs[3],lsum);
|
||||||
|
rsum = diffuser_do(p->rdifs[1],rsum);
|
||||||
|
rsum = diffuser_do(p->rdifs[2],rsum);
|
||||||
|
rsum = diffuser_do(p->rdifs[3],rsum);
|
||||||
|
|
||||||
|
*yl = lsum;
|
||||||
|
*yr = rsum;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void gverb_set_roomsize(ty_gverb *p, const float a)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (a <= 1.0 || (a != a)) {
|
||||||
|
p->roomsize = 1.0;
|
||||||
|
} else {
|
||||||
|
p->roomsize = a;
|
||||||
|
}
|
||||||
|
p->largestdelay = p->rate * p->roomsize * 0.00294f;
|
||||||
|
|
||||||
|
p->fdnlens[0] = f_round(1.000000f*p->largestdelay);
|
||||||
|
p->fdnlens[1] = f_round(0.816490f*p->largestdelay);
|
||||||
|
p->fdnlens[2] = f_round(0.707100f*p->largestdelay);
|
||||||
|
p->fdnlens[3] = f_round(0.632450f*p->largestdelay);
|
||||||
|
for(i = 0; i < FDNORDER; i++) {
|
||||||
|
p->fdngains[i] = -powf((float)p->alpha, p->fdnlens[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
p->taps[0] = 5+f_round(0.410f*p->largestdelay);
|
||||||
|
p->taps[1] = 5+f_round(0.300f*p->largestdelay);
|
||||||
|
p->taps[2] = 5+f_round(0.155f*p->largestdelay);
|
||||||
|
p->taps[3] = 5+f_round(0.000f*p->largestdelay);
|
||||||
|
|
||||||
|
for(i = 0; i < FDNORDER; i++) {
|
||||||
|
p->tapgains[i] = powf((float)p->alpha, p->taps[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void gverb_set_revtime(ty_gverb *p,float a)
|
||||||
|
{
|
||||||
|
float ga,gt;
|
||||||
|
double n;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
p->revtime = a;
|
||||||
|
|
||||||
|
ga = 60.0;
|
||||||
|
gt = p->revtime;
|
||||||
|
ga = powf(10.0f,-ga/20.0f);
|
||||||
|
n = p->rate*gt;
|
||||||
|
p->alpha = (double)powf(ga,1.0f/n);
|
||||||
|
|
||||||
|
for(i = 0; i < FDNORDER; i++) {
|
||||||
|
p->fdngains[i] = -powf((float)p->alpha, p->fdnlens[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void gverb_set_damping(ty_gverb *p,float a)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
p->fdndamping = a;
|
||||||
|
for(i = 0; i < FDNORDER; i++) {
|
||||||
|
damper_set(p->fdndamps[i],p->fdndamping);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void gverb_set_inputbandwidth(ty_gverb *p,float a)
|
||||||
|
{
|
||||||
|
p->inputbandwidth = a;
|
||||||
|
damper_set(p->inputdamper,1.0 - p->inputbandwidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void gverb_set_earlylevel(ty_gverb *p,float a)
|
||||||
|
{
|
||||||
|
p->earlylevel = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void gverb_set_taillevel(ty_gverb *p,float a)
|
||||||
|
{
|
||||||
|
p->taillevel = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
85
libraries/audio-client/external/gverb/include/gverbdsp.h
vendored
Executable file
85
libraries/audio-client/external/gverb/include/gverbdsp.h
vendored
Executable file
|
@ -0,0 +1,85 @@
|
||||||
|
|
||||||
|
#ifndef GVERBDSP_H
|
||||||
|
#define GVERBDSP_H
|
||||||
|
|
||||||
|
#include "ladspa-util.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int size;
|
||||||
|
int idx;
|
||||||
|
float *buf;
|
||||||
|
} ty_fixeddelay;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int size;
|
||||||
|
float coeff;
|
||||||
|
int idx;
|
||||||
|
float *buf;
|
||||||
|
} ty_diffuser;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float damping;
|
||||||
|
float delay;
|
||||||
|
} ty_damper;
|
||||||
|
|
||||||
|
ty_diffuser *diffuser_make(int, float);
|
||||||
|
void diffuser_free(ty_diffuser *);
|
||||||
|
void diffuser_flush(ty_diffuser *);
|
||||||
|
//float diffuser_do(ty_diffuser *, float);
|
||||||
|
|
||||||
|
ty_damper *damper_make(float);
|
||||||
|
void damper_free(ty_damper *);
|
||||||
|
void damper_flush(ty_damper *);
|
||||||
|
//void damper_set(ty_damper *, float);
|
||||||
|
//float damper_do(ty_damper *, float);
|
||||||
|
|
||||||
|
ty_fixeddelay *fixeddelay_make(int);
|
||||||
|
void fixeddelay_free(ty_fixeddelay *);
|
||||||
|
void fixeddelay_flush(ty_fixeddelay *);
|
||||||
|
//float fixeddelay_read(ty_fixeddelay *, int);
|
||||||
|
//void fixeddelay_write(ty_fixeddelay *, float);
|
||||||
|
|
||||||
|
int isprime(int);
|
||||||
|
int nearest_prime(int, float);
|
||||||
|
|
||||||
|
static __inline float diffuser_do(ty_diffuser *p, float x)
|
||||||
|
{
|
||||||
|
float y,w;
|
||||||
|
|
||||||
|
w = x - p->buf[p->idx]*p->coeff;
|
||||||
|
w = flush_to_zero(w);
|
||||||
|
y = p->buf[p->idx] + w*p->coeff;
|
||||||
|
p->buf[p->idx] = w;
|
||||||
|
p->idx = (p->idx + 1) % p->size;
|
||||||
|
return(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline float fixeddelay_read(ty_fixeddelay *p, int n)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
i = (p->idx - n + p->size) % p->size;
|
||||||
|
return(p->buf[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void fixeddelay_write(ty_fixeddelay *p, float x)
|
||||||
|
{
|
||||||
|
p->buf[p->idx] = x;
|
||||||
|
p->idx = (p->idx + 1) % p->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void damper_set(ty_damper *p, float damping)
|
||||||
|
{
|
||||||
|
p->damping = damping;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline float damper_do(ty_damper *p, float x)
|
||||||
|
{
|
||||||
|
float y;
|
||||||
|
|
||||||
|
y = x*(1.0-p->damping) + p->delay*p->damping;
|
||||||
|
p->delay = y;
|
||||||
|
return(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
234
libraries/audio-client/external/gverb/include/ladspa-util.h
vendored
Executable file
234
libraries/audio-client/external/gverb/include/ladspa-util.h
vendored
Executable file
|
@ -0,0 +1,234 @@
|
||||||
|
/* Some misc util functions for audio DSP work, written by Steve Harris,
|
||||||
|
* December 2000
|
||||||
|
*
|
||||||
|
* steve@plugin.org.uk
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LADSPA_UTIL_H
|
||||||
|
#define LADSPA_UTIL_H
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define buffer_write(a, b) a=(b)
|
||||||
|
|
||||||
|
// 16.16 fixpoint
|
||||||
|
typedef union {
|
||||||
|
int32_t all;
|
||||||
|
struct {
|
||||||
|
#ifdef WORDS_BIGENDIAN
|
||||||
|
int16_t in;
|
||||||
|
uint16_t fr;
|
||||||
|
#else
|
||||||
|
uint16_t fr;
|
||||||
|
int16_t in;
|
||||||
|
#endif
|
||||||
|
} part;
|
||||||
|
} fixp16;
|
||||||
|
|
||||||
|
// 32.32 fixpoint
|
||||||
|
typedef union {
|
||||||
|
int64_t all;
|
||||||
|
struct {
|
||||||
|
#ifdef WORDS_BIGENDIAN
|
||||||
|
int32_t in;
|
||||||
|
uint32_t fr;
|
||||||
|
#else
|
||||||
|
uint32_t fr;
|
||||||
|
int32_t in;
|
||||||
|
#endif
|
||||||
|
} part;
|
||||||
|
} fixp32;
|
||||||
|
|
||||||
|
/* 32 bit "pointer cast" union */
|
||||||
|
typedef union {
|
||||||
|
float f;
|
||||||
|
int32_t i;
|
||||||
|
} ls_pcast32;
|
||||||
|
|
||||||
|
// Sometimes it doesn't get defined, even though it eists and C99 is declared
|
||||||
|
long int lrintf (float x);
|
||||||
|
|
||||||
|
// 1.0 / ln(2)
|
||||||
|
#define LN2R 1.442695041f
|
||||||
|
|
||||||
|
/* detet floating point denormal numbers by comparing them to the smallest
|
||||||
|
* normal, crap, but reliable */
|
||||||
|
#define DN_CHECK(x, l) if (fabs(x) < 1e-38) printf("DN: " l"\n")
|
||||||
|
|
||||||
|
// Denormalise floats, only actually needed for PIII and recent PowerPC
|
||||||
|
//#define FLUSH_TO_ZERO(fv) (((*(unsigned int*)&(fv))&0x7f800000)==0)?0.0f:(fv)
|
||||||
|
|
||||||
|
static __inline float flush_to_zero(float f)
|
||||||
|
{
|
||||||
|
ls_pcast32 v;
|
||||||
|
|
||||||
|
v.f = f;
|
||||||
|
|
||||||
|
// original: return (v.i & 0x7f800000) == 0 ? 0.0f : f;
|
||||||
|
// version from Tim Blechmann
|
||||||
|
return (v.i & 0x7f800000) < 0x08000000 ? 0.0f : f;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void round_to_zero(volatile float *f)
|
||||||
|
{
|
||||||
|
*f += 1e-18;
|
||||||
|
*f -= 1e-18;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A set of branchless clipping operations from Laurent de Soras */
|
||||||
|
|
||||||
|
static __inline float f_max(float x, float a)
|
||||||
|
{
|
||||||
|
x -= a;
|
||||||
|
x += fabs(x);
|
||||||
|
x *= 0.5;
|
||||||
|
x += a;
|
||||||
|
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline float f_min(float x, float b)
|
||||||
|
{
|
||||||
|
x = b - x;
|
||||||
|
x += fabs(x);
|
||||||
|
x *= 0.5;
|
||||||
|
x = b - x;
|
||||||
|
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline float f_clamp(float x, float a, float b)
|
||||||
|
{
|
||||||
|
const float x1 = fabs(x - a);
|
||||||
|
const float x2 = fabs(x - b);
|
||||||
|
|
||||||
|
x = x1 + a + b;
|
||||||
|
x -= x2;
|
||||||
|
x *= 0.5;
|
||||||
|
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Limit a value to be l<=v<=u
|
||||||
|
#define LIMIT(v,l,u) ((v)<(l)?(l):((v)>(u)?(u):(v)))
|
||||||
|
|
||||||
|
// Truncate-to-zero modulo (ANSI C doesn't specify) will only work
|
||||||
|
// if -m < v < 2m
|
||||||
|
#define MOD(v,m) (v<0?v+m:(v>=m?v-m:v))
|
||||||
|
|
||||||
|
// Truncate-to-zero modulo (ANSI C doesn't specify) will only work
|
||||||
|
// if v > -m and v < m
|
||||||
|
#define NEG_MOD(v,m) ((v)<0?((v)+(m)):(v))
|
||||||
|
|
||||||
|
// Convert a value in dB's to a coefficent
|
||||||
|
#define DB_CO(g) ((g) > -90.0f ? powf(10.0f, (g) * 0.05f) : 0.0f)
|
||||||
|
#define CO_DB(v) (20.0f * log10f(v))
|
||||||
|
|
||||||
|
// Linearly interpolate [ = a * (1 - f) + b * f]
|
||||||
|
#define LIN_INTERP(f,a,b) ((a) + (f) * ((b) - (a)))
|
||||||
|
|
||||||
|
// Cubic interpolation function
|
||||||
|
static __inline float cube_interp(const float fr, const float inm1, const float
|
||||||
|
in, const float inp1, const float inp2)
|
||||||
|
{
|
||||||
|
return in + 0.5f * fr * (inp1 - inm1 +
|
||||||
|
fr * (4.0f * inp1 + 2.0f * inm1 - 5.0f * in - inp2 +
|
||||||
|
fr * (3.0f * (in - inp1) - inm1 + inp2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fast sin^2 aproxiamtion, adapted from jan AT rpgfan's posting to the
|
||||||
|
* music-dsp list */
|
||||||
|
static __inline float f_sin_sq(float angle)
|
||||||
|
{
|
||||||
|
const float asqr = angle * angle;
|
||||||
|
float result = -2.39e-08f;
|
||||||
|
|
||||||
|
result *= asqr;
|
||||||
|
result += 2.7526e-06f;
|
||||||
|
result *= asqr;
|
||||||
|
result -= 1.98409e-04f;
|
||||||
|
result *= asqr;
|
||||||
|
result += 8.3333315e-03f;
|
||||||
|
result *= asqr;
|
||||||
|
result -= 1.666666664e-01f;
|
||||||
|
result *= asqr;
|
||||||
|
result += 1.0f;
|
||||||
|
result *= angle;
|
||||||
|
|
||||||
|
return result * result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_LRINTF
|
||||||
|
|
||||||
|
#define f_round(f) lrintf(f)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// Round float to int using IEEE int* hack
|
||||||
|
static __inline int f_round(float f)
|
||||||
|
{
|
||||||
|
ls_pcast32 p;
|
||||||
|
|
||||||
|
p.f = f;
|
||||||
|
p.f += (3<<22);
|
||||||
|
|
||||||
|
return p.i - 0x4b400000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Truncate float to int
|
||||||
|
static __inline int f_trunc(float f)
|
||||||
|
{
|
||||||
|
return f_round(floorf(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Andrew Simper's pow(2, x) aproximation from the music-dsp list */
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
/* original */
|
||||||
|
static __inline float f_pow2(float x)
|
||||||
|
{
|
||||||
|
long *px = (long*)(&x); // store address of float as long pointer
|
||||||
|
const float tx = (x-0.5f) + (3<<22); // temporary value for truncation
|
||||||
|
const long lx = *((long*)&tx) - 0x4b400000; // integer power of 2
|
||||||
|
const float dx = x-(float)(lx); // float remainder of power of 2
|
||||||
|
|
||||||
|
x = 1.0f + dx*(0.6960656421638072f + // cubic apporoximation of 2^x
|
||||||
|
dx*(0.224494337302845f + // for x in the range [0, 1]
|
||||||
|
dx*(0.07944023841053369f)));
|
||||||
|
*px += (lx<<23); // add integer power of 2 to exponent
|
||||||
|
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* union version */
|
||||||
|
static __inline float f_pow2(float x)
|
||||||
|
{
|
||||||
|
ls_pcast32 *px, tx, lx;
|
||||||
|
float dx;
|
||||||
|
|
||||||
|
px = (ls_pcast32 *)&x; // store address of float as long pointer
|
||||||
|
tx.f = (x-0.5f) + (3<<22); // temporary value for truncation
|
||||||
|
lx.i = tx.i - 0x4b400000; // integer power of 2
|
||||||
|
dx = x - (float)lx.i; // float remainder of power of 2
|
||||||
|
|
||||||
|
x = 1.0f + dx * (0.6960656421638072f + // cubic apporoximation of 2^x
|
||||||
|
dx * (0.224494337302845f + // for x in the range [0, 1]
|
||||||
|
dx * (0.07944023841053369f)));
|
||||||
|
(*px).i += (lx.i << 23); // add integer power of 2 to exponent
|
||||||
|
|
||||||
|
return (*px).f;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Fast exponentiation function, y = e^x */
|
||||||
|
#define f_exp(x) f_pow2(x * LN2R)
|
||||||
|
|
||||||
|
#endif
|
14
libraries/audio-client/external/gverb/readme.txt
vendored
Normal file
14
libraries/audio-client/external/gverb/readme.txt
vendored
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
Instructions for adding the Gverb library to Interface
|
||||||
|
(This is a required library)
|
||||||
|
Clément Brisset, October 22nd, 2014
|
||||||
|
|
||||||
|
1. Go to https://github.com/highfidelity/gverb
|
||||||
|
Or download the sources directly via this link:
|
||||||
|
https://github.com/highfidelity/gverb/archive/master.zip
|
||||||
|
|
||||||
|
2. Extract the archive
|
||||||
|
|
||||||
|
3. Place the directories “include” and “src” in libraries/audio-client/external/gverb
|
||||||
|
(Normally next to this readme)
|
||||||
|
|
||||||
|
4. Clear your build directory, run cmake, build and you should be all set.
|
207
libraries/audio-client/external/gverb/src/gverb.c
vendored
Executable file
207
libraries/audio-client/external/gverb/src/gverb.c
vendored
Executable file
|
@ -0,0 +1,207 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (C) 1999 Juhana Sadeharju
|
||||||
|
kouhia at nic.funet.fi
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "gverbdsp.h"
|
||||||
|
#include "gverb.h"
|
||||||
|
#include "../include/ladspa-util.h"
|
||||||
|
|
||||||
|
ty_gverb *gverb_new(int srate, float maxroomsize, float roomsize,
|
||||||
|
float revtime,
|
||||||
|
float damping, float spread,
|
||||||
|
float inputbandwidth, float earlylevel,
|
||||||
|
float taillevel)
|
||||||
|
{
|
||||||
|
ty_gverb *p;
|
||||||
|
float ga,gb,gt;
|
||||||
|
int i,n;
|
||||||
|
float r;
|
||||||
|
float diffscale;
|
||||||
|
int a,b,c,cc,d,dd,e;
|
||||||
|
float spread1,spread2;
|
||||||
|
|
||||||
|
p = (ty_gverb *)malloc(sizeof(ty_gverb));
|
||||||
|
p->rate = srate;
|
||||||
|
p->fdndamping = damping;
|
||||||
|
p->maxroomsize = maxroomsize;
|
||||||
|
p->roomsize = roomsize;
|
||||||
|
p->revtime = revtime;
|
||||||
|
p->earlylevel = earlylevel;
|
||||||
|
p->taillevel = taillevel;
|
||||||
|
|
||||||
|
p->maxdelay = p->rate*p->maxroomsize/340.0;
|
||||||
|
p->largestdelay = p->rate*p->roomsize/340.0;
|
||||||
|
|
||||||
|
|
||||||
|
/* Input damper */
|
||||||
|
|
||||||
|
p->inputbandwidth = inputbandwidth;
|
||||||
|
p->inputdamper = damper_make(1.0 - p->inputbandwidth);
|
||||||
|
|
||||||
|
|
||||||
|
/* FDN section */
|
||||||
|
|
||||||
|
|
||||||
|
p->fdndels = (ty_fixeddelay **)calloc(FDNORDER, sizeof(ty_fixeddelay *));
|
||||||
|
for(i = 0; i < FDNORDER; i++) {
|
||||||
|
p->fdndels[i] = fixeddelay_make((int)p->maxdelay+1000);
|
||||||
|
}
|
||||||
|
p->fdngains = (float *)calloc(FDNORDER, sizeof(float));
|
||||||
|
p->fdnlens = (int *)calloc(FDNORDER, sizeof(int));
|
||||||
|
|
||||||
|
p->fdndamps = (ty_damper **)calloc(FDNORDER, sizeof(ty_damper *));
|
||||||
|
for(i = 0; i < FDNORDER; i++) {
|
||||||
|
p->fdndamps[i] = damper_make(p->fdndamping);
|
||||||
|
}
|
||||||
|
|
||||||
|
ga = 60.0;
|
||||||
|
gt = p->revtime;
|
||||||
|
ga = powf(10.0f,-ga/20.0f);
|
||||||
|
n = p->rate*gt;
|
||||||
|
p->alpha = pow((double)ga, 1.0/(double)n);
|
||||||
|
|
||||||
|
gb = 0.0;
|
||||||
|
for(i = 0; i < FDNORDER; i++) {
|
||||||
|
if (i == 0) gb = 1.000000*p->largestdelay;
|
||||||
|
if (i == 1) gb = 0.816490*p->largestdelay;
|
||||||
|
if (i == 2) gb = 0.707100*p->largestdelay;
|
||||||
|
if (i == 3) gb = 0.632450*p->largestdelay;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
p->fdnlens[i] = nearest_prime((int)gb, 0.5);
|
||||||
|
#else
|
||||||
|
p->fdnlens[i] = f_round(gb);
|
||||||
|
#endif
|
||||||
|
p->fdngains[i] = -powf((float)p->alpha,p->fdnlens[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
p->d = (float *)calloc(FDNORDER, sizeof(float));
|
||||||
|
p->u = (float *)calloc(FDNORDER, sizeof(float));
|
||||||
|
p->f = (float *)calloc(FDNORDER, sizeof(float));
|
||||||
|
|
||||||
|
/* Diffuser section */
|
||||||
|
|
||||||
|
diffscale = (float)p->fdnlens[3]/(210+159+562+410);
|
||||||
|
spread1 = spread;
|
||||||
|
spread2 = 3.0*spread;
|
||||||
|
|
||||||
|
b = 210;
|
||||||
|
r = 0.125541;
|
||||||
|
a = spread1*r;
|
||||||
|
c = 210+159+a;
|
||||||
|
cc = c-b;
|
||||||
|
r = 0.854046;
|
||||||
|
a = spread2*r;
|
||||||
|
d = 210+159+562+a;
|
||||||
|
dd = d-c;
|
||||||
|
e = 1341-d;
|
||||||
|
|
||||||
|
p->ldifs = (ty_diffuser **)calloc(4, sizeof(ty_diffuser *));
|
||||||
|
p->ldifs[0] = diffuser_make((int)(diffscale*b),0.75);
|
||||||
|
p->ldifs[1] = diffuser_make((int)(diffscale*cc),0.75);
|
||||||
|
p->ldifs[2] = diffuser_make((int)(diffscale*dd),0.625);
|
||||||
|
p->ldifs[3] = diffuser_make((int)(diffscale*e),0.625);
|
||||||
|
|
||||||
|
b = 210;
|
||||||
|
r = -0.568366;
|
||||||
|
a = spread1*r;
|
||||||
|
c = 210+159+a;
|
||||||
|
cc = c-b;
|
||||||
|
r = -0.126815;
|
||||||
|
a = spread2*r;
|
||||||
|
d = 210+159+562+a;
|
||||||
|
dd = d-c;
|
||||||
|
e = 1341-d;
|
||||||
|
|
||||||
|
p->rdifs = (ty_diffuser **)calloc(4, sizeof(ty_diffuser *));
|
||||||
|
p->rdifs[0] = diffuser_make((int)(diffscale*b),0.75);
|
||||||
|
p->rdifs[1] = diffuser_make((int)(diffscale*cc),0.75);
|
||||||
|
p->rdifs[2] = diffuser_make((int)(diffscale*dd),0.625);
|
||||||
|
p->rdifs[3] = diffuser_make((int)(diffscale*e),0.625);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Tapped delay section */
|
||||||
|
|
||||||
|
p->tapdelay = fixeddelay_make(44000);
|
||||||
|
p->taps = (int *)calloc(FDNORDER, sizeof(int));
|
||||||
|
p->tapgains = (float *)calloc(FDNORDER, sizeof(float));
|
||||||
|
|
||||||
|
p->taps[0] = 5+0.410*p->largestdelay;
|
||||||
|
p->taps[1] = 5+0.300*p->largestdelay;
|
||||||
|
p->taps[2] = 5+0.155*p->largestdelay;
|
||||||
|
p->taps[3] = 5+0.000*p->largestdelay;
|
||||||
|
|
||||||
|
for(i = 0; i < FDNORDER; i++) {
|
||||||
|
p->tapgains[i] = pow(p->alpha,(double)p->taps[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gverb_free(ty_gverb *p)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
damper_free(p->inputdamper);
|
||||||
|
for(i = 0; i < FDNORDER; i++) {
|
||||||
|
fixeddelay_free(p->fdndels[i]);
|
||||||
|
damper_free(p->fdndamps[i]);
|
||||||
|
diffuser_free(p->ldifs[i]);
|
||||||
|
diffuser_free(p->rdifs[i]);
|
||||||
|
}
|
||||||
|
free(p->fdndels);
|
||||||
|
free(p->fdngains);
|
||||||
|
free(p->fdnlens);
|
||||||
|
free(p->fdndamps);
|
||||||
|
free(p->d);
|
||||||
|
free(p->u);
|
||||||
|
free(p->f);
|
||||||
|
free(p->ldifs);
|
||||||
|
free(p->rdifs);
|
||||||
|
free(p->taps);
|
||||||
|
free(p->tapgains);
|
||||||
|
fixeddelay_free(p->tapdelay);
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gverb_flush(ty_gverb *p)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
damper_flush(p->inputdamper);
|
||||||
|
for(i = 0; i < FDNORDER; i++) {
|
||||||
|
fixeddelay_flush(p->fdndels[i]);
|
||||||
|
damper_flush(p->fdndamps[i]);
|
||||||
|
diffuser_flush(p->ldifs[i]);
|
||||||
|
diffuser_flush(p->rdifs[i]);
|
||||||
|
}
|
||||||
|
memset(p->d, 0, FDNORDER * sizeof(float));
|
||||||
|
memset(p->u, 0, FDNORDER * sizeof(float));
|
||||||
|
memset(p->f, 0, FDNORDER * sizeof(float));
|
||||||
|
fixeddelay_flush(p->tapdelay);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* swh: other functions are now in the .h file for inlining */
|
130
libraries/audio-client/external/gverb/src/gverbdsp.c
vendored
Executable file
130
libraries/audio-client/external/gverb/src/gverbdsp.c
vendored
Executable file
|
@ -0,0 +1,130 @@
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (C) 1999 Juhana Sadeharju
|
||||||
|
kouhia at nic.funet.fi
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "gverbdsp.h"
|
||||||
|
|
||||||
|
#define TRUE 1
|
||||||
|
#define FALSE 0
|
||||||
|
|
||||||
|
ty_diffuser *diffuser_make(int size, float coeff)
|
||||||
|
{
|
||||||
|
ty_diffuser *p;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
p = (ty_diffuser *)malloc(sizeof(ty_diffuser));
|
||||||
|
p->size = size;
|
||||||
|
p->coeff = coeff;
|
||||||
|
p->idx = 0;
|
||||||
|
p->buf = (float *)malloc(size*sizeof(float));
|
||||||
|
for (i = 0; i < size; i++) p->buf[i] = 0.0;
|
||||||
|
return(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void diffuser_free(ty_diffuser *p)
|
||||||
|
{
|
||||||
|
free(p->buf);
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void diffuser_flush(ty_diffuser *p)
|
||||||
|
{
|
||||||
|
memset(p->buf, 0, p->size * sizeof(float));
|
||||||
|
}
|
||||||
|
|
||||||
|
ty_damper *damper_make(float damping)
|
||||||
|
{
|
||||||
|
ty_damper *p;
|
||||||
|
|
||||||
|
p = (ty_damper *)malloc(sizeof(ty_damper));
|
||||||
|
p->damping = damping;
|
||||||
|
p->delay = 0.0f;
|
||||||
|
return(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void damper_free(ty_damper *p)
|
||||||
|
{
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void damper_flush(ty_damper *p)
|
||||||
|
{
|
||||||
|
p->delay = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
ty_fixeddelay *fixeddelay_make(int size)
|
||||||
|
{
|
||||||
|
ty_fixeddelay *p;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
p = (ty_fixeddelay *)malloc(sizeof(ty_fixeddelay));
|
||||||
|
p->size = size;
|
||||||
|
p->idx = 0;
|
||||||
|
p->buf = (float *)malloc(size*sizeof(float));
|
||||||
|
for (i = 0; i < size; i++) p->buf[i] = 0.0;
|
||||||
|
return(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fixeddelay_free(ty_fixeddelay *p)
|
||||||
|
{
|
||||||
|
free(p->buf);
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fixeddelay_flush(ty_fixeddelay *p)
|
||||||
|
{
|
||||||
|
memset(p->buf, 0, p->size * sizeof(float));
|
||||||
|
}
|
||||||
|
|
||||||
|
int isprime(int n)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
const unsigned int lim = (int)sqrtf((float)n);
|
||||||
|
|
||||||
|
if (n == 2) return(TRUE);
|
||||||
|
if ((n & 1) == 0) return(FALSE);
|
||||||
|
for(i = 3; i <= lim; i += 2)
|
||||||
|
if ((n % i) == 0) return(FALSE);
|
||||||
|
return(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int nearest_prime(int n, float rerror)
|
||||||
|
/* relative error; new prime will be in range
|
||||||
|
* [n-n*rerror, n+n*rerror];
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
int bound,k;
|
||||||
|
|
||||||
|
if (isprime(n)) return(n);
|
||||||
|
/* assume n is large enough and n*rerror enough smaller than n */
|
||||||
|
bound = n*rerror;
|
||||||
|
for(k = 1; k <= bound; k++) {
|
||||||
|
if (isprime(n+k)) return(n+k);
|
||||||
|
if (isprime(n-k)) return(n-k);
|
||||||
|
}
|
||||||
|
return(-1);
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
//
|
//
|
||||||
// Audio.cpp
|
// AudioClient.cpp
|
||||||
// interface/src
|
// interface/src
|
||||||
//
|
//
|
||||||
// Created by Stephen Birarda on 1/22/13.
|
// Created by Stephen Birarda on 1/22/13.
|
||||||
|
@ -28,30 +28,27 @@
|
||||||
#include <VersionHelpers.h>
|
#include <VersionHelpers.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <AudioConstants.h>
|
|
||||||
|
|
||||||
#include <QtCore/QBuffer>
|
#include <QtCore/QBuffer>
|
||||||
#include <QtMultimedia/QAudioInput>
|
#include <QtMultimedia/QAudioInput>
|
||||||
#include <QtMultimedia/QAudioOutput>
|
#include <QtMultimedia/QAudioOutput>
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
#include <AudioInjector.h>
|
|
||||||
#include <NodeList.h>
|
#include <NodeList.h>
|
||||||
#include <PacketHeaders.h>
|
#include <PacketHeaders.h>
|
||||||
|
|
||||||
#include <PositionalAudioStream.h>
|
|
||||||
|
|
||||||
#include <SharedUtil.h>
|
#include <SharedUtil.h>
|
||||||
#include <UUID.h>
|
#include <UUID.h>
|
||||||
|
|
||||||
#include "Application.h"
|
#include "AudioInjector.h"
|
||||||
|
#include "AudioConstants.h"
|
||||||
|
#include "PositionalAudioStream.h"
|
||||||
|
|
||||||
#include "Audio.h"
|
#include "AudioClient.h"
|
||||||
|
|
||||||
static const int RECEIVED_AUDIO_STREAM_CAPACITY_FRAMES = 100;
|
static const int RECEIVED_AUDIO_STREAM_CAPACITY_FRAMES = 100;
|
||||||
|
|
||||||
Audio::Audio() :
|
AudioClient::AudioClient() :
|
||||||
AbstractAudioInterface(),
|
AbstractAudioInterface(),
|
||||||
_audioInput(NULL),
|
_audioInput(NULL),
|
||||||
_desiredInputFormat(),
|
_desiredInputFormat(),
|
||||||
|
@ -95,13 +92,13 @@ Audio::Audio() :
|
||||||
// clear the array of locally injected samples
|
// clear the array of locally injected samples
|
||||||
memset(_localProceduralSamples, 0, AudioConstants::NETWORK_FRAME_BYTES_PER_CHANNEL);
|
memset(_localProceduralSamples, 0, AudioConstants::NETWORK_FRAME_BYTES_PER_CHANNEL);
|
||||||
|
|
||||||
connect(&_receivedAudioStream, &MixedProcessedAudioStream::processSamples, this, &Audio::processReceivedSamples, Qt::DirectConnection);
|
connect(&_receivedAudioStream, &MixedProcessedAudioStream::processSamples, this, &AudioClient::processReceivedSamples, Qt::DirectConnection);
|
||||||
|
|
||||||
// Initialize GVerb
|
// Initialize GVerb
|
||||||
initGverb();
|
initGverb();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::reset() {
|
void AudioClient::reset() {
|
||||||
_receivedAudioStream.reset();
|
_receivedAudioStream.reset();
|
||||||
_stats.reset();
|
_stats.reset();
|
||||||
_noiseSource.reset();
|
_noiseSource.reset();
|
||||||
|
@ -110,7 +107,7 @@ void Audio::reset() {
|
||||||
_inputGain.reset();
|
_inputGain.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::audioMixerKilled() {
|
void AudioClient::audioMixerKilled() {
|
||||||
_outgoingAvatarAudioSequenceNumber = 0;
|
_outgoingAvatarAudioSequenceNumber = 0;
|
||||||
_stats.reset();
|
_stats.reset();
|
||||||
}
|
}
|
||||||
|
@ -358,7 +355,7 @@ void linearResampling(const int16_t* sourceSamples, int16_t* destinationSamples,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::start() {
|
void AudioClient::start() {
|
||||||
|
|
||||||
// set up the desired audio format
|
// set up the desired audio format
|
||||||
_desiredInputFormat.setSampleRate(AudioConstants::SAMPLE_RATE);
|
_desiredInputFormat.setSampleRate(AudioConstants::SAMPLE_RATE);
|
||||||
|
@ -397,7 +394,7 @@ void Audio::start() {
|
||||||
_inputGain.setParameters(1.0f,0.0f);
|
_inputGain.setParameters(1.0f,0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::stop() {
|
void AudioClient::stop() {
|
||||||
|
|
||||||
_inputFrameBuffer.finalize();
|
_inputFrameBuffer.finalize();
|
||||||
_inputGain.finalize();
|
_inputGain.finalize();
|
||||||
|
@ -410,12 +407,12 @@ void Audio::stop() {
|
||||||
switchOutputToAudioDevice(QAudioDeviceInfo());
|
switchOutputToAudioDevice(QAudioDeviceInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Audio::getDefaultDeviceName(QAudio::Mode mode) {
|
QString AudioClient::getDefaultDeviceName(QAudio::Mode mode) {
|
||||||
QAudioDeviceInfo deviceInfo = defaultAudioDeviceForMode(mode);
|
QAudioDeviceInfo deviceInfo = defaultAudioDeviceForMode(mode);
|
||||||
return deviceInfo.deviceName();
|
return deviceInfo.deviceName();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<QString> Audio::getDeviceNames(QAudio::Mode mode) {
|
QVector<QString> AudioClient::getDeviceNames(QAudio::Mode mode) {
|
||||||
QVector<QString> deviceNames;
|
QVector<QString> deviceNames;
|
||||||
foreach(QAudioDeviceInfo audioDevice, QAudioDeviceInfo::availableDevices(mode)) {
|
foreach(QAudioDeviceInfo audioDevice, QAudioDeviceInfo::availableDevices(mode)) {
|
||||||
deviceNames << audioDevice.deviceName().trimmed();
|
deviceNames << audioDevice.deviceName().trimmed();
|
||||||
|
@ -423,17 +420,17 @@ QVector<QString> Audio::getDeviceNames(QAudio::Mode mode) {
|
||||||
return deviceNames;
|
return deviceNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Audio::switchInputToAudioDevice(const QString& inputDeviceName) {
|
bool AudioClient::switchInputToAudioDevice(const QString& inputDeviceName) {
|
||||||
qDebug() << "DEBUG [" << inputDeviceName << "] [" << getNamedAudioDeviceForMode(QAudio::AudioInput, inputDeviceName).deviceName() << "]";
|
qDebug() << "DEBUG [" << inputDeviceName << "] [" << getNamedAudioDeviceForMode(QAudio::AudioInput, inputDeviceName).deviceName() << "]";
|
||||||
return switchInputToAudioDevice(getNamedAudioDeviceForMode(QAudio::AudioInput, inputDeviceName));
|
return switchInputToAudioDevice(getNamedAudioDeviceForMode(QAudio::AudioInput, inputDeviceName));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Audio::switchOutputToAudioDevice(const QString& outputDeviceName) {
|
bool AudioClient::switchOutputToAudioDevice(const QString& outputDeviceName) {
|
||||||
qDebug() << "DEBUG [" << outputDeviceName << "] [" << getNamedAudioDeviceForMode(QAudio::AudioOutput, outputDeviceName).deviceName() << "]";
|
qDebug() << "DEBUG [" << outputDeviceName << "] [" << getNamedAudioDeviceForMode(QAudio::AudioOutput, outputDeviceName).deviceName() << "]";
|
||||||
return switchOutputToAudioDevice(getNamedAudioDeviceForMode(QAudio::AudioOutput, outputDeviceName));
|
return switchOutputToAudioDevice(getNamedAudioDeviceForMode(QAudio::AudioOutput, outputDeviceName));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::initGverb() {
|
void AudioClient::initGverb() {
|
||||||
// Initialize a new gverb instance
|
// Initialize a new gverb instance
|
||||||
_gverbLocal = gverb_new(_outputFormat.sampleRate(), _reverbOptions->getMaxRoomSize(), _reverbOptions->getRoomSize(),
|
_gverbLocal = gverb_new(_outputFormat.sampleRate(), _reverbOptions->getMaxRoomSize(), _reverbOptions->getRoomSize(),
|
||||||
_reverbOptions->getReverbTime(), _reverbOptions->getDamping(), _reverbOptions->getSpread(),
|
_reverbOptions->getReverbTime(), _reverbOptions->getDamping(), _reverbOptions->getSpread(),
|
||||||
|
@ -460,7 +457,7 @@ void Audio::initGverb() {
|
||||||
gverb_set_taillevel(_gverb, DB_CO(_reverbOptions->getTailLevel()));
|
gverb_set_taillevel(_gverb, DB_CO(_reverbOptions->getTailLevel()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::updateGverbOptions() {
|
void AudioClient::updateGverbOptions() {
|
||||||
bool reverbChanged = false;
|
bool reverbChanged = false;
|
||||||
if (_receivedAudioStream.hasReverb()) {
|
if (_receivedAudioStream.hasReverb()) {
|
||||||
|
|
||||||
|
@ -487,7 +484,7 @@ void Audio::updateGverbOptions() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::setReverbOptions(const AudioEffectOptions* options) {
|
void AudioClient::setReverbOptions(const AudioEffectOptions* options) {
|
||||||
// Save the new options
|
// Save the new options
|
||||||
_scriptReverbOptions.setMaxRoomSize(options->getMaxRoomSize());
|
_scriptReverbOptions.setMaxRoomSize(options->getMaxRoomSize());
|
||||||
_scriptReverbOptions.setRoomSize(options->getRoomSize());
|
_scriptReverbOptions.setRoomSize(options->getRoomSize());
|
||||||
|
@ -507,7 +504,7 @@ void Audio::setReverbOptions(const AudioEffectOptions* options) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::addReverb(ty_gverb* gverb, int16_t* samplesData, int numSamples, QAudioFormat& audioFormat, bool noEcho) {
|
void AudioClient::addReverb(ty_gverb* gverb, int16_t* samplesData, int numSamples, QAudioFormat& audioFormat, bool noEcho) {
|
||||||
float wetFraction = DB_CO(_reverbOptions->getWetLevel());
|
float wetFraction = DB_CO(_reverbOptions->getWetLevel());
|
||||||
float dryFraction = (noEcho) ? 0.0f : (1.0f - wetFraction);
|
float dryFraction = (noEcho) ? 0.0f : (1.0f - wetFraction);
|
||||||
|
|
||||||
|
@ -536,7 +533,7 @@ void Audio::addReverb(ty_gverb* gverb, int16_t* samplesData, int numSamples, QAu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::handleLocalEchoAndReverb(QByteArray& inputByteArray) {
|
void AudioClient::handleLocalEchoAndReverb(QByteArray& inputByteArray) {
|
||||||
// If there is server echo, reverb will be applied to the recieved audio stream so no need to have it here.
|
// If there is server echo, reverb will be applied to the recieved audio stream so no need to have it here.
|
||||||
bool hasLocalReverb = (_reverb || _receivedAudioStream.hasReverb()) &&
|
bool hasLocalReverb = (_reverb || _receivedAudioStream.hasReverb()) &&
|
||||||
!_shouldEchoToServer;
|
!_shouldEchoToServer;
|
||||||
|
@ -576,7 +573,7 @@ void Audio::handleLocalEchoAndReverb(QByteArray& inputByteArray) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::handleAudioInput() {
|
void AudioClient::handleAudioInput() {
|
||||||
static char audioDataPacket[MAX_PACKET_SIZE];
|
static char audioDataPacket[MAX_PACKET_SIZE];
|
||||||
|
|
||||||
static int numBytesPacketHeader = numBytesForPacketHeaderGivenPacketType(PacketTypeMicrophoneAudioNoEcho);
|
static int numBytesPacketHeader = numBytesForPacketHeaderGivenPacketType(PacketTypeMicrophoneAudioNoEcho);
|
||||||
|
@ -758,7 +755,7 @@ void Audio::handleAudioInput() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::processReceivedSamples(const QByteArray& inputBuffer, QByteArray& outputBuffer) {
|
void AudioClient::processReceivedSamples(const QByteArray& inputBuffer, QByteArray& outputBuffer) {
|
||||||
const int numNetworkOutputSamples = inputBuffer.size() / sizeof(int16_t);
|
const int numNetworkOutputSamples = inputBuffer.size() / sizeof(int16_t);
|
||||||
const int numDeviceOutputSamples = numNetworkOutputSamples * (_outputFormat.sampleRate() * _outputFormat.channelCount())
|
const int numDeviceOutputSamples = numNetworkOutputSamples * (_outputFormat.sampleRate() * _outputFormat.channelCount())
|
||||||
/ (_desiredOutputFormat.sampleRate() * _desiredOutputFormat.channelCount());
|
/ (_desiredOutputFormat.sampleRate() * _desiredOutputFormat.channelCount());
|
||||||
|
@ -785,7 +782,7 @@ void Audio::processReceivedSamples(const QByteArray& inputBuffer, QByteArray& ou
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::sendMuteEnvironmentPacket() {
|
void AudioClient::sendMuteEnvironmentPacket() {
|
||||||
QByteArray mutePacket = byteArrayWithPopulatedHeader(PacketTypeMuteEnvironment);
|
QByteArray mutePacket = byteArrayWithPopulatedHeader(PacketTypeMuteEnvironment);
|
||||||
QDataStream mutePacketStream(&mutePacket, QIODevice::Append);
|
QDataStream mutePacketStream(&mutePacket, QIODevice::Append);
|
||||||
|
|
||||||
|
@ -805,7 +802,7 @@ void Audio::sendMuteEnvironmentPacket() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::addReceivedAudioToStream(const QByteArray& audioByteArray) {
|
void AudioClient::addReceivedAudioToStream(const QByteArray& audioByteArray) {
|
||||||
if (_audioOutput) {
|
if (_audioOutput) {
|
||||||
// Audio output must exist and be correctly set up if we're going to process received audio
|
// Audio output must exist and be correctly set up if we're going to process received audio
|
||||||
_receivedAudioStream.parseData(audioByteArray);
|
_receivedAudioStream.parseData(audioByteArray);
|
||||||
|
@ -814,7 +811,7 @@ void Audio::addReceivedAudioToStream(const QByteArray& audioByteArray) {
|
||||||
Application::getInstance()->getBandwidthMeter()->inputStream(BandwidthMeter::AUDIO).updateValue(audioByteArray.size());
|
Application::getInstance()->getBandwidthMeter()->inputStream(BandwidthMeter::AUDIO).updateValue(audioByteArray.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::parseAudioEnvironmentData(const QByteArray &packet) {
|
void AudioClient::parseAudioEnvironmentData(const QByteArray &packet) {
|
||||||
int numBytesPacketHeader = numBytesForPacketHeader(packet);
|
int numBytesPacketHeader = numBytesForPacketHeader(packet);
|
||||||
const char* dataAt = packet.constData() + numBytesPacketHeader;
|
const char* dataAt = packet.constData() + numBytesPacketHeader;
|
||||||
|
|
||||||
|
@ -835,12 +832,12 @@ void Audio::parseAudioEnvironmentData(const QByteArray &packet) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::toggleMute() {
|
void AudioClient::toggleMute() {
|
||||||
_muted = !_muted;
|
_muted = !_muted;
|
||||||
muteToggled();
|
muteToggled();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::setIsStereoInput(bool isStereoInput) {
|
void AudioClient::setIsStereoInput(bool isStereoInput) {
|
||||||
if (isStereoInput != _isStereoInput) {
|
if (isStereoInput != _isStereoInput) {
|
||||||
_isStereoInput = isStereoInput;
|
_isStereoInput = isStereoInput;
|
||||||
|
|
||||||
|
@ -855,21 +852,21 @@ void Audio::setIsStereoInput(bool isStereoInput) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::toggleAudioSourceInject() {
|
void AudioClient::toggleAudioSourceInject() {
|
||||||
_audioSourceInjectEnabled = !_audioSourceInjectEnabled;
|
_audioSourceInjectEnabled = !_audioSourceInjectEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::selectAudioSourcePinkNoise() {
|
void AudioClient::selectAudioSourcePinkNoise() {
|
||||||
_noiseSourceEnabled = true;
|
_noiseSourceEnabled = true;
|
||||||
_toneSourceEnabled = false;
|
_toneSourceEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::selectAudioSourceSine440() {
|
void AudioClient::selectAudioSourceSine440() {
|
||||||
_toneSourceEnabled = true;
|
_toneSourceEnabled = true;
|
||||||
_noiseSourceEnabled = false;
|
_noiseSourceEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Audio::outputLocalInjector(bool isStereo, qreal volume, AudioInjector* injector) {
|
bool AudioClient::outputLocalInjector(bool isStereo, qreal volume, AudioInjector* injector) {
|
||||||
if (injector->getLocalBuffer()) {
|
if (injector->getLocalBuffer()) {
|
||||||
QAudioFormat localFormat = _desiredOutputFormat;
|
QAudioFormat localFormat = _desiredOutputFormat;
|
||||||
localFormat.setChannelCount(isStereo ? 2 : 1);
|
localFormat.setChannelCount(isStereo ? 2 : 1);
|
||||||
|
@ -895,13 +892,13 @@ bool Audio::outputLocalInjector(bool isStereo, qreal volume, AudioInjector* inje
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Audio::outputFormatChanged() {
|
void AudioClient::outputFormatChanged() {
|
||||||
int outputFormatChannelCountTimesSampleRate = _outputFormat.channelCount() * _outputFormat.sampleRate();
|
int outputFormatChannelCountTimesSampleRate = _outputFormat.channelCount() * _outputFormat.sampleRate();
|
||||||
_outputFrameSize = AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * outputFormatChannelCountTimesSampleRate / _desiredOutputFormat.sampleRate();
|
_outputFrameSize = AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * outputFormatChannelCountTimesSampleRate / _desiredOutputFormat.sampleRate();
|
||||||
_receivedAudioStream.outputFormatChanged(outputFormatChannelCountTimesSampleRate);
|
_receivedAudioStream.outputFormatChanged(outputFormatChannelCountTimesSampleRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Audio::switchInputToAudioDevice(const QAudioDeviceInfo& inputDeviceInfo) {
|
bool AudioClient::switchInputToAudioDevice(const QAudioDeviceInfo& inputDeviceInfo) {
|
||||||
bool supportedFormat = false;
|
bool supportedFormat = false;
|
||||||
|
|
||||||
// cleanup any previously initialized device
|
// cleanup any previously initialized device
|
||||||
|
@ -946,7 +943,7 @@ bool Audio::switchInputToAudioDevice(const QAudioDeviceInfo& inputDeviceInfo) {
|
||||||
return supportedFormat;
|
return supportedFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::outputNotify() {
|
void AudioClient::outputNotify() {
|
||||||
int recentUnfulfilled = _audioOutputIODevice.getRecentUnfulfilledReads();
|
int recentUnfulfilled = _audioOutputIODevice.getRecentUnfulfilledReads();
|
||||||
if (recentUnfulfilled > 0) {
|
if (recentUnfulfilled > 0) {
|
||||||
if (_outputStarveDetectionEnabled) {
|
if (_outputStarveDetectionEnabled) {
|
||||||
|
@ -970,7 +967,7 @@ void Audio::outputNotify() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Audio::switchOutputToAudioDevice(const QAudioDeviceInfo& outputDeviceInfo) {
|
bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo& outputDeviceInfo) {
|
||||||
bool supportedFormat = false;
|
bool supportedFormat = false;
|
||||||
|
|
||||||
// cleanup any previously initialized device
|
// cleanup any previously initialized device
|
||||||
|
@ -998,7 +995,7 @@ bool Audio::switchOutputToAudioDevice(const QAudioDeviceInfo& outputDeviceInfo)
|
||||||
_audioOutput = new QAudioOutput(outputDeviceInfo, _outputFormat, this);
|
_audioOutput = new QAudioOutput(outputDeviceInfo, _outputFormat, this);
|
||||||
_audioOutput->setBufferSize(_outputBufferSizeFrames * _outputFrameSize * sizeof(int16_t));
|
_audioOutput->setBufferSize(_outputBufferSizeFrames * _outputFrameSize * sizeof(int16_t));
|
||||||
|
|
||||||
connect(_audioOutput, &QAudioOutput::notify, this, &Audio::outputNotify);
|
connect(_audioOutput, &QAudioOutput::notify, this, &AudioClient::outputNotify);
|
||||||
|
|
||||||
qDebug() << "Output Buffer capacity in frames: " << _audioOutput->bufferSize() / sizeof(int16_t) / (float)_outputFrameSize;
|
qDebug() << "Output Buffer capacity in frames: " << _audioOutput->bufferSize() / sizeof(int16_t) / (float)_outputFrameSize;
|
||||||
|
|
||||||
|
@ -1017,7 +1014,7 @@ bool Audio::switchOutputToAudioDevice(const QAudioDeviceInfo& outputDeviceInfo)
|
||||||
return supportedFormat;
|
return supportedFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::setOutputBufferSize(int numFrames) {
|
void AudioClient::setOutputBufferSize(int numFrames) {
|
||||||
numFrames = std::min(std::max(numFrames, MIN_AUDIO_OUTPUT_BUFFER_SIZE_FRAMES), MAX_AUDIO_OUTPUT_BUFFER_SIZE_FRAMES);
|
numFrames = std::min(std::max(numFrames, MIN_AUDIO_OUTPUT_BUFFER_SIZE_FRAMES), MAX_AUDIO_OUTPUT_BUFFER_SIZE_FRAMES);
|
||||||
if (numFrames != _outputBufferSizeFrames) {
|
if (numFrames != _outputBufferSizeFrames) {
|
||||||
qDebug() << "Audio output buffer size (frames): " << numFrames;
|
qDebug() << "Audio output buffer size (frames): " << numFrames;
|
||||||
|
@ -1037,18 +1034,18 @@ void Audio::setOutputBufferSize(int numFrames) {
|
||||||
// proportional to the accelerator ratio.
|
// proportional to the accelerator ratio.
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
const float Audio::CALLBACK_ACCELERATOR_RATIO = 0.1f;
|
const float AudioClient::CALLBACK_ACCELERATOR_RATIO = 0.1f;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
const float Audio::CALLBACK_ACCELERATOR_RATIO = 2.0f;
|
const float AudioClient::CALLBACK_ACCELERATOR_RATIO = 2.0f;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef Q_OS_LINUX
|
#ifdef Q_OS_LINUX
|
||||||
const float Audio::CALLBACK_ACCELERATOR_RATIO = 2.0f;
|
const float AudioClient::CALLBACK_ACCELERATOR_RATIO = 2.0f;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int Audio::calculateNumberOfInputCallbackBytes(const QAudioFormat& format) const {
|
int AudioClient::calculateNumberOfInputCallbackBytes(const QAudioFormat& format) const {
|
||||||
int numInputCallbackBytes = (int)(((AudioConstants::NETWORK_FRAME_BYTES_PER_CHANNEL
|
int numInputCallbackBytes = (int)(((AudioConstants::NETWORK_FRAME_BYTES_PER_CHANNEL
|
||||||
* format.channelCount()
|
* format.channelCount()
|
||||||
* (format.sampleRate() / AudioConstants::SAMPLE_RATE))
|
* (format.sampleRate() / AudioConstants::SAMPLE_RATE))
|
||||||
|
@ -1057,7 +1054,7 @@ int Audio::calculateNumberOfInputCallbackBytes(const QAudioFormat& format) const
|
||||||
return numInputCallbackBytes;
|
return numInputCallbackBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Audio::calculateDeviceToNetworkInputRatio(int numBytes) const {
|
float AudioClient::calculateDeviceToNetworkInputRatio(int numBytes) const {
|
||||||
float inputToNetworkInputRatio = (int)((_numInputCallbackBytes
|
float inputToNetworkInputRatio = (int)((_numInputCallbackBytes
|
||||||
* CALLBACK_ACCELERATOR_RATIO
|
* CALLBACK_ACCELERATOR_RATIO
|
||||||
/ AudioConstants::NETWORK_FRAME_BYTES_PER_CHANNEL) + 0.5f);
|
/ AudioConstants::NETWORK_FRAME_BYTES_PER_CHANNEL) + 0.5f);
|
||||||
|
@ -1065,18 +1062,18 @@ float Audio::calculateDeviceToNetworkInputRatio(int numBytes) const {
|
||||||
return inputToNetworkInputRatio;
|
return inputToNetworkInputRatio;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Audio::calculateNumberOfFrameSamples(int numBytes) const {
|
int AudioClient::calculateNumberOfFrameSamples(int numBytes) const {
|
||||||
int frameSamples = (int)(numBytes * CALLBACK_ACCELERATOR_RATIO + 0.5f) / sizeof(int16_t);
|
int frameSamples = (int)(numBytes * CALLBACK_ACCELERATOR_RATIO + 0.5f) / sizeof(int16_t);
|
||||||
return frameSamples;
|
return frameSamples;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Audio::getInputRingBufferMsecsAvailable() const {
|
float AudioClient::getInputRingBufferMsecsAvailable() const {
|
||||||
int bytesInInputRingBuffer = _inputRingBuffer.samplesAvailable() * sizeof(int16_t);
|
int bytesInInputRingBuffer = _inputRingBuffer.samplesAvailable() * sizeof(int16_t);
|
||||||
float msecsInInputRingBuffer = bytesInInputRingBuffer / (float)(_inputFormat.bytesForDuration(USECS_PER_MSEC));
|
float msecsInInputRingBuffer = bytesInInputRingBuffer / (float)(_inputFormat.bytesForDuration(USECS_PER_MSEC));
|
||||||
return msecsInInputRingBuffer;
|
return msecsInInputRingBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Audio::getAudioOutputMsecsUnplayed() const {
|
float AudioClient::getAudioOutputMsecsUnplayed() const {
|
||||||
if (!_audioOutput) {
|
if (!_audioOutput) {
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
|
@ -1085,7 +1082,7 @@ float Audio::getAudioOutputMsecsUnplayed() const {
|
||||||
return msecsAudioOutputUnplayed;
|
return msecsAudioOutputUnplayed;
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 Audio::AudioOutputIODevice::readData(char * data, qint64 maxSize) {
|
qint64 AudioClient::AudioOutputIODevice::readData(char * data, qint64 maxSize) {
|
||||||
int samplesRequested = maxSize / sizeof(int16_t);
|
int samplesRequested = maxSize / sizeof(int16_t);
|
||||||
int samplesPopped;
|
int samplesPopped;
|
||||||
int bytesWritten;
|
int bytesWritten;
|
|
@ -1,5 +1,5 @@
|
||||||
//
|
//
|
||||||
// Audio.h
|
// AudioClient.h
|
||||||
// interface/src
|
// interface/src
|
||||||
//
|
//
|
||||||
// Created by Stephen Birarda on 1/22/13.
|
// Created by Stephen Birarda on 1/22/13.
|
||||||
|
@ -9,43 +9,38 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef hifi_Audio_h
|
#ifndef hifi_AudioClient_h
|
||||||
#define hifi_Audio_h
|
#define hifi_AudioClient_h
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <QAudio>
|
#include <QtCore/QByteArray>
|
||||||
#include <QAudioInput>
|
#include <QtCore/QElapsedTimer>
|
||||||
#include <QElapsedTimer>
|
|
||||||
#include <QGLWidget>
|
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
#include <QtCore/QVector>
|
#include <QtCore/QVector>
|
||||||
|
#include <QtMultimedia/QAudio>
|
||||||
#include <QtMultimedia/QAudioFormat>
|
#include <QtMultimedia/QAudioFormat>
|
||||||
#include <QVector>
|
#include <QtMultimedia/QAudioInput>
|
||||||
#include <QByteArray>
|
|
||||||
|
|
||||||
#include <AbstractAudioInterface.h>
|
#include <AbstractAudioInterface.h>
|
||||||
|
#include <AudioBuffer.h>
|
||||||
|
#include <AudioEffectOptions.h>
|
||||||
|
#include <AudioFormat.h>
|
||||||
|
#include <AudioGain.h>
|
||||||
#include <AudioRingBuffer.h>
|
#include <AudioRingBuffer.h>
|
||||||
|
#include <AudioSourceTone.h>
|
||||||
|
#include <AudioSourceNoise.h>
|
||||||
|
#include <AudioStreamStats.h>
|
||||||
#include <DependencyManager.h>
|
#include <DependencyManager.h>
|
||||||
|
#include <MixedProcessedAudioStream.h>
|
||||||
|
#include <RingBufferHistory.h>
|
||||||
#include <StDev.h>
|
#include <StDev.h>
|
||||||
|
|
||||||
#include "InterfaceConfig.h"
|
|
||||||
#include "audio/AudioIOStats.h"
|
|
||||||
#include "audio/AudioNoiseGate.h"
|
|
||||||
#include "AudioStreamStats.h"
|
|
||||||
#include "Recorder.h"
|
#include "Recorder.h"
|
||||||
#include "RingBufferHistory.h"
|
|
||||||
#include "AudioRingBuffer.h"
|
|
||||||
#include "AudioFormat.h"
|
|
||||||
#include "AudioBuffer.h"
|
|
||||||
#include "AudioSourceTone.h"
|
|
||||||
#include "AudioSourceNoise.h"
|
|
||||||
#include "AudioGain.h"
|
|
||||||
|
|
||||||
#include "MixedProcessedAudioStream.h"
|
|
||||||
#include "AudioEffectOptions.h"
|
|
||||||
|
|
||||||
|
#include "AudioIOStats.h"
|
||||||
|
#include "AudioNoiseGate.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#pragma warning( push )
|
#pragma warning( push )
|
||||||
|
@ -73,14 +68,14 @@ class QAudioInput;
|
||||||
class QAudioOutput;
|
class QAudioOutput;
|
||||||
class QIODevice;
|
class QIODevice;
|
||||||
|
|
||||||
class Audio : public AbstractAudioInterface, public Dependency {
|
class AudioClient : public AbstractAudioInterface, public Dependency {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
SINGLETON_DEPENDENCY
|
SINGLETON_DEPENDENCY
|
||||||
public:
|
public:
|
||||||
|
|
||||||
class AudioOutputIODevice : public QIODevice {
|
class AudioOutputIODevice : public QIODevice {
|
||||||
public:
|
public:
|
||||||
AudioOutputIODevice(MixedProcessedAudioStream& receivedAudioStream, Audio* audio) :
|
AudioOutputIODevice(MixedProcessedAudioStream& receivedAudioStream, AudioClient* audio) :
|
||||||
_receivedAudioStream(receivedAudioStream), _audio(audio), _unfulfilledReads(0) {};
|
_receivedAudioStream(receivedAudioStream), _audio(audio), _unfulfilledReads(0) {};
|
||||||
|
|
||||||
void start() { open(QIODevice::ReadOnly); }
|
void start() { open(QIODevice::ReadOnly); }
|
||||||
|
@ -91,7 +86,7 @@ public:
|
||||||
int getRecentUnfulfilledReads() { int unfulfilledReads = _unfulfilledReads; _unfulfilledReads = 0; return unfulfilledReads; }
|
int getRecentUnfulfilledReads() { int unfulfilledReads = _unfulfilledReads; _unfulfilledReads = 0; return unfulfilledReads; }
|
||||||
private:
|
private:
|
||||||
MixedProcessedAudioStream& _receivedAudioStream;
|
MixedProcessedAudioStream& _receivedAudioStream;
|
||||||
Audio* _audio;
|
AudioClient* _audio;
|
||||||
int _unfulfilledReads;
|
int _unfulfilledReads;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -179,7 +174,7 @@ signals:
|
||||||
void inputReceived(const QByteArray& inputSamples);
|
void inputReceived(const QByteArray& inputSamples);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Audio();
|
AudioClient();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void outputFormatChanged();
|
void outputFormatChanged();
|
||||||
|
@ -278,4 +273,4 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // hifi_Audio_h
|
#endif // hifi_AudioClient_h
|
|
@ -9,14 +9,12 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "InterfaceConfig.h"
|
|
||||||
|
|
||||||
#include <AudioConstants.h>
|
#include <AudioConstants.h>
|
||||||
#include <MixedProcessedAudioStream.h>
|
#include <MixedProcessedAudioStream.h>
|
||||||
#include <NodeList.h>
|
#include <NodeList.h>
|
||||||
#include <PositionalAudioStream.h>
|
#include <PositionalAudioStream.h>
|
||||||
|
|
||||||
#include "Audio.h"
|
#include "AudioClient.h"
|
||||||
|
|
||||||
#include "AudioIOStats.h"
|
#include "AudioIOStats.h"
|
||||||
|
|
||||||
|
@ -27,7 +25,7 @@ const int APPROXIMATELY_30_SECONDS_OF_AUDIO_PACKETS = (int)(30.0f * 1000.0f / Au
|
||||||
|
|
||||||
AudioIOStats::AudioIOStats(MixedProcessedAudioStream* receivedAudioStream) :
|
AudioIOStats::AudioIOStats(MixedProcessedAudioStream* receivedAudioStream) :
|
||||||
_receivedAudioStream(receivedAudioStream),
|
_receivedAudioStream(receivedAudioStream),
|
||||||
_audioInputMsecsReadStats(MSECS_PER_SECOND / (float)AudioConstants::NETWORK_FRAME_MSECS * Audio::CALLBACK_ACCELERATOR_RATIO, FRAMES_AVAILABLE_STATS_WINDOW_SECONDS),
|
_audioInputMsecsReadStats(MSECS_PER_SECOND / (float)AudioConstants::NETWORK_FRAME_MSECS * AudioClient::CALLBACK_ACCELERATOR_RATIO, FRAMES_AVAILABLE_STATS_WINDOW_SECONDS),
|
||||||
_inputRingBufferMsecsAvailableStats(1, FRAMES_AVAILABLE_STATS_WINDOW_SECONDS),
|
_inputRingBufferMsecsAvailableStats(1, FRAMES_AVAILABLE_STATS_WINDOW_SECONDS),
|
||||||
_audioOutputMsecsUnplayedStats(1, FRAMES_AVAILABLE_STATS_WINDOW_SECONDS),
|
_audioOutputMsecsUnplayedStats(1, FRAMES_AVAILABLE_STATS_WINDOW_SECONDS),
|
||||||
_lastSentAudioPacket(0),
|
_lastSentAudioPacket(0),
|
||||||
|
@ -97,7 +95,7 @@ void AudioIOStats::parseAudioStreamStatsPacket(const QByteArray& packet) {
|
||||||
|
|
||||||
void AudioIOStats::sendDownstreamAudioStatsPacket() {
|
void AudioIOStats::sendDownstreamAudioStatsPacket() {
|
||||||
|
|
||||||
auto audioIO = DependencyManager::get<Audio>();
|
auto audioIO = DependencyManager::get<AudioClient>();
|
||||||
|
|
||||||
// since this function is called every second, we'll sample for some of our stats here
|
// since this function is called every second, we'll sample for some of our stats here
|
||||||
_inputRingBufferMsecsAvailableStats.update(audioIO->getInputRingBufferMsecsAvailable());
|
_inputRingBufferMsecsAvailableStats.update(audioIO->getInputRingBufferMsecsAvailable());
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// AudioBuffer.h
|
// AudioBuffer.h
|
||||||
// hifi
|
// libraries/audio/src
|
||||||
//
|
//
|
||||||
// Created by Craig Hansen-Sturm on 8/29/14.
|
// Created by Craig Hansen-Sturm on 8/29/14.
|
||||||
// Copyright 2014 High Fidelity, Inc.
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
|
#include "AudioFormat.h"
|
||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
class AudioFrameBuffer {
|
class AudioFrameBuffer {
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
#include "InboundAudioStream.h"
|
#include "InboundAudioStream.h"
|
||||||
|
|
||||||
class Audio;
|
class AudioClient;
|
||||||
|
|
||||||
class MixedProcessedAudioStream : public InboundAudioStream {
|
class MixedProcessedAudioStream : public InboundAudioStream {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// Recorder.h
|
// Recorder.h
|
||||||
//
|
// libraries/avatars/src
|
||||||
//
|
//
|
||||||
// Created by Clement on 8/7/14.
|
// Created by Clement on 8/7/14.
|
||||||
// Copyright 2014 High Fidelity, Inc.
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
|
|
Loading…
Reference in a new issue