2 * "Small" audio modules for modular synthesis
4 * Copyright (C) 2001-2007 Krzysztof Foltman
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General
17 * Public License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02111-1307, USA.
21 #ifndef __CALF_MODULES_SMALL_H
22 #define __CALF_MODULES_SMALL_H
27 #include "plugininfo.h"
28 #include "lv2_polymorphic_port.h"
29 #include "lv2helpers.h"
31 namespace calf_plugins
{
33 /// Empty implementations for plugin functions. Note, that some functions aren't virtual, because they're called via the particular
34 /// subclass via template wrappers (ladspa_small_wrapper<> etc), not via base class pointer/reference. On the other hand,
35 /// other functions are virtual when overhead is acceptable (instantiation time functions etc.)
36 class null_small_audio_module
: public uri_map_access
41 uint32_t poly_type_control
, poly_type_audio
;
42 /// for polymorphic ports: "is audio" flags for first 32 ports (should be sufficient for most plugins)
43 uint32_t poly_port_types
;
45 null_small_audio_module()
48 , poly_type_control(0)
54 /// Called when host changes type of the polymorphic port
55 inline void set_port_type(uint32_t port
, uint32_t type
, void *type_data
) {
58 uint32_t port_mask
= 1 << port
;
59 if (type
== poly_type_control
)
60 poly_port_types
&= ~port_mask
;
61 else if (type
== poly_type_audio
)
62 poly_port_types
|= port_mask
;
63 on_port_types_changed();
66 /// Returns 1 for audio ports and 0 for control ports
67 inline unsigned int port_is_audio(unsigned int port
) {
68 return (poly_port_types
>> port
) & 1;
71 /// Returns (unsigned)-1 for audio ports and 0 for control ports
72 inline unsigned int port_audio_mask(unsigned int port
) {
73 return 0 - ((poly_port_types
>> port
) & 1);
76 /// Returns (unsigned)-1 for audio ports and 0 for control ports
77 static inline unsigned int port_audio_mask(unsigned int port
, uint32_t poly_port_types
) {
78 return 0 - ((poly_port_types
>> port
) & 1);
81 virtual void on_port_types_changed() {}
82 inline void set_bundle_path(const char *path
) {}
83 /// Called to map all the necessary URIs
84 virtual void map_uris()
86 poly_type_control
= map_uri(LV2_POLYMORPHIC_PORT_URI
, "http://lv2plug.in/ns/lv2core#ControlPort");
87 poly_type_audio
= map_uri(LV2_POLYMORPHIC_PORT_URI
, "http://lv2plug.in/ns/lv2core#AudioPort");
89 /// Called on instantiation with the list of LV2 features called
90 virtual void use_features(const LV2_Feature
*const *features
) {
93 use_feature((*features
)->URI
, (*features
)->data
);
97 /// LADSPA-esque activate function, except it is called after ports are connected, not before
98 inline void activate() {}
99 /// LADSPA-esque deactivate function
100 inline void deactivate() {}
101 /// Set sample rate for the plugin
102 inline void set_sample_rate(uint32_t sr
) { srate
= sr
; odsr
= 1.0 / sr
; }
103 static inline const void *ext_data(const char *URI
) { return NULL
; }
106 /// Templatized version useful when the number of inputs and outputs is small
107 template<unsigned int Inputs
, unsigned int Outputs
>
108 class small_audio_module_base
: public null_small_audio_module
111 enum { in_count
= Inputs
, out_count
= Outputs
};
113 float *ins
[in_count
];
115 float *outs
[out_count
];
118 template<class Module
>
119 struct lv2_small_wrapper
121 typedef Module instance
;
122 static LV2_Descriptor descriptor
;
124 static uint32_t poly_port_types
;
126 lv2_small_wrapper(const char *id
)
128 uri
= "http://calf.sourceforge.net/small_plugins/" + std::string(id
);
129 descriptor
.URI
= uri
.c_str();
130 descriptor
.instantiate
= cb_instantiate
;
131 descriptor
.connect_port
= cb_connect
;
132 descriptor
.activate
= cb_activate
;
133 descriptor
.run
= cb_run
;
134 descriptor
.deactivate
= cb_deactivate
;
135 descriptor
.cleanup
= cb_cleanup
;
136 descriptor
.extension_data
= cb_ext_data
;
138 plugin_port_type_grabber
ptg(poly_port_types
);
139 Module::plugin_info(&ptg
);
142 static void cb_connect(LV2_Handle Instance
, uint32_t port
, void *DataLocation
) {
143 unsigned long ins
= Module::in_count
;
144 unsigned long outs
= Module::out_count
;
145 instance
*const mod
= (instance
*)Instance
;
147 mod
->ins
[port
] = (float *)DataLocation
;
148 else if (port
< ins
+ outs
)
149 mod
->outs
[port
- ins
] = (float *)DataLocation
;
152 static void cb_activate(LV2_Handle Instance
) {
153 // Note the changed semantics (now more LV2-like)
154 instance
*const mod
= (instance
*)Instance
;
158 static void cb_deactivate(LV2_Handle Instance
) {
159 instance
*const mod
= (instance
*)Instance
;
163 static uint32_t cb_set_type(LV2_Handle Instance
, uint32_t port
, uint32_t type
, void *type_data
)
165 instance
*const mod
= (instance
*)Instance
;
166 mod
->set_port_type(port
, type
, type_data
);
170 static LV2_Handle
cb_instantiate(const LV2_Descriptor
* Descriptor
, double sample_rate
, const char *bundle_path
, const LV2_Feature
*const *features
)
172 instance
*mod
= new instance();
173 mod
->poly_port_types
= poly_port_types
;
174 // XXXKF some people use fractional sample rates; we respect them ;-)
175 mod
->set_bundle_path(bundle_path
);
176 mod
->use_features(features
);
177 mod
->set_sample_rate((uint32_t)sample_rate
);
181 static void cb_run(LV2_Handle Instance
, uint32_t SampleCount
) {
182 instance
*const mod
= (instance
*)Instance
;
183 mod
->process(SampleCount
);
186 static void cb_cleanup(LV2_Handle Instance
) {
187 instance
*const mod
= (instance
*)Instance
;
191 static const void *cb_ext_data(const char *URI
) {
192 return Module::ext_data(URI
);
196 extern const LV2_Descriptor
*lv2_small_descriptor(uint32_t index
);