Browse Source

Deal with AU plugin macros and use them for global names, cleanup

Signed-off-by: falkTX <falktx@falktx.com>
pull/452/head
falkTX 1 year ago
parent
commit
0594d74dfa
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
9 changed files with 638 additions and 145 deletions
  1. +24
    -1
      distrho/DistrhoInfo.hpp
  2. +465
    -94
      distrho/src/DistrhoPluginAU.cpp
  3. +34
    -15
      distrho/src/DistrhoPluginChecks.h
  4. +22
    -16
      distrho/src/DistrhoPluginExport.cpp
  5. +4
    -6
      distrho/src/DistrhoPluginInternal.hpp
  6. +64
    -10
      distrho/src/DistrhoUIAU.mm
  7. +17
    -1
      examples/CairoUI/DistrhoPluginInfo.h
  8. +4
    -1
      examples/Info/DistrhoPluginInfo.h
  9. +4
    -1
      examples/Parameters/DistrhoPluginInfo.h

+ 24
- 1
distrho/DistrhoInfo.hpp View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2024 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -667,6 +667,29 @@ START_NAMESPACE_DISTRHO
*/
#define DISTRHO_UI_URI DISTRHO_PLUGIN_URI "#UI"

/**
The AudioUnit type for a plugin.@n
This is a 4-character symbol, automatically set by DPF based on other plugin macros.
See https://developer.apple.com/documentation/audiotoolbox/1584142-audio_unit_types for more information.
*/
#define DISTRHO_PLUGIN_AU_TYPE aufx

/**
The AudioUnit subtype for a plugin.@n
This is a 4-character symbol which identifies a plugin.@n
It must be unique within a manufacturer's plugins, but different manufacturers can use the same subtype.
@note This macro is required when building AU plugins
*/
#define DISTRHO_PLUGIN_AU_SUBTYPE test

/**
The AudioUnit manufacturer for a plugin.@n
This is a 4-character symbol with at least one non-lower case character.@n
Plugins from the same brand/maker should use the same symbol.
@note This macro is required when building AU plugins
*/
#define DISTRHO_PLUGIN_AU_MANUFACTURER Dstr

/**
Custom LV2 category for the plugin.@n
This is a single string, and can be one of the following values:


+ 465
- 94
distrho/src/DistrhoPluginAU.cpp
File diff suppressed because it is too large
View File


+ 34
- 15
distrho/src/DistrhoPluginChecks.h View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2023 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2024 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -23,7 +23,7 @@

#include "DistrhoPluginInfo.h"

// -----------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
// Check if all required macros are defined

#ifndef DISTRHO_PLUGIN_NAME
@@ -42,7 +42,7 @@
# error DISTRHO_PLUGIN_URI undefined!
#endif

// -----------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
// Define optional macros if not done yet

#ifndef DISTRHO_PLUGIN_HAS_UI
@@ -110,7 +110,26 @@
# define DISTRHO_UI_USE_NANOVG 0
#endif

// -----------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
// Define DISTRHO_PLUGIN_AU_TYPE if needed

#ifndef DISTRHO_PLUGIN_AU_TYPE
# if DISTRHO_PLUGIN_IS_SYNTH
# define DISTRHO_PLUGIN_AU_TYPE aumu /* kAudioUnitType_MusicDevice */
# elif (DISTRHO_PLUGIN_WANT_MIDI_INPUT || DISTRHO_PLUGIN_WANT_MIDI_OUTPUT) && DISTRHO_PLUGIN_NUM_INPUTS != 0 && DISTRHO_PLUGIN_NUM_OUTPUTS != 0
# define DISTRHO_PLUGIN_AU_TYPE aumf /* kAudioUnitType_MusicEffect */
# elif (DISTRHO_PLUGIN_WANT_MIDI_INPUT || DISTRHO_PLUGIN_WANT_MIDI_OUTPUT) && DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS != 0
# define DISTRHO_PLUGIN_AU_TYPE aumu /* kAudioUnitType_MusicDevice */
# elif (DISTRHO_PLUGIN_WANT_MIDI_INPUT || DISTRHO_PLUGIN_WANT_MIDI_OUTPUT) && DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS != 0
# define DISTRHO_PLUGIN_AU_TYPE aumi /* kAudioUnitType_MIDIProcessor */
# elif DISTRHO_PLUGIN_NUM_INPUTS == 0 && DISTRHO_PLUGIN_NUM_OUTPUTS != 0
# define DISTRHO_PLUGIN_AU_TYPE augn /* kAudioUnitType_Generator */
# else
# define DISTRHO_PLUGIN_AU_TYPE aufx /* kAudioUnitType_Effect */
# endif
#endif

// --------------------------------------------------------------------------------------------------------------------
// Define DISTRHO_PLUGIN_HAS_EMBED_UI if needed

#ifndef DISTRHO_PLUGIN_HAS_EMBED_UI
@@ -121,21 +140,21 @@
# endif
#endif

// -----------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
// Define DISTRHO_UI_URI if needed

#ifndef DISTRHO_UI_URI
# define DISTRHO_UI_URI DISTRHO_PLUGIN_URI "#DPF_UI"
#endif

// -----------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
// Test if synth has audio outputs

#if DISTRHO_PLUGIN_IS_SYNTH && DISTRHO_PLUGIN_NUM_OUTPUTS == 0
# error Synths need audio output to work!
#endif

// -----------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
// Enable MIDI input if synth, test if midi-input disabled when synth

#ifndef DISTRHO_PLUGIN_WANT_MIDI_INPUT
@@ -144,7 +163,7 @@
# error Synths need MIDI input to work!
#endif

// -----------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
// Enable state if plugin wants state files (deprecated)

#ifdef DISTRHO_PLUGIN_WANT_STATEFILES
@@ -156,7 +175,7 @@
# endif
#endif

// -----------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
// Enable full state if plugin exports presets

#if DISTRHO_PLUGIN_WANT_PROGRAMS && DISTRHO_PLUGIN_WANT_STATE && defined(DISTRHO_PLUGIN_WANT_FULL_STATE_WAS_NOT_SET)
@@ -165,7 +184,7 @@
# define DISTRHO_PLUGIN_WANT_FULL_STATE 1
#endif

// -----------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
// Disable file browser if using external UI

#if DISTRHO_UI_FILE_BROWSER && DISTRHO_PLUGIN_HAS_EXTERNAL_UI
@@ -174,7 +193,7 @@
# define DISTRHO_UI_FILE_BROWSER 0
#endif

// -----------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
// Disable UI if DGL or external UI is not available

#if (defined(DGL_CAIRO) && ! defined(HAVE_CAIRO)) || (defined(DGL_OPENGL) && ! defined(HAVE_OPENGL))
@@ -187,7 +206,7 @@
# define DISTRHO_PLUGIN_HAS_UI 0
#endif

// -----------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
// Make sure both default width and height are provided

#if defined(DISTRHO_UI_DEFAULT_WIDTH) && !defined(DISTRHO_UI_DEFAULT_HEIGHT)
@@ -198,7 +217,7 @@
# error DISTRHO_UI_DEFAULT_HEIGHT is defined but DISTRHO_UI_DEFAULT_WIDTH is not
#endif

// -----------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
// Other UI defaults

#ifndef DISTRHO_UI_USE_CAIRO
@@ -209,13 +228,13 @@
# define DISTRHO_UI_USE_CUSTOM 0
#endif

// -----------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
// Prevent users from messing about with DPF internals

#ifdef DISTRHO_UI_IS_STANDALONE
# error DISTRHO_UI_IS_STANDALONE must not be defined
#endif

// -----------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------

#endif // DISTRHO_PLUGIN_CHECKS_H_INCLUDED

+ 22
- 16
distrho/src/DistrhoPluginExport.cpp View File

@@ -17,6 +17,14 @@
#include "DistrhoPluginInternal.hpp"
#include "../DistrhoPluginUtils.hpp"

#ifndef DISTRHO_PLUGIN_AU_SUBTYPE
# error DISTRHO_PLUGIN_AU_SUBTYPE undefined!
#endif

#ifndef DISTRHO_PLUGIN_AU_MANUFACTURER
# error DISTRHO_PLUGIN_AU_MANUFACTURER undefined!
#endif

#include <fstream>
#include <iostream>

@@ -37,6 +45,13 @@ void generate_au_plist(const PluginExporter& plugin,
const uint32_t minorVersion = (version & 0x00FF00) >> 8;
const uint32_t microVersion = (version & 0x0000FF) >> 0;

#define MACRO_STR2(s) #s
#define MACRO_STR(s) MACRO_STR2(s)

static_assert(sizeof(MACRO_STR(DISTRHO_PLUGIN_AU_TYPE)) == 5, "The macro DISTRHO_PLUGIN_AU_TYPE has incorrect length");
static_assert(sizeof(MACRO_STR(DISTRHO_PLUGIN_AU_SUBTYPE)) == 5, "The macro DISTRHO_PLUGIN_AU_SUBTYPE has incorrect length");
static_assert(sizeof(MACRO_STR(DISTRHO_PLUGIN_AU_MANUFACTURER)) == 5, "The macro DISTRHO_PLUGIN_AU_MANUFACTURER has incorrect length");

outputFile << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
outputFile << "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n";
outputFile << "<plist>\n";
@@ -72,24 +87,12 @@ void generate_au_plist(const PluginExporter& plugin,
outputFile << " <string>" << plugin.getDescription() << "</string>\n";
outputFile << " <key>factoryFunction</key>\n";
outputFile << " <string>PluginAUFactory</string>\n";
outputFile << " <key>manufacturer</key>\n";
outputFile << " <string>Dstr</string>\n";
outputFile << " <key>type</key>\n";
#if DISTRHO_PLUGIN_IS_SYNTH
outputFile << " <string>aumu</string>\n"; // kAudioUnitType_MusicDevice
#elif (DISTRHO_PLUGIN_WANT_MIDI_INPUT || DISTRHO_PLUGIN_WANT_MIDI_OUTPUT) && DISTRHO_PLUGIN_NUM_INPUTS != 0 && DISTRHO_PLUGIN_NUM_OUTPUTS != 0
outputFile << " <string>aumf</string>\n"; // kAudioUnitType_MusicEffect
#elif (DISTRHO_PLUGIN_WANT_MIDI_INPUT || DISTRHO_PLUGIN_WANT_MIDI_OUTPUT) && DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS != 0
outputFile << " <string>aumu</string>\n"; // kAudioUnitType_MusicDevice
#elif (DISTRHO_PLUGIN_WANT_MIDI_INPUT || DISTRHO_PLUGIN_WANT_MIDI_OUTPUT) && DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS != 0
outputFile << " <string>aumi</string>\n"; // kAudioUnitType_MIDIProcessor
#elif DISTRHO_PLUGIN_NUM_INPUTS == 0 && DISTRHO_PLUGIN_NUM_OUTPUTS != 0
outputFile << " <string>augn</string>\n"; // kAudioUnitType_Generator
#else
outputFile << " <string>aufx</string>\n"; // kAudioUnitType_Effect
#endif
outputFile << " <string>" MACRO_STR(DISTRHO_PLUGIN_AU_TYPE) "</string>\n";
outputFile << " <key>subtype</key>\n";
outputFile << " <string>Cair</string>\n";
outputFile << " <string>" MACRO_STR(DISTRHO_PLUGIN_AU_SUBTYPE) "</string>\n";
outputFile << " <key>manufacturer</key>\n";
outputFile << " <string>" MACRO_STR(DISTRHO_PLUGIN_AU_MANUFACTURER) "</string>\n";
outputFile << " <key>version</key>\n";
outputFile << " <integer>" << version << "</integer>\n";
outputFile << " <key>resourceUsage</key>\n";
@@ -104,6 +107,9 @@ void generate_au_plist(const PluginExporter& plugin,
outputFile << " </dict>\n";
outputFile << "</plist>\n";

#undef MACRO_STR
#undef MACRO_STR2

outputFile.close();
std::cout << " done!" << std::endl;
}


+ 4
- 6
distrho/src/DistrhoPluginInternal.hpp View File

@@ -1017,14 +1017,14 @@ public:
return true;
}

bool setSampleRate(const double sampleRate, const bool doCallback = false)
void setSampleRate(const double sampleRate, const bool doCallback = false)
{
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, false);
DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, false);
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,);
DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
DISTRHO_SAFE_ASSERT(sampleRate > 0.0);

if (d_isEqual(fData->sampleRate, sampleRate))
return false;
return;

fData->sampleRate = sampleRate;

@@ -1034,8 +1034,6 @@ public:
fPlugin->sampleRateChanged(sampleRate);
if (fIsActive) fPlugin->activate();
}

return true;
}

private:


+ 64
- 10
distrho/src/DistrhoUIAU.mm View File

@@ -19,12 +19,20 @@
#define Point AudioUnitPoint
#define Size AudioUnitSize

// #include <AudioUnit/AudioUnit.h>
#include <AudioUnit/AudioUnit.h>
#include <AudioUnit/AUCocoaUIView.h>

#undef Point
#undef Size

#ifndef DISTRHO_PLUGIN_AU_SUBTYPE
# error DISTRHO_PLUGIN_AU_SUBTYPE undefined!
#endif

#ifndef DISTRHO_PLUGIN_AU_MANUFACTURER
# error DISTRHO_PLUGIN_AU_MANUFACTURER undefined!
#endif

START_NAMESPACE_DISTRHO

// --------------------------------------------------------------------------------------------------------------------
@@ -47,11 +55,11 @@ extern const char* d_nextBundlePath;
class DPF_UI_AU
{
public:
DPF_UI_AU(const AudioUnit inAU,
DPF_UI_AU(const AudioUnit component,
const intptr_t winId,
const double sampleRate,
void* const instancePointer)
: fAU(inAU),
: fComponent(component),
fTimerRef(nullptr),
fUI(this, winId, sampleRate,
editParameterCallback,
@@ -72,10 +80,14 @@ public:
DISTRHO_SAFE_ASSERT_RETURN(fTimerRef != nullptr,);

CFRunLoopAddTimer(CFRunLoopGetCurrent(), fTimerRef, kCFRunLoopCommonModes);

AudioUnitAddPropertyListener(fComponent, 19003, auPropertyChangedCallback, this);
}

~DPF_UI_AU()
{
AudioUnitRemovePropertyListenerWithUserData(fComponent, 19003, auPropertyChangedCallback, this);

if (fTimerRef != nullptr)
{
CFRunLoopRemoveTimer(CFRunLoopGetCurrent(), fTimerRef, kCFRunLoopCommonModes);
@@ -89,7 +101,7 @@ public:
}

private:
const AudioUnit fAU;
const AudioUnit fComponent;
CFRunLoopTimerRef fTimerRef;

UIExporter fUI;
@@ -107,11 +119,44 @@ private:
static_cast<DPF_UI_AU*>(info)->idleCallback();
}

// ----------------------------------------------------------------------------------------------------------------
// AU callbacks

void auPropertyChanged(const AudioUnitPropertyID prop, const AudioUnitElement elem)
{
switch (prop)
{
case 19003:
{
AudioUnitParameterValue value;
if (AudioUnitGetParameter(fComponent, elem, kAudioUnitScope_Global, 0, &value) == noErr)
fUI.parameterChanged(elem, value);
}
break;
}
}

static void auPropertyChangedCallback(void* const userData,
const AudioUnit component,
const AudioUnitPropertyID prop,
const AudioUnitScope scope,
const AudioUnitElement elem)
{
DPF_UI_AU* const self = static_cast<DPF_UI_AU*>(userData);

DISTRHO_SAFE_ASSERT_RETURN(self != nullptr,);
DISTRHO_SAFE_ASSERT_RETURN(self->fComponent == component,);
DISTRHO_SAFE_ASSERT_UINT_RETURN(scope == kAudioUnitScope_Global, scope,);

self->auPropertyChanged(prop, elem);
}

// ----------------------------------------------------------------------------------------------------------------
// DPF callbacks

void editParameter(uint32_t, bool) const
void editParameter(const uint32_t rindex, const bool started) const
{
AudioUnitSetProperty(fComponent, 19002, kAudioUnitScope_Global, rindex, &started, sizeof(bool));
}

static void editParameterCallback(void* const ptr, const uint32_t rindex, const bool started)
@@ -119,8 +164,9 @@ private:
static_cast<DPF_UI_AU*>(ptr)->editParameter(rindex, started);
}

void setParameterValue(uint32_t, float)
void setParameterValue(const uint32_t rindex, const float value)
{
AudioUnitSetProperty(fComponent, 19001, kAudioUnitScope_Global, rindex, &value, sizeof(float));
}

static void setParameterCallback(void* const ptr, const uint32_t rindex, const float value)
@@ -166,13 +212,18 @@ END_NAMESPACE_DISTRHO

// --------------------------------------------------------------------------------------------------------------------

@interface DPF_UI_ViewFactory : NSObject<AUCocoaUIBase>
#define MACRO_NAME2(a, b, c, d, e, f) a ## b ## c ## d ## e ## f
#define MACRO_NAME(a, b, c, d, e, f) MACRO_NAME2(a, b, c, d, e, f)

#define COCOA_VIEW_CLASS_NAME MACRO_NAME(CocoaAUView_, DISTRHO_PLUGIN_AU_TYPE, _, DISTRHO_PLUGIN_AU_SUBTYPE, _, DISTRHO_PLUGIN_AU_MANUFACTURER)

@interface COCOA_VIEW_CLASS_NAME : NSObject<AUCocoaUIBase>
{
DPF_UI_AU* ui;
}
@end

@implementation DPF_UI_ViewFactory
@implementation COCOA_VIEW_CLASS_NAME

- (NSString*) description
{
@@ -184,17 +235,20 @@ END_NAMESPACE_DISTRHO
return 0;
}

- (NSView*) uiViewForAudioUnit:(AudioUnit)inAU withSize:(NSSize)inPreferredSize
- (NSView*) uiViewForAudioUnit:(AudioUnit)component withSize:(NSSize)inPreferredSize
{
const double sampleRate = d_nextSampleRate;
const intptr_t winId = 0;
void* const instancePointer = nullptr;

ui = new DPF_UI_AU(inAU, winId, sampleRate, instancePointer);
ui = new DPF_UI_AU(component, winId, sampleRate, instancePointer);

return ui->getNativeView();
}

@end

#undef MACRO_NAME
#undef MACRO_NAME2

// --------------------------------------------------------------------------------------------------------------------

+ 17
- 1
examples/CairoUI/DistrhoPluginInfo.h View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2024 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -39,6 +39,22 @@
*/
#define DISTRHO_PLUGIN_URI "http://distrho.sf.net/examples/CairoUI"

/**
The AudioUnit subtype for a plugin.
This is a 4-character symbol which identifies a plugin.
It must be unique within a manufacturer's plugins, but different manufacturers can use the same subtype.
@note This macro is required when building AU plugins
*/
#define DISTRHO_PLUGIN_AU_SUBTYPE cair

/**
The AudioUnit manufacturer for a plugin.
This is a 4-character symbol with at least one non-lower case character.
Plugins from the same brand/maker should use the same symbol.
@note This macro is required when building AU plugins
*/
#define DISTRHO_PLUGIN_AU_MANUFACTURER Dstr

/**
The plugin id when exporting in CLAP format, in reverse URI form.
@note This macro is required when building CLAP plugins


+ 4
- 1
examples/Info/DistrhoPluginInfo.h View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2024 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -22,6 +22,9 @@
#define DISTRHO_PLUGIN_URI "http://distrho.sf.net/examples/Info"
#define DISTRHO_PLUGIN_CLAP_ID "studio.kx.distrho.examples.info"

#define DISTRHO_PLUGIN_AU_SUBTYPE info
#define DISTRHO_PLUGIN_AU_MANUFACTURER Dstr

#define DISTRHO_PLUGIN_HAS_UI 1
#define DISTRHO_PLUGIN_IS_RT_SAFE 1
#define DISTRHO_PLUGIN_NUM_INPUTS 2


+ 4
- 1
examples/Parameters/DistrhoPluginInfo.h View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2024 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -22,6 +22,9 @@
#define DISTRHO_PLUGIN_URI "http://distrho.sf.net/examples/Parameters"
#define DISTRHO_PLUGIN_CLAP_ID "studio.kx.distrho.examples.parameters"

#define DISTRHO_PLUGIN_AU_SUBTYPE parm
#define DISTRHO_PLUGIN_AU_MANUFACTURER Dstr

#define DISTRHO_PLUGIN_HAS_UI 1
#define DISTRHO_PLUGIN_IS_RT_SAFE 1
#define DISTRHO_PLUGIN_NUM_INPUTS 2


Loading…
Cancel
Save