Pulp
1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
au_v2_entry.hpp
Go to the documentation of this file.
1
#pragma once
2
3
// Generic AU v2 entry point generator
4
// Plugin developers include this and call PULP_AU_PLUGIN() with their factory
5
// function and a class name. All AudioUnitSDK boilerplate is generated.
6
//
7
// Usage (in one .cpp file per AU plugin):
8
// #include "my_processor.hpp"
9
// #include <pulp/format/au_v2_entry.hpp>
10
//
11
// // The class name determines the factory function: MyPluginAUFactory
12
// // This must match the factoryFunction in Info.plist.au
13
// PULP_AU_PLUGIN(MyPluginAU, my_namespace::create_my_processor)
14
//
15
// This generates:
16
// - A class MyPluginAU : PulpAUEffect (the AudioUnit implementation)
17
// - A factory function MyPluginAUFactory (for the Info.plist factoryFunction)
18
// - Plugin registration via PULP_REGISTER_PLUGIN
19
20
// Apple-only: pulls in AudioUnitSDK. No-op on non-Apple so the header stays
21
// self-contained on the Linux header-hygiene check.
22
#if defined(__APPLE__)
23
24
#include <
pulp/format/au_v2_adapter.hpp
>
25
#include <
pulp/format/registry.hpp
>
26
#include <AudioUnitSDK/AUPlugInDispatch.h>
27
#include <AudioUnitSDK/ComponentBase.h>
28
29
// Generate an AU v2 entry point for an audio-only effect (`aufx`).
30
// ClassName determines the factory function name: ClassNameFactory
31
// factory_fn is the ProcessorFactory function that creates the Processor
32
//
33
// Uses AUBaseFactory: the component exposes the base AU selectors only. An
34
// `aufx` host never delivers MIDI, so no MusicDevice selectors are needed.
35
// If the plugin's descriptor sets `accepts_midi = true` (packaged `aumf`),
36
// use PULP_AU_MIDI_PLUGIN instead — see below.
37
#define PULP_AU_PLUGIN(ClassName, factory_fn) \
38
PULP_REGISTER_PLUGIN(factory_fn) \
39
class ClassName : public pulp::format::au::PulpAUEffect { \
40
public: \
41
explicit ClassName(AudioComponentInstance ci) : PulpAUEffect(ci) {} \
42
}; \
43
AUSDK_COMPONENT_ENTRY(ausdk::AUBaseFactory, ClassName)
44
45
// Generate an AU v2 entry point for a MIDI-receiving effect (`aumf`,
46
// kAudioUnitType_MusicEffect). Identical to PULP_AU_PLUGIN except the
47
// component is registered through AUMIDIEffectFactory, whose AUMIDILookup
48
// dispatches the MusicDevice MIDIEvent + SysEx selectors to the base class.
49
//
50
// PulpAUEffect already derives ausdk::AUMIDIEffectBase and implements
51
// HandleMIDIEvent / HandleSysEx, but with the plain AUBaseFactory those
52
// selectors are never wired, so the host's MusicDeviceMIDIEvent call returns
53
// -4 (unimpErr) and auval fails ("-4 IN CALL MusicDeviceMIDIEvent"). The
54
// factory is the ONLY difference — the lookup table, not the C++ class, is
55
// what carries the MIDI dispatch.
56
//
57
// Pairing rule (must match or the component is invalid): use this macro
58
// exactly when the bundle is typed `aumf` and the descriptor sets
59
// `accepts_midi = true`. Instruments (`aumu`) that also implement
60
// StartNote/StopNote use the instrument entry (AUMusicDeviceFactory) instead.
61
#define PULP_AU_MIDI_PLUGIN(ClassName, factory_fn) \
62
PULP_REGISTER_PLUGIN(factory_fn) \
63
class ClassName : public pulp::format::au::PulpAUEffect { \
64
public: \
65
explicit ClassName(AudioComponentInstance ci) : PulpAUEffect(ci) {} \
66
}; \
67
AUSDK_COMPONENT_ENTRY(ausdk::AUMIDIEffectFactory, ClassName)
68
69
// ── Multi-plugin bundle variants ─────────────────────────────────────────
70
// One binary hosts many plugins. Unlike the single-plugin macros above, these
71
// bind each component to its OWN factory lexically (via the factory-taking
72
// PulpAUEffect ctor), so instantiation never consults the legacy global slot,
73
// and they register a KEYED entry (which never touches that global). Expand
74
// once per component; N per binary is legal (AUSDK_COMPONENT_ENTRY generates a
75
// distinct ClassNameFactory each time). Pass PluginRegistration metadata
76
// (id + AU codes) so tools/enumeration and per-plugin editor assets resolve.
77
// The registration braced-init is passed as trailing __VA_ARGS__ so its
78
// internal commas (`{.id=…, .au_subtype=…}`) survive the preprocessor — parens
79
// don't protect brace commas, and an extra paren pair would form a GNU
80
// statement-expression. au_factory therefore comes BEFORE the init.
81
//
82
// `factory_fn` is the SINGLE source of truth: it binds the AU class ctor AND is
83
// force-assigned onto the registration's `.factory`, overwriting whatever the
84
// braced-init said. So the factory the host constructs (lexical ctor arg) and
85
// the factory `find_plugin`/`registered_plugins` report are provably the same
86
// function — a caller cannot desync them by passing a stray `.factory`. Callers
87
// therefore MUST NOT set `.factory` in the braced-init (it is ignored).
88
#define PULP_AU_BUNDLE_ENTRY_(ClassName, factory_fn, au_factory, ...) \
89
namespace { \
90
struct ClassName##_Registrar { \
91
ClassName##_Registrar() { \
92
::pulp::format::PluginRegistration reg __VA_ARGS__; \
93
reg.factory = factory_fn; \
94
::pulp::format::register_plugin(reg); \
95
} \
96
} ClassName##_registrar_; \
97
} \
98
class ClassName : public pulp::format::au::PulpAUEffect { \
99
public: \
100
explicit ClassName(AudioComponentInstance ci) \
101
: PulpAUEffect(ci, factory_fn) {} \
102
}; \
103
AUSDK_COMPONENT_ENTRY(au_factory, ClassName)
104
105
// `aufx` component in a bundle. The trailing arg is a PluginRegistration
106
// braced-init WITHOUT `.factory` (bound from factory_fn), e.g.
107
// PULP_AU_BUNDLE_PLUGIN(FooAU, create_foo,
108
// {.id="com.x.foo", .au_type='aufx',
109
// .au_subtype='Foo1', .au_manufacturer='Mfr '})
110
#define PULP_AU_BUNDLE_PLUGIN(ClassName, factory_fn, ...) \
111
PULP_AU_BUNDLE_ENTRY_(ClassName, factory_fn, ausdk::AUBaseFactory, __VA_ARGS__)
112
113
// `aumf` (MusicEffect) component in a bundle.
114
#define PULP_AU_BUNDLE_MIDI_PLUGIN(ClassName, factory_fn, ...) \
115
PULP_AU_BUNDLE_ENTRY_(ClassName, factory_fn, ausdk::AUMIDIEffectFactory, __VA_ARGS__)
116
117
#endif
// defined(__APPLE__)
au_v2_adapter.hpp
registry.hpp
core
format
include
pulp
format
au_v2_entry.hpp
Generated by
1.15.0