Skip to content

Commit dff2789

Browse files
committed
0.8.0
1 parent adf1f2b commit dff2789

File tree

15 files changed

+224
-47
lines changed

15 files changed

+224
-47
lines changed

CMakeLists.txt

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/common/bootstrap.cmake")
55

66
project(${_name} VERSION ${_version})
77

8-
option(ENABLE_FRONTEND_API "Use obs-frontend-api for UI functionality" ON)
9-
option(ENABLE_QT "Use Qt functionality" ON)
8+
option(ENABLE_FRONTEND_API "Use obs-frontend-api for UI functionality" OFF)
9+
option(ENABLE_QT "Use Qt functionality" OFF)
1010

1111
include(compilerconfig)
1212
include(defaults)
@@ -18,32 +18,37 @@ find_package(libobs REQUIRED)
1818
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE OBS::libobs)
1919

2020
if(ENABLE_FRONTEND_API)
21-
find_package(obs-frontend-api REQUIRED)
22-
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE OBS::obs-frontend-api)
21+
find_package(obs-frontend-api REQUIRED)
22+
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE OBS::obs-frontend-api)
2323
endif()
2424

2525
if(ENABLE_QT)
26-
find_package(Qt6 COMPONENTS Widgets Core)
27-
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE Qt6::Core Qt6::Widgets)
28-
target_compile_options(
29-
${CMAKE_PROJECT_NAME}
30-
PRIVATE $<$<C_COMPILER_ID:Clang,AppleClang>:-Wno-quoted-include-in-framework-header -Wno-comma>
31-
)
32-
set_target_properties(
33-
${CMAKE_PROJECT_NAME}
34-
PROPERTIES AUTOMOC ON AUTOUIC ON AUTORCC ON
35-
)
26+
find_package(Qt6 COMPONENTS Widgets Core)
27+
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE Qt6::Core Qt6::Widgets)
28+
target_compile_options(
29+
${CMAKE_PROJECT_NAME}
30+
PRIVATE
31+
$<$<C_COMPILER_ID:Clang,AppleClang>:-Wno-quoted-include-in-framework-header
32+
-Wno-comma>
33+
)
34+
set_target_properties(
35+
${CMAKE_PROJECT_NAME}
36+
PROPERTIES AUTOMOC ON AUTOUIC ON AUTORCC ON
37+
)
3638
endif()
3739

3840
file(GLOB_RECURSE _sources CONFIGURE_DEPENDS src/*.cpp)
3941
target_sources(${CMAKE_PROJECT_NAME} PRIVATE ${_sources})
4042

4143
set_target_properties_plugin(${CMAKE_PROJECT_NAME} PROPERTIES OUTPUT_NAME ${_name})
4244

43-
configure_file(src/config.h.in config.h @ONLY)
44-
4545
set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES CXX_STANDARD 23)
4646

4747
add_subdirectory(lib/atkaudio)
4848

49-
include(./lib/atkaudio/cmake/cpack.cmake)
49+
file(READ "${CMAKE_SOURCE_DIR}/buildspec.json" buildspec)
50+
string(JSON PLUGIN_DISPLAY_NAME GET ${buildspec} displayName)
51+
52+
configure_file(src/config.h.in config.h @ONLY)
53+
54+
include(./lib/atkaudio/cmake/cpack.cmake)

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ VST3 plugin host for OBS.
55
Up to 8 channels.
66
Sidechain support.
77
AU plugins on Apple macOS.
8-
LV2 plugins on Linux.
8+
LADSPA and LV2 plugins on Linux.
99

1010
## Device I/O
1111
Send and receive audio directly into and from audio devices.

lib/atkaudio/CMakeLists.txt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,23 @@ target_compile_definitions(
3232
JUCE_PLUGINHOST_VST3=1
3333
JUCE_PLUGINHOST_VST=0
3434
JUCE_PLUGINHOST_AU=1
35-
JUCE_USE_CURL=0
35+
JUCE_USE_CURL=1
3636
JUCE_WEB_BROWSER=0
3737
JUCE_MODAL_LOOPS_PERMITTED=1 # we use QT event loop, so this is needed
3838
)
3939

40+
set_target_properties(${PROJECT_NAME} PROPERTIES
41+
JUCE_NEEDS_WEB_BROWSER FALSE
42+
JUCE_NEEDS_CURL TRUE
43+
JUCE_IS_PLUGIN TRUE
44+
)
45+
4046
if(UNIX AND NOT APPLE)
4147
target_compile_definitions(
4248
${PROJECT_NAME}
4349
PRIVATE
4450
JUCE_PLUGINHOST_LV2=1
51+
JUCE_PLUGINHOST_LADSPA=1
4552
)
4653
endif()
4754

lib/atkaudio/cmake/cpack.cmake

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,20 @@ else()
4444
set(CPACK_PACKAGE_EXTENSION "pkg")
4545
endif()
4646

47+
if(UNIX AND NOT APPLE)
48+
49+
endif()
50+
4751
if(NOT WIN32)
4852
return()
4953
endif()
5054

5155

5256
set(CPACK_RELEASE_STAGING_DIRECTORY "${CMAKE_SOURCE_DIR}/release")
5357
set(BUILD_TYPE_FOR_CPACK "RelWithDebInfo")
58+
if(NOT EXISTS ${CMAKE_BINARY_DIR}/${BUILD_TYPE_FOR_CPACK})
59+
set(BUILD_TYPE_FOR_CPACK "Debug")
60+
endif()
5461
if(DEFINED ENV{CI})
5562
set(BUILD_TYPE_FOR_CPACK "Release")
5663
endif()

lib/atkaudio/src/atkaudio/DeviceIo/AudioAppDemo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ class AudioAppMainWindow final : public DocumentWindow
244244
{
245245
public:
246246
AudioAppMainWindow(AudioAppDemo& demo)
247-
: DocumentWindow("", Colours::lightgrey, DocumentWindow::minimiseButton | DocumentWindow::closeButton)
247+
: DocumentWindow("", Colours::lightgrey, DocumentWindow::minimiseButton | DocumentWindow::closeButton, false)
248248
, audioApp(demo)
249249
{
250250
setContentOwned(&demo, true);

lib/atkaudio/src/atkaudio/DeviceIo/DeviceIo.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,9 @@ struct atk::DeviceIo::Impl : public juce::Timer
172172

173173
void setVisible(bool visible)
174174
{
175+
if (!mainWindow->isOnDesktop())
176+
mainWindow->addToDesktop(juce::ComponentPeer::StyleFlags{});
177+
175178
mainWindow->setVisible(visible);
176179
if (visible && mainWindow->isMinimised())
177180
mainWindow->setMinimised(false);

lib/atkaudio/src/atkaudio/PluginHost/JuceHostPlugin.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ class HostAudioProcessorImpl
1616
: public AudioProcessor
1717
, private ChangeListener
1818
{
19+
static inline juce::InterProcessLock appPropertiesLock{"pluginHostAppPropertiesLock"};
20+
1921
public:
2022
HostAudioProcessorImpl()
2123
: AudioProcessor(
@@ -37,6 +39,7 @@ class HostAudioProcessorImpl
3739
opt.ignoreCaseOfKeyNames = false;
3840
opt.storageFormat = PropertiesFile::StorageFormat::storeAsXML;
3941
opt.osxLibrarySubFolder = "Application Support";
42+
opt.processLock = &appPropertiesLock;
4043
return opt;
4144
}()
4245
);

lib/atkaudio/src/atkaudio/PluginHost/PluginHost.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ struct atk::PluginHost::Impl : public juce::Timer
9393

9494
void setVisible(bool visible)
9595
{
96+
if (!mainWindow->isOnDesktop())
97+
mainWindow->addToDesktop(juce::ComponentPeer::StyleFlags{});
98+
9699
mainWindow->setVisible(visible);
97100
if (visible && mainWindow->isMinimised())
98101
mainWindow->setMinimised(false);

lib/atkaudio/src/atkaudio/PluginHost/StandaloneFilterWindow.h

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -519,12 +519,14 @@ class StandalonePluginHolder2
519519
auto extra = r.removeFromTop(itemHeight);
520520

521521
auto seperatorHeight = (itemHeight >> 1);
522-
shouldMuteButton.setBounds(Rectangle<int>(
523-
extra.proportionOfWidth(0.35f),
524-
seperatorHeight,
525-
extra.proportionOfWidth(0.60f),
526-
deviceSelector.getItemHeight()
527-
));
522+
shouldMuteButton.setBounds(
523+
Rectangle<int>(
524+
extra.proportionOfWidth(0.35f),
525+
seperatorHeight,
526+
extra.proportionOfWidth(0.60f),
527+
deviceSelector.getItemHeight()
528+
)
529+
);
528530

529531
r.removeFromTop(seperatorHeight);
530532
}
@@ -595,26 +597,13 @@ class StandaloneFilterWindow
595597
Colour backgroundColour,
596598
std::unique_ptr<StandalonePluginHolder2> pluginHolderIn
597599
)
598-
: DocumentWindow(title, backgroundColour, DocumentWindow::minimiseButton | DocumentWindow::closeButton)
600+
: DocumentWindow(title, backgroundColour, DocumentWindow::minimiseButton | DocumentWindow::closeButton, false)
599601
, pluginHolder(std::move(pluginHolderIn))
600-
// , optionsButton("Options")
601602
{
602603
setConstrainer(&decoratorConstrainer);
603604

604-
#if JUCE_IOS || JUCE_ANDROID
605-
setTitleBarHeight(0);
606-
#else
607605
setTitleBarButtonsRequired(DocumentWindow::minimiseButton | DocumentWindow::closeButton, false);
608606

609-
// Component::addAndMakeVisible(optionsButton);
610-
// optionsButton.addListener(this);
611-
// optionsButton.setTriggeredOnMouseDown(true);
612-
#endif
613-
614-
#if JUCE_IOS || JUCE_ANDROID
615-
setFullScreen(true);
616-
updateContent();
617-
#else
618607
updateContent();
619608

620609
const auto windowScreenBounds = [this]() -> Rectangle<int>
@@ -657,7 +646,6 @@ class StandaloneFilterWindow
657646
if (auto* processor = getAudioProcessor())
658647
if (auto* editor = processor->getActiveEditor())
659648
setResizable(editor->isResizable(), false);
660-
#endif
661649
}
662650

663651
~StandaloneFilterWindow() override
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
#pragma once
2+
#include "LookAndFeel.h"
3+
4+
#include <config.h>
5+
#include <juce_audio_utils/juce_audio_utils.h>
6+
7+
constexpr auto OWNER = "atkAudio";
8+
constexpr auto DISPLAY_NAME = PLUGIN_DISPLAY_NAME;
9+
constexpr auto REPO = "PluginForObsRelease";
10+
constexpr auto VERSION = PLUGIN_VERSION;
11+
constexpr auto JSON_VALUE = "tag_name";
12+
constexpr auto FILENAME = "atkaudio-pluginforobs.zip";
13+
14+
class UpdateCheck
15+
: public juce::ModalComponentManager::Callback
16+
, public juce::DeletedAtShutdown
17+
{
18+
public:
19+
UpdateCheck(const juce::String& repoOwner = OWNER, const juce::String& repoName = REPO)
20+
: DeletedAtShutdown()
21+
, owner(repoOwner)
22+
, repo(repoName)
23+
{
24+
checkForUpdate();
25+
}
26+
27+
juce::String getValueFromJson(const juce::String& jsonString, const juce::String& key)
28+
{
29+
juce::var json = juce::JSON::parse(jsonString);
30+
if (json.isObject())
31+
{
32+
auto jsonObject = json.getDynamicObject();
33+
if (jsonObject->hasProperty(key))
34+
return jsonObject->getProperty(key).toString();
35+
}
36+
return {};
37+
}
38+
39+
bool isNewerVersionThanCurrent(
40+
const juce::String& remoteVersion, //
41+
const juce::String& localVersion = VERSION
42+
)
43+
{
44+
jassert(remoteVersion.isNotEmpty());
45+
46+
auto remoteTokens = juce::StringArray::fromTokens(remoteVersion, ".", {});
47+
auto localTokens = juce::StringArray::fromTokens(localVersion, ".", {});
48+
49+
if (remoteTokens[0].getIntValue() == localTokens[0].getIntValue())
50+
{
51+
if (remoteTokens[1].getIntValue() == localTokens[1].getIntValue())
52+
return remoteTokens[2].getIntValue() > localTokens[2].getIntValue();
53+
54+
return remoteTokens[1].getIntValue() > localTokens[1].getIntValue();
55+
}
56+
57+
return remoteTokens[0].getIntValue() > localTokens[0].getIntValue();
58+
}
59+
60+
void checkForUpdate()
61+
{
62+
juce::URL versionURL("https://api.github.com/repos/" + owner + "/" + repo + "/releases/latest");
63+
64+
std::unique_ptr<juce::InputStream> inStream(versionURL.createInputStream(
65+
juce::URL::InputStreamOptions(juce::URL::ParameterHandling::inAddress).withConnectionTimeoutMs(5000)
66+
));
67+
68+
if (inStream == nullptr)
69+
return;
70+
71+
auto remoteVersionString = inStream->readEntireStreamAsString().trim();
72+
73+
if (remoteVersionString.isEmpty())
74+
return;
75+
76+
auto currentVersionString = VERSION;
77+
remoteVersionString = getValueFromJson(remoteVersionString, JSON_VALUE);
78+
79+
auto isRemoteVersionNewer = isNewerVersionThanCurrent(remoteVersionString);
80+
81+
if (isRemoteVersionNewer)
82+
{
83+
auto res = juce::AlertWindow::showOkCancelBox(
84+
juce::AlertWindow::InfoIcon,
85+
PLUGIN_DISPLAY_NAME,
86+
"A new version is available: " + remoteVersionString + "\nWould you like to download it?",
87+
"Download",
88+
"Cancel",
89+
nullptr,
90+
this
91+
);
92+
}
93+
}
94+
95+
private:
96+
void modalStateFinished(int returnValue) override
97+
{
98+
if (returnValue != 0)
99+
juce::URL("https://github.com/" + owner + "/" + repo + "/releases/latest/download/" + FILENAME)
100+
.launchInDefaultBrowser();
101+
}
102+
103+
juce::String owner;
104+
juce::String repo;
105+
106+
JUCE_DECLARE_SINGLETON(UpdateCheck, true)
107+
};

0 commit comments

Comments
 (0)