Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions frontend/data/locale/en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1309,6 +1309,8 @@ Basic.Settings.Advanced.Video.HdrNominalPeakLevel="HDR Nominal Peak Level"
Basic.Settings.Advanced.Audio.MonitoringDevice="Monitoring Device"
Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Default"
Basic.Settings.Advanced.Audio.DisableAudioDucking="Disable Windows audio ducking"
Basic.Settings.Advanced.Audio.AsioMonitoringDevice="ASIO Monitoring Device"
Basic.Settings.Audio.AsioMonitoring="Setup Panel"
Basic.Settings.Advanced.StreamDelay="Stream Delay"
Basic.Settings.Advanced.StreamDelay.Duration="Duration"
Basic.Settings.Advanced.StreamDelay.Preserve="Preserve cutoff point (increase delay) when reconnecting"
Expand Down
6 changes: 6 additions & 0 deletions frontend/data/themes/Yami.obt
Original file line number Diff line number Diff line change
Expand Up @@ -1406,6 +1406,12 @@ QPushButton::menu-indicator {
width: 25px;
}

QWidget QFormLayout > QToolButton#asioMonitoring {
min-width: 0px;
max-width: 16777215px;
text-align: center;
}

QToolButton {
border: 1px solid var(--button_border);
}
Expand Down
24 changes: 24 additions & 0 deletions frontend/forms/OBSBasicSettings.ui
Original file line number Diff line number Diff line change
Expand Up @@ -6233,6 +6233,29 @@
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="asioDeviceLabel">
<property name="text">
<string>Basic.Settings.Advanced.Audio.AsioMonitoringDevice</string>
</property>
<property name="buddy">
<cstring>asioMonitoring</cstring>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QToolButton" name="asioMonitoring">
<property name="text">
<string>Basic.Settings.Audio.AsioMonitoring</string>
</property>
<property name="objectName">
<string>asioMonitoring</string>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed"/>
</property>
</widget>
</item>
</layout>
</widget>
</item>
Expand Down Expand Up @@ -8861,6 +8884,7 @@
<tabstop>meterDecayRate</tabstop>
<tabstop>peakMeterType</tabstop>
<tabstop>monitoringDevice</tabstop>
<tabstop>asioMonitoring</tabstop>
<tabstop>disableAudioDucking</tabstop>
<tabstop>lowLatencyBuffering</tabstop>
<tabstop>baseResolution</tabstop>
Expand Down
1 change: 1 addition & 0 deletions frontend/plugins/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
add_subdirectory(aja-output-ui)
add_obs_plugin(asio-output-ui PLATFORMS WINDOWS)
add_subdirectory(decklink-captions)
add_subdirectory(decklink-output-ui)
add_subdirectory(frontend-tools)
93 changes: 93 additions & 0 deletions frontend/plugins/asio-output-ui/ASIOSettingsDialog.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/* Copyright (c) 2022-2025 pkv <[email protected]>
*
* This file is part of win-asio.
*
* This file and all modifications by pkv <[email protected]> are licensed under
* the GNU General Public License, version 3 or later.
*/

#include "ASIOSettingsDialog.h"
#include <util/util.hpp>

extern void output_start();
extern void output_stop();
extern bool output_running;
extern std::string g_currentDeviceName;

ASIOSettingsDialog::ASIOSettingsDialog(QWidget *parent, obs_output_t *output, OBSData settings)
: QDialog(parent),
ui(new Ui::Output),
_output(output),
_settings(settings),
currentDeviceName("")
{
ui->setupUi(this);
setSizeGripEnabled(true);
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
propertiesView = nullptr;
}

void ASIOSettingsDialog::ShowHideDialog(bool enabled)
{
SetupPropertiesView(enabled);
setVisible(!isVisible());
}

void ASIOSettingsDialog::SetupPropertiesView(bool enabled)
{
if (propertiesView)
delete propertiesView;

propertiesView = new OBSPropertiesView(_settings, "asio_output",
(PropertiesReloadCallback)obs_get_output_properties, 170);

if (enabled) {
ui->propertiesLayout->addWidget(propertiesView);
currentDeviceName = g_currentDeviceName;
} else {
QLabel *noAsioLabel = new QLabel(obs_module_text("AsioOutput.Disabled"), this);
noAsioLabel->setWordWrap(true);
noAsioLabel->setAlignment(Qt::AlignCenter);
ui->propertiesLayout->addWidget(noAsioLabel);
adjustSize();
}

connect(propertiesView, &OBSPropertiesView::Changed, this, &ASIOSettingsDialog::PropertiesChanged);
}

void ASIOSettingsDialog::SaveSettings()
{
BPtr<char> modulePath = obs_module_get_config_path(obs_current_module(), "");
os_mkdirs(modulePath);
BPtr<char> path = obs_module_get_config_path(obs_current_module(), "asioOutputProps.json");
obs_data_t *settings = propertiesView->GetSettings();

if (settings)
obs_data_save_json_safe(settings, path, "tmp", "bak");
}

void ASIOSettingsDialog::PropertiesChanged()
{
obs_output_update(_output, _settings);
SaveSettings();
const char *dev = obs_data_get_string(_settings, "device_name");
const std::string newDevice = (dev && *dev) ? dev : std::string{};

const bool wasEmpty = currentDeviceName.empty();
const bool nowEmpty = newDevice.empty();

if (wasEmpty && !nowEmpty) {
// None -> Valid device: start if not running
if (!output_running)
output_start();
} else if (!wasEmpty && nowEmpty) {
// Valid device -> None: stop if running
if (output_running)
output_stop();
} else if (!nowEmpty && newDevice != currentDeviceName) {
// output was already started so do nothing ...
}

currentDeviceName = newDevice;
g_currentDeviceName = newDevice;
}
47 changes: 47 additions & 0 deletions frontend/plugins/asio-output-ui/ASIOSettingsDialog.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/* Copyright (c) 2022-2025 pkv <[email protected]>
*
* This file is part of win-asio.
*
* This file and all modifications by pkv <[email protected]> are licensed under
* the GNU General Public License, version 3 or later.
*/
#ifdef __cplusplus
#define EXPORT_C extern "C"
#else
#define EXPORT_C
#endif

#pragma once
#include <obs-module.h>
#include <obs-frontend-api.h>
#include <obs.hpp>
#include <properties-view.hpp>

#include <QDialog>
#include <QAction>
#include <QMainWindow>
#include <QLabel>

#include "./forms/ui_output.h"

#include <util/platform.h>

class ASIOSettingsDialog : public QDialog {
Q_OBJECT

public:
explicit ASIOSettingsDialog(QWidget *parent = 0, obs_output_t *output = nullptr, OBSData settings = nullptr);
std::unique_ptr<Ui_Output> ui;
void ShowHideDialog(bool enabled);
void SetupPropertiesView(bool enabled);
void SaveSettings();
OBSData _settings;
obs_output_t *_output;
std::string currentDeviceName;

public slots:
void PropertiesChanged();

private:
OBSPropertiesView *propertiesView;
};
27 changes: 27 additions & 0 deletions frontend/plugins/asio-output-ui/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
cmake_minimum_required(VERSION 3.28...3.30)

find_package(Qt6 REQUIRED Widgets)

add_library(asio-output-ui MODULE)
add_library(OBS::asio-output-ui ALIAS asio-output-ui)

target_sources(asio-output-ui PRIVATE asio-ui-main.cpp ASIOSettingsDialog.cpp ASIOSettingsDialog.h)

target_sources(asio-output-ui PRIVATE forms/output.ui)

target_link_libraries(asio-output-ui PRIVATE OBS::libobs OBS::frontend-api OBS::properties-view Qt::Widgets)

configure_file(cmake/windows/obs-module.rc.in asio-output-ui.rc)
target_sources(asio-output-ui PRIVATE asio-output-ui.rc)

set_property(TARGET asio-output-ui APPEND PROPERTY AUTORCC_OPTIONS --format-version 1)

set_target_properties_obs(
asio-output-ui
PROPERTIES FOLDER frontend
PREFIX ""
AUTOMOC ON
AUTOUIC ON
AUTORCC ON
AUTOUIC_SEARCH_PATHS forms
)
Loading