You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
719 lines
22 KiB
719 lines
22 KiB
3 years ago
|
/*
|
||
|
Calf Box, an open source musical instrument.
|
||
|
Copyright (C) 2010-2011 Krzysztof Foltman
|
||
|
|
||
|
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 3 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, see <http://www.gnu.org/licenses/>.
|
||
|
*/
|
||
|
|
||
|
#ifndef CBOX_SAMPLER_LAYER_H
|
||
|
#define CBOX_SAMPLER_LAYER_H
|
||
|
|
||
|
#include "dom.h"
|
||
|
#include "wavebank.h"
|
||
|
#include <stdio.h>
|
||
|
#include <stdint.h>
|
||
|
|
||
|
// arbitrary value that doesn't collide with a useful range
|
||
|
#define SAMPLER_CURVE_GAP -100000
|
||
|
#define NO_HI_BPM_VALUE 10000
|
||
|
#define CC_COUNT 128
|
||
|
#define EXT_CC_COUNT 143
|
||
|
|
||
|
struct sampler_program;
|
||
|
struct sampler_voice;
|
||
|
struct sampler_prevoice;
|
||
|
struct sampler_noteinitfunc;
|
||
|
struct sampler_module;
|
||
|
|
||
|
enum sampler_player_type
|
||
|
{
|
||
|
spt_inactive,
|
||
|
spt_mono16,
|
||
|
spt_stereo16,
|
||
|
spt_finished
|
||
|
};
|
||
|
|
||
|
enum sampler_loop_mode
|
||
|
{
|
||
|
slm_unknown,
|
||
|
slm_no_loop,
|
||
|
slm_one_shot,
|
||
|
slm_loop_continuous,
|
||
|
slm_loop_sustain, // unsupported
|
||
|
slm_one_shot_chokeable,
|
||
|
slmcount
|
||
|
};
|
||
|
|
||
|
#define ENUM_VALUES_sampler_loop_mode(MACRO) \
|
||
|
MACRO("no_loop", slm_no_loop) \
|
||
|
MACRO("one_shot", slm_one_shot) \
|
||
|
MACRO("loop_continuous", slm_loop_continuous) \
|
||
|
MACRO("loop_sustain", slm_loop_sustain) \
|
||
|
MACRO("one_shot_chokeable", slm_one_shot_chokeable)
|
||
|
|
||
|
enum sampler_off_mode
|
||
|
{
|
||
|
som_unknown,
|
||
|
som_normal,
|
||
|
som_fast
|
||
|
};
|
||
|
|
||
|
#define ENUM_VALUES_sampler_off_mode(MACRO) \
|
||
|
MACRO("normal", som_normal) \
|
||
|
MACRO("fast", som_fast)
|
||
|
|
||
|
enum sampler_vel_mode
|
||
|
{
|
||
|
svm_unknown,
|
||
|
svm_current,
|
||
|
svm_previous
|
||
|
};
|
||
|
|
||
|
#define ENUM_VALUES_sampler_vel_mode(MACRO) \
|
||
|
MACRO("current", svm_current) \
|
||
|
MACRO("previous", svm_previous)
|
||
|
|
||
|
enum sampler_trigger
|
||
|
{
|
||
|
stm_attack,
|
||
|
stm_release,
|
||
|
stm_first,
|
||
|
stm_legato,
|
||
|
};
|
||
|
|
||
|
#define ENUM_VALUES_sampler_trigger(MACRO) \
|
||
|
MACRO("attack", stm_attack) \
|
||
|
MACRO("release", stm_release) \
|
||
|
MACRO("first", stm_first) \
|
||
|
MACRO("legato", stm_legato)
|
||
|
|
||
|
enum sampler_filter_type
|
||
|
{
|
||
|
sft_unknown,
|
||
|
sft_lp12,
|
||
|
sft_hp12,
|
||
|
sft_bp6,
|
||
|
sft_lp24,
|
||
|
sft_hp24,
|
||
|
sft_bp12,
|
||
|
sft_lp6,
|
||
|
sft_hp6,
|
||
|
sft_lp12nr,
|
||
|
sft_hp12nr,
|
||
|
sft_lp24nr,
|
||
|
sft_hp24nr,
|
||
|
sft_lp24hybrid,
|
||
|
sft_lp36,
|
||
|
};
|
||
|
|
||
|
#define ENUM_VALUES_sampler_filter_type(MACRO) \
|
||
|
MACRO("lpf_2p", sft_lp12) \
|
||
|
MACRO("hpf_2p", sft_hp12) \
|
||
|
MACRO("bpf_2p", sft_bp6) \
|
||
|
MACRO("lpf_4p", sft_lp24) \
|
||
|
MACRO("hpf_4p", sft_hp24) \
|
||
|
MACRO("bpf_4p", sft_bp12) \
|
||
|
MACRO("lpf_1p", sft_lp6) \
|
||
|
MACRO("hpf_1p", sft_hp6) \
|
||
|
MACRO("lpf_2p_nores", sft_lp12nr) \
|
||
|
MACRO("hpf_2p_nores", sft_hp12nr) \
|
||
|
MACRO("lpf_4p_nores", sft_lp24nr) \
|
||
|
MACRO("hpf_4p_nores", sft_hp24nr) \
|
||
|
MACRO("lpf_4p_hybrid", sft_lp24hybrid) \
|
||
|
MACRO("lpf_6p", sft_lp36) \
|
||
|
|
||
|
enum sampler_xf_curve
|
||
|
{
|
||
|
stxc_power,
|
||
|
stxc_gain,
|
||
|
};
|
||
|
|
||
|
#define ENUM_VALUES_sampler_xf_curve(MACRO) \
|
||
|
MACRO("power", stxc_power) \
|
||
|
MACRO("gain", stxc_gain)
|
||
|
|
||
|
#define ENUM_LIST(MACRO) \
|
||
|
MACRO(sampler_loop_mode) \
|
||
|
MACRO(sampler_off_mode) \
|
||
|
MACRO(sampler_vel_mode) \
|
||
|
MACRO(sampler_trigger) \
|
||
|
MACRO(sampler_filter_type) \
|
||
|
MACRO(sampler_xf_curve) \
|
||
|
|
||
|
#define MAKE_FROM_TO_STRING_EXTERN(enumtype) \
|
||
|
extern const char *enumtype##_to_string(enum enumtype value); \
|
||
|
extern gboolean enumtype##_from_string(const char *name, enum enumtype *value);
|
||
|
|
||
|
ENUM_LIST(MAKE_FROM_TO_STRING_EXTERN)
|
||
|
|
||
|
enum sampler_modsrc
|
||
|
{
|
||
|
smsrc_cc0 = 0,
|
||
|
|
||
|
smsrc_pitchbend = 128,
|
||
|
smsrc_chanaft_sfz2 = 129,
|
||
|
smsrc_lastpolyaft = 130, // ?
|
||
|
smsrc_noteonvel = 131,
|
||
|
smsrc_noteoffvel = 132,
|
||
|
smsrc_keynotenum = 133,
|
||
|
smsrc_keynotegate = 134,
|
||
|
smsrc_random_unipolar = 135,
|
||
|
smsrc_random_bipolar = 136,
|
||
|
smsrc_alternate = 137,
|
||
|
smsrc_keydelta = 140,
|
||
|
smsrc_keydelta_abs = 141,
|
||
|
smsrc_tempo = 142,
|
||
|
|
||
|
// those are per-note, not per-channel
|
||
|
smsrc_vel,
|
||
|
smsrc_chanaft,
|
||
|
smsrc_polyaft,
|
||
|
smsrc_pitch,
|
||
|
smsrc_pitchenv,
|
||
|
smsrc_filenv,
|
||
|
smsrc_ampenv,
|
||
|
smsrc_pitchlfo,
|
||
|
smsrc_fillfo,
|
||
|
smsrc_amplfo,
|
||
|
smsrc_none,
|
||
|
|
||
|
smsrccount,
|
||
|
smsrc_perchan_offset = 0,
|
||
|
smsrc_perchan_count = smsrc_vel,
|
||
|
smsrc_pernote_offset = smsrc_vel,
|
||
|
smsrc_pernote_count = smsrccount - smsrc_pernote_offset,
|
||
|
|
||
|
smsrc_ampeg = smsrc_ampenv,
|
||
|
smsrc_fileg = smsrc_filenv,
|
||
|
smsrc_pitcheg = smsrc_pitchenv,
|
||
|
};
|
||
|
|
||
|
enum sampler_moddest
|
||
|
{
|
||
|
smdest_gain,
|
||
|
smdest_pitch,
|
||
|
smdest_cutoff,
|
||
|
smdest_resonance,
|
||
|
smdest_tonectl,
|
||
|
smdest_pan,
|
||
|
smdest_amplitude,
|
||
|
smdest_cutoff2,
|
||
|
smdest_resonance2,
|
||
|
smdest_pitchlfo_freq,
|
||
|
smdest_fillfo_freq,
|
||
|
smdest_amplfo_freq,
|
||
|
|
||
|
smdest_eq1_freq,
|
||
|
smdest_eq1_bw,
|
||
|
smdest_eq1_gain,
|
||
|
smdest_eq2_freq,
|
||
|
smdest_eq2_bw,
|
||
|
smdest_eq2_gain,
|
||
|
smdest_eq3_freq,
|
||
|
smdest_eq3_bw,
|
||
|
smdest_eq3_gain,
|
||
|
|
||
|
smdestcount,
|
||
|
|
||
|
smdest_from_amplfo = smdest_gain,
|
||
|
smdest_from_fillfo = smdest_cutoff,
|
||
|
smdest_from_pitchlfo = smdest_pitch,
|
||
|
smdest_from_ampeg = smdest_gain,
|
||
|
smdest_from_fileg = smdest_cutoff,
|
||
|
smdest_from_pitcheg = smdest_pitch,
|
||
|
|
||
|
smdest_ampeg_stage = 0x80,
|
||
|
smdest_fileg_stage = 0x90,
|
||
|
smdest_pitcheg_stage = 0xA0,
|
||
|
|
||
|
smdest_eg_stage_start = 0x80,
|
||
|
smdest_eg_stage_end = 0xAF,
|
||
|
};
|
||
|
|
||
|
struct sampler_modulation_key
|
||
|
{
|
||
|
enum sampler_modsrc src;
|
||
|
enum sampler_modsrc src2;
|
||
|
enum sampler_moddest dest;
|
||
|
};
|
||
|
|
||
|
struct sampler_modulation_value
|
||
|
{
|
||
|
float amount;
|
||
|
float smooth;
|
||
|
float step;
|
||
|
unsigned int curve_id:12;
|
||
|
unsigned int has_amount:1;
|
||
|
unsigned int has_curve:1;
|
||
|
unsigned int has_smooth:1;
|
||
|
unsigned int has_step:1;
|
||
|
};
|
||
|
|
||
|
#define SAMPLER_COLL_FIELD_LIST_sampler_modulation(MACRO, ...) \
|
||
|
MACRO(amount, has_amount, float, 0, ## __VA_ARGS__) \
|
||
|
MACRO(curve_id, has_curve, uint32_t, 0, ## __VA_ARGS__) \
|
||
|
MACRO(smooth, has_smooth, float, 0, ## __VA_ARGS__) \
|
||
|
MACRO(step, has_step, float, 0, ## __VA_ARGS__)
|
||
|
|
||
|
#define SAMPLER_COLL_CHAIN_LIST_sampler_modulation(MACRO, ...) \
|
||
|
MACRO(modulations, modulation, ## __VA_ARGS__)
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
typedef void (*SamplerNoteInitFunc)(struct sampler_noteinitfunc *nif, struct sampler_voice *voice);
|
||
|
typedef void (*SamplerNoteInitFunc2)(struct sampler_noteinitfunc *nif, struct sampler_prevoice *prevoice);
|
||
|
|
||
|
struct sampler_noteinitfunc_key
|
||
|
{
|
||
|
union {
|
||
|
SamplerNoteInitFunc notefunc_voice;
|
||
|
SamplerNoteInitFunc2 notefunc_prevoice;
|
||
|
};
|
||
|
int variant;
|
||
|
};
|
||
|
|
||
|
struct sampler_noteinitfunc_value
|
||
|
{
|
||
|
float value;
|
||
|
uint32_t curve_id;
|
||
|
float step;
|
||
|
unsigned int has_value:1;
|
||
|
unsigned int has_curve:1;
|
||
|
unsigned int has_step:1;
|
||
|
};
|
||
|
|
||
|
enum sampler_noteinitfunc_envelope_variant
|
||
|
{
|
||
|
snif_env_delay = 0,
|
||
|
snif_env_attack = 1,
|
||
|
snif_env_hold = 2,
|
||
|
snif_env_decay = 3,
|
||
|
snif_env_sustain = 4,
|
||
|
snif_env_release = 5,
|
||
|
snif_env_start = 6,
|
||
|
};
|
||
|
|
||
|
#define SAMPLER_COLL_FIELD_LIST_sampler_noteinitfunc(MACRO, ...) \
|
||
|
MACRO(value, has_value, float, 0, ## __VA_ARGS__) \
|
||
|
MACRO(curve_id, has_curve, int, 0, ## __VA_ARGS__) \
|
||
|
MACRO(step, has_step, float, 0, ## __VA_ARGS__)
|
||
|
|
||
|
#define SAMPLER_COLL_CHAIN_LIST_sampler_noteinitfunc(MACRO, ...) \
|
||
|
MACRO(voice_nifs, voice_nif, ## __VA_ARGS__) \
|
||
|
MACRO(prevoice_nifs, prevoice_nif, ## __VA_ARGS__)
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
struct sampler_cc_range_key
|
||
|
{
|
||
|
uint8_t cc_number;
|
||
|
};
|
||
|
|
||
|
struct sampler_cc_range_value
|
||
|
{
|
||
|
uint8_t locc;
|
||
|
uint8_t hicc;
|
||
|
uint8_t has_locc:1;
|
||
|
uint8_t has_hicc:1;
|
||
|
};
|
||
|
|
||
|
#define SAMPLER_COLL_FIELD_LIST_sampler_cc_range(MACRO, ...) \
|
||
|
MACRO(locc, has_locc, uint8_t, 0, ## __VA_ARGS__) \
|
||
|
MACRO(hicc, has_hicc, uint8_t, 127, ## __VA_ARGS__)
|
||
|
|
||
|
#define SAMPLER_COLL_CHAIN_LIST_sampler_cc_range(MACRO, ...) \
|
||
|
MACRO(on_cc, on_cc, ## __VA_ARGS__) \
|
||
|
MACRO(cc, cc, ## __VA_ARGS__) \
|
||
|
MACRO(xfin_cc, xfin_cc, ## __VA_ARGS__) \
|
||
|
MACRO(xfout_cc, xfout_cc, ## __VA_ARGS__)
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
struct sampler_flex_lfo_key
|
||
|
{
|
||
|
uint32_t id;
|
||
|
};
|
||
|
|
||
|
struct sampler_flex_lfo_value
|
||
|
{
|
||
|
// Note: layout/order must be identical to sampler_lfo_params
|
||
|
float freq;
|
||
|
float delay;
|
||
|
float fade;
|
||
|
int wave;
|
||
|
|
||
|
uint8_t has_freq:1;
|
||
|
uint8_t has_delay:1;
|
||
|
uint8_t has_fade:1;
|
||
|
uint8_t has_wave:1;
|
||
|
};
|
||
|
|
||
|
#define SAMPLER_COLL_FIELD_LIST_sampler_flex_lfo(MACRO, ...) \
|
||
|
MACRO(freq, has_freq, float, 0, ## __VA_ARGS__) \
|
||
|
MACRO(delay, has_delay, float, 0, ## __VA_ARGS__) \
|
||
|
MACRO(fade, has_fade, float, 0, ## __VA_ARGS__) \
|
||
|
MACRO(wave, has_wave, int, 0, ## __VA_ARGS__)
|
||
|
|
||
|
#define SAMPLER_COLL_CHAIN_LIST_sampler_flex_lfo(MACRO, ...) \
|
||
|
MACRO(flex_lfos, flex_lfos, ## __VA_ARGS__)
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
#define SAMPLER_COLL_LIST(MACRO) \
|
||
|
MACRO(sampler_modulation) \
|
||
|
MACRO(sampler_noteinitfunc) \
|
||
|
MACRO(sampler_cc_range) \
|
||
|
MACRO(sampler_flex_lfo)
|
||
|
|
||
|
#define SAMPLER_COLL_DEFINITION(sname) \
|
||
|
struct sname \
|
||
|
{ \
|
||
|
struct sname##_key key; \
|
||
|
struct sname##_value value; \
|
||
|
struct sname *next; \
|
||
|
};
|
||
|
|
||
|
SAMPLER_COLL_LIST(SAMPLER_COLL_DEFINITION)
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
struct sampler_lfo_params
|
||
|
{
|
||
|
float freq;
|
||
|
float delay;
|
||
|
float fade;
|
||
|
int wave;
|
||
|
};
|
||
|
|
||
|
struct sampler_eq_params
|
||
|
{
|
||
|
float freq;
|
||
|
float bw;
|
||
|
float gain;
|
||
|
float effective_freq;
|
||
|
float vel2freq;
|
||
|
float vel2gain;
|
||
|
};
|
||
|
|
||
|
typedef int midi_note_t;
|
||
|
|
||
|
/*
|
||
|
* Transforms:
|
||
|
* notransform - self-explanatory
|
||
|
* dBamp - amplitude/gain stored as dB
|
||
|
*/
|
||
|
|
||
|
#define SAMPLER_FIXED_FIELDS(MACRO) \
|
||
|
MACRO##_string(sample) \
|
||
|
MACRO(uint32_t, offset, 0) \
|
||
|
MACRO(uint32_t, offset_random, 0) \
|
||
|
MACRO(uint32_t, loop_start, 0) \
|
||
|
MACRO(uint32_t, loop_end, 0) \
|
||
|
MACRO(uint32_t, end, 0) \
|
||
|
MACRO(uint32_t, loop_overlap, (uint32_t)-1) \
|
||
|
MACRO##_enum(sampler_loop_mode, loop_mode, slm_unknown) \
|
||
|
MACRO##_enum(sampler_trigger, trigger, stm_attack) \
|
||
|
MACRO##_dBamp(float, volume, 0) \
|
||
|
MACRO(float, amplitude, 100) \
|
||
|
MACRO(float, pan, 0) \
|
||
|
MACRO(float, position, 0) \
|
||
|
MACRO(float, width, 100) \
|
||
|
MACRO(float, tune, 0) \
|
||
|
MACRO(int, transpose, 0) \
|
||
|
MACRO(int, lochan, 1) \
|
||
|
MACRO(int, hichan, 16) \
|
||
|
MACRO(float, lorand, 0) \
|
||
|
MACRO(float, hirand, 1) \
|
||
|
MACRO(midi_note_t, key, -1) \
|
||
|
MACRO(midi_note_t, lokey, 0) \
|
||
|
MACRO(midi_note_t, hikey, 127) \
|
||
|
MACRO(midi_note_t, pitch_keycenter, 60) \
|
||
|
MACRO(int, pitch_keytrack, 100) \
|
||
|
MACRO(midi_note_t, fil_keycenter, 60) \
|
||
|
MACRO(int, fil_keytrack, 0) \
|
||
|
MACRO(midi_note_t, fil2_keycenter, 60) \
|
||
|
MACRO(int, fil2_keytrack, 0) \
|
||
|
MACRO(midi_note_t, amp_keycenter, 60) \
|
||
|
MACRO(int, amp_keytrack, 0) \
|
||
|
MACRO(int, fil_veltrack, 0) \
|
||
|
MACRO(int, fil2_veltrack, 0) \
|
||
|
MACRO(int, amp_veltrack, 100) \
|
||
|
MACRO(int, lovel, 0) \
|
||
|
MACRO(int, hivel, 127) \
|
||
|
MACRO(int, lobend, -8192) \
|
||
|
MACRO(int, hibend, 8192) \
|
||
|
MACRO(int, lochanaft, 0) \
|
||
|
MACRO(int, hichanaft, 127) \
|
||
|
MACRO(int, lopolyaft, 0) \
|
||
|
MACRO(int, hipolyaft, 127) \
|
||
|
MACRO(float, lobpm, 0.0) \
|
||
|
MACRO(float, hibpm, NO_HI_BPM_VALUE) \
|
||
|
MACRO(int, velcurve_quadratic, 1) \
|
||
|
MACRO##_enum(sampler_filter_type, fil_type, sft_lp12) \
|
||
|
MACRO##_enum(sampler_filter_type, fil2_type, sft_lp12) \
|
||
|
MACRO##_enum(sampler_off_mode, off_mode, som_unknown) \
|
||
|
MACRO##_enum(sampler_vel_mode, vel_mode, svm_current) \
|
||
|
MACRO(float, cutoff, -1) \
|
||
|
MACRO##_dBamp(float, resonance, 0) \
|
||
|
MACRO(float, cutoff2, -1) \
|
||
|
MACRO##_dBamp(float, resonance2, 0) \
|
||
|
MACRO(midi_note_t, sw_lokey, 0) \
|
||
|
MACRO(midi_note_t, sw_hikey, 127) \
|
||
|
MACRO(midi_note_t, sw_last, -1) \
|
||
|
MACRO(midi_note_t, sw_down, -1) \
|
||
|
MACRO(midi_note_t, sw_up, -1) \
|
||
|
MACRO(midi_note_t, sw_previous, -1) \
|
||
|
MACRO(midi_note_t, sw_default, -1) \
|
||
|
MACRO(int, seq_position, 1) \
|
||
|
MACRO(int, seq_length, 1) \
|
||
|
MACRO(float, sync_offset, 0) \
|
||
|
MACRO(int, effect1bus, 1) \
|
||
|
MACRO(int, effect2bus, 2) \
|
||
|
MACRO(float, effect1, 0) \
|
||
|
MACRO(float, effect2, 0) \
|
||
|
MACRO(float, delay, 0) \
|
||
|
MACRO(int, output, 0) \
|
||
|
MACRO(int, group, 0) \
|
||
|
MACRO(int, off_by, 0) \
|
||
|
MACRO(int, count, 0) \
|
||
|
MACRO(int, bend_up, 200) \
|
||
|
MACRO(int, bend_down, -200) \
|
||
|
MACRO(int, bend_step, 1) \
|
||
|
MACRO(int, timestretch, 0) \
|
||
|
MACRO(float, timestretch_jump, 500) \
|
||
|
MACRO(float, timestretch_crossfade, 100) \
|
||
|
MACRO(float, rt_decay, 0) \
|
||
|
MACRO(float, tonectl, 0) \
|
||
|
MACRO(float, tonectl_freq, 0) \
|
||
|
MACRO(float, reloffset, 0) \
|
||
|
MACRO(float, xfin_lokey, 0) \
|
||
|
MACRO(float, xfin_hikey, 0) \
|
||
|
MACRO(float, xfout_lokey, 127) \
|
||
|
MACRO(float, xfout_hikey, 127) \
|
||
|
MACRO##_enum(sampler_xf_curve, xf_keycurve, stxc_power) \
|
||
|
MACRO(float, xfin_lovel, 0) \
|
||
|
MACRO(float, xfin_hivel, 0) \
|
||
|
MACRO(float, xfout_lovel, 127) \
|
||
|
MACRO(float, xfout_hivel, 127) \
|
||
|
MACRO##_enum(sampler_xf_curve, xf_velcurve, stxc_power) \
|
||
|
MACRO##_ccrange(xfin_cc, xfin_) \
|
||
|
MACRO##_ccrange(xfout_cc, xfout_) \
|
||
|
MACRO##_enum(sampler_xf_curve, xf_cccurve, stxc_power) \
|
||
|
MACRO##_dahdsr(amp_env, ampeg, 0) \
|
||
|
MACRO##_dahdsr(filter_env, fileg, 1) \
|
||
|
MACRO##_dahdsr(pitch_env, pitcheg, 2) \
|
||
|
MACRO##_lfo(amp_lfo, amplfo, 0) \
|
||
|
MACRO##_lfo(filter_lfo, fillfo, 1) \
|
||
|
MACRO##_lfo(pitch_lfo, pitchlfo, 2) \
|
||
|
MACRO##_eq(eq1, eq1, 0) \
|
||
|
MACRO##_eq(eq2, eq2, 1) \
|
||
|
MACRO##_eq(eq3, eq3, 2) \
|
||
|
MACRO##_ccrange(on_cc, on_) \
|
||
|
MACRO##_ccrange(cc, ) \
|
||
|
MACRO##_midicurve(amp_velcurve) \
|
||
|
|
||
|
// XXXKF: consider making send1gain the dBamp type... except it's
|
||
|
// a linear percentage value in SFZ spec - bit weird!
|
||
|
|
||
|
#define DAHDSR_FIELDS(MACRO, ...) \
|
||
|
MACRO(start, 0, 0, ## __VA_ARGS__) \
|
||
|
MACRO(delay, 1, 0, ## __VA_ARGS__) \
|
||
|
MACRO(attack, 2, 0, ## __VA_ARGS__) \
|
||
|
MACRO(hold, 3, 0, ## __VA_ARGS__) \
|
||
|
MACRO(decay, 4, 0, ## __VA_ARGS__) \
|
||
|
MACRO(sustain, 5, 100, ## __VA_ARGS__) \
|
||
|
MACRO(release, 6, 0.05, ## __VA_ARGS__) \
|
||
|
|
||
|
#define LFO_FIELDS(MACRO, ...) \
|
||
|
MACRO(freq, 0, 0, ## __VA_ARGS__) \
|
||
|
MACRO(delay, 1, 0, ## __VA_ARGS__) \
|
||
|
MACRO(fade, 2, 0, ## __VA_ARGS__) \
|
||
|
MACRO(wave, 3, 1, ## __VA_ARGS__) \
|
||
|
|
||
|
#define EQ_FIELDS(MACRO, ...) \
|
||
|
MACRO(freq, 0, 0, ## __VA_ARGS__) \
|
||
|
MACRO(bw, 1, 1, ## __VA_ARGS__) \
|
||
|
MACRO(gain, 2, 0, ## __VA_ARGS__) \
|
||
|
MACRO(vel2freq, 3, 0, ## __VA_ARGS__) \
|
||
|
MACRO(vel2gain, 5, 0, ## __VA_ARGS__) \
|
||
|
|
||
|
#define PROC_SUBSTRUCT_HAS_FIELD(name, index, param, def_value) \
|
||
|
unsigned int name:1;
|
||
|
#define PROC_SUBSTRUCT_RESET_FIELD(name, index, def_value, param, dst) \
|
||
|
dst->param.name = def_value;
|
||
|
#define PROC_SUBSTRUCT_RESET_HAS_FIELD(name, index, def_value, param, dst) \
|
||
|
dst->has_##param.name = 0;
|
||
|
#define PROC_SUBSTRUCT_CLONE(name, index, def_value, param, dst, src) \
|
||
|
dst->param.name = src->param.name; \
|
||
|
dst->has_##param.name = src->has_##param.name;
|
||
|
|
||
|
struct sampler_dahdsr_has_fields
|
||
|
{
|
||
|
DAHDSR_FIELDS(PROC_SUBSTRUCT_HAS_FIELD, name)
|
||
|
};
|
||
|
|
||
|
struct sampler_lfo_has_fields
|
||
|
{
|
||
|
LFO_FIELDS(PROC_SUBSTRUCT_HAS_FIELD, name)
|
||
|
};
|
||
|
|
||
|
struct sampler_eq_has_fields
|
||
|
{
|
||
|
EQ_FIELDS(PROC_SUBSTRUCT_HAS_FIELD, name)
|
||
|
};
|
||
|
|
||
|
struct sampler_midi_curve
|
||
|
{
|
||
|
float values[128];
|
||
|
uint8_t has_values[128];
|
||
|
};
|
||
|
|
||
|
#define PROC_FIELDS_TO_STRUCT(type, name, def_value) \
|
||
|
type name;
|
||
|
#define PROC_FIELDS_TO_STRUCT_string(name) \
|
||
|
gchar *name; \
|
||
|
gboolean name##_changed;
|
||
|
#define PROC_FIELDS_TO_STRUCT_dBamp(type, name, def_value) \
|
||
|
type name; \
|
||
|
type name##_linearized;
|
||
|
#define PROC_FIELDS_TO_STRUCT_enum(enumtype, name, def_value) \
|
||
|
enum enumtype name;
|
||
|
#define PROC_FIELDS_TO_STRUCT_dahdsr(name, parname, index) \
|
||
|
struct cbox_dahdsr name; \
|
||
|
struct cbox_envelope_shape name##_shape;
|
||
|
#define PROC_FIELDS_TO_STRUCT_lfo(name, parname, index) \
|
||
|
struct sampler_lfo_params name;
|
||
|
#define PROC_FIELDS_TO_STRUCT_eq(name, parname, index) \
|
||
|
struct sampler_eq_params name;
|
||
|
#define PROC_FIELDS_TO_STRUCT_ccrange(name, parname) \
|
||
|
struct sampler_cc_range *name;
|
||
|
#define PROC_FIELDS_TO_STRUCT_midicurve(name) \
|
||
|
struct sampler_midi_curve name;
|
||
|
|
||
|
#define PROC_HAS_FIELD(type, name, def_value) \
|
||
|
unsigned int has_##name:1;
|
||
|
#define PROC_HAS_FIELD_string(name) \
|
||
|
unsigned int has_##name:1;
|
||
|
#define PROC_HAS_FIELD_dBamp(type, name, def_value) \
|
||
|
PROC_HAS_FIELD(type, name, def_value)
|
||
|
#define PROC_HAS_FIELD_enum(enumtype, name, def_value) \
|
||
|
PROC_HAS_FIELD(type, name, def_value)
|
||
|
|
||
|
#define PROC_HAS_FIELD_dahdsr(name, parname, index) \
|
||
|
struct sampler_dahdsr_has_fields has_##name;
|
||
|
#define PROC_HAS_FIELD_lfo(name, parname, index) \
|
||
|
struct sampler_lfo_has_fields has_##name;
|
||
|
#define PROC_HAS_FIELD_eq(name, parname, index) \
|
||
|
struct sampler_eq_has_fields has_##name;
|
||
|
#define PROC_HAS_FIELD_ccrange(name, parname)
|
||
|
#define PROC_HAS_FIELD_midicurve(name)
|
||
|
|
||
|
CBOX_EXTERN_CLASS(sampler_layer)
|
||
|
|
||
|
enum sampler_layer_mod_bitmasks
|
||
|
{
|
||
|
slmb_ampeg_cc = 0x01,
|
||
|
slmb_fileg_cc = 0x02,
|
||
|
slmb_pitcheg_cc = 0x04,
|
||
|
};
|
||
|
|
||
|
struct sampler_layer_computed
|
||
|
{
|
||
|
// computed values:
|
||
|
struct cbox_waveform *eff_waveform;
|
||
|
enum sampler_loop_mode eff_loop_mode;
|
||
|
uint32_t eff_loop_start, eff_loop_end;
|
||
|
float eff_freq;
|
||
|
gboolean eff_use_keyswitch:1;
|
||
|
gboolean eff_use_simple_trigger_logic:1;
|
||
|
gboolean eff_use_xfcc:1;
|
||
|
gboolean eff_use_prevoice:1;
|
||
|
gboolean eff_use_channel_mixer:1;
|
||
|
gboolean eff_use_filter_mods:1;
|
||
|
gboolean eff_is_silent:1;
|
||
|
int16_t scratch_loop[2 * MAX_INTERPOLATION_ORDER * 2];
|
||
|
int16_t scratch_end[2 * MAX_INTERPOLATION_ORDER * 2];
|
||
|
float resonance_scaled, resonance2_scaled;
|
||
|
float logcutoff, logcutoff2;
|
||
|
uint32_t eq_bitmask, mod_bitmask;
|
||
|
int eff_num_stages, eff_num_stages2;
|
||
|
|
||
|
float eff_amp_velcurve[128];
|
||
|
};
|
||
|
|
||
|
struct sampler_layer_data
|
||
|
{
|
||
|
SAMPLER_FIXED_FIELDS(PROC_FIELDS_TO_STRUCT)
|
||
|
SAMPLER_FIXED_FIELDS(PROC_HAS_FIELD)
|
||
|
|
||
|
struct sampler_modulation *modulations;
|
||
|
struct sampler_noteinitfunc *voice_nifs, *prevoice_nifs;
|
||
|
struct sampler_flex_lfo *flex_lfos;
|
||
|
|
||
|
struct sampler_layer_computed computed;
|
||
|
};
|
||
|
|
||
|
struct sampler_layer
|
||
|
{
|
||
|
CBOX_OBJECT_HEADER()
|
||
|
struct cbox_command_target cmd_target;
|
||
|
|
||
|
struct sampler_layer_data data, *runtime;
|
||
|
|
||
|
struct sampler_module *module;
|
||
|
struct sampler_program *parent_program;
|
||
|
struct sampler_layer *parent, *default_child;
|
||
|
|
||
|
int current_seq_position;
|
||
|
|
||
|
GHashTable *unknown_keys;
|
||
|
GHashTable *child_layers;
|
||
|
};
|
||
|
|
||
|
extern struct sampler_layer *sampler_layer_new(struct sampler_module *m, struct sampler_program *parent_program, struct sampler_layer *parent_group);
|
||
|
extern struct sampler_layer *sampler_layer_new_from_section(struct sampler_module *m, struct sampler_program *parent_program, struct sampler_layer *parent_group, const char *cfg_section);
|
||
|
extern struct sampler_layer *sampler_layer_new_clone(struct sampler_layer *layer, struct sampler_module *m, struct sampler_program *parent_program, struct sampler_layer *parent_group);
|
||
|
extern void sampler_layer_set_modulation(struct sampler_layer *l, enum sampler_modsrc src, enum sampler_modsrc src2, enum sampler_moddest dest, float amount, int flags);
|
||
|
extern void sampler_layer_set_modulation1(struct sampler_layer *l, enum sampler_modsrc src, enum sampler_moddest dest, float amount, int flags);
|
||
|
extern void sampler_layer_add_nif(struct sampler_layer *l, SamplerNoteInitFunc notefunc_voice, SamplerNoteInitFunc2 notefunc_prevoice, int variant, float param);
|
||
|
extern void sampler_layer_load_overrides(struct sampler_layer *l, const char *cfg_section);
|
||
|
extern void sampler_layer_data_finalize(struct sampler_layer_data *l, struct sampler_layer_data *parent, struct sampler_program *p);
|
||
|
extern void sampler_layer_reset_switches(struct sampler_layer *l, struct sampler_module *m);
|
||
|
extern gboolean sampler_layer_apply_param(struct sampler_layer *l, const char *key, const char *value, GError **error);
|
||
|
extern gboolean sampler_layer_unapply_param(struct sampler_layer *l, const char *key, GError **error);
|
||
|
extern gchar *sampler_layer_to_string(struct sampler_layer *l, gboolean show_inherited);
|
||
|
extern void sampler_layer_dump(struct sampler_layer *l, FILE *f);
|
||
|
extern void sampler_layer_update(struct sampler_layer *l);
|
||
|
|
||
|
extern void sampler_layer_data_clone(struct sampler_layer_data *dst, const struct sampler_layer_data *src, gboolean copy_hasattr);
|
||
|
extern void sampler_layer_data_close(struct sampler_layer_data *l);
|
||
|
extern void sampler_layer_data_destroy(struct sampler_layer_data *l);
|
||
|
|
||
|
extern void sampler_nif_vel2pitch(struct sampler_noteinitfunc *nif, struct sampler_voice *v);
|
||
|
extern void sampler_nif_vel2offset(struct sampler_noteinitfunc *nif, struct sampler_voice *v);
|
||
|
extern void sampler_nif_vel2reloffset(struct sampler_noteinitfunc *nif, struct sampler_voice *v);
|
||
|
extern void sampler_nif_vel2env(struct sampler_noteinitfunc *nif, struct sampler_voice *v);
|
||
|
extern void sampler_nif_cc2offset(struct sampler_noteinitfunc *nif, struct sampler_voice *v);
|
||
|
extern void sampler_nif_cc2reloffset(struct sampler_noteinitfunc *nif, struct sampler_voice *v);
|
||
|
extern void sampler_nif_addrandom(struct sampler_noteinitfunc *nif, struct sampler_voice *v);
|
||
|
|
||
|
extern void sampler_nif_cc2delay(struct sampler_noteinitfunc *nif, struct sampler_prevoice *pv);
|
||
|
extern void sampler_nif_addrandomdelay(struct sampler_noteinitfunc *nif, struct sampler_prevoice *pv);
|
||
|
extern void sampler_nif_syncbeats(struct sampler_noteinitfunc *nif, struct sampler_prevoice *pv);
|
||
|
|
||
|
extern void sampler_midi_curve_init(struct sampler_midi_curve *curve);
|
||
|
extern void sampler_midi_curve_interpolate(const struct sampler_midi_curve *curve, float dest[128], float def_start, float def_end, gboolean is_quadratic);
|
||
|
|
||
|
#endif
|