synthio: Generalize vibrato into bend

bend can be static, sweep, or vibrato
This commit is contained in:
Jeff Epler 2023-05-10 08:40:09 -05:00
parent c48d385e94
commit 1d1907b98b
No known key found for this signature in database
GPG Key ID: D5BF15AB975AB4DE
10 changed files with 153 additions and 69 deletions

View File

@ -30,6 +30,7 @@
#include "py/objproperty.h"
#include "py/runtime.h"
#include "shared-bindings/util.h"
#include "shared-bindings/synthio/__init__.h"
#include "shared-bindings/synthio/Note.h"
#include "shared-module/synthio/Note.h"
@ -38,8 +39,9 @@ static const mp_arg_t note_properties[] = {
{ MP_QSTR_amplitude, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_INT(1) } },
{ MP_QSTR_tremolo_rate, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = NULL } },
{ MP_QSTR_tremolo_depth, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = NULL } },
{ MP_QSTR_vibrato_rate, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = NULL } },
{ MP_QSTR_vibrato_depth, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = NULL } },
{ MP_QSTR_bend_rate, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = NULL } },
{ MP_QSTR_bend_depth, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = NULL } },
{ MP_QSTR_bend_mode, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = (mp_obj_t)MP_ROM_PTR(&bend_mode_VIBRATO_obj) } },
{ MP_QSTR_waveform, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_NONE } },
{ MP_QSTR_envelope, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_NONE } },
};
@ -53,17 +55,16 @@ static const mp_arg_t note_properties[] = {
//| envelope: Optional[Envelope] = None,
//| tremolo_depth: float = 0.0,
//| tremolo_rate: float = 0.0,
//| vibrato_depth: float = 0.0,
//| vibrato_rate: float = 0.0,
//| bend_depth: float = 0.0,
//| bend_rate: float = 0.0,
//| ) -> None:
//| """Construct a Note object, with a frequency in Hz, and optional amplitude (volume), waveform, envelope, tremolo (volume change) and vibrato (frequency change).
//| """Construct a Note object, with a frequency in Hz, and optional amplitude (volume), waveform, envelope, tremolo (volume change) and bend (frequency change).
//|
//| If waveform or envelope are `None` the synthesizer object's default waveform or envelope are used.
//|
//| If the same Note object is played on multiple Synthesizer objects, the result is undefined.
//| """
STATIC mp_obj_t synthio_note_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
enum { ARG_frequency, ARG_amplitude, ARG_waveform, ARG_envelope, ARG_tremolo_rate, ARG_tremolo_depth, ARG_vibrato_rate, ARG_vibrato_depth };
mp_arg_val_t args[MP_ARRAY_SIZE(note_properties)];
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(note_properties), note_properties, args);
@ -158,46 +159,67 @@ MP_PROPERTY_GETSET(synthio_note_tremolo_rate_obj,
(mp_obj_t)&synthio_note_get_tremolo_rate_obj,
(mp_obj_t)&synthio_note_set_tremolo_rate_obj);
//| vibrato_depth: float
//| """The vibrato depth of the note, from 0 to 1
//|
//| A depth of 0 disables vibrato. A depth of 1 corresponds to a vibrato of ±1
//| octave. A depth of (1/12) = 0.833 corresponds to a vibrato of ±1 semitone,
//| bend_mode: BendMode
//| """The type of bend operation"""
STATIC mp_obj_t synthio_note_get_bend_mode(mp_obj_t self_in) {
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
return cp_enum_find(&synthio_bend_mode_type, common_hal_synthio_note_get_bend_mode(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(synthio_note_get_bend_mode_obj, synthio_note_get_bend_mode);
STATIC mp_obj_t synthio_note_set_bend_mode(mp_obj_t self_in, mp_obj_t arg) {
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
common_hal_synthio_note_set_bend_mode(self, cp_enum_value(&synthio_bend_mode_type, arg, MP_QSTR_bend_mode));
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_2(synthio_note_set_bend_mode_obj, synthio_note_set_bend_mode);
MP_PROPERTY_GETSET(synthio_note_bend_mode_obj,
(mp_obj_t)&synthio_note_get_bend_mode_obj,
(mp_obj_t)&synthio_note_set_bend_mode_obj);
//
//|
//| bend_depth: float
//| """The bend depth of the note, from -1 to +1
//|
//| A depth of 0 disables bend. A depth of 1 corresponds to a bend of 1
//| octave. A depth of (1/12) = 0.833 corresponds to a bend of 1 semitone,
//| and a depth of .00833 corresponds to one musical cent.
//| """
STATIC mp_obj_t synthio_note_get_vibrato_depth(mp_obj_t self_in) {
STATIC mp_obj_t synthio_note_get_bend_depth(mp_obj_t self_in) {
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
return mp_obj_new_float(common_hal_synthio_note_get_vibrato_depth(self));
return mp_obj_new_float(common_hal_synthio_note_get_bend_depth(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(synthio_note_get_vibrato_depth_obj, synthio_note_get_vibrato_depth);
MP_DEFINE_CONST_FUN_OBJ_1(synthio_note_get_bend_depth_obj, synthio_note_get_bend_depth);
STATIC mp_obj_t synthio_note_set_vibrato_depth(mp_obj_t self_in, mp_obj_t arg) {
STATIC mp_obj_t synthio_note_set_bend_depth(mp_obj_t self_in, mp_obj_t arg) {
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
common_hal_synthio_note_set_vibrato_depth(self, mp_obj_get_float(arg));
common_hal_synthio_note_set_bend_depth(self, mp_obj_get_float(arg));
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_2(synthio_note_set_vibrato_depth_obj, synthio_note_set_vibrato_depth);
MP_PROPERTY_GETSET(synthio_note_vibrato_depth_obj,
(mp_obj_t)&synthio_note_get_vibrato_depth_obj,
(mp_obj_t)&synthio_note_set_vibrato_depth_obj);
MP_DEFINE_CONST_FUN_OBJ_2(synthio_note_set_bend_depth_obj, synthio_note_set_bend_depth);
MP_PROPERTY_GETSET(synthio_note_bend_depth_obj,
(mp_obj_t)&synthio_note_get_bend_depth_obj,
(mp_obj_t)&synthio_note_set_bend_depth_obj);
//| vibrato_rate: float
//| """The vibrato rate of the note, in Hz."""
STATIC mp_obj_t synthio_note_get_vibrato_rate(mp_obj_t self_in) {
//| bend_rate: float
//| """The bend rate of the note, in Hz."""
STATIC mp_obj_t synthio_note_get_bend_rate(mp_obj_t self_in) {
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
return mp_obj_new_float(common_hal_synthio_note_get_vibrato_rate(self));
return mp_obj_new_float(common_hal_synthio_note_get_bend_rate(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(synthio_note_get_vibrato_rate_obj, synthio_note_get_vibrato_rate);
MP_DEFINE_CONST_FUN_OBJ_1(synthio_note_get_bend_rate_obj, synthio_note_get_bend_rate);
STATIC mp_obj_t synthio_note_set_vibrato_rate(mp_obj_t self_in, mp_obj_t arg) {
STATIC mp_obj_t synthio_note_set_bend_rate(mp_obj_t self_in, mp_obj_t arg) {
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
common_hal_synthio_note_set_vibrato_rate(self, mp_obj_get_float(arg));
common_hal_synthio_note_set_bend_rate(self, mp_obj_get_float(arg));
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_2(synthio_note_set_vibrato_rate_obj, synthio_note_set_vibrato_rate);
MP_PROPERTY_GETSET(synthio_note_vibrato_rate_obj,
(mp_obj_t)&synthio_note_get_vibrato_rate_obj,
(mp_obj_t)&synthio_note_set_vibrato_rate_obj);
MP_DEFINE_CONST_FUN_OBJ_2(synthio_note_set_bend_rate_obj, synthio_note_set_bend_rate);
MP_PROPERTY_GETSET(synthio_note_bend_rate_obj,
(mp_obj_t)&synthio_note_get_bend_rate_obj,
(mp_obj_t)&synthio_note_set_bend_rate_obj);
//| waveform: Optional[ReadableBuffer]
//| """The waveform of this note. Setting the waveform to a buffer of a different size resets the note's phase."""
@ -249,8 +271,9 @@ STATIC const mp_rom_map_elem_t synthio_note_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_envelope), MP_ROM_PTR(&synthio_note_envelope_obj) },
{ MP_ROM_QSTR(MP_QSTR_tremolo_depth), MP_ROM_PTR(&synthio_note_tremolo_depth_obj) },
{ MP_ROM_QSTR(MP_QSTR_tremolo_rate), MP_ROM_PTR(&synthio_note_tremolo_rate_obj) },
{ MP_ROM_QSTR(MP_QSTR_vibrato_depth), MP_ROM_PTR(&synthio_note_vibrato_depth_obj) },
{ MP_ROM_QSTR(MP_QSTR_vibrato_rate), MP_ROM_PTR(&synthio_note_vibrato_rate_obj) },
{ MP_ROM_QSTR(MP_QSTR_bend_depth), MP_ROM_PTR(&synthio_note_bend_depth_obj) },
{ MP_ROM_QSTR(MP_QSTR_bend_rate), MP_ROM_PTR(&synthio_note_bend_rate_obj) },
{ MP_ROM_QSTR(MP_QSTR_bend_mode), MP_ROM_PTR(&synthio_note_bend_mode_obj) },
};
STATIC MP_DEFINE_CONST_DICT(synthio_note_locals_dict, synthio_note_locals_dict_table);

View File

@ -4,6 +4,7 @@
typedef struct synthio_note_obj synthio_note_obj_t;
extern const mp_obj_type_t synthio_note_type;
typedef enum synthio_bend_mode_e synthio_bend_mode_t;
mp_float_t common_hal_synthio_note_get_frequency(synthio_note_obj_t *self);
void common_hal_synthio_note_set_frequency(synthio_note_obj_t *self, mp_float_t value);
@ -17,11 +18,14 @@ void common_hal_synthio_note_set_tremolo_rate(synthio_note_obj_t *self, mp_float
mp_float_t common_hal_synthio_note_get_tremolo_depth(synthio_note_obj_t *self);
void common_hal_synthio_note_set_tremolo_depth(synthio_note_obj_t *self, mp_float_t value);
mp_float_t common_hal_synthio_note_get_vibrato_rate(synthio_note_obj_t *self);
void common_hal_synthio_note_set_vibrato_rate(synthio_note_obj_t *self, mp_float_t value);
synthio_bend_mode_t common_hal_synthio_note_get_bend_mode(synthio_note_obj_t *self);
void common_hal_synthio_note_set_bend_mode(synthio_note_obj_t *self, synthio_bend_mode_t value);
mp_float_t common_hal_synthio_note_get_vibrato_depth(synthio_note_obj_t *self);
void common_hal_synthio_note_set_vibrato_depth(synthio_note_obj_t *self, mp_float_t value);
mp_float_t common_hal_synthio_note_get_bend_rate(synthio_note_obj_t *self);
void common_hal_synthio_note_set_bend_rate(synthio_note_obj_t *self, mp_float_t value);
mp_float_t common_hal_synthio_note_get_bend_depth(synthio_note_obj_t *self);
void common_hal_synthio_note_set_bend_depth(synthio_note_obj_t *self, mp_float_t value);
mp_obj_t common_hal_synthio_note_get_waveform_obj(synthio_note_obj_t *self);
void common_hal_synthio_note_set_waveform(synthio_note_obj_t *self, mp_obj_t value);

View File

@ -287,7 +287,7 @@ STATIC mp_obj_t onevo_to_hz(mp_obj_t arg) {
MP_DEFINE_CONST_FUN_OBJ_1(synthio_onevo_to_hz_obj, onevo_to_hz);
MAKE_ENUM_VALUE(synthio_bend_mode_type, bend_mode, STATIC, SYNTHIO_BEND_MODE_STATIC);
MAKE_ENUM_VALUE(synthio_bend_mode_type, bend_mode, TREMOLO, SYNTHIO_BEND_MODE_TREMOLO);
MAKE_ENUM_VALUE(synthio_bend_mode_type, bend_mode, VIBRATO, SYNTHIO_BEND_MODE_VIBRATO);
MAKE_ENUM_VALUE(synthio_bend_mode_type, bend_mode, SWEEP, SYNTHIO_BEND_MODE_SWEEP);
//|
@ -297,7 +297,7 @@ MAKE_ENUM_VALUE(synthio_bend_mode_type, bend_mode, SWEEP, SYNTHIO_BEND_MODE_SWEE
//| STATIC: object
//| """The Note's pitch is modified by its ``pitch_bend_depth``. ``pitch_bend_rate`` is ignored."""
//|
//| TREMOLO: object
//| VIBRATO: object
//| """The Note's pitch varies by ``±pitch_bend_depth` at a rate of ``pitch_bend_rate``Hz."""
//|
//| SWEEP: object
@ -305,7 +305,7 @@ MAKE_ENUM_VALUE(synthio_bend_mode_type, bend_mode, SWEEP, SYNTHIO_BEND_MODE_SWEE
//|
MAKE_ENUM_MAP(synthio_bend_mode) {
MAKE_ENUM_MAP_ENTRY(bend_mode, STATIC),
MAKE_ENUM_MAP_ENTRY(bend_mode, TREMOLO),
MAKE_ENUM_MAP_ENTRY(bend_mode, VIBRATO),
MAKE_ENUM_MAP_ENTRY(bend_mode, SWEEP),
};

View File

@ -27,11 +27,13 @@
#pragma once
#include "py/objnamedtuple.h"
#include "py/enum.h"
typedef enum {
SYNTHIO_BEND_MODE_STATIC, SYNTHIO_BEND_MODE_TREMOLO, SYNTHIO_BEND_MODE_SWEEP
typedef enum synthio_bend_mode_e {
SYNTHIO_BEND_MODE_STATIC, SYNTHIO_BEND_MODE_VIBRATO, SYNTHIO_BEND_MODE_SWEEP
} synthio_bend_mode_t;
extern const cp_enum_obj_t bend_mode_VIBRATO_obj;
extern const mp_obj_type_t synthio_bend_mode_type;
typedef struct synthio_synth synthio_synth_t;
extern int16_t shared_bindings_synthio_square_wave[];

View File

@ -76,25 +76,34 @@ void common_hal_synthio_note_set_tremolo_rate(synthio_note_obj_t *self, mp_float
}
}
mp_float_t common_hal_synthio_note_get_vibrato_depth(synthio_note_obj_t *self) {
return self->vibrato_descr.amplitude;
mp_float_t common_hal_synthio_note_get_bend_depth(synthio_note_obj_t *self) {
return self->bend_descr.amplitude;
}
void common_hal_synthio_note_set_vibrato_depth(synthio_note_obj_t *self, mp_float_t value_in) {
mp_float_t val = mp_arg_validate_float_range(value_in, 0, 1, MP_QSTR_vibrato_depth);
self->vibrato_descr.amplitude = val;
self->vibrato_state.amplitude_scaled = round_float_to_int(val * 32767);
void common_hal_synthio_note_set_bend_depth(synthio_note_obj_t *self, mp_float_t value_in) {
mp_float_t val = mp_arg_validate_float_range(value_in, -1, 1, MP_QSTR_bend_depth);
self->bend_descr.amplitude = val;
self->bend_state.amplitude_scaled = round_float_to_int(val * 32767);
}
mp_float_t common_hal_synthio_note_get_vibrato_rate(synthio_note_obj_t *self) {
return self->vibrato_descr.frequency;
mp_float_t common_hal_synthio_note_get_bend_rate(synthio_note_obj_t *self) {
return self->bend_descr.frequency;
}
void common_hal_synthio_note_set_vibrato_rate(synthio_note_obj_t *self, mp_float_t value_in) {
mp_float_t val = mp_arg_validate_float_range(value_in, 0, 60, MP_QSTR_vibrato_rate);
self->vibrato_descr.frequency = val;
synthio_bend_mode_t common_hal_synthio_note_get_bend_mode(synthio_note_obj_t *self) {
return self->bend_mode;
}
void common_hal_synthio_note_set_bend_mode(synthio_note_obj_t *self, synthio_bend_mode_t value) {
self->bend_mode = value;
}
void common_hal_synthio_note_set_bend_rate(synthio_note_obj_t *self, mp_float_t value_in) {
mp_float_t val = mp_arg_validate_float_range(value_in, 0, 60, MP_QSTR_bend_rate);
self->bend_descr.frequency = val;
if (self->sample_rate != 0) {
self->vibrato_state.dds = synthio_frequency_convert_float_to_dds(val, self->sample_rate);
self->bend_state.dds = synthio_frequency_convert_float_to_dds(val, self->sample_rate);
}
}
@ -139,8 +148,8 @@ void synthio_note_recalculate(synthio_note_obj_t *self, int32_t sample_rate) {
synthio_lfo_set(&self->tremolo_state, &self->tremolo_descr, sample_rate);
self->tremolo_state.offset_scaled = 32768 - self->tremolo_state.amplitude_scaled;
synthio_lfo_set(&self->vibrato_state, &self->vibrato_descr, sample_rate);
self->vibrato_state.offset_scaled = 32768;
synthio_lfo_set(&self->bend_state, &self->bend_descr, sample_rate);
self->bend_state.offset_scaled = 32768;
}
void synthio_note_start(synthio_note_obj_t *self, int32_t sample_rate) {
@ -176,10 +185,23 @@ STATIC uint32_t pitch_bend(uint32_t frequency_scaled, uint16_t bend_value) {
return (frequency_scaled * (uint64_t)f) >> (15 + down);
}
STATIC int synthio_bend_value(synthio_note_obj_t *self, int16_t dur) {
switch (self->bend_mode) {
case SYNTHIO_BEND_MODE_STATIC:
return self->bend_state.amplitude_scaled + self->bend_state.offset_scaled;
case SYNTHIO_BEND_MODE_VIBRATO:
return synthio_lfo_step(&self->bend_state, dur);
case SYNTHIO_BEND_MODE_SWEEP:
return synthio_sweep_step(&self->bend_state, dur);
default:
return 32768;
}
}
uint32_t synthio_note_step(synthio_note_obj_t *self, int32_t sample_rate, int16_t dur, uint16_t *loudness) {
int tremolo_value = synthio_lfo_step(&self->tremolo_state, dur);
int vibrato_value = synthio_lfo_step(&self->vibrato_state, dur);
*loudness = (*loudness * tremolo_value) >> 15;
uint32_t frequency_scaled = pitch_bend(self->frequency_scaled, vibrato_value);
int bend_value = synthio_bend_value(self, dur);
uint32_t frequency_scaled = pitch_bend(self->frequency_scaled, bend_value);
return frequency_scaled;
}

View File

@ -27,6 +27,7 @@
#pragma once
#include "shared-module/synthio/__init__.h"
#include "shared-bindings/synthio/__init__.h"
typedef struct synthio_note_obj {
mp_obj_base_t base;
@ -39,8 +40,9 @@ typedef struct synthio_note_obj {
int32_t frequency_scaled;
int32_t amplitude_scaled;
synthio_lfo_descr_t tremolo_descr, vibrato_descr;
synthio_lfo_state_t tremolo_state, vibrato_state;
synthio_bend_mode_t bend_mode;
synthio_lfo_descr_t tremolo_descr, bend_descr;
synthio_lfo_state_t tremolo_state, bend_state;
mp_buffer_info_t waveform_buf;
synthio_envelope_definition_t envelope_def;

View File

@ -402,6 +402,18 @@ void synthio_lfo_set(synthio_lfo_state_t *state, const synthio_lfo_descr_t *desc
state->dds = synthio_frequency_convert_float_to_dds(descr->frequency * 65536, sample_rate);
}
int synthio_sweep_step(synthio_lfo_state_t *state, uint16_t dur) {
uint32_t phase = state->phase;
uint16_t whole_phase = phase >> 16;
// advance the phase accumulator
state->phase = phase + state->dds * dur;
if (state->phase < phase) {
state->phase = 0xffffffff;
}
return (state->amplitude_scaled * whole_phase) / 65536 + state->offset_scaled;
}
int synthio_lfo_step(synthio_lfo_state_t *state, uint16_t dur) {
uint32_t phase = state->phase;
uint16_t whole_phase = phase >> 16;

View File

@ -81,7 +81,8 @@ typedef struct {
} synthio_lfo_descr_t;
typedef struct {
uint32_t amplitude_scaled, offset_scaled, dds, phase;
int32_t amplitude_scaled;
uint32_t offset_scaled, dds, phase;
} synthio_lfo_state_t;
@ -107,3 +108,4 @@ uint32_t synthio_frequency_convert_scaled_to_dds(uint64_t frequency_scaled, int3
void synthio_lfo_set(synthio_lfo_state_t *state, const synthio_lfo_descr_t *descr, uint32_t sample_rate);
int synthio_lfo_step(synthio_lfo_state_t *state, uint16_t dur);
int synthio_sweep_step(synthio_lfo_state_t *state, uint16_t dur);

View File

@ -18,7 +18,7 @@ sine = np.array(
)
envelope = synthio.Envelope(
attack_time=0.1, decay_time=0.05, release_time=0.2, attack_level=1, sustain_level=0.8
attack_time=0.1, decay_time=0.05, release_time=0.2, attack_level=0.8, sustain_level=0.8
)
synth = synthio.Synthesizer(sample_rate=48000)
@ -63,8 +63,8 @@ def synthesize2(synth):
def synthesize3(synth):
n = synthio.Note(
frequency=synthio.midi_to_hz(60),
vibrato_depth=0.1,
vibrato_rate=8,
bend_depth=0.1,
bend_rate=8,
waveform=sine,
envelope=envelope,
)
@ -79,8 +79,8 @@ def synthesize4(synth):
frequency=synthio.midi_to_hz(60),
tremolo_depth=0.1,
tremolo_rate=1.5,
vibrato_depth=0.1,
vibrato_rate=3,
bend_depth=0.1,
bend_rate=3,
waveform=sine,
envelope=envelope,
)
@ -109,6 +109,23 @@ def synthesize5(synth):
yield 36
def synthesize6(synth):
n = synthio.Note(
frequency=synthio.midi_to_hz(60),
tremolo_depth=0.1,
tremolo_rate=1.5,
bend_depth=-5 / 12,
bend_rate=1 / 2,
bend_mode=synthio.BendType.SWEEP,
waveform=sine,
envelope=envelope,
)
synth.press((n,))
yield 720
synth.release_all()
yield 36
def chain(*args):
for a in args:
yield from a
@ -119,7 +136,7 @@ with wave.open("tune-noenv.wav", "w") as f:
f.setnchannels(1)
f.setsampwidth(2)
f.setframerate(48000)
for n in chain(synthesize5(synth)):
for n in chain(synthesize6(synth)):
for i in range(n):
result, data = audiocore.get_buffer(synth)
f.writeframes(data)

View File

@ -1,10 +1,10 @@
()
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
(Note(frequency=830.6076004423605, amplitude=1.0, tremolo_rate=0.0, tremolo_depth=0.0, vibrato_rate=0.0, vibrato_depth=0.0, waveform=None, envelope=None),)
(Note(frequency=830.6076004423605, amplitude=1.0, tremolo_rate=0.0, tremolo_depth=0.0, bend_rate=0.0, bend_depth=0.0, bend_mode=synthio.BendType.VIBRATO, waveform=None, envelope=None),)
[-16383, -16383, -16383, -16383, 16383, 16383, 16383, 16383, 16383, -16383, -16383, -16383, -16383, -16383, 16383, 16383, 16383, 16383, 16383, -16383, -16383, -16383, -16383, -16383]
(Note(frequency=830.6076004423605, amplitude=1.0, tremolo_rate=0.0, tremolo_depth=0.0, vibrato_rate=0.0, vibrato_depth=0.0, waveform=None, envelope=None), Note(frequency=830.6076004423605, amplitude=1.0, tremolo_rate=0.0, tremolo_depth=0.0, vibrato_rate=0.0, vibrato_depth=0.0, waveform=None, envelope=None))
(Note(frequency=830.6076004423605, amplitude=1.0, tremolo_rate=0.0, tremolo_depth=0.0, bend_rate=0.0, bend_depth=0.0, bend_mode=synthio.BendType.VIBRATO, waveform=None, envelope=None), Note(frequency=830.6076004423605, amplitude=1.0, tremolo_rate=0.0, tremolo_depth=0.0, bend_rate=0.0, bend_depth=0.0, bend_mode=synthio.BendType.VIBRATO, waveform=None, envelope=None))
[0, 0, 0, 0, 0, 0, 0, 0, 28045, 0, 0, 0, 0, -28046, 0, 0, 0, 0, 28045, 0, 0, 0, 0, -28046]
(Note(frequency=830.6076004423605, amplitude=1.0, tremolo_rate=0.0, tremolo_depth=0.0, vibrato_rate=0.0, vibrato_depth=0.0, waveform=None, envelope=None),)
(Note(frequency=830.6076004423605, amplitude=1.0, tremolo_rate=0.0, tremolo_depth=0.0, bend_rate=0.0, bend_depth=0.0, bend_mode=synthio.BendType.VIBRATO, waveform=None, envelope=None),)
[0, 0, 0, 28045, 0, 0, 0, 0, 0, 0, 0, 0, 28045, 0, 0, 0, 0, -28046, 0, 0, 0, 0, 28045, 0]
(-5242, 5242)
(-10485, 10484)