File: SoundPlugin.h

package info (click to toggle)
radium-compressor 0.5.1%2Bgit20190909-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 1,064 kB
  • sloc: cpp: 8,708; ansic: 1,636; makefile: 91; sh: 42
file content (318 lines) | stat: -rw-r--r-- 11,107 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
/* Copyright 2012 Kjetil S. Matheussen

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. */



#ifndef AUDIO_SOUNDPLUGIN_H
#define AUDIO_SOUNDPLUGIN_H

#include "../common/hashmap_proc.h"
#include "Smooth_proc.h"

/*
  get_effect_value / set_effect value is screwed up.
  All the horrible code and hacks stems from the bad decision of scaling values between 0 and 1.
  This must be fixed.
 */


#ifdef __cplusplus
extern "C"{
#endif

enum{
  EFFNUM_INPUT_VOLUME = 0,  // This one must be first.
  EFFNUM_INPUT_VOLUME_ONOFF,

  EFFNUM_VOLUME,
  EFFNUM_VOLUME_ONOFF,

  EFFNUM_OUTPUT_VOLUME,
  EFFNUM_OUTPUT_VOLUME_ONOFF,

  EFFNUM_BUS1,
  EFFNUM_BUS1_ONOFF,

  EFFNUM_BUS2,
  EFFNUM_BUS2_ONOFF,

  EFFNUM_PAN,
  EFFNUM_PAN_ONOFF,

  EFFNUM_DRYWET,
  EFFNUM_EFFECTS_ONOFF,

  EFFNUM_LOWPASS_FREQ,
  EFFNUM_LOWPASS_ONOFF,

  EFFNUM_EQ1_FREQ,
  EFFNUM_EQ1_GAIN,
  EFFNUM_EQ1_ONOFF,

  EFFNUM_EQ2_FREQ,
  EFFNUM_EQ2_GAIN,
  EFFNUM_EQ2_ONOFF,

  EFFNUM_LOWSHELF_FREQ,
  EFFNUM_LOWSHELF_GAIN,
  EFFNUM_LOWSHELF_ONOFF,

  EFFNUM_HIGHSHELF_FREQ,
  EFFNUM_HIGHSHELF_GAIN,
  EFFNUM_HIGHSHELF_ONOFF,

  EFFNUM_EQ_SHOW_GUI,

  EFFNUM_COMP_RATIO, // Note that the order for the compressor parameters must be the same as the compressor parameters in system_compresssor_wrapper_proc.h
  EFFNUM_COMP_THRESHOLD,
  EFFNUM_COMP_ATTACK,
  EFFNUM_COMP_RELEASE,
  EFFNUM_COMP_OUTPUT_VOLUME,
  EFFNUM_COMP_ONOFF,

  EFFNUM_COMP_SHOW_GUI,

  EFFNUM_DELAY_TIME,
  EFFNUM_DELAY_ONOFF,

  NUM_SYSTEM_EFFECTS
};



enum{
  EFFECT_FORMAT_FLOAT,
  EFFECT_FORMAT_INT,
  EFFECT_FORMAT_BOOL,
  EFFECT_FORMAT_RADIO
};

enum ValueFormat{
  PLUGIN_FORMAT_NATIVE,
  PLUGIN_FORMAT_SCALED // scaled between 0 and 1
};

struct SoundPlugin;

#if 0
  // maybe
struct SoundPluginEffect{
  float (*get_effect_display_min_value)(const struct SoundPluginType *plugin_type);
  float (*get_effect_display_max_value)(const struct SoundPluginType *plugin_type);
  int (*get_effect_format)(const struct SoundPluginType *plugin_type); // Must return one of the EFFECT_* values above.

  const char *(*get_effect_name)(const struct SoundPluginType *plugin_type);
  const char *(*get_effect_description)(const struct SoundPluginType *plugin_type);

  void (*get_display_value_string)(struct SoundPlugin *plugin, char *buffer, int buffersize);

  // Returns true if you want to call SP_RT_get_effect_value_array to get effect values for this effect.
  // If not, set_effect_value will be called instead.
  bool (*effect_is_RT)(const struct SoundPluginType *plugin_type);

  // This functions is called if SoundPluginType->effect_is_RT(effect_num) returns false
  void (*set_effect_value)(struct SoundPlugin *plugin, int64_t time, float value);

  float (*get_effect_value)(struct SoundPlugin *plugin_type);
};
#endif


// Note that only the fields 'name' and 'is_instrument' will be accessed before the call to 'create_plugin_data'.
// The 'is_instrument' field will also be re-read after a call to 'create_plugin_data', in case it had the wrong value before.
typedef struct SoundPluginType{
  const char *type_name; // I.e. Ladspa / Vst / FluidSynth / etc. Must be unique.
  const char *name;      // i.e. zita-reverb / low-pass filter / etc. Must be unique within plugins with the same type_name.

  const char *info;     // Contains text inside the info box which appear when pressing the button with the name of the plugin. Can be NULL.

  int num_inputs;
  int num_outputs;

  bool is_instrument; // Should be set to true if it is not known until instantiation whether it is an instrument.

  bool note_handling_is_RT;

  int num_effects;

  bool plugin_takes_care_of_savable_values; // For instance, if a VST plugin has it's own editor, we ask the plugin for values instead of using savable_effect_values (which contains the last set value). Then this value is true.

  int (*get_effect_format)(const struct SoundPluginType *plugin_type, int effect_num); // Must return one of the EFFECT_* values above.

  int (*get_effect_num)(const struct SoundPluginType *plugin_type, const char *effect_name); // Necessary to implement this if the order of effects may change in the future.
  const char *(*get_effect_name)(const struct SoundPluginType *plugin_type, int effect_num); // The effect name is used as effect id. Two effects can not have the same name.
  const char *(*get_effect_description)(const struct SoundPluginType *plugin_type, int effect_num);

  void (*get_display_value_string)(struct SoundPlugin *plugin, int effect_num, char *buffer, int buffersize);

  // Returns true if you want to call SP_RT_get_effect_value_array to get effect values for this effect.
  // If not, set_effect_value will be called instead.
  bool (*effect_is_RT)(const struct SoundPluginType *plugin_type, int effect_num);

  void *(*create_plugin_data)(const struct SoundPluginType *plugin_type, struct SoundPlugin *plugin, float sample_rate, int block_size); // Called by Radium during the instantiation of a plugin. The function returns plugin->data.
  void (*cleanup_plugin_data)(struct SoundPlugin *plugin);

  // If set, this callback will be called when the 'num_frames' argument to RT_process changes. The audio thread is suspended while this function is called.
  void (*buffer_size_is_changed)(struct SoundPlugin *plugin, int new_buffer_size);

  // The sound processing function. Note that the inputs and outputs arrays are likely to point to the same sound buffers.
  // For instance, if the plugin has one input and one output, inputs[0] and outputs[0] are very likely to be equal.
  void (*RT_process)(struct SoundPlugin *plugin, int64_t time, int num_frames, float **inputs, float **outputs);

  // These two functions are not used if SoundPluginType->note_handling_is_RT is false (currently, these two functions are note used at all)
  void (*RT_play_note)(struct SoundPlugin *plugin, int64_t time, int note_num, float volume, float pan);
  void (*RT_stop_note)(struct SoundPlugin *plugin, int64_t time, int note_num, float volume);

  // These three functions are not used if SoundPluginType->note_handling_is_RT is true
  void (*play_note)(struct SoundPlugin *plugin, int64_t time, int note_num, float volume, float pan);
  void (*set_note_volume)(struct SoundPlugin *plugin, int64_t time, int note_num, float volume);
  void (*stop_note)(struct SoundPlugin *plugin, int64_t time, int note_num, float volume);
  
  // Returns the number of channels it can provide peaks for. (calling this function with ch=-1 is considered a dummy operation, except that the return value is correct)
  int (*get_peaks)(struct SoundPlugin *plugin, int note_num, int ch, float pan, int64_t start_time, int64_t end_time, float *min_value, float *max_value);

  // This functions is called if SoundPluginType->effect_is_RT(effect_num) returns false
  void (*set_effect_value)(struct SoundPlugin *plugin, int64_t time, int effect_num, float value, enum ValueFormat value_format);

  float (*get_effect_value)(struct SoundPlugin *plugin, int effect_num, enum ValueFormat value_format);

  void (*show_gui)(struct SoundPlugin *plugin);
  void (*hide_gui)(struct SoundPlugin *plugin);

  void (*recreate_from_state)(struct SoundPlugin *plugin, hash_t *state);
  void (*create_state)(struct SoundPlugin *plugin, hash_t *state);

  // Free use by the plugin
  void *data;

  // Used by Radium
  int instance_num; // Only used to autocreate a name

} SoundPluginType;

typedef struct SystemFilter{
  struct SoundPlugin **plugins;
  bool is_on;
  bool was_on;
  bool was_off;
} SystemFilter;

enum BusDescendantType{
  IS_BUS_DESCENDANT,
  IS_NOT_A_BUS_DESCENDANT,
  MAYBE_A_BUS_DESCENDANT,
};

typedef struct SoundPlugin{
  const SoundPluginType *type;

  // Data used by the plugin (the value returned by 'create_plugin_data')
  void *data;

  // Data below handled by Radium.

  struct Patch *patch; // The patch points to the plugin and the plugin points to the patch. However, the patch outlives the plugin. Plugin comes and goes, while the patch stays.
                       // Beware that this value might be NULL.

  float *savable_effect_values; // When dragging a slider, we want to save that value. But we don't want to save the last sent out automation value. (saving to disk, that is)
  float *initial_effect_values; // Used when resetting.

  bool editor_is_on;

  // Data used by SoundProducer
  Smooth input_volume;
  bool input_volume_is_on;

  float volume;
  bool volume_is_on;

  Smooth output_volume;
  bool output_volume_is_on;

  Smooth bus_volume[2];
  bool bus_volume_is_on[2];

  Smooth pan; // between 0 and 1
  bool pan_is_on;

  Smooth drywet;
  bool effects_are_on;

  SystemFilter lowpass;
  float lowpass_freq;

  SystemFilter eq1;
  float eq1_freq;
  float eq1_db;

  SystemFilter eq2;
  float eq2_freq;
  float eq2_db;

  SystemFilter lowshelf;
  float lowshelf_freq;
  float lowshelf_db;

  SystemFilter highshelf;
  float highshelf_freq;
  float highshelf_db;

  SystemFilter delay;
  float delay_time;

  bool show_equalizer_gui;

  SystemFilter comp;
  void *compressor;

  bool show_compressor_gui;

  float *volume_peak_values;
  float *volume_peak_values_for_chip;

  float *output_volume_peak_values;

  float *input_volume_peak_values;
  float *input_volume_peak_values_for_chip;

  float *system_volume_peak_values; // The one in the status bar. (Only if this is the system out plugin.) Set in Jack_plugin.c
  float *bus_volume_peak_values[2];

  enum BusDescendantType bus_descendant_type; // Is 'IS_BUS_DESCENDANT' for all descendants of bus plugins. To prevent accidental feedback loops.

} SoundPlugin;


// Call this function to get effects from the realtime process.
// For instance, if there is a volume starting from 0.5, and ending at 1.0, in the current block of 1024 frames,
// then the function will return {0.5, 0.50048828125, 0.5009765625, ..., 1.0}
//
// This functions can only be called if SoundPluginType->effect_is_RT(effect_num) returns true
float *RT_get_effect_value_array(SoundPlugin *plugin, int effect_num);

// RT_get_note_volume_array works the same way, but for note volumes. If several similar note_nums (i.e. same note_num value)
// are playing at the same time, the returned array will contain the values for one of those notes. It is undefined
// which of them.
//
// The functions can only be called if SoundPluginType->note_handling_is_RT is true
float *RT_get_note_volume_array(SoundPlugin *plugin, int note_num);


#ifdef __cplusplus
}
#endif

#endif // AUDIO_SOUNDPLUGIN_H