2 Calf Box, an open source musical instrument.
3 Copyright (C) 2010-2013 Krzysztof Foltman
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "config-api.h"
26 #include "sampler_impl.h"
27 #include "sfzloader.h"
38 float sampler_sine_wave
[2049];
40 GQuark
cbox_sampler_error_quark()
42 return g_quark_from_string("cbox-sampler-error-quark");
45 static void sampler_process_block(struct cbox_module
*module
, cbox_sample_t
**inputs
, cbox_sample_t
**outputs
);
46 static void sampler_process_event(struct cbox_module
*module
, const uint8_t *data
, uint32_t len
);
47 static void sampler_destroyfunc(struct cbox_module
*module
);
49 void sampler_steal_voice(struct sampler_module
*m
)
52 struct sampler_voice
*voice_found
= NULL
;
53 for (int i
= 0; i
< 16; i
++)
55 FOREACH_VOICE(m
->channels
[i
].voices_running
, v
)
57 if (v
->amp_env
.cur_stage
== 15)
59 int age
= m
->serial_no
- v
->serial_no
;
60 if (v
->gen
.loop_start
== -1)
61 age
+= (int)((v
->gen
.bigpos
>> 32) * 100.0 / v
->gen
.cur_sample_end
);
74 voice_found
->released
= 1;
75 cbox_envelope_go_to(&voice_found
->amp_env
, 15);
79 static inline float clip01(float v
)
88 void sampler_process_block(struct cbox_module
*module
, cbox_sample_t
**inputs
, cbox_sample_t
**outputs
)
90 struct sampler_module
*m
= (struct sampler_module
*)module
;
92 //float channels[2][CBOX_BLOCK_SIZE];
94 for (int c
= 0; c
< m
->output_pairs
+ m
->aux_pairs
; c
++)
97 for (int i
= 0; i
< CBOX_BLOCK_SIZE
; i
++)
98 outputs
[oo
][i
] = outputs
[oo
+ 1][i
] = 0.f
;
101 int vcount
= 0, vrel
= 0;
102 for (int i
= 0; i
< 16; i
++)
105 FOREACH_VOICE(m
->channels
[i
].voices_running
, v
)
107 sampler_voice_process(v
, m
, outputs
);
109 if (v
->amp_env
.cur_stage
== 15)
113 m
->channels
[i
].active_voices
= cvcount
;
116 m
->active_voices
= vcount
;
117 if (vcount
- vrel
> m
->max_voices
)
118 sampler_steal_voice(m
);
120 m
->current_time
+= CBOX_BLOCK_SIZE
;
123 void sampler_channel_process_cc(struct sampler_channel
*c
, int cc
, int val
)
125 struct sampler_module
*m
= c
->module
;
126 // Handle CC triggering.
127 if (c
->program
&& c
->program
->rll
&& c
->program
->rll
->layers_oncc
&& m
->voices_free
)
129 struct sampler_rll
*rll
= c
->program
->rll
;
130 if (!(rll
->cc_trigger_bitmask
[cc
>> 5] & (1 << (cc
& 31))))
132 int old_value
= c
->cc
[cc
];
133 for (GSList
*p
= rll
->layers_oncc
; p
; p
= p
->next
)
135 struct sampler_layer
*layer
= p
->data
;
136 assert(layer
->runtime
);
137 // Only trigger on transition between 'out of range' and 'in range' values.
138 // XXXKF I'm not sure if it's what is expected here, but don't have
139 // the reference implementation handy.
140 if (layer
->runtime
->on_cc_number
== cc
&&
141 (val
>= layer
->runtime
->on_locc
&& val
<= layer
->runtime
->on_hicc
) &&
142 !(old_value
>= layer
->runtime
->on_locc
&& old_value
<= layer
->runtime
->on_hicc
))
144 struct sampler_voice
*v
= m
->voices_free
;
145 int exgroups
[MAX_RELEASED_GROUPS
], exgroupcount
= 0;
146 sampler_voice_start(v
, c
, layer
->runtime
, layer
->runtime
->pitch_keycenter
, 127, exgroups
, &exgroupcount
);
147 sampler_channel_release_groups(c
, -1, exgroups
, exgroupcount
);
151 int was_enabled
= c
->cc
[cc
] >= 64;
152 int enabled
= val
>= 64;
156 if (was_enabled
&& !enabled
)
158 sampler_channel_stop_sustained(c
);
162 if (was_enabled
&& !enabled
)
163 sampler_channel_stop_sostenuto(c
);
164 else if (!was_enabled
&& enabled
)
165 sampler_channel_capture_sostenuto(c
);
170 sampler_channel_stop_all(c
);
173 // Recommended Practice (RP-015) Response to Reset All Controllers
174 // http://www.midi.org/techspecs/rp15.php
175 sampler_channel_process_cc(c
, 64, 0);
176 sampler_channel_process_cc(c
, 66, 0);
180 c
->cc
[smsrc_chanaft
] = 0;
181 // XXXKF reset polyphonic pressure values when supported
188 void sampler_process_event(struct cbox_module
*module
, const uint8_t *data
, uint32_t len
)
190 struct sampler_module
*m
= (struct sampler_module
*)module
;
193 int cmd
= data
[0] >> 4;
194 int chn
= data
[0] & 15;
195 struct sampler_channel
*c
= &m
->channels
[chn
];
199 sampler_channel_stop_note(c
, data
[1], data
[2], FALSE
);
204 sampler_channel_start_note(c
, data
[1], data
[2], FALSE
);
206 sampler_channel_stop_note(c
, data
[1], data
[2], FALSE
);
210 // handle chokeable one shot layers
212 sampler_channel_stop_note(c
, data
[1], data
[2], TRUE
);
213 // polyphonic pressure not handled
217 sampler_channel_process_cc(c
, data
[1], data
[2]);
221 sampler_channel_program_change(c
, data
[1]);
225 c
->cc
[smsrc_chanaft
] = data
[1];
229 c
->pitchwheel
= data
[1] + 128 * data
[2] - 8192;
236 static int get_first_free_program_no(struct sampler_module
*m
)
241 // XXXKF this has a N-squared complexity - but I'm not seeing
242 // this being used with more than 10 programs at the same time
243 // in the near future
247 for (int i
= 0; i
< m
->program_count
; i
++)
249 if (m
->programs
[i
]->prog_no
== prog_no
)
260 static int find_program(struct sampler_module
*m
, int prog_no
)
262 for (int i
= 0; i
< m
->program_count
; i
++)
264 if (m
->programs
[i
]->prog_no
== prog_no
)
270 struct release_program_voices_data
272 struct sampler_module
*module
;
274 struct sampler_program
*old_pgm
, *new_pgm
;
275 uint16_t channels_to_wait_for
;
278 static int release_program_voices_execute(void *data
)
280 struct release_program_voices_data
*rpv
= data
;
281 struct sampler_module
*m
= rpv
->module
;
284 for (int i
= 0; i
< 16; i
++)
286 uint16_t mask
= 1 << i
;
287 struct sampler_channel
*c
= &m
->channels
[i
];
288 if (c
->program
== rpv
->old_pgm
|| c
->program
== NULL
)
290 sampler_channel_set_program_RT(c
, rpv
->new_pgm
);
291 rpv
->channels_to_wait_for
|= mask
;
293 if (rpv
->channels_to_wait_for
& mask
)
295 FOREACH_VOICE(c
->voices_running
, v
)
299 sampler_voice_inactivate(v
, TRUE
);
302 // This is a new voice, started after program change, so it
303 // should not be terminated and waited for.
304 if (v
->program
== rpv
->new_pgm
)
306 // The voice is still going, so repeat until it fades out
308 // If not in final fadeout stage, force final fadeout.
309 if (v
->amp_env
.cur_stage
!= 15)
312 cbox_envelope_go_to(&v
->amp_env
, 15);
321 static void swap_program(struct sampler_module
*m
, int index
, struct sampler_program
*pgm
, gboolean delete_old
)
323 static struct cbox_rt_cmd_definition release_program_voices
= { NULL
, release_program_voices_execute
, NULL
};
325 struct sampler_program
*old_program
= NULL
;
327 old_program
= cbox_rt_swap_pointers(m
->module
.rt
, (void **)&m
->programs
[index
], pgm
);
329 old_program
= cbox_rt_array_remove(m
->module
.rt
, (void ***)&m
->programs
, &m
->program_count
, index
);
331 struct release_program_voices_data data
= {m
, old_program
, pgm
, 0};
333 cbox_rt_execute_cmd_sync(m
->module
.rt
, &release_program_voices
, &data
);
335 if (delete_old
&& old_program
)
336 CBOX_DELETE(old_program
);
339 static void select_initial_program(struct sampler_module
*m
)
341 static struct cbox_rt_cmd_definition release_program_voices
= { NULL
, release_program_voices_execute
, NULL
};
342 struct release_program_voices_data data
= {m
, NULL
, m
->programs
[0], 0};
343 cbox_rt_execute_cmd_sync(m
->module
.rt
, &release_program_voices
, &data
);
346 static gboolean
load_program_at(struct sampler_module
*m
, const char *cfg_section
, const char *name
, int prog_no
, struct sampler_program
**ppgm
, GError
**error
)
348 struct sampler_program
*pgm
= NULL
;
349 int index
= find_program(m
, prog_no
);
350 pgm
= sampler_program_new_from_cfg(m
, cfg_section
, name
, prog_no
, error
);
356 swap_program(m
, index
, pgm
, TRUE
);
360 struct sampler_program
**programs
= malloc(sizeof(struct sampler_program
*) * (m
->program_count
+ 1));
361 memcpy(programs
, m
->programs
, sizeof(struct sampler_program
*) * m
->program_count
);
362 programs
[m
->program_count
] = pgm
;
365 free(cbox_rt_swap_pointers_and_update_count(m
->module
.rt
, (void **)&m
->programs
, programs
, &m
->program_count
, m
->program_count
+ 1));
366 if (m
->program_count
== 1)
367 select_initial_program(m
);
371 void sampler_unselect_program(struct sampler_module
*m
, struct sampler_program
*prg
)
373 // Ensure no new notes are played on that program
374 prg
->deleting
= TRUE
;
375 // Remove from the list of available programs, so that it cannot be selected again
376 for (int i
= 0; i
< m
->program_count
; i
++)
378 if (m
->programs
[i
] == prg
)
379 swap_program(m
, i
, NULL
, FALSE
);
383 static gboolean
load_from_string(struct sampler_module
*m
, const char *sample_dir
, const char *sfz_data
, const char *name
, int prog_no
, struct sampler_program
**ppgm
, GError
**error
)
385 int index
= find_program(m
, prog_no
);
386 struct sampler_program
*pgm
= sampler_program_new(m
, prog_no
, name
, sample_dir
);
387 pgm
->source_file
= g_strdup("string");
388 if (!sampler_module_load_program_sfz(m
, pgm
, sfz_data
, TRUE
, error
))
396 swap_program(m
, index
, pgm
, TRUE
);
402 struct sampler_program
**programs
= calloc((m
->program_count
+ 1), sizeof(struct sampler_program
*));
403 memcpy(programs
, m
->programs
, sizeof(struct sampler_program
*) * m
->program_count
);
404 programs
[m
->program_count
] = pgm
;
407 free(cbox_rt_swap_pointers_and_update_count(m
->module
.rt
, (void **)&m
->programs
, programs
, &m
->program_count
, m
->program_count
+ 1));
408 if (m
->program_count
== 1)
409 select_initial_program(m
);
413 gboolean
sampler_process_cmd(struct cbox_command_target
*ct
, struct cbox_command_target
*fb
, struct cbox_osc_command
*cmd
, GError
**error
)
415 struct sampler_module
*m
= (struct sampler_module
*)ct
->user_data
;
417 if (!strcmp(cmd
->command
, "/status") && !strcmp(cmd
->arg_types
, ""))
419 if (!cbox_check_fb_channel(fb
, cmd
->command
, error
))
421 for (int i
= 0; i
< 16; i
++)
423 struct sampler_channel
*channel
= &m
->channels
[i
];
425 if (channel
->program
)
426 result
= cbox_execute_on(fb
, NULL
, "/patch", "iis", error
, i
+ 1, channel
->program
->prog_no
, channel
->program
->name
);
428 result
= cbox_execute_on(fb
, NULL
, "/patch", "iis", error
, i
+ 1, -1, "");
431 if (!(cbox_execute_on(fb
, NULL
, "/channel_voices", "ii", error
, i
+ 1, channel
->active_voices
) &&
432 cbox_execute_on(fb
, NULL
, "/volume", "ii", error
, i
+ 1, sampler_channel_addcc(channel
, 7)) &&
433 cbox_execute_on(fb
, NULL
, "/pan", "ii", error
, i
+ 1, sampler_channel_addcc(channel
, 10))))
437 return cbox_execute_on(fb
, NULL
, "/active_voices", "i", error
, m
->active_voices
) &&
438 cbox_execute_on(fb
, NULL
, "/active_pipes", "i", error
, cbox_prefetch_stack_get_active_pipe_count(m
->pipe_stack
)) &&
439 cbox_execute_on(fb
, NULL
, "/polyphony", "i", error
, MAX_SAMPLER_VOICES
) &&
440 CBOX_OBJECT_DEFAULT_STATUS(&m
->module
, fb
, error
);
443 if (!strcmp(cmd
->command
, "/patches") && !strcmp(cmd
->arg_types
, ""))
445 if (!cbox_check_fb_channel(fb
, cmd
->command
, error
))
447 for (int i
= 0; i
< m
->program_count
; i
++)
449 struct sampler_program
*prog
= m
->programs
[i
];
450 if (!cbox_execute_on(fb
, NULL
, "/patch", "isoi", error
, prog
->prog_no
, prog
->name
, prog
, prog
->in_use
))
455 else if (!strcmp(cmd
->command
, "/polyphony") && !strcmp(cmd
->arg_types
, "i"))
457 int polyphony
= CBOX_ARG_I(cmd
, 0);
458 if (polyphony
< 1 || polyphony
> MAX_SAMPLER_VOICES
)
460 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Invalid polyphony %d (must be between 1 and %d)", polyphony
, (int)MAX_SAMPLER_VOICES
);
463 m
->max_voices
= polyphony
;
466 else if (!strcmp(cmd
->command
, "/set_patch") && !strcmp(cmd
->arg_types
, "ii"))
468 int channel
= CBOX_ARG_I(cmd
, 0);
469 if (channel
< 1 || channel
> 16)
471 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Invalid channel %d", channel
);
474 int value
= CBOX_ARG_I(cmd
, 1);
475 struct sampler_program
*pgm
= NULL
;
476 for (int i
= 0; i
< m
->program_count
; i
++)
478 if (m
->programs
[i
]->prog_no
== value
)
480 pgm
= m
->programs
[i
];
484 sampler_channel_set_program(&m
->channels
[channel
- 1], pgm
);
487 else if (!strcmp(cmd
->command
, "/load_patch") && !strcmp(cmd
->arg_types
, "iss"))
489 struct sampler_program
*pgm
= NULL
;
490 if (!load_program_at(m
, CBOX_ARG_S(cmd
, 1), CBOX_ARG_S(cmd
, 2), CBOX_ARG_I(cmd
, 0), &pgm
, error
))
493 return cbox_execute_on(fb
, NULL
, "/uuid", "o", error
, pgm
);
496 else if (!strcmp(cmd
->command
, "/load_patch_from_file") && !strcmp(cmd
->arg_types
, "iss"))
498 struct sampler_program
*pgm
= NULL
;
499 char *cfg_section
= g_strdup_printf("spgm:!%s", CBOX_ARG_S(cmd
, 1));
500 gboolean res
= load_program_at(m
, cfg_section
, CBOX_ARG_S(cmd
, 2), CBOX_ARG_I(cmd
, 0), &pgm
, error
);
502 if (res
&& pgm
&& fb
)
503 return cbox_execute_on(fb
, NULL
, "/uuid", "o", error
, pgm
);
506 else if (!strcmp(cmd
->command
, "/load_patch_from_string") && !strcmp(cmd
->arg_types
, "isss"))
508 struct sampler_program
*pgm
= NULL
;
509 if (!load_from_string(m
, CBOX_ARG_S(cmd
, 1), CBOX_ARG_S(cmd
, 2), CBOX_ARG_S(cmd
, 3), CBOX_ARG_I(cmd
, 0), &pgm
, error
))
512 return cbox_execute_on(fb
, NULL
, "/uuid", "o", error
, pgm
);
515 else if (!strcmp(cmd
->command
, "/get_unused_program") && !strcmp(cmd
->arg_types
, ""))
517 if (!cbox_check_fb_channel(fb
, cmd
->command
, error
))
519 return cbox_execute_on(fb
, NULL
, "/program_no", "i", error
, get_first_free_program_no(m
));
522 return cbox_object_default_process_cmd(ct
, fb
, cmd
, error
);
526 gboolean
sampler_select_program(struct sampler_module
*m
, int channel
, const gchar
*preset
, GError
**error
)
528 for (int i
= 0; i
< m
->program_count
; i
++)
530 if (!strcmp(m
->programs
[i
]->name
, preset
))
532 sampler_channel_set_program(&m
->channels
[channel
], m
->programs
[i
]);
536 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Preset not found: %s", preset
);
540 MODULE_CREATE_FUNCTION(sampler
)
543 static int inited
= 0;
546 for (int i
= 0; i
< 2049; i
++)
547 sampler_sine_wave
[i
] = sin(i
* M_PI
/ 1024.0);
551 int max_voices
= cbox_config_get_int(cfg_section
, "polyphony", MAX_SAMPLER_VOICES
);
552 if (max_voices
< 1 || max_voices
> MAX_SAMPLER_VOICES
)
554 g_set_error(error
, CBOX_SAMPLER_ERROR
, CBOX_SAMPLER_ERROR_INVALID_LAYER
, "%s: invalid polyphony value", cfg_section
);
557 int output_pairs
= cbox_config_get_int(cfg_section
, "output_pairs", 1);
558 if (output_pairs
< 1 || output_pairs
> 16)
560 g_set_error(error
, CBOX_SAMPLER_ERROR
, CBOX_SAMPLER_ERROR_INVALID_LAYER
, "%s: invalid output pairs value", cfg_section
);
563 int aux_pairs
= cbox_config_get_int(cfg_section
, "aux_pairs", 0);
564 if (aux_pairs
< 0 || aux_pairs
> 4)
566 g_set_error(error
, CBOX_SAMPLER_ERROR
, CBOX_SAMPLER_ERROR_INVALID_LAYER
, "%s: invalid aux pairs value", cfg_section
);
570 struct sampler_module
*m
= calloc(1, sizeof(struct sampler_module
));
571 CALL_MODULE_INIT(m
, 0, (output_pairs
+ aux_pairs
) * 2, sampler
);
572 m
->output_pairs
= output_pairs
;
573 m
->aux_pairs
= aux_pairs
;
574 m
->module
.aux_offset
= m
->output_pairs
* 2;
575 m
->module
.process_event
= sampler_process_event
;
576 m
->module
.process_block
= sampler_process_block
;
578 m
->max_voices
= max_voices
;
581 // XXXKF read defaults from some better place, like config
582 // XXXKF allow dynamic change of the number of the pipes
583 m
->pipe_stack
= cbox_prefetch_stack_new(MAX_SAMPLER_VOICES
, cbox_config_get_int("streaming", "streambuf_size", 65536));
585 float srate
= m
->module
.srate
;
586 for (i
= 0; i
< 12800; i
++)
588 float freq
= 440 * pow(2, (i
- 5700) / 1200.0);
591 if (freq
> srate
* 0.45)
593 float omega
=(float)(2*M_PI
*freq
/srate
);
594 m
->sincos
[i
].sine
= sinf(omega
);
595 m
->sincos
[i
].cosine
= cosf(omega
);
596 m
->sincos
[i
].prewarp
= 2.0 * tan(hz2w(freq
, srate
) * 0.5f
);
601 gchar
*s
= g_strdup_printf("program%d", i
);
602 char *p
= cbox_config_get_string(cfg_section
, s
);
607 m
->program_count
= i
;
611 m
->programs
= calloc(m
->program_count
, sizeof(struct sampler_program
*));
613 for (i
= 0; i
< m
->program_count
; i
++)
615 gchar
*s
= g_strdup_printf("program%d", i
);
616 char *pgm_section
= NULL
;
618 const char *pgm_name
= cbox_config_get_string(cfg_section
, s
);
620 char *at
= strchr(pgm_name
, '@');
623 pgm_id
= atoi(at
+ 1);
624 s
= g_strndup(pgm_name
, at
- pgm_name
);
625 pgm_section
= g_strdup_printf("spgm:%s", s
);
631 pgm_section
= g_strdup_printf("spgm:%s", pgm_name
);
634 m
->programs
[i
] = sampler_program_new_from_cfg(m
, pgm_section
, pgm_section
+ 5, pgm_id
, error
);
644 // XXXKF free programs/layers, first ensuring that they're fully initialised
648 m
->voices_free
= NULL
;
649 memset(m
->voices_all
, 0, sizeof(m
->voices_all
));
650 for (i
= 0; i
< MAX_SAMPLER_VOICES
; i
++)
652 struct sampler_voice
*v
= &m
->voices_all
[i
];
653 v
->gen
.mode
= spt_inactive
;
654 sampler_voice_link(&m
->voices_free
, v
);
656 m
->active_voices
= 0;
658 for (i
= 0; i
< 16; i
++)
659 sampler_channel_init(&m
->channels
[i
], m
);
661 for (i
= 0; i
< 16; i
++)
663 gchar
*key
= g_strdup_printf("channel%d", i
+ 1);
664 gchar
*preset
= cbox_config_get_string(cfg_section
, key
);
667 if (!sampler_select_program(m
, i
, preset
, error
))
669 CBOX_DELETE(&m
->module
);
680 void sampler_destroyfunc(struct cbox_module
*module
)
682 struct sampler_module
*m
= (struct sampler_module
*)module
;
686 for (i
= 0; i
< m
->program_count
;)
689 CBOX_DELETE(m
->programs
[i
]);
693 for (i
= 0; i
< 16; i
++)
695 assert (m
->channels
[i
].voices_running
== NULL
);
697 cbox_prefetch_stack_destroy(m
->pipe_stack
);
701 #define MAKE_TO_STRING_CONTENT(name, v) \
704 #define MAKE_FROM_STRING_CONTENT(n, v) \
705 if (!strcmp(name, n)) { *value = v; return TRUE; }
707 #define MAKE_FROM_TO_STRING(enumtype) \
708 const char *enumtype##_to_string(enum enumtype value) \
711 ENUM_VALUES_##enumtype(MAKE_TO_STRING_CONTENT) \
712 default: return NULL; \
716 gboolean enumtype##_from_string(const char *name, enum enumtype *value) \
718 ENUM_VALUES_##enumtype(MAKE_FROM_STRING_CONTENT) \
722 ENUM_LIST(MAKE_FROM_TO_STRING
)
724 //////////////////////////////////////////////////////////////////////////
725 // Note initialisation functions
727 void sampler_nif_vel2pitch(struct sampler_noteinitfunc
*nif
, struct sampler_voice
*v
)
729 v
->pitch_shift
+= nif
->param
* v
->vel
* (1.0 / 127.0);
732 void sampler_nif_cc2delay(struct sampler_noteinitfunc
*nif
, struct sampler_voice
*v
)
734 v
->delay
+= nif
->param
* v
->channel
->cc
[nif
->variant
] * (1.0 / 127.0) * v
->channel
->module
->module
.srate
;
737 void sampler_nif_addrandom(struct sampler_noteinitfunc
*nif
, struct sampler_voice
*v
)
739 float rnd
= rand() * 1.0 / RAND_MAX
;
743 v
->gain_shift
+= rnd
* nif
->param
;
746 v
->cutoff_shift
+= rnd
* nif
->param
;
749 v
->pitch_shift
+= rnd
* nif
->param
; // this is in cents
754 void sampler_nif_vel2env(struct sampler_noteinitfunc
*nif
, struct sampler_voice
*v
)
756 int env_type
= (nif
->variant
) >> 4;
757 struct cbox_envelope
*env
= NULL
;
764 env
= &v
->filter_env
;
772 if (env
->shape
!= &v
->dyn_envs
[env_type
])
774 memcpy(&v
->dyn_envs
[env_type
], env
->shape
, sizeof(struct cbox_envelope_shape
));
775 env
->shape
= &v
->dyn_envs
[env_type
];
777 float param
= nif
->param
* v
->vel
* (1.0 / 127.0);
778 if ((nif
->variant
& 15) == 4)
780 cbox_envelope_modify_dahdsr(env
->shape
, nif
->variant
& 15, param
, v
->channel
->module
->module
.srate
* (1.0 / CBOX_BLOCK_SIZE
));
783 //////////////////////////////////////////////////////////////////////////
785 struct cbox_module_livecontroller_metadata sampler_controllers
[] = {
788 struct cbox_module_keyrange_metadata sampler_keyranges
[] = {
791 DEFINE_MODULE(sampler
, 0, 2)