* `qtversion`: Choose to build with either Qt5 or Qt6
+* `buildinfo`: Additional info used to describe the build
+
For example:
```sh
$ meson setup -Drtaudio=enabled builddir
+- Version: "2.0.2"
+ Date: 2023-09-01
+ Description:
+ - (added) VS Mode latency categories for Linux audio devices
+ - (added) VS Mode audio warnings for high latency Linux devices
+ - (updated) Improved support for Pipewire latency on Linux
+ - (fixed) Crash on Windows when using the JACK audio backend
+ - (fixed) Include ALSA support for Linux builds using meson
+ - (fixed) VS Mode overlapping UI elements with max scaling
+ - (fixed) Don't require git to be present for meson builds
+ - (fixed) Linux man page description and meson build errors
- Version: "2.0.1"
Date: 2023-08-29
Description:
c_defines += ['-DNDEBUG']
endif
-git_tags_cmd = run_command('git', 'describe', '--tags', check: false)
-git_hash_cmd = run_command('git', 'rev-parse', '--short', 'HEAD', check: false)
-if git_tags_cmd.returncode() == 0 and git_hash_cmd.returncode() == 0
- git_tags = git_tags_cmd.stdout().strip()
- git_hash = git_hash_cmd.stdout().strip()
- defines += ['-DJACKTRIP_BUILD_INFO=' + git_tags + '-' + git_hash]
+build_info = get_option('buildinfo')
+git = find_program('git', required: false)
+if build_info == '' and git.found()
+ git_tags_cmd = run_command(git, 'describe', '--tags', check: false)
+ git_hash_cmd = run_command(git, 'rev-parse', '--short', 'HEAD', check: false)
+ if git_tags_cmd.returncode() == 0 and git_hash_cmd.returncode() == 0
+ git_tags = git_tags_cmd.stdout().strip()
+ git_hash = git_hash_cmd.stdout().strip()
+ build_info = git_tags + '-' + git_hash
+ endif
+endif
+if build_info != ''
+ message('Build info: ' + build_info)
+ defines += ['-DJACKTRIP_BUILD_INFO=' + build_info]
endif
src = [ 'src/DataProtocol.cpp',
if help2man.found()
gzip = find_program('gzip', required: false)
help2man_opts = [
+ '--name="high-quality system for audio network performances"',
'--no-info',
'--section=1']
manfile = custom_target('jacktrip.1',
install_dir: get_option('mandir') / 'man1')
if gzip.found()
custom_target('jacktrip.1.gz',
+ input: manfile,
output: 'jacktrip.1.gz',
- command: [gzip, '-k', manfile],
+ command: [gzip, '-k', '-f', '@INPUT@'],
install: true,
install_dir: get_option('mandir') / 'man1')
endif
option('noupdater', type : 'boolean', value : 'false', description: 'Build without auto-update support')
option('nofeedback', type : 'boolean', value : 'false', description: 'Build without feedback detection')
option('profile', type: 'combo', choices: ['default', 'development'], value: 'default', description: 'Choose build profile / Sets desktop id accordingly')
-option('qtversion', type : 'combo', choices: ['', '5', '6'], description: 'Choose to build with either Qt5 or Qt6')
\ No newline at end of file
+option('qtversion', type : 'combo', choices: ['', '5', '6'], description: 'Choose to build with either Qt5 or Qt6')
+option('buildinfo', type : 'string', value : '', yield : true, description: 'Additional info used to describe the build')
\ No newline at end of file
{
"app_name": "JackTrip",
"releases": [
+ {
+ "version": "2.0.1",
+ "changelog": "Full changelog at https://github.com/jacktrip/jacktrip/releases/tag/v2.0.1",
+ "download": {
+ "date": "2023-08-30T00:00:00Z",
+ "url": "https://files.jacktrip.org/app-builds/JackTrip-v2.0.1-macOS-x64-signed-installer.pkg",
+ "downloadSize": "177272934",
+ "sha256": "5f12f512cd372beb01c6c888c8bbbaf4c1e5cf61881db9cd91c5d2c8582531b5"
+ }
+ },
{
"version": "2.0.0",
"changelog": "Full changelog at https://github.com/jacktrip/jacktrip/releases/tag/v2.0.0",
{
"app_name": "JackTrip",
"releases": [
+ {
+ "version": "2.0.1",
+ "changelog": "Full changelog at https://github.com/jacktrip/jacktrip/releases/tag/v2.0.1",
+ "download": {
+ "date": "2023-08-30T00:00:00Z",
+ "url": "https://files.jacktrip.org/app-builds/JackTrip-v2.0.1-Windows-x64-signed-installer.msi",
+ "downloadSize": "95846400",
+ "sha256": "aeb8934b7ef5ab274a135f575b13f16e1e93b42cfc631cfefa611477ae092c23"
+ }
+ },
{
"version": "2.0.0",
"changelog": "Full changelog at https://github.com/jacktrip/jacktrip/releases/tag/v2.0.0",
{
"app_name": "JackTrip",
"releases": [
+ {
+ "version": "2.0.1",
+ "changelog": "Full changelog at https://github.com/jacktrip/jacktrip/releases/tag/v2.0.1",
+ "download": {
+ "date": "2023-08-30T00:00:00Z",
+ "url": "https://files.jacktrip.org/app-builds/JackTrip-v2.0.1-Linux-x64-binary.zip",
+ "downloadSize": "1216267",
+ "sha256": "eb7f10108e4cd2ef09b3df8b83f67187dc9174ac632dcb0ddd61087e65c3f0cb"
+ }
+ },
{
"version": "2.0.0",
"changelog": "Full changelog at https://github.com/jacktrip/jacktrip/releases/tag/v2.0.0",
{
"app_name": "JackTrip",
"releases": [
+ {
+ "version": "2.0.1",
+ "changelog": "Full changelog at https://github.com/jacktrip/jacktrip/releases/tag/v2.0.1",
+ "download": {
+ "date": "2023-08-30T00:00:00Z",
+ "url": "https://files.jacktrip.org/app-builds/JackTrip-v2.0.1-macOS-x64-signed-installer.pkg",
+ "downloadSize": "177272934",
+ "sha256": "5f12f512cd372beb01c6c888c8bbbaf4c1e5cf61881db9cd91c5d2c8582531b5"
+ }
+ },
{
"version": "2.0.0",
"changelog": "Full changelog at https://github.com/jacktrip/jacktrip/releases/tag/v2.0.0",
{
"app_name": "JackTrip",
"releases": [
+ {
+ "version": "2.0.1",
+ "changelog": "Full changelog at https://github.com/jacktrip/jacktrip/releases/tag/v2.0.1",
+ "download": {
+ "date": "2023-08-30T00:00:00Z",
+ "url": "https://files.jacktrip.org/app-builds/JackTrip-v2.0.1-Windows-x64-signed-installer.msi",
+ "downloadSize": "95846400",
+ "sha256": "aeb8934b7ef5ab274a135f575b13f16e1e93b42cfc631cfefa611477ae092c23"
+ }
+ },
{
"version": "2.0.0",
"changelog": "Full changelog at https://github.com/jacktrip/jacktrip/releases/tag/v2.0.0",
}
}
+//*******************************************************************************
+void AudioInterface::setPipewireLatency(unsigned int bufferSize, unsigned int sampleRate)
+{
+ if (bufferSize == 0 || sampleRate == 0)
+ return;
+#if defined(__unix__)
+ char latency_env[40];
+ sprintf(latency_env, "%d/%d", bufferSize, sampleRate);
+ setenv("PIPEWIRE_LATENCY", latency_env, 1);
+#endif
+}
+
//*******************************************************************************
void AudioInterface::appendProcessPluginToNetwork(ProcessPlugin* plugin)
{
mWarningHelpUrl = "https://help.jacktrip.org/hc/en-us/articles/4409919243155";
mHighLatencyFlag = true;
break;
+ case DEVICE_WARN_ALSA_LATENCY:
+ mWarningMsg =
+ "You audio device drivers may cause high latency or audio delay. Use "
+ "JACK backend or Linux ALSA drivers to reduce audio delays.";
+ mWarningHelpUrl = "";
+ mHighLatencyFlag = true;
+ break;
default:
mWarningMsg = "";
mWarningHelpUrl = "";
enum warningMessageT {
DEVICE_WARN_NONE,
DEVICE_WARN_BUFFER_LATENCY,
- DEVICE_WARN_ASIO_LATENCY
+ DEVICE_WARN_ASIO_LATENCY,
+ DEVICE_WARN_ALSA_LATENCY
};
enum errorMessageT {
const int8_t* const input, sample_t* output,
const AudioInterface::audioBitResolutionT sourceBitResolution);
+ /** \brief Sets PIPEWIRE_LATENCY environment variable on unix */
+ static void setPipewireLatency(unsigned int bufferSize, unsigned int sampleRate);
+
//--------------SETTERS---------------------------------------------
virtual void setInputChannels(QVarLengthArray<int> inputChans)
{
break;
}
}
- std::free(ports);
+ jack_free(ports);
}
// Get physical input (playback) ports
break;
}
}
- std::free(ports);
+ jack_free(ports);
}
}
//*******************************************************************************
void RtAudioDevice::printVerbose() const
{
- cout << "Audio Device [" << this->api << " - " << this->ID << "] : " << this->name
- << endl;
+ cout << "Audio Device [" << RtAudio::getApiDisplayName(this->api) << " - "
+ << this->ID << "] : " << this->name << endl;
cout << " Output Channels : " << this->outputChannels << endl;
cout << " Input Channels : " << this->inputChannels << endl;
cout << " Supported Sampling Rates: ";
AudioInterface::setDevicesWarningMsg(AudioInterface::DEVICE_WARN_NONE);
AudioInterface::setDevicesErrorMsg(AudioInterface::DEVICE_ERR_SAME_ASIO);
}
+#else
+ if (in_device.api == RtAudio::LINUX_PULSE
+ || in_device.api == RtAudio::LINUX_OSS) {
+ AudioInterface::setDevicesWarningMsg(
+ AudioInterface::DEVICE_WARN_ALSA_LATENCY);
+ AudioInterface::setDevicesErrorMsg(AudioInterface::DEVICE_ERR_NONE);
+ }
#endif
} else {
AudioInterface::setDevicesWarningMsg(AudioInterface::DEVICE_WARN_NONE);
#if defined(__unix__)
if (mChangeDefaultBS or mChangeDefaultSR) {
- char latency_env[40];
- sprintf(latency_env, "%d/%d", mAudioBufferSize, mSampleRate);
- setenv("PIPEWIRE_LATENCY", latency_env, 1);
+ AudioInterface::setPipewireLatency(mAudioBufferSize, mSampleRate);
}
#endif
outputCombo.currentIndex = index
outputCombo.popup.close()
audio.outputDevice = modelData.text
- if (modelData.category === "Low-Latency (ASIO)") {
- let inputComboIdx = inputCombo.model.findIndex(it => it.category === "Low-Latency (ASIO)" && it.text === modelData.text);
+ if (modelData.category.startsWith("Low-Latency")) {
+ let inputComboIdx = inputCombo.model.findIndex(it => it.category.startsWith("Low-Latency") && it.text === modelData.text);
if (inputComboIdx !== null && inputComboIdx !== undefined) {
inputCombo.currentIndex = inputComboIdx;
audio.inputDevice = modelData.text
inputCombo.currentIndex = index
inputCombo.popup.close()
audio.inputDevice = modelData.text
- if (modelData.category === "Low-Latency (ASIO)") {
- let outputComboIdx = outputCombo.model.findIndex(it => it.category === "Low-Latency (ASIO)" && it.text === modelData.text);
+ if (modelData.category.startsWith("Low-Latency")) {
+ let outputComboIdx = outputCombo.model.findIndex(it => it.category.startsWith("Low-Latency") && it.text === modelData.text);
if (outputComboIdx !== null && outputComboIdx !== undefined) {
outputCombo.currentIndex = outputComboIdx;
audio.outputDevice = modelData.text
outputCombo.currentIndex = index
outputCombo.popup.close()
audio.outputDevice = modelData.text
- if (modelData.category === "Low-Latency (ASIO)") {
- let inputComboIdx = inputCombo.model.findIndex(it => it.category === "Low-Latency (ASIO)" && it.text === modelData.text);
+ if (modelData.category.startsWith("Low-Latency")) {
+ let inputComboIdx = inputCombo.model.findIndex(it => it.category.startsWith("Low-Latency") && it.text === modelData.text);
if (inputComboIdx !== null && inputComboIdx !== undefined) {
inputCombo.currentIndex = inputComboIdx;
audio.inputDevice = modelData.text
inputCombo.currentIndex = index
inputCombo.popup.close()
audio.inputDevice = modelData.text
- if (modelData.category === "Low-Latency (ASIO)") {
- let outputComboIdx = outputCombo.model.findIndex(it => it.category === "Low-Latency (ASIO)" && it.text === modelData.text);
+ if (modelData.category.startsWith("Low-Latency")) {
+ let outputComboIdx = outputCombo.model.findIndex(it => it.category.startsWith("Low-Latency") && it.text === modelData.text);
if (outputComboIdx !== null && outputComboIdx !== undefined) {
outputCombo.currentIndex = outputComboIdx;
audio.outputDevice = modelData.text
Component {
id: inputControls
-
+
ColumnLayout {
anchors.fill: parent
spacing: 2
Item {
Layout.fillHeight: true
- Layout.preferredWidth: 100
+ Layout.preferredWidth: 100 * virtualstudio.uiScale
Loader {
id: typeIconIndicator
Meter {
anchors.fill: parent
- anchors.topMargin: 5 * virtualstudio.uiScale
- anchors.rightMargin: 8 * virtualstudio.uiScale
+ anchors.topMargin: 5
+ anchors.rightMargin: 8
model: isInput ? audio.inputMeterLevels : audio.outputMeterLevels
clipped: isInput ? audio.inputClipped : audio.outputClipped
enabled: true
property string disabledButtonText: "#D3D4D4"
property string saveButtonText: "#DB0A0A"
property int minifiedHeight: 36
- property int fullHeight: 80
+ property int fullHeight: 84
id: deviceControlsGroup
width: parent.width
property int bins: Math.max(15, width/20)
property int innerMargin: 2 * virtualstudio.uiScale
property int boxRadius: 3 * virtualstudio.uiScale
- property int boxThickness: 12 * virtualstudio.uiScale
+ property int boxThickness: 12
required property bool clipped
property bool enabled: true
property string meterColor: enabled ? (virtualstudio.darkMode ? "#5B5858" : "#D3D4D4") : (virtualstudio.darkMode ? "#7b7979" : "#EAECEC")
anchors.rightMargin: 32 * virtualstudio.uiScale
anchors.verticalCenter: parent.verticalCenter
}
-
+
Text {
id: gettingStartedText2
visible: recommendationScreen === "fiber"
Item {
id: acknowledgedButtonsContainer
- width: 320
+ width: 320 * virtualstudio.uiScale
anchors.top: acknowledgedSubheader.bottom
anchors.topMargin: 64 * virtualstudio.uiScale
}
}
-
Button {
id: acknowledgedNoButton
anchors.right: parent.right
audio.restartAudio();
}
font.family: "Poppins"
- enabled: audio.audioBackend != "JACK"
}
Text {
x: 48 * virtualstudio.uiScale
text: "Buffer Size"
font { family: "Poppins"; pixelSize: fontMedium * virtualstudio.fontScale * virtualstudio.uiScale }
- visible: audio.audioBackend != "JACK"
color: textColour
}
anchors.left: showLabel ? tooltip.right : parent.left
anchors.leftMargin: showLabel ? 8 * virtualstudio.uiScale : 0
anchors.verticalCenter: label.verticalCenter
- width: 16 * virtualstudio.uiScale
- height: 16 * virtualstudio.uiScale
+ width: 16
+ height: 16
icon.source: "quiet.svg"
color: iconColor
}
id: louderIcon
anchors.right: parent.right
anchors.verticalCenter: label.verticalCenter
- width: 18 * virtualstudio.uiScale
- height: 18 * virtualstudio.uiScale
+ width: 18
+ height: 18
icon.source: "loud.svg"
color: iconColor
}
handle: Rectangle {
x: slider.leftPadding + slider.visualPosition * (slider.availableWidth - width)
y: slider.topPadding + slider.availableHeight / 2 - height / 2
- implicitWidth: 20 * virtualstudio.uiScale
- implicitHeight: 20 * virtualstudio.uiScale
+ implicitWidth: 18 * virtualstudio.uiScale
+ implicitHeight: 18 * virtualstudio.uiScale
radius: implicitWidth / 2
color: slider.pressed ? sliderPressedColour : "white"
border.width: 3
#ifdef RT_AUDIO
if (m_ui->backendComboBox->currentIndex() == 1) {
+ unsigned int bufferSize = m_ui->bufferSizeComboBox->currentText().toInt();
+ unsigned int sampleRate = m_ui->sampleRateComboBox->currentText().toInt();
m_jackTrip->setAudiointerfaceMode(JackTrip::RTAUDIO);
- m_jackTrip->setSampleRate(
- m_ui->sampleRateComboBox->currentText().toInt());
- m_jackTrip->setAudioBufferSizeInSamples(
- m_ui->bufferSizeComboBox->currentText().toInt());
+ m_jackTrip->setSampleRate(sampleRate);
+ m_jackTrip->setAudioBufferSizeInSamples(bufferSize);
// we assume that first entry is "(default)"
if (m_ui->inputDeviceComboBox->currentIndex() == 0) {
m_jackTrip->setInputDevice("");
m_jackTrip->setOutputDevice(
m_ui->outputDeviceComboBox->currentText().toStdString());
}
+ AudioInterface::setPipewireLatency(bufferSize, sampleRate);
}
#endif
m_devicePtr->disconnect();
m_devicePtr.reset();
}
- m_webChannelServer->close();
m_testMode = test;
settings.remove(QStringLiteral("UserId"));
settings.endGroup();
+ // stop timers, clear data, etc.
+ resetState();
+
// clear user data
m_userMetadata = QJsonObject();
m_userId.clear();
m_uiMode = QJackTrip::STANDARD;
settings.setValue(QStringLiteral("UiMode"), m_uiMode);
- m_webChannelServer->close();
- m_refreshTimer.stop();
- m_heartbeatTimer.stop();
+ // stop timers, clear data, etc.
+ resetState();
+ setWindowState(QStringLiteral("start"));
+ m_auth->logout();
if (m_showFirstRun) {
m_showFirstRun = false;
m_devicePtr.reset();
}
- m_webChannelServer->close();
-
QUrl logoutURL = QUrl("https://auth.jacktrip.org/v2/logout");
QUrlQuery query;
query.addQueryItem(QStringLiteral("client_id"), AUTH_CLIENT_ID);
settings.remove(QStringLiteral("UserId"));
settings.endGroup();
+ // stop timers, clear data, etc.
+ resetState();
+
// clear user data
m_refreshToken.clear();
m_userMetadata = QJsonObject();
m_isExiting = true;
emit isExitingChanged();
- m_startTimer.stop();
- m_refreshTimer.stop();
- m_heartbeatTimer.stop();
- m_networkOutageTimer.stop();
+ // stop timers, clear data, etc.
+ resetState();
+
if (m_onConnectedScreen) {
// manually disconnect on self-managed studios
if (!m_currentStudio.id().isEmpty() && !m_currentStudio.isManaged()) {
}
msgBox.exec();
- if (shouldSwitchToRtAudio)
- m_audioConfigPtr->setAudioBackend("RtAudio");
if (m_jackTripRunning)
connectionFinished();
}
}
}
+void VirtualStudio::resetState()
+{
+ m_webChannelServer->close();
+ m_refreshTimer.stop();
+ m_heartbeatTimer.stop();
+ m_startTimer.stop();
+ m_networkOutageTimer.stop();
+ m_firstRefresh = true;
+}
+
void VirtualStudio::getServerList(bool signalRefresh, int index)
{
QMutexLocker refreshLock(&m_refreshMutex);
void VirtualStudio::getSubscriptions()
{
+ if (m_userId.isEmpty()) {
+ qDebug() << "Invalid user ID";
+ return;
+ }
QNetworkReply* reply = m_api->getSubscriptions(m_userId);
connect(reply, &QNetworkReply::finished, this, [&, reply]() {
if (reply->error() != QNetworkReply::NoError) {
void exit();
private:
+ void resetState();
void getServerList(bool signalRefresh = false, int index = -1);
void getSubscriptions();
void getRegions();
#include "vsApi.h"
+#include "../jacktrip_globals.h"
+
VsApi::VsApi(QNetworkAccessManager* networkAccessManager)
{
m_networkAccessManager = networkAccessManager;
QNetworkReply* VsApi::get(const QUrl& url)
{
QNetworkRequest request = QNetworkRequest(url);
+ request.setRawHeader(QByteArray("User-Agent"),
+ QString("JackTrip/%1 (Qt)").arg(gVersion).toUtf8());
request.setRawHeader(QByteArray("Authorization"),
QString("Bearer %1").arg(m_accessToken).toUtf8());
QNetworkReply* VsApi::post(const QUrl& url, const QByteArray& data)
{
QNetworkRequest request = QNetworkRequest(url);
+ request.setRawHeader(QByteArray("User-Agent"),
+ QString("JackTrip/%1 (Qt)").arg(gVersion).toUtf8());
request.setRawHeader(QByteArray("Authorization"),
QString("Bearer %1").arg(m_accessToken).toUtf8());
request.setRawHeader(QByteArray("Content-Type"),
QNetworkReply* VsApi::put(const QUrl& url, const QByteArray& data)
{
QNetworkRequest request = QNetworkRequest(url);
+ request.setRawHeader(QByteArray("User-Agent"),
+ QString("JackTrip/%1 (Qt)").arg(gVersion).toUtf8());
request.setRawHeader(QByteArray("Authorization"),
QString("Bearer %1").arg(m_accessToken).toUtf8());
request.setRawHeader(QByteArray("Content-Type"),
QNetworkReply* VsApi::deleteResource(const QUrl& url)
{
QNetworkRequest request = QNetworkRequest(url);
+ request.setRawHeader(QByteArray("User-Agent"),
+ QString("JackTrip/%1 (Qt)").arg(gVersion).toUtf8());
request.setRawHeader(QByteArray("Authorization"),
QString("Bearer %1").arg(m_accessToken).toUtf8());
if (getUseRtAudio())
return;
m_backend = AudioBackendType::RTAUDIO;
- refreshDevices();
} else {
if (!getUseRtAudio())
return;
emit feedbackDetectionEnabledChanged();
}
-void VsAudio::setBufferSize([[maybe_unused]] int bufSize)
+void VsAudio::setBufferSize(int bufSize)
{
if (m_audioBufferSize == bufSize)
return;
{
AudioInterface* ifPtr = nullptr;
+#if defined(__unix__)
+ AudioInterface::setPipewireLatency(getBufferSize(), m_sampleRate);
+#endif
+
// Create AudioInterface Client Object
if (isBackendAvailable<AudioInterfaceMode::ALL>() && jackIsAvailable()) {
// all backends area available
AudioInterface* VsAudio::newJackAudioInterface([[maybe_unused]] JackTrip* jackTripPtr)
{
- static const int numJackChannels = 2;
- AudioInterface* ifPtr = nullptr;
+ AudioInterface* ifPtr = nullptr;
#ifndef NO_JACK
+ static const int numJackChannels = 2;
if constexpr (isBackendAvailable<AudioInterfaceMode::ALL>()
|| isBackendAvailable<AudioInterfaceMode::JACK>()) {
QVarLengthArray<int> inputChans;
updateDeviceModels();
} else {
m_parentPtr->setAudioBackend("RtAudio");
+ updateDeviceModels();
}
}
#endif
}
if (m_audioInterfacePtr.isNull()) {
- emit signalError(QStringLiteral("Failed to initialize audio interface"));
return;
}
// initialize plugins and start the audio callback process
m_audioInterfacePtr->initPlugins(false);
m_audioInterfacePtr->startProcess();
-
- if (m_parentPtr->m_backend == VsAudio::AudioBackendType::JACK) {
- // this crashes on windows
-#ifndef _WIN32
- m_audioInterfacePtr->connectDefaultPorts();
-#endif
- }
+ m_audioInterfacePtr->connectDefaultPorts();
m_parentPtr->updateDeviceMessages(*m_audioInterfacePtr);
m_parentPtr->setAudioReady(true);
channels.append(devices[n].outputChannels);
}
-#ifdef _WIN32
switch (devices[n].api) {
case RtAudio::WINDOWS_ASIO:
categories.append("Low-Latency (ASIO)");
break;
case RtAudio::WINDOWS_WASAPI:
- categories.append("High-Latency (Non-ASIO)");
+ categories.append("High-Latency (WASAPI)");
break;
case RtAudio::WINDOWS_DS:
- categories.append("High-Latency (Non-ASIO)");
+ categories.append("High-Latency (DirectSound)");
+ break;
+ case RtAudio::LINUX_ALSA:
+ categories.append("Low-Latency (ALSA)");
+ break;
+ case RtAudio::LINUX_PULSE:
+ categories.append("High-Latency (Pulse)");
+ break;
+ case RtAudio::LINUX_OSS:
+ categories.append("High-Latency (OSS)");
break;
default:
categories.append("");
break;
}
-#else
- categories.append("");
-#endif
}
}
connect(&mSocket, &QWebSocket::binaryMessageReceived, this,
&VsPinger::onReceivePingMessage);
connect(&mSocket, &QWebSocket::connected, this, &VsPinger::onConnected);
+#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
+ connect(&mSocket,
+ QOverload<QAbstractSocket::SocketError>::of(&QWebSocket::errorOccurred), this,
+ &VsPinger::onError);
+#else
connect(&mSocket, QOverload<QAbstractSocket::SocketError>::of(&QWebSocket::error),
this, &VsPinger::onError);
+#endif
connect(&mTimer, &QTimer::timeout, this, &VsPinger::onPingTimer);
}
connect(m_webSocket.get(),
QOverload<const QList<QSslError>&>::of(&QWebSocket::sslErrors), this,
&VsWebSocket::onSslErrors);
+#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
+ connect(m_webSocket.get(),
+ QOverload<QAbstractSocket::SocketError>::of(&QWebSocket::errorOccurred), this,
+ &VsWebSocket::onError);
+#else
connect(m_webSocket.get(),
QOverload<QAbstractSocket::SocketError>::of(&QWebSocket::error), this,
&VsWebSocket::onError);
+#endif
connect(m_webSocket.get(), &QWebSocket::textMessageReceived, this,
&VsWebSocket::textMessageReceived);
}
#include "AudioInterface.h"
-constexpr const char* const gVersion = "2.0.1"; ///< JackTrip version
+constexpr const char* const gVersion = "2.0.2"; ///< JackTrip version
//*******************************************************************************
/// \name Default Values