fix bw_{note_queue,voice_alloc}, synth_poly begins to work
This commit is contained in:
parent
b2169b6792
commit
6cecf0d654
1
TODO
1
TODO
@ -49,6 +49,7 @@ code:
|
|||||||
* revise typedef style (see https://stackoverflow.com/questions/54752861/using-an-anonymous-struct-vs-a-named-struct-with-typedef)
|
* revise typedef style (see https://stackoverflow.com/questions/54752861/using-an-anonymous-struct-vs-a-named-struct-with-typedef)
|
||||||
* sr-dependent vs cr-dependent coeffs? see synth poly example
|
* sr-dependent vs cr-dependent coeffs? see synth poly example
|
||||||
* bw_buf_copy (to be used in bw_slew_lim)?
|
* bw_buf_copy (to be used in bw_slew_lim)?
|
||||||
|
* C++ compound literals...
|
||||||
|
|
||||||
build system:
|
build system:
|
||||||
* make makefiles handle paths with spaces etc
|
* make makefiles handle paths with spaces etc
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
|
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
|
||||||
|
|
||||||
TARGET = bw_example_synth_mono
|
TARGET = bw_example_synth_poly
|
||||||
|
|
||||||
C_SOURCES += ${ROOT_DIR}/../src/bw_example_synth_mono.c
|
C_SOURCES += ${ROOT_DIR}/../src/bw_example_synth_poly.c
|
||||||
|
|
||||||
SYNTH := yes
|
SYNTH := yes
|
||||||
|
|
||||||
|
@ -90,33 +90,28 @@ void bw_example_synth_poly_set_sample_rate(bw_example_synth_poly *instance, floa
|
|||||||
bw_phase_gen_set_sample_rate(&instance->voices[i].vco2_phase_gen_coeffs, sample_rate);
|
bw_phase_gen_set_sample_rate(&instance->voices[i].vco2_phase_gen_coeffs, sample_rate);
|
||||||
bw_phase_gen_set_sample_rate(&instance->voices[i].vco3_phase_gen_coeffs, sample_rate);
|
bw_phase_gen_set_sample_rate(&instance->voices[i].vco3_phase_gen_coeffs, sample_rate);
|
||||||
bw_svf_set_sample_rate(&instance->voices[i].vcf_coeffs, sample_rate);
|
bw_svf_set_sample_rate(&instance->voices[i].vcf_coeffs, sample_rate);
|
||||||
voices[i].gate = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void bw_example_synth_poly_reset(bw_example_synth_poly *instance) {
|
void bw_example_synth_poly_reset(bw_example_synth_poly *instance) {
|
||||||
const float v = instance->params[p_vcf_cutoff];
|
const float v = instance->params[p_vcf_cutoff];
|
||||||
const float cutoff = 20.f + (20e3f - 20.f) * v * v * v;
|
const float cutoff = 20.f + (20e3f - 20.f) * v * v * v;
|
||||||
bw_svf_set_cutoff(&instance->vcf_coeffs, bw_clipf(cutoff, 20.f, 20e3f));
|
for (int i = 0; i < N_VOICES; i++)
|
||||||
|
bw_svf_set_cutoff(&instance->voices[i].vcf_coeffs, bw_clipf(cutoff, 20.f, 20e3f));
|
||||||
|
|
||||||
bw_note_queue_reset(&instance->note_queue);
|
bw_note_queue_reset(&instance->note_queue);
|
||||||
bw_osc_pulse_reset_coeffs(&instance->vco1_pulse_coeffs);
|
bw_osc_pulse_reset_coeffs(&instance->vco1_pulse_coeffs);
|
||||||
bw_osc_tri_reset_coeffs(&instance->vco1_tri_coeffs);
|
bw_osc_tri_reset_coeffs(&instance->vco1_tri_coeffs);
|
||||||
bw_gain_reset_coeffs(&instance->vco1_gain_coeffs);
|
bw_gain_reset_coeffs(&instance->vco1_gain_coeffs);
|
||||||
bw_phase_gen_reset_coeffs(&instance->vco2_phase_gen_coeffs);
|
|
||||||
bw_osc_pulse_reset_coeffs(&instance->vco2_pulse_coeffs);
|
bw_osc_pulse_reset_coeffs(&instance->vco2_pulse_coeffs);
|
||||||
bw_osc_tri_reset_coeffs(&instance->vco2_tri_coeffs);
|
bw_osc_tri_reset_coeffs(&instance->vco2_tri_coeffs);
|
||||||
bw_gain_reset_coeffs(&instance->vco2_gain_coeffs);
|
bw_gain_reset_coeffs(&instance->vco2_gain_coeffs);
|
||||||
bw_phase_gen_reset_coeffs(&instance->vco3_phase_gen_coeffs);
|
|
||||||
bw_osc_pulse_reset_coeffs(&instance->vco3_pulse_coeffs);
|
bw_osc_pulse_reset_coeffs(&instance->vco3_pulse_coeffs);
|
||||||
bw_osc_tri_reset_coeffs(&instance->vco3_tri_coeffs);
|
bw_osc_tri_reset_coeffs(&instance->vco3_tri_coeffs);
|
||||||
bw_gain_reset_coeffs(&instance->vco3_gain_coeffs);
|
bw_gain_reset_coeffs(&instance->vco3_gain_coeffs);
|
||||||
bw_gain_reset_coeffs(&instance->noise_gain_coeffs);
|
bw_gain_reset_coeffs(&instance->noise_gain_coeffs);
|
||||||
bw_env_gen_reset_coeffs(&instance->vcf_env_gen_coeffs);
|
bw_env_gen_reset_coeffs(&instance->vcf_env_gen_coeffs);
|
||||||
bw_env_gen_reset_state(&instance->vcf_env_gen_coeffs, &instance->vcf_env_gen_state);
|
|
||||||
bw_svf_reset_coeffs(&instance->vcf_coeffs);
|
|
||||||
bw_env_gen_reset_coeffs(&instance->vca_env_gen_coeffs);
|
bw_env_gen_reset_coeffs(&instance->vca_env_gen_coeffs);
|
||||||
bw_env_gen_reset_state(&instance->vca_env_gen_coeffs, &instance->vca_env_gen_state);
|
|
||||||
bw_phase_gen_reset_coeffs(&instance->a440_phase_gen_coeffs);
|
bw_phase_gen_reset_coeffs(&instance->a440_phase_gen_coeffs);
|
||||||
bw_phase_gen_reset_state(&instance->a440_phase_gen_coeffs, &instance->a440_phase_gen_state, 0.f);
|
bw_phase_gen_reset_state(&instance->a440_phase_gen_coeffs, &instance->a440_phase_gen_state, 0.f);
|
||||||
bw_gain_reset_coeffs(&instance->gain_coeffs);
|
bw_gain_reset_coeffs(&instance->gain_coeffs);
|
||||||
@ -124,12 +119,20 @@ void bw_example_synth_poly_reset(bw_example_synth_poly *instance) {
|
|||||||
bw_ppm_reset_state(&instance->ppm_coeffs, &instance->ppm_state);
|
bw_ppm_reset_state(&instance->ppm_coeffs, &instance->ppm_state);
|
||||||
|
|
||||||
for (int i = 0; i < N_VOICES; i++) {
|
for (int i = 0; i < N_VOICES; i++) {
|
||||||
bw_phase_gen_reset_state(&instance->vco1_phase_gen_coeffs, &instance->voices[i].vco1_phase_gen_state, 0.f);
|
bw_phase_gen_reset_coeffs(&instance->voices[i].vco2_phase_gen_coeffs);
|
||||||
bw_phase_gen_reset_state(&instance->vco2_phase_gen_coeffs, &instance->voices[i].vco2_phase_gen_state, 0.f);
|
bw_phase_gen_reset_coeffs(&instance->voices[i].vco3_phase_gen_coeffs);
|
||||||
bw_phase_gen_reset_state(&instance->vco3_phase_gen_coeffs, &instance->voices[i].vco3_phase_gen_state, 0.f);
|
bw_svf_reset_coeffs(&instance->voices[i].vcf_coeffs);
|
||||||
|
|
||||||
|
bw_phase_gen_reset_state(&instance->voices[i].vco1_phase_gen_coeffs, &instance->voices[i].vco1_phase_gen_state, 0.f);
|
||||||
|
bw_phase_gen_reset_state(&instance->voices[i].vco2_phase_gen_coeffs, &instance->voices[i].vco2_phase_gen_state, 0.f);
|
||||||
|
bw_phase_gen_reset_state(&instance->voices[i].vco3_phase_gen_coeffs, &instance->voices[i].vco3_phase_gen_state, 0.f);
|
||||||
bw_osc_filt_reset_state(&instance->voices[i].osc_filt_state);
|
bw_osc_filt_reset_state(&instance->voices[i].osc_filt_state);
|
||||||
bw_pink_filt_reset_state(&instance->pink_filt_coeffs, &instance->voices[i].pink_filt_state);
|
bw_pink_filt_reset_state(&instance->pink_filt_coeffs, &instance->voices[i].pink_filt_state);
|
||||||
bw_svf_reset_state(&instance->vcf_coeffs, &instance->voices[i].vcf_state, 0.f);
|
bw_svf_reset_state(&instance->voices[i].vcf_coeffs, &instance->voices[i].vcf_state, 0.f);
|
||||||
|
bw_env_gen_reset_state(&instance->vcf_env_gen_coeffs, &instance->voices[i].vcf_env_gen_state);
|
||||||
|
bw_env_gen_reset_state(&instance->vca_env_gen_coeffs, &instance->voices[i].vca_env_gen_state);
|
||||||
|
|
||||||
|
instance->voices[i].gate = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
instance->pitch_bend = 0.f;
|
instance->pitch_bend = 0.f;
|
||||||
@ -137,12 +140,14 @@ void bw_example_synth_poly_reset(bw_example_synth_poly *instance) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void note_on(void *BW_RESTRICT voice, unsigned char note, float velocity) {
|
static void note_on(void *BW_RESTRICT voice, unsigned char note, float velocity) {
|
||||||
|
(void)velocity;
|
||||||
bw_example_synth_poly_voice *v = (bw_example_synth_poly_voice *)voice;
|
bw_example_synth_poly_voice *v = (bw_example_synth_poly_voice *)voice;
|
||||||
v->note = note;
|
v->note = note;
|
||||||
v->gate = 1;
|
v->gate = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void note_off(void *BW_RESTRICT voice, float velocity) {
|
static void note_off(void *BW_RESTRICT voice, float velocity) {
|
||||||
|
(void)velocity;
|
||||||
bw_example_synth_poly_voice *v = (bw_example_synth_poly_voice *)voice;
|
bw_example_synth_poly_voice *v = (bw_example_synth_poly_voice *)voice;
|
||||||
v->gate = 0;
|
v->gate = 0;
|
||||||
}
|
}
|
||||||
@ -158,58 +163,87 @@ static char is_free(void *BW_RESTRICT voice) {
|
|||||||
return !v->gate && phase == bw_env_gen_phase_off;
|
return !v->gate && phase == bw_env_gen_phase_off;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void bw_example_synth_poly_process(bw_example_synth_poly *instance, const float** x, float** y, int n_samples) {
|
void bw_example_synth_poly_process(bw_example_synth_poly *instance, const float** x, float** y, int n_samples) {
|
||||||
// FIXME: control-rate modulations are asynchronous here...
|
// FIXME: control-rate modulations are asynchronous here...
|
||||||
// it's all good as long as hosts gives us buffers whose length is a multiple of 32,
|
// it's all good as long as hosts gives us buffers whose length is a multiple of 32,
|
||||||
// otherwise it's probably still ok but a bit "swingy"
|
// otherwise it's probably still ok but a bit "swingy"
|
||||||
|
|
||||||
(void)x;
|
(void)x;
|
||||||
|
|
||||||
static bw_voice_alloc_opts alloc_opts = { bw_voice_alloc_mode_low, note_on, note_off, get_note, is_free };
|
static bw_voice_alloc_opts alloc_opts = { bw_voice_alloc_mode_low, note_on, note_off, get_note, is_free };
|
||||||
bw_voice_alloc(&alloc_opts, &instance->note_queue, &instance->voices, N_VOICES);
|
void *voices[N_VOICES];
|
||||||
|
for (int i = 0; i < N_VOICES; i++)
|
||||||
|
voices[i] = (void *)(instance->voices + i);
|
||||||
|
bw_voice_alloc(&alloc_opts, &instance->note_queue, voices, N_VOICES);
|
||||||
bw_note_queue_clear(&instance->note_queue);
|
bw_note_queue_clear(&instance->note_queue);
|
||||||
|
|
||||||
const float f1 =
|
const float df1 =
|
||||||
6.f * instance->params[p_vco1_coarse] - 3.f
|
6.f * instance->params[p_vco1_coarse] - 3.f
|
||||||
+ 2.f * instance->pitch_bend - 1.f
|
+ 2.f * instance->pitch_bend - 1.f
|
||||||
+ 8.333333333333333e-2f * (2.f * (instance->params[p_master_tune] + instance->params[p_vco1_fine]) - 71.f);
|
+ 8.333333333333333e-2f * (2.f * (instance->params[p_master_tune] + instance->params[p_vco1_fine]) - 71.f);
|
||||||
const float f2 =
|
const float df2 =
|
||||||
6.f * instance->params[p_vco2_coarse] - 3.f
|
6.f * instance->params[p_vco2_coarse] - 3.f
|
||||||
+ 2.f * instance->pitch_bend - 1.f
|
+ 2.f * instance->pitch_bend - 1.f
|
||||||
+ 8.333333333333333e-2f * (2.f * (instance->params[p_master_tune] + instance->params[p_vco2_fine]) - 71.f);
|
+ 8.333333333333333e-2f * (2.f * (instance->params[p_master_tune] + instance->params[p_vco2_fine]) - 71.f);
|
||||||
const float f3 =
|
const float df3 =
|
||||||
6.f * instance->params[p_vco3_coarse] - 3.f
|
6.f * instance->params[p_vco3_coarse] - 3.f
|
||||||
+ 2.f * instance->pitch_bend - 1.f
|
+ 2.f * instance->pitch_bend - 1.f
|
||||||
+ 8.333333333333333e-2f * (2.f * (instance->params[p_master_tune] + instance->params[p_vco3_fine]) - 71.f);
|
+ 8.333333333333333e-2f * (2.f * (instance->params[p_master_tune] + instance->params[p_vco3_fine]) - 71.f);
|
||||||
for (int i = 0; i < N_VOICES; i++) {
|
for (int i = 0; i < N_VOICES; i++) {
|
||||||
int n = instance->params[p_vco3_kbd] >= 0.5f ? instance->voices[i].note : 0;
|
int n3 = instance->params[p_vco3_kbd] >= 0.5f ? instance->voices[i].note : 0;
|
||||||
bw_phase_gen_set_frequency(&instance->voices[i].vco1_phase_gen_coeffs, 440.f * bw_pow2f_3(f1 + 8.333333333333333e-2f * instance->voices[i].note));
|
bw_phase_gen_set_frequency(&instance->voices[i].vco1_phase_gen_coeffs, 440.f * bw_pow2f_3(df1 + 8.333333333333333e-2f * instance->voices[i].note));
|
||||||
bw_phase_gen_set_frequency(&instance->voices[i].vco2_phase_gen_coeffs, 440.f * bw_pow2f_3(f2 + 8.333333333333333e-2f * instance->voices[i].note));
|
bw_phase_gen_set_frequency(&instance->voices[i].vco2_phase_gen_coeffs, 440.f * bw_pow2f_3(df2 + 8.333333333333333e-2f * instance->voices[i].note));
|
||||||
bw_phase_gen_set_frequency(&instance->voices[i].vco3_phase_gen_coeffs, 440.f * bw_pow2f_3(f3 + 8.333333333333333e-2f * n));
|
bw_phase_gen_set_frequency(&instance->voices[i].vco3_phase_gen_coeffs, 440.f * bw_pow2f_3(df3 + 8.333333333333333e-2f * n3));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float *b0[N_VOICES], *b1[N_VOICES], *b2[N_VOICES], *b3[N_VOICES];
|
||||||
for (int j = 0; j < N_VOICES; j++) {
|
for (int j = 0; j < N_VOICES; j++) {
|
||||||
bw_phase_gen_update_coeffs_ctrl(&instance->voices[i].vco1_phase_gen_coeffs);
|
b0[j] = instance->voices[j].buf[0];
|
||||||
bw_phase_gen_update_coeffs_ctrl(&instance->voices[i].vco2_phase_gen_coeffs);
|
b1[j] = instance->voices[j].buf[1];
|
||||||
bw_phase_gen_update_coeffs_ctrl(&instance->voices[i].vco3_phase_gen_coeffs);
|
b2[j] = instance->voices[j].buf[2];
|
||||||
|
b3[j] = instance->voices[j].buf[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < n_samples; i++) {
|
for (int i = 0; i < n_samples; i += BUFFER_SIZE) {
|
||||||
for (int j = 0; j < N_VOICES; j++) {
|
float *out = y[0] + i;
|
||||||
bw_phase_gen_update_coeffs_audio(&instance->voices[i].vco1_phase_gen_coeffs);
|
int n = bw_minf(n_samples - i, BUFFER_SIZE);
|
||||||
bw_phase_gen_update_coeffs_audio(&instance->voices[i].vco2_phase_gen_coeffs);
|
|
||||||
bw_phase_gen_update_coeffs_audio(&instance->voices[i].vco3_phase_gen_coeffs);
|
for (int j = 0; j < N_VOICES; j++)
|
||||||
|
bw_phase_gen_process(&instance->voices[j].vco3_phase_gen_coeffs, &instance->voices[j].vco3_phase_gen_state, NULL, b0[j], b1[j], n);
|
||||||
|
if (instance->params[p_vco3_waveform] >= (1.f / 4.f + 1.f / 2.f)) {
|
||||||
|
bw_osc_tri_process_multi(&instance->vco3_tri_coeffs, (const float **)b0, (const float **)b1, b0, N_VOICES, n);
|
||||||
|
bw_osc_pulse_reset_coeffs(&instance->vco3_pulse_coeffs);
|
||||||
|
} else if (instance->params[p_vco3_waveform] >= (1.f / 4.f)) {
|
||||||
|
bw_osc_pulse_process_multi(&instance->vco3_pulse_coeffs, (const float **)b0, (const float **)b1, b0, N_VOICES, n);
|
||||||
|
bw_osc_tri_reset_coeffs(&instance->vco3_tri_coeffs);
|
||||||
|
} else {
|
||||||
|
for (int j = 0; j < N_VOICES; j++)
|
||||||
|
bw_osc_saw_process(&instance->vco_saw_coeffs, b0[j], b1[j], b0[j], n);
|
||||||
|
bw_osc_pulse_reset_coeffs(&instance->vco3_pulse_coeffs);
|
||||||
|
bw_osc_tri_reset_coeffs(&instance->vco3_tri_coeffs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//...
|
||||||
|
|
||||||
|
bw_buf_fill(out, 0.f, n);
|
||||||
for (int j = 0; j < N_VOICES; j++) {
|
for (int j = 0; j < N_VOICES; j++) {
|
||||||
float p1, p1inc;
|
bw_example_synth_poly_voice *v = instance->voices + j;
|
||||||
bw_phase_gen_process1(&instance->voices[i].vco1_phase_gen_coeffs, &instance->voices[i].vco1_phase_gen_state, &p1, &p1inc;
|
if (v->gate)
|
||||||
|
bw_buf_mix(out, out, b0[j], n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bw_phase_gen_process(&instance->a440_phase_gen_coeffs, &instance->a440_phase_gen_state, NULL, instance->buf, NULL, n);
|
||||||
|
bw_osc_sin_process(instance->buf, instance->buf, n);
|
||||||
|
if (instance->params[p_a440] >= 0.5f)
|
||||||
|
bw_buf_mix(out, out, instance->buf, n);
|
||||||
|
|
||||||
|
bw_gain_process(&instance->gain_coeffs, out, out, n);
|
||||||
|
bw_ppm_process(&instance->ppm_coeffs, &instance->ppm_state, out, NULL, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
//...
|
//...
|
||||||
|
|
||||||
|
/*
|
||||||
for (int i = 0; i < n_samples; i += BUFFER_SIZE) {
|
for (int i = 0; i < n_samples; i += BUFFER_SIZE) {
|
||||||
float *out = y[0] + i;
|
float *out = y[0] + i;
|
||||||
int n = bw_minf(n_samples - i, BUFFER_SIZE);
|
int n = bw_minf(n_samples - i, BUFFER_SIZE);
|
||||||
@ -305,6 +339,7 @@ void bw_example_synth_poly_process(bw_example_synth_poly *instance, const float*
|
|||||||
bw_gain_process(&instance->gain_coeffs, out, out, n);
|
bw_gain_process(&instance->gain_coeffs, out, out, n);
|
||||||
bw_ppm_process(&instance->ppm_coeffs, &instance->ppm_state, out, NULL, n);
|
bw_ppm_process(&instance->ppm_coeffs, &instance->ppm_state, out, NULL, n);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void bw_example_synth_poly_set_parameter(bw_example_synth_poly *instance, int index, float value) {
|
void bw_example_synth_poly_set_parameter(bw_example_synth_poly *instance, int index, float value) {
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <bw_note_queue.h>
|
||||||
#include <bw_phase_gen.h>
|
#include <bw_phase_gen.h>
|
||||||
#include <bw_osc_saw.h>
|
#include <bw_osc_saw.h>
|
||||||
#include <bw_osc_pulse.h>
|
#include <bw_osc_pulse.h>
|
||||||
@ -100,6 +101,8 @@ struct _bw_example_synth_poly_voice {
|
|||||||
|
|
||||||
unsigned char note;
|
unsigned char note;
|
||||||
char gate;
|
char gate;
|
||||||
|
|
||||||
|
float buf[4][BUFFER_SIZE];
|
||||||
};
|
};
|
||||||
typedef struct _bw_example_synth_poly_voice bw_example_synth_poly_voice;
|
typedef struct _bw_example_synth_poly_voice bw_example_synth_poly_voice;
|
||||||
|
|
||||||
@ -127,7 +130,7 @@ struct _bw_example_synth_poly {
|
|||||||
bw_ppm_coeffs ppm_coeffs;
|
bw_ppm_coeffs ppm_coeffs;
|
||||||
bw_ppm_state ppm_state;
|
bw_ppm_state ppm_state;
|
||||||
|
|
||||||
bw_example_poly_synth_voice voices[N_VOICES];
|
bw_example_synth_poly_voice voices[N_VOICES];
|
||||||
|
|
||||||
// Parameters
|
// Parameters
|
||||||
float params[p_n];
|
float params[p_n];
|
||||||
@ -138,7 +141,7 @@ struct _bw_example_synth_poly {
|
|||||||
float mod_wheel;
|
float mod_wheel;
|
||||||
|
|
||||||
// Buffers
|
// Buffers
|
||||||
float buf[4][BUFFER_SIZE];
|
float buf[BUFFER_SIZE];
|
||||||
};
|
};
|
||||||
typedef struct _bw_example_synth_poly bw_example_synth_poly;
|
typedef struct _bw_example_synth_poly bw_example_synth_poly;
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
|
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
|
||||||
|
|
||||||
NAME := bw_example_synth_mono
|
NAME := bw_example_synth_poly
|
||||||
SOURCES = ${SOURCES_COMMON} ${ROOT_DIR}/../src/bw_example_synth_mono.c
|
SOURCES = ${SOURCES_COMMON} ${ROOT_DIR}/../src/bw_example_synth_poly.c
|
||||||
|
|
||||||
include ${ROOT_DIR}/../../common/vst3/vst3.mk
|
include ${ROOT_DIR}/../../common/vst3/vst3.mk
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Brickworks
|
* Brickworks
|
||||||
*
|
*
|
||||||
* Copyright (C) 2022 Orastron Srl unipersonale
|
* Copyright (C) 2023 Orastron Srl unipersonale
|
||||||
*
|
*
|
||||||
* Brickworks is free software: you can redistribute it and/or modify
|
* Brickworks is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -23,14 +23,14 @@
|
|||||||
|
|
||||||
#define PLUGIN_SUBCATEGORY "Instrument|Synth"
|
#define PLUGIN_SUBCATEGORY "Instrument|Synth"
|
||||||
|
|
||||||
#define PLUGIN_GUID_1 0x5af9b172
|
#define PLUGIN_GUID_1 0x14f4e502
|
||||||
#define PLUGIN_GUID_2 0x95ef439c
|
#define PLUGIN_GUID_2 0xf2314c26
|
||||||
#define PLUGIN_GUID_3 0xb10ed6f0
|
#define PLUGIN_GUID_3 0xa89226a1
|
||||||
#define PLUGIN_GUID_4 0xb962eef1
|
#define PLUGIN_GUID_4 0xd539f201
|
||||||
|
|
||||||
#define CTRL_GUID_1 0xed4990b0
|
#define CTRL_GUID_1 0xd7917a95
|
||||||
#define CTRL_GUID_2 0x89894215
|
#define CTRL_GUID_2 0xb3e14394
|
||||||
#define CTRL_GUID_3 0x96fc7cda
|
#define CTRL_GUID_3 0xa6c5bcb7
|
||||||
#define CTRL_GUID_4 0x5a56cec9
|
#define CTRL_GUID_4 0x852d78bb
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
|
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
|
||||||
SOURCES = ${SOURCES_COMMON} ${ROOT_DIR}/../src/bw_example_synth_mono.c
|
SOURCES = ${SOURCES_COMMON} ${ROOT_DIR}/../src/bw_example_synth_poly.c
|
||||||
SYNTH := yes
|
SYNTH := yes
|
||||||
NEEDS_MEMSET := yes
|
NEEDS_MEMSET := yes
|
||||||
|
|
||||||
|
@ -92,9 +92,10 @@ static inline void bw_note_queue_add(bw_note_queue *BW_RESTRICT queue, unsigned
|
|||||||
* change at any time in future versions. Please, do not use it directly. */
|
* change at any time in future versions. Please, do not use it directly. */
|
||||||
|
|
||||||
static inline void bw_note_queue_reset(bw_note_queue *BW_RESTRICT queue) {
|
static inline void bw_note_queue_reset(bw_note_queue *BW_RESTRICT queue) {
|
||||||
for (char i = 0; i < 128; i++)
|
for (int i = 0; i < 128; i++)
|
||||||
queue->status[i] = { 0, 0.f };
|
queue->status[i] = (bw_note_queue_status){ .pressed = 0, .velocity = 0.f };
|
||||||
queue->n_pressed = 0;
|
queue->n_pressed = 0;
|
||||||
|
queue->n_events = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void bw_note_queue_clear(bw_note_queue *BW_RESTRICT queue) {
|
static inline void bw_note_queue_clear(bw_note_queue *BW_RESTRICT queue) {
|
||||||
@ -113,14 +114,14 @@ static inline void bw_note_queue_add(bw_note_queue *BW_RESTRICT queue, unsigned
|
|||||||
if (i == queue->n_events)
|
if (i == queue->n_events)
|
||||||
queue->n_events++;
|
queue->n_events++;
|
||||||
else
|
else
|
||||||
went_off = queue->events[i].went_off || queue->events[i].velocity <= 0.f;
|
went_off = queue->events[i].went_off || !queue->events[i].status.pressed;
|
||||||
|
|
||||||
queue->events[i] = { note, { pressed, velocity }, went_off || force_went_off };
|
queue->events[i] = (bw_note_queue_event){ .note = note, .status = { pressed, velocity }, .went_off = went_off || force_went_off };
|
||||||
if (pressed && !queue->status[note].pressed)
|
if (pressed && !queue->status[note].pressed)
|
||||||
queue->n_pressed++;
|
queue->n_pressed++;
|
||||||
else if (!pressed && queue->status[note].pressed)
|
else if (!pressed && queue->status[note].pressed)
|
||||||
queue->n_pressed--;
|
queue->n_pressed--;
|
||||||
queue->status[note] = { pressed, velocity };
|
queue->status[note] = (bw_note_queue_status){ .pressed = pressed, .velocity = velocity };
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -51,7 +51,7 @@ extern "C" {
|
|||||||
/*! api {{{
|
/*! api {{{
|
||||||
* #### bw_voice_alloc_mode
|
* #### bw_voice_alloc_mode
|
||||||
* ```>>> */
|
* ```>>> */
|
||||||
typedef enum
|
typedef enum {
|
||||||
bw_voice_alloc_mode_low,
|
bw_voice_alloc_mode_low,
|
||||||
bw_voice_alloc_mode_high
|
bw_voice_alloc_mode_high
|
||||||
} bw_voice_alloc_mode;
|
} bw_voice_alloc_mode;
|
||||||
@ -92,7 +92,7 @@ void bw_voice_alloc(const bw_voice_alloc_opts *BW_RESTRICT opts, bw_note_queue *
|
|||||||
|
|
||||||
if (ev->status.pressed) {
|
if (ev->status.pressed) {
|
||||||
for (int j = 0; j < n_voices; j++)
|
for (int j = 0; j < n_voices; j++)
|
||||||
if (opt->is_free(voices[j])) {
|
if (opts->is_free(voices[j])) {
|
||||||
opts->note_on(voices[j], ev->note, ev->status.velocity);
|
opts->note_on(voices[j], ev->note, ev->status.velocity);
|
||||||
goto next_event;
|
goto next_event;
|
||||||
}
|
}
|
||||||
@ -111,7 +111,7 @@ void bw_voice_alloc(const bw_voice_alloc_opts *BW_RESTRICT opts, bw_note_queue *
|
|||||||
}
|
}
|
||||||
|
|
||||||
next_event:;
|
next_event:;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
Loading…
Reference in New Issue
Block a user