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
|