1 /*
2  * Copyright (C) 2020 Hermann meyer
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  * --------------------------------------------------------------------------
18  */
19 
20 #pragma once
21 
22 #ifndef FLUIDA_H_
23 #define FLUIDA_H_
24 
25 #include <lv2.h>
26 #include <lv2/lv2plug.in/ns/ext/atom/atom.h>
27 #include <lv2/lv2plug.in/ns/ext/atom/util.h>
28 #include "lv2/lv2plug.in/ns/ext/atom/forge.h"
29 #include <lv2/lv2plug.in/ns/ext/midi/midi.h>
30 #include <lv2/lv2plug.in/ns/ext/urid/urid.h>
31 #include "lv2/lv2plug.in/ns/ext/patch/patch.h"
32 #include "lv2/lv2plug.in/ns/ext/options/options.h"
33 #include "lv2/lv2plug.in/ns/ext/state/state.h"
34 #include "lv2/lv2plug.in/ns/ext/worker/worker.h"
35 
36 #define PLUGIN_URI "https://github.com/brummer10/Fluida.lv2"
37 #define PLUGIN_UI_URI "https://github.com/brummer10/Fluida_gui"
38 
39 
40 #define FLUIDA__soundfont           PLUGIN_URI "#soundfont"
41 #define FLUIDA__sflist_start        PLUGIN_URI "#sflist_start"
42 #define FLUIDA__sflist_next         PLUGIN_URI "#sflist_next"
43 #define FLUIDA__sflist_end          PLUGIN_URI "#sflist_end"
44 #define FLUIDA__instrument          PLUGIN_URI "#instrument"
45 #define FLUIDA__load                PLUGIN_URI "#load"
46 #define FLUIDA__state               PLUGIN_URI "#state"
47 #define FLUIDA__rev_lev             PLUGIN_URI "#reverb_level"
48 #define FLUIDA__rev_width           PLUGIN_URI "#reverb_width"
49 #define FLUIDA__rev_damp            PLUGIN_URI "#reverb_damp"
50 #define FLUIDA__rev_size            PLUGIN_URI "#reverb_size"
51 #define FLUIDA__rev_on              PLUGIN_URI "#reverb_on"
52 #define FLUIDA__chorus_type         PLUGIN_URI "#chorus_type"
53 #define FLUIDA__chorus_depth        PLUGIN_URI "#chorus_depth"
54 #define FLUIDA__chorus_speed        PLUGIN_URI "#chorus_speed"
55 #define FLUIDA__chorus_lev          PLUGIN_URI "#chorus_lev"
56 #define FLUIDA__chorus_voices       PLUGIN_URI "#chorus_voices"
57 #define FLUIDA__chorus_on           PLUGIN_URI "#chorus_on"
58 #define FLUIDA__channel_pressure    PLUGIN_URI "#channel_pressure"
59 
60 
61 typedef struct {
62     LV2_URID atom_Object;
63     LV2_URID atom_Int;
64     LV2_URID atom_Float;
65     LV2_URID atom_Bool;
66     LV2_URID atom_Vector;
67     LV2_URID atom_Path;
68     LV2_URID atom_String;
69     LV2_URID atom_URID;
70     LV2_URID atom_eventTransfer;
71     LV2_URID fluida_soundfont;
72     LV2_URID fluida_sflist_start;
73     LV2_URID fluida_sflist_next;
74     LV2_URID fluida_sflist_end;
75     LV2_URID fluida_state;
76     LV2_URID fluida_instrument;
77     LV2_URID fluida_rev_lev;
78     LV2_URID fluida_rev_width;
79     LV2_URID fluida_rev_damp;
80     LV2_URID fluida_rev_size;
81     LV2_URID fluida_rev_on;
82     LV2_URID fluida_chorus_type;
83     LV2_URID fluida_chorus_depth;
84     LV2_URID fluida_chorus_speed;
85     LV2_URID fluida_chorus_lev;
86     LV2_URID fluida_chorus_voices;
87     LV2_URID fluida_chorus_on;
88     LV2_URID fluida_channel_pressure;
89     LV2_URID patch_Put;
90     LV2_URID patch_Get;
91     LV2_URID patch_Set;
92     LV2_URID patch_property;
93     LV2_URID patch_value;
94 } FluidaLV2URIs;
95 
map_fluidalv2_uris(LV2_URID_Map * map,FluidaLV2URIs * uris)96 static inline void map_fluidalv2_uris(LV2_URID_Map* map, FluidaLV2URIs* uris) {
97     uris->atom_Object             = map->map(map->handle, LV2_ATOM__Object);
98     uris->atom_Int                = map->map(map->handle, LV2_ATOM__Int);
99     uris->atom_Float              = map->map(map->handle, LV2_ATOM__Float);
100     uris->atom_Bool               = map->map(map->handle, LV2_ATOM__Bool);
101     uris->atom_Vector             = map->map(map->handle, LV2_ATOM__Vector);
102     uris->atom_Path               = map->map(map->handle, LV2_ATOM__Path);
103     uris->atom_String             = map->map(map->handle, LV2_ATOM__String);
104     uris->atom_URID               = map->map(map->handle, LV2_ATOM__URID);
105     uris->atom_eventTransfer      = map->map(map->handle, LV2_ATOM__eventTransfer);
106     uris->fluida_soundfont        = map->map(map->handle, FLUIDA__soundfont);
107     uris->fluida_sflist_start     = map->map(map->handle, FLUIDA__sflist_start);
108     uris->fluida_sflist_next      = map->map(map->handle, FLUIDA__sflist_next);
109     uris->fluida_sflist_end       = map->map(map->handle, FLUIDA__sflist_end);
110     uris->fluida_instrument       = map->map(map->handle, FLUIDA__instrument);
111     uris->fluida_rev_lev          = map->map(map->handle, FLUIDA__rev_lev);
112     uris->fluida_rev_width        = map->map(map->handle, FLUIDA__rev_width);
113     uris->fluida_rev_damp         = map->map(map->handle, FLUIDA__rev_damp);
114     uris->fluida_rev_size         = map->map(map->handle, FLUIDA__rev_size);
115     uris->fluida_rev_on           = map->map(map->handle, FLUIDA__rev_on);
116     uris->fluida_chorus_type      = map->map(map->handle, FLUIDA__chorus_type);
117     uris->fluida_chorus_depth     = map->map(map->handle, FLUIDA__chorus_depth);
118     uris->fluida_chorus_speed     = map->map(map->handle, FLUIDA__chorus_speed);
119     uris->fluida_chorus_lev       = map->map(map->handle, FLUIDA__chorus_lev);
120     uris->fluida_chorus_voices    = map->map(map->handle, FLUIDA__chorus_voices);
121     uris->fluida_chorus_on        = map->map(map->handle, FLUIDA__chorus_on);
122     uris->fluida_channel_pressure = map->map(map->handle, FLUIDA__channel_pressure);
123     uris->fluida_state            = map->map(map->handle, FLUIDA__state);
124     uris->patch_Put               = map->map(map->handle, LV2_PATCH__Put);
125     uris->patch_Get               = map->map(map->handle, LV2_PATCH__Get);
126     uris->patch_Set               = map->map(map->handle, LV2_PATCH__Set);
127     uris->patch_property          = map->map(map->handle, LV2_PATCH__property);
128     uris->patch_value             = map->map(map->handle, LV2_PATCH__value);
129 }
130 
131 // write
132 
write_set_file(LV2_Atom_Forge * forge,const FluidaLV2URIs * uris,const char * filename)133 static inline LV2_Atom* write_set_file(LV2_Atom_Forge* forge,
134                         const FluidaLV2URIs* uris, const char* filename) {
135     LV2_Atom_Forge_Frame frame;
136     LV2_Atom* set = (LV2_Atom*)lv2_atom_forge_object(
137                         forge, &frame, 1, uris->patch_Set);
138 
139     lv2_atom_forge_key(forge, uris->patch_property);
140     lv2_atom_forge_urid(forge, uris->fluida_soundfont);
141     lv2_atom_forge_key(forge, uris->patch_value);
142     lv2_atom_forge_path(forge, filename, strlen(filename));
143 
144     lv2_atom_forge_pop(forge, &frame);
145     return set;
146 }
147 
write_set_instrument(LV2_Atom_Forge * forge,const FluidaLV2URIs * uris,int value)148 static inline LV2_Atom* write_set_instrument(LV2_Atom_Forge* forge,
149                         const FluidaLV2URIs* uris, int value) {
150     LV2_Atom_Forge_Frame frame;
151     LV2_Atom* set = (LV2_Atom*)lv2_atom_forge_object(
152                         forge, &frame, 1, uris->fluida_instrument);
153 
154     lv2_atom_forge_key(forge, uris->patch_property);
155     lv2_atom_forge_urid(forge, uris->atom_Int);
156     lv2_atom_forge_key(forge, uris->patch_value);
157     lv2_atom_forge_int(forge, value);
158 
159     lv2_atom_forge_pop(forge, &frame);
160     return set;
161 }
162 
write_get_sflist(LV2_Atom_Forge * forge,const FluidaLV2URIs * uris,int instrument)163 static inline LV2_Atom* write_get_sflist(LV2_Atom_Forge* forge,
164                         const FluidaLV2URIs* uris, int instrument) {
165     LV2_Atom_Forge_Frame frame;
166     LV2_Atom* set = (LV2_Atom*)lv2_atom_forge_object(
167                         forge, &frame, 1, uris->fluida_sflist_start);
168 
169     lv2_atom_forge_key(forge, uris->patch_property);
170     lv2_atom_forge_urid(forge, uris->atom_Int);
171     lv2_atom_forge_key(forge, uris->patch_value);
172     lv2_atom_forge_int(forge, instrument);
173     lv2_atom_forge_pop(forge, &frame);
174     return set;
175 }
176 
write_get_sflist_next(LV2_Atom_Forge * forge,const FluidaLV2URIs * uris,int instrument)177 static inline LV2_Atom* write_get_sflist_next(LV2_Atom_Forge* forge,
178                         const FluidaLV2URIs* uris, int instrument) {
179     LV2_Atom_Forge_Frame frame;
180     LV2_Atom* set = (LV2_Atom*)lv2_atom_forge_object(
181                         forge, &frame, 1, uris->fluida_sflist_next);
182 
183     lv2_atom_forge_key(forge, uris->patch_property);
184     lv2_atom_forge_urid(forge, uris->atom_Int);
185     lv2_atom_forge_key(forge, uris->patch_value);
186     lv2_atom_forge_int(forge, instrument);
187     lv2_atom_forge_pop(forge, &frame);
188     return set;
189 }
190 
write_set_gui(LV2_Atom_Forge * forge,const FluidaLV2URIs * uris,int instrument)191 static inline LV2_Atom* write_set_gui(LV2_Atom_Forge* forge,
192                         const FluidaLV2URIs* uris, int instrument) {
193     LV2_Atom_Forge_Frame frame;
194     LV2_Atom* set = (LV2_Atom*)lv2_atom_forge_object(
195                         forge, &frame, 1, uris->fluida_state);
196 
197     lv2_atom_forge_key(forge, uris->patch_property);
198     lv2_atom_forge_urid(forge, uris->atom_Int);
199     lv2_atom_forge_key(forge, uris->patch_value);
200     lv2_atom_forge_int(forge, instrument);
201     lv2_atom_forge_pop(forge, &frame);
202     return set;
203 }
204 
205 // read
206 
read_set_file(const FluidaLV2URIs * uris,const LV2_Atom_Object * obj)207 static inline const LV2_Atom* read_set_file(const FluidaLV2URIs* uris,
208                                             const LV2_Atom_Object* obj) {
209     if (obj->body.otype != uris->patch_Set) {
210         return NULL;
211     }
212     const LV2_Atom* property = NULL;
213     lv2_atom_object_get(obj, uris->patch_property, &property, 0);
214     if (!property || (property->type != uris->atom_URID) ||
215             (((LV2_Atom_URID*)property)->body != uris->fluida_soundfont)) {
216         return NULL;
217     }
218     const LV2_Atom* file_path = NULL;
219     lv2_atom_object_get(obj, uris->patch_value, &file_path, 0);
220     if (!file_path || (file_path->type != uris->atom_Path)) {
221         return NULL;
222     }
223     return file_path;
224 }
225 
read_set_instrument(const FluidaLV2URIs * uris,const LV2_Atom_Object * obj)226 static inline const LV2_Atom* read_set_instrument(const FluidaLV2URIs* uris,
227                                                 const LV2_Atom_Object* obj) {
228     if (obj->body.otype != uris->fluida_instrument) {
229         return NULL;
230     }
231     const LV2_Atom* property = NULL;
232     lv2_atom_object_get(obj, uris->patch_property, &property, 0);
233     if (!property || (property->type != uris->atom_URID) ||
234             (((LV2_Atom_URID*)property)->body != uris->atom_Int)) {
235         return NULL;
236     }
237     const LV2_Atom* instrument = NULL;
238     lv2_atom_object_get(obj, uris->patch_value, &instrument, 0);
239     if (!instrument || (instrument->type != uris->atom_Int)) {
240         return NULL;
241     }
242     return instrument;
243 }
244 
read_set_gui(const FluidaLV2URIs * uris,const LV2_Atom_Object * obj)245 static inline const LV2_Atom* read_set_gui(const FluidaLV2URIs* uris,
246                                             const LV2_Atom_Object* obj) {
247     if (obj->body.otype != uris->fluida_state) {
248         return NULL;
249     }
250     const LV2_Atom* property = NULL;
251     lv2_atom_object_get(obj, uris->patch_property, &property, 0);
252     if (!property || (property->type != uris->atom_URID) ||
253             (((LV2_Atom_URID*)property)->body != uris->atom_Int)) {
254         return NULL;
255     }
256     const LV2_Atom* value = NULL;
257     lv2_atom_object_get(obj, uris->patch_value, &value, 0);
258     if (!value || (value->type != uris->atom_Int)) {
259         return NULL;
260     }
261     return value;
262 }
263 
264 typedef enum
265 {
266     EFFECTS_OUTPUT,
267     EFFECTS_OUTPUT1,
268     MIDI_IN,
269     NOTIFY,
270 } PortIndex;
271 
272 #endif //FLUIDA_H_
273