synthio: allow negative amplitudes
Previously, negative amplitudes were clamped to zero. Now, they are allowed to range from -ALMOST_ONE to +ALMOST_ONE. This is useful in certain circumstances, such as using synthio to create CV-like outputs that can be positive or negative, by using the amplitude property of the note.
This commit is contained in:
parent
383f79718a
commit
c92ad33a9c
@ -214,7 +214,7 @@ STATIC uint32_t pitch_bend(uint32_t frequency_scaled, int32_t bend_value) {
|
|||||||
#define ONE MICROPY_FLOAT_CONST(1.)
|
#define ONE MICROPY_FLOAT_CONST(1.)
|
||||||
#define ALMOST_ONE (MICROPY_FLOAT_CONST(32767.) / 32768)
|
#define ALMOST_ONE (MICROPY_FLOAT_CONST(32767.) / 32768)
|
||||||
|
|
||||||
uint32_t synthio_note_step(synthio_note_obj_t *self, int32_t sample_rate, int16_t dur, uint16_t loudness[2]) {
|
uint32_t synthio_note_step(synthio_note_obj_t *self, int32_t sample_rate, int16_t dur, int16_t loudness[2]) {
|
||||||
int panning = synthio_block_slot_get_scaled(&self->panning, -ALMOST_ONE, ALMOST_ONE);
|
int panning = synthio_block_slot_get_scaled(&self->panning, -ALMOST_ONE, ALMOST_ONE);
|
||||||
int left_panning_scaled, right_panning_scaled;
|
int left_panning_scaled, right_panning_scaled;
|
||||||
if (panning >= 0) {
|
if (panning >= 0) {
|
||||||
@ -225,7 +225,7 @@ uint32_t synthio_note_step(synthio_note_obj_t *self, int32_t sample_rate, int16_
|
|||||||
left_panning_scaled = 32767 + panning;
|
left_panning_scaled = 32767 + panning;
|
||||||
}
|
}
|
||||||
|
|
||||||
int amplitude = synthio_block_slot_get_scaled(&self->amplitude, ZERO, ALMOST_ONE);
|
int amplitude = synthio_block_slot_get_scaled(&self->amplitude, -ALMOST_ONE, ALMOST_ONE);
|
||||||
left_panning_scaled = (left_panning_scaled * amplitude) >> 15;
|
left_panning_scaled = (left_panning_scaled * amplitude) >> 15;
|
||||||
right_panning_scaled = (right_panning_scaled * amplitude) >> 15;
|
right_panning_scaled = (right_panning_scaled * amplitude) >> 15;
|
||||||
loudness[0] = (loudness[0] * left_panning_scaled) >> 15;
|
loudness[0] = (loudness[0] * left_panning_scaled) >> 15;
|
||||||
|
@ -55,6 +55,6 @@ typedef struct synthio_note_obj {
|
|||||||
} synthio_note_obj_t;
|
} synthio_note_obj_t;
|
||||||
|
|
||||||
void synthio_note_recalculate(synthio_note_obj_t *self, int32_t sample_rate);
|
void synthio_note_recalculate(synthio_note_obj_t *self, int32_t sample_rate);
|
||||||
uint32_t synthio_note_step(synthio_note_obj_t *self, int32_t sample_rate, int16_t dur, uint16_t loudness[2]);
|
uint32_t synthio_note_step(synthio_note_obj_t *self, int32_t sample_rate, int16_t dur, int16_t loudness[2]);
|
||||||
void synthio_note_start(synthio_note_obj_t *self, int32_t sample_rate);
|
void synthio_note_start(synthio_note_obj_t *self, int32_t sample_rate);
|
||||||
bool synthio_note_playing(synthio_note_obj_t *self);
|
bool synthio_note_playing(synthio_note_obj_t *self);
|
||||||
|
@ -172,7 +172,7 @@ int16_t mix_down_sample(int32_t sample) {
|
|||||||
return sample;
|
return sample;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool synth_note_into_buffer(synthio_synth_t *synth, int chan, int32_t *out_buffer32, int16_t dur, uint16_t loudness[2]) {
|
static bool synth_note_into_buffer(synthio_synth_t *synth, int chan, int32_t *out_buffer32, int16_t dur, int16_t loudness[2]) {
|
||||||
mp_obj_t note_obj = synth->span.note_obj[chan];
|
mp_obj_t note_obj = synth->span.note_obj[chan];
|
||||||
|
|
||||||
int32_t sample_rate = synth->sample_rate;
|
int32_t sample_rate = synth->sample_rate;
|
||||||
@ -298,7 +298,7 @@ STATIC mp_obj_t synthio_synth_get_note_filter(mp_obj_t note_obj) {
|
|||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC void sum_with_loudness(int32_t *out_buffer32, int32_t *tmp_buffer32, uint16_t loudness[2], size_t dur, int synth_chan) {
|
STATIC void sum_with_loudness(int32_t *out_buffer32, int32_t *tmp_buffer32, int16_t loudness[2], size_t dur, int synth_chan) {
|
||||||
if (synth_chan == 1) {
|
if (synth_chan == 1) {
|
||||||
for (size_t i = 0; i < dur; i++) {
|
for (size_t i = 0; i < dur; i++) {
|
||||||
*out_buffer32++ += (*tmp_buffer32++ *loudness[0]) >> 16;
|
*out_buffer32++ += (*tmp_buffer32++ *loudness[0]) >> 16;
|
||||||
@ -344,7 +344,7 @@ void synthio_synth_synthesize(synthio_synth_t *synth, uint8_t **bufptr, uint32_t
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t loudness[2] = {synth->envelope_state[chan].level, synth->envelope_state[chan].level};
|
int16_t loudness[2] = {synth->envelope_state[chan].level, synth->envelope_state[chan].level};
|
||||||
|
|
||||||
if (!synth_note_into_buffer(synth, chan, tmp_buffer32, dur, loudness)) {
|
if (!synth_note_into_buffer(synth, chan, tmp_buffer32, dur, loudness)) {
|
||||||
// for some other reason, such as being above nyquist, note
|
// for some other reason, such as being above nyquist, note
|
||||||
|
@ -3,8 +3,8 @@ from synthnotehelper import *
|
|||||||
|
|
||||||
@synth_test
|
@synth_test
|
||||||
def gen(synth):
|
def gen(synth):
|
||||||
l = LFO(bend_out, offset=0.2, scale=0.8, rate=4, once=True)
|
l = LFO(sine, offset=0.2, scale=0.8, rate=2)
|
||||||
yield [l]
|
yield [l]
|
||||||
n = Note(128, amplitude=l)
|
n = Note(8, amplitude=l)
|
||||||
synth.press(n)
|
synth.press(n)
|
||||||
yield 1 / 4
|
yield 2
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user