Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Effects: Add support for GUIs and reference implementation for Audio Unit #13888

Open
wants to merge 48 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
3a63771
EffectManifest: Add hasUI
fwcd Nov 14, 2024
e94a0b7
LateNight: Add button for toggling UI
fwcd Nov 14, 2024
70a882e
Tooltips: Add effect UI button tooltip
fwcd Nov 14, 2024
6332b3a
LateNight: Make visibility of effect UI buttons configurable
fwcd Nov 14, 2024
29fef3b
EffectProcessor: Add createUI
fwcd Nov 15, 2024
39cb386
AudioUnitManifest: Set hasUI using hasCustomView
fwcd Nov 15, 2024
ab8fd9f
EngineEffect: Add createUI
fwcd Nov 15, 2024
b05f7fd
Skins: Use snake_case for ui_shown control
fwcd Nov 15, 2024
98962c0
EffectSlot: Manage effect UI
fwcd Nov 15, 2024
bcde59b
AudioUnitEffectProcessor: Set up demo view
fwcd Nov 15, 2024
602e7db
AudioUnitEffectProcessor: Load actual UI
fwcd Nov 15, 2024
f230de1
AudioUnitManager: Expose name
fwcd Nov 15, 2024
fe85369
AudioUnitEffectProcessor: Include name of audio unit in log messages
fwcd Nov 15, 2024
e2180f0
AudioUnitEffectProcessor: Improve error messages
fwcd Nov 15, 2024
f8965da
AudioUnitEffectProcessor: Add missing nil check for cocoaViewInfo
fwcd Nov 15, 2024
f4e8c45
AudioUnitEffectProcessor: Add missing initialization of cocoaViewInfo
fwcd Nov 15, 2024
39b7639
AudioUnitEffectProcessor: Fall back to generic AU view if needed
fwcd Nov 15, 2024
9c88da2
AudioUnitEffectProcessor: Set window style mask
fwcd Nov 15, 2024
705fceb
AudioUnitEffectProcessor: Add missing NSWindowStyleMaskUtilityWindow
fwcd Nov 15, 2024
0c86df7
AudioUnitEffectProcessor: Automatically resize the dialog to fit
fwcd Nov 15, 2024
79874f1
AudioUnitEffectProcessor: Factor out DlgAudioUnit
fwcd Nov 15, 2024
05ec78b
DlgAudioUnit: Disable resizing again
fwcd Nov 15, 2024
ce1ca98
DlgAudioUnit: Use std::variant for error handling
fwcd Nov 15, 2024
3d88b15
EngineEffect: Only forward-declare QDialog for effect UI
fwcd Nov 15, 2024
5afac2a
AudioUnitManifest: Set hasUI to true for all audio units
fwcd Nov 15, 2024
253e4e1
EffectSlot: Automatically update UI when effect changes
fwcd Nov 16, 2024
c6fd37a
Effects: Abstract out DlgEffect
fwcd Nov 16, 2024
6758aa2
DlgEffect: Add support for embedding custom UI
fwcd Nov 16, 2024
3ac86b8
DlgAudioUnit: Embed native UI using the intended API
fwcd Nov 16, 2024
dfec19f
DlgEffect: Make it a floating tool window
fwcd Nov 16, 2024
7ceb5a9
DlgEffect: Add transitive include
fwcd Nov 16, 2024
fcd6c46
DlgAudioUnit: Set fixed size on dialog
fwcd Nov 16, 2024
bd2edb4
DlgEffect: Add virtual destructor
fwcd Nov 16, 2024
4d2ad2d
DlgAudioUnit: Properly remove resize observer in destructor
fwcd Nov 16, 2024
5dce250
DlgAudioUnit: Use non-fixed-size resize again (for now)
fwcd Nov 16, 2024
d63bd58
DlgEffect: Emit closed signal on close
fwcd Nov 16, 2024
046bd9c
DlgEffect: Add short doc comment
fwcd Nov 16, 2024
338ad88
EffectSlot/DlgEffect: Synchronize close state properly
fwcd Nov 16, 2024
4a60b28
EffectSlot/LateNight: Show/hide effect UI button based on effect
fwcd Nov 17, 2024
d61c622
LateNight: Move effect UI button to after the enable button
fwcd Nov 17, 2024
1911448
EffectSlot: Persist effect UI position
fwcd Nov 17, 2024
e01cbac
EffectProcessor: Remove blanket dialog title
fwcd Nov 17, 2024
c554b53
EffectProcessor: Word doc comment on UI more accurately
fwcd Nov 17, 2024
8610411
LateNight: Remove accidental change
fwcd Nov 17, 2024
f6d44de
EffectSlot: Trigger updateEffectUI via effectChanged
fwcd Nov 18, 2024
586dd6a
EffectSlot: Update UI button in updateEffectUI
fwcd Nov 18, 2024
6a43c6b
DlgAudioUnit: Only apply resize observer to custom UI
fwcd Nov 18, 2024
a346955
DlgAudioUnit: Wait for instantiation before loading UI
fwcd Nov 26, 2024
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
7 changes: 6 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1073,6 +1073,7 @@ add_library(
src/effects/chains/pergroupeffectchain.cpp
src/effects/chains/quickeffectchain.cpp
src/effects/chains/standardeffectchain.cpp
src/effects/dlgeffect.cpp
src/effects/effectbuttonparameterslot.cpp
src/effects/effectchain.cpp
src/effects/effectchainmixmode.cpp
Expand Down Expand Up @@ -1875,10 +1876,14 @@ if(APPLE)
src/effects/backends/audiounit/audiounitmanager.mm
src/effects/backends/audiounit/audiouniteffectprocessor.mm
src/effects/backends/audiounit/audiounitmanifest.mm
src/effects/backends/audiounit/dlgaudiounit.mm
)
target_link_libraries(
mixxx-lib
PRIVATE "-weak_framework AudioToolbox" "-weak_framework AVFAudio"
PRIVATE
"-weak_framework AudioToolbox"
"-weak_framework AVFAudio"
"-weak_framework CoreAudioKit"
)
target_compile_definitions(mixxx-lib PUBLIC __AU_EFFECTS__)
endif()
Expand Down
28 changes: 28 additions & 0 deletions res/skins/LateNight/fx/slot_controls.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,34 @@
<SetVariable name="ConfigKey">[<Variable name="FxRack_FxUnit_FxNum"/>],enabled</SetVariable>
</Template>

<WidgetGroup>
<Layout>vertical</Layout>
<SizePolicy>min,min</SizePolicy>
<Children>
<WidgetGroup>
<Layout>vertical</Layout>
<SizePolicy>min,min</SizePolicy>
<Children>
<Template src="skins:LateNight/controls/button_2state.xml">
<SetVariable name="TooltipId">EffectSlot_ui_shown</SetVariable>
<SetVariable name="ObjectName">FxUiButton</SetVariable>
<SetVariable name="BtnSize">square</SetVariable>
<SetVariable name="Size">26f,26f</SetVariable>
<SetVariable name="ConfigKey">[<Variable name="FxRack_FxUnit_FxNum"/>],ui_shown</SetVariable>
</Template>
</Children>
<Connection>
<ConfigKey persist="true">[<Variable name="FxRack_FxUnit_FxNum"/>],uibutton_shown</ConfigKey>
<BindProperty>visible</BindProperty>
</Connection>
</WidgetGroup>
</Children>
<Connection>
<ConfigKey persist="true">[Skin],show_effectuibuttons</ConfigKey>
<BindProperty>visible</BindProperty>
</Connection>
</WidgetGroup>

<Template src="skins:LateNight/fx/meta_knob.xml"/>

<EffectSelector>
Expand Down
69 changes: 69 additions & 0 deletions res/skins/LateNight/palemoon/buttons/btn__fx_ui.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
45 changes: 45 additions & 0 deletions res/skins/LateNight/palemoon/buttons/btn__fx_ui_active.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions res/skins/LateNight/skin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
<!-- Effects -->
<attribute persist="true" config_key="[Skin],show_effectrack">1</attribute>
<attribute persist="true" config_key="[Skin],show_4effectunits">0</attribute>
<attribute persist="true" config_key="[Skin],show_effectuibuttons">1</attribute>
<attribute persist="true" config_key="[Skin],show_superknobs">0</attribute>
<!-- Samplers -->
<attribute persist="true" config_key="[Skin],show_samplers">0</attribute>
Expand Down
20 changes: 16 additions & 4 deletions res/skins/LateNight/skin_settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -428,10 +428,22 @@ Description:
<SetVariable name="Setting">[Skin],show_effectrack</SetVariable>
</Template>

<Template src="skins:LateNight/helpers/skin_settings_button_2state.xml">
<SetVariable name="Text">Super Knobs</SetVariable>
<SetVariable name="Setting">[Skin],show_superknobs</SetVariable>
</Template>
<WidgetGroup>
<ObjectName>SkinSettingsCategory</ObjectName>
<SizePolicy>me,min</SizePolicy>
<Layout>vertical</Layout>
<Children>
<Template src="skins:LateNight/helpers/skin_settings_button_2state.xml">
<SetVariable name="Text">Effect UI Buttons</SetVariable>
<SetVariable name="Setting">[Skin],show_effectuibuttons</SetVariable>
</Template>

<Template src="skins:LateNight/helpers/skin_settings_button_2state.xml">
<SetVariable name="Text">Super Knobs</SetVariable>
<SetVariable name="Setting">[Skin],show_superknobs</SetVariable>
</Template>
</Children>
</WidgetGroup>
</Children>
</WidgetGroup>
</Children>
Expand Down
12 changes: 12 additions & 0 deletions res/skins/LateNight/style_palemoon.qss
Original file line number Diff line number Diff line change
Expand Up @@ -1602,6 +1602,7 @@ WPushButton#LoopActivate[displayValue="0"],
#EQKillButtonBox WPushButton[displayValue="0"],
WPushButton#StemMuteButton[displayValue="0"],
WPushButton#QuickEffectButton[displayValue="0"],
WPushButton#FxUiButton[displayValue="0"],
WPushButton#FxToggleButton[displayValue="0"],
#MicAuxUnit WPushButton[displayValue="0"],
#MicDuckingContainer WPushButton[displayValue="0"],
Expand Down Expand Up @@ -1723,6 +1724,8 @@ QPushButton#pushButtonRecording:checked,
}

/* Green for Fx toggles, QuickEffect + Fx12 */
#FxUnit1 #FxUiButton[displayValue="1"],
#FxUnit2 #FxUiButton[displayValue="1"],
#FxUnit1 #FxToggleButton[displayValue="1"],
#FxUnit2 #FxToggleButton[displayValue="1"],
WPushButton#VinylStatus[displayValue="1"], /* enabled, OK */
Expand All @@ -1736,6 +1739,8 @@ WPushButton#VinylStatus[displayValue="1"], /* enabled, OK */
background-color: #236b00;
}
/* Blue for Fx buttons 3/4 */
#FxUnit3 #FxUiButton[displayValue="1"],
#FxUnit4 #FxUiButton[displayValue="1"],
#FxUnit3 #FxToggleButton[displayValue="1"],
#FxUnit4 #FxToggleButton[displayValue="1"]
WBeatSpinBox::up-button:pressed,
Expand Down Expand Up @@ -2297,6 +2302,13 @@ WPushButton#PlayDeck[value="0"] {
image: url(skins:LateNight/palemoon/buttons/btn__fx_mixmode_d+w.svg) no-repeat center center;
}

#FxUiButton[value="0"] {
image: url(skins:LateNight/palemoon/buttons/btn__fx_ui.svg) no-repeat center center;
}
#FxUiButton[value="1"] {
image: url(skins:LateNight/palemoon/buttons/btn__fx_ui_active.svg) no-repeat center center;
}

#FxToggleButton[value="0"] {
image: url(skins:LateNight/palemoon/buttons/btn__fx_toggle.svg) no-repeat center center;
}
Expand Down
5 changes: 5 additions & 0 deletions src/effects/backends/audiounit/audiouniteffectprocessor.h
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
#pragma once

#import <AVFAudio/AVFAudio.h>
#import <AppKit/AppKit.h>
#import <AudioToolbox/AudioToolbox.h>
#import <CoreAudioTypes/CoreAudioTypes.h>

#include <QList>
#include <atomic>
#include <memory>

#include "audio/types.h"
#include "effects/backends/audiounit/audiounitmanager.h"
#include "effects/backends/effectprocessor.h"
#include "effects/dlgeffect.h"
#include "engine/engine.h"

class AudioUnitEffectGroupState final : public EffectState {
Expand Down Expand Up @@ -54,6 +57,8 @@ class AudioUnitEffectProcessor final : public EffectProcessorImpl<AudioUnitEffec
const EffectEnableState enableState,
const GroupFeatureState& groupFeatures) override;

std::unique_ptr<DlgEffect> createUI() override;

private:
AudioUnitManagerPointer m_pManager;

Expand Down
13 changes: 12 additions & 1 deletion src/effects/backends/audiounit/audiouniteffectprocessor.mm
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
#import <AVFAudio/AVFAudio.h>
#import <AppKit/AppKit.h>
#import <AudioToolbox/AudioToolbox.h>
#import <CoreAudioKit/CoreAudioKit.h>
#import <CoreAudioTypes/CoreAudioBaseTypes.h>
#include <CoreAudioTypes/CoreAudioTypes.h>
#import <CoreAudioTypes/CoreAudioTypes.h>

#include <QLabel>
#include <QMutex>
#include <QVBoxLayout>
#include <QtGlobal>
#include <algorithm>
#include <memory>

#include "effects/backends/audiounit/audiouniteffectprocessor.h"
#include "effects/backends/audiounit/audiounitmanager.h"
#include "effects/backends/audiounit/dlgaudiounit.h"
#include "engine/effects/engineeffectparameter.h"
#include "engine/engine.h"
#include "util/assert.h"
Expand Down Expand Up @@ -251,3 +258,7 @@
}
}
}

std::unique_ptr<DlgEffect> AudioUnitEffectProcessor::createUI() {
return std::make_unique<DlgAudioUnit>(m_pManager);
}
3 changes: 3 additions & 0 deletions src/effects/backends/audiounit/audiounitmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ class AudioUnitManager {
/// the timeout was reached instead.
bool waitForAudioUnit(int timeoutMs) const;

/// Fetches the audio unit's name.
QString getName() const;

private:
QString m_name;
std::atomic<bool> m_isInstantiated;
Expand Down
4 changes: 4 additions & 0 deletions src/effects/backends/audiounit/audiounitmanager.mm
Original file line number Diff line number Diff line change
Expand Up @@ -145,3 +145,7 @@
m_audioUnit = audioUnit;
m_isInstantiated.store(true);
}

QString AudioUnitManager::getName() const {
return m_name;
}
5 changes: 5 additions & 0 deletions src/effects/backends/audiounit/audiounitmanifest.mm
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@
setDescription(QString::fromNSString([component typeName]));
setAuthor(QString::fromNSString([component manufacturerName]));

// All audio units provide a UI (not just if [component hasCustomView] is
// set) since they provide a generic fallback UI, which may be useful for
// effects with many different parameters.
setHasUI(true);

// Instantiate audio unit (out-of-process) to load parameters
AudioUnitManagerPointer pManager = AudioUnitManager::create(component);

Expand Down
16 changes: 16 additions & 0 deletions src/effects/backends/audiounit/dlgaudiounit.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#pragma once

#include "effects/backends/audiounit/audiounitmanagerpointer.h"
#include "effects/dlgeffect.h"

/// A dialog hosting the UI of an Audio Unit.
class DlgAudioUnit : public DlgEffect {
Q_OBJECT

public:
DlgAudioUnit(AudioUnitManagerPointer pManager);
virtual ~DlgAudioUnit();

private:
id m_resizeObserver;
};
Loading
Loading