From fde9ca22b7bea6aad5d6f494057d0cacce340543 Mon Sep 17 00:00:00 2001
From: moon2 <moon2protonmail@protonmail.com>
Date: Sun, 23 Apr 2023 23:18:57 +0200
Subject: [PATCH] a bit more synth functions

---
 badge23/synth.c                            | 40 +++++++++++++++++++--
 badge23/synth.h                            | 11 +++++-
 micropython/ports/esp32/badge23_mp_synth.c | 42 ++++++++++++++++++----
 python_payload/cap_touch_demo.py           |  6 +++-
 4 files changed, 88 insertions(+), 11 deletions(-)

diff --git a/badge23/synth.c b/badge23/synth.c
index 1c87a89b11..f31b2fb6f4 100644
--- a/badge23/synth.c
+++ b/badge23/synth.c
@@ -17,7 +17,7 @@ float ks_osc(ks_osc_t * ks, float input){
 float waveshaper(uint8_t shape, float in);
 float nes_noise(uint16_t * reg, uint8_t mode, uint8_t run);
 
-void trad_env(trad_osc_t * osc){
+void run_trad_env(trad_osc_t * osc){
     switch(osc->env_phase){
         case 0:
             osc->env = 0; osc->counter = 0; osc->env_counter = 0;
@@ -63,8 +63,8 @@ void trad_env(trad_osc_t * osc){
     }
 }
 
-float trad_osc(trad_osc_t * osc){
-    trad_env(osc);
+float run_trad_osc(trad_osc_t * osc){
+    run_trad_env(osc);
     if(!osc->env_phase) return 0;
     float ret = 0;
 
@@ -165,3 +165,37 @@ float waveshaper(uint8_t shape, float in){
     }
     return in;
 }
+
+#define NAT_LOG_SEMITONE 0.05776226504666215
+
+void trad_osc_set_freq_semitone(trad_osc_t * osc, float bend){
+    osc->freq = 440. * exp(bend * NAT_LOG_SEMITONE);
+}
+
+void trad_osc_set_freq_Hz(trad_osc_t * osc, float freq){
+    osc->freq = freq;
+}
+
+void trad_osc_set_waveform(trad_osc_t * osc, uint8_t waveform){
+    osc->waveform = waveform;
+}
+
+void trad_osc_set_attack(trad_osc_t * osc, uint16_t attack){
+    osc->attack_steps = attack;
+}
+
+void trad_osc_set_decay(trad_osc_t * osc, uint16_t decay){
+    osc->decay_steps = decay;
+}
+
+void trad_env_stop(trad_osc_t * osc){
+    if(osc->env_phase) osc->env_phase = 3; 
+}
+
+void trad_env_fullstop(trad_osc_t * osc){
+    osc->env_phase = 0; //stop and skip decay phase
+}
+
+void trad_env_start(trad_osc_t * osc){
+    osc->env_phase = 1; //put into attack phase;
+}
diff --git a/badge23/synth.h b/badge23/synth.h
index 5d498731cd..50f52fcd5a 100644
--- a/badge23/synth.h
+++ b/badge23/synth.h
@@ -45,4 +45,13 @@ typedef struct {
     float real_feedback;        //compensated feedback value
 } ks_osc_t; //karplus strong
 
-float trad_osc(trad_osc_t * osc);
+float run_trad_osc(trad_osc_t * osc);
+
+void trad_osc_set_freq_semitone(trad_osc_t * osc, float bend);
+void trad_osc_set_freq_Hz(trad_osc_t * osc, float freq);
+void trad_osc_set_waveform(trad_osc_t * osc, uint8_t waveform);
+void trad_osc_set_attack(trad_osc_t * osc, uint16_t attack);
+void trad_osc_set_decay(trad_osc_t * osc, uint16_t decay);
+void trad_env_stop(trad_osc_t * osc);
+void trad_env_fullstop(trad_osc_t * osc);
+void trad_env_start(trad_osc_t * osc);
diff --git a/micropython/ports/esp32/badge23_mp_synth.c b/micropython/ports/esp32/badge23_mp_synth.c
index 822e44018e..a36a1200db 100644
--- a/micropython/ports/esp32/badge23_mp_synth.c
+++ b/micropython/ports/esp32/badge23_mp_synth.c
@@ -39,7 +39,7 @@ STATIC mp_obj_t tinysynth_make_new(const mp_obj_type_t *type, size_t n_args, siz
     self->osc.waveform = 1;
     self->osc.skip_hold = mp_obj_get_int(args[1]);
     //set_extra_synth(&(self->osc));
-    self->source_index = add_audio_source(&(self->osc), trad_osc);
+    self->source_index = add_audio_source(&(self->osc), run_trad_osc);
 
     return MP_OBJ_FROM_PTR(self);
 }
@@ -47,27 +47,53 @@ STATIC mp_obj_t tinysynth_make_new(const mp_obj_type_t *type, size_t n_args, siz
 // Class methods
 STATIC mp_obj_t tinysynth_start(mp_obj_t self_in) {
     synth_tinysynth_obj_t *self = MP_OBJ_TO_PTR(self_in);
-    self->osc.env_phase = 1;
+    trad_env_start(&(self->osc));
     return mp_const_none;
 }
 MP_DEFINE_CONST_FUN_OBJ_1(tinysynth_start_obj, tinysynth_start);
 
 STATIC mp_obj_t tinysynth_stop(mp_obj_t self_in) {
     synth_tinysynth_obj_t *self = MP_OBJ_TO_PTR(self_in);
-    if(self->osc.env_phase){
-        self->osc.env_phase = 3;
-    }
+    trad_env_stop(&(self->osc));
     return mp_const_none;
 }
 MP_DEFINE_CONST_FUN_OBJ_1(tinysynth_stop_obj, tinysynth_stop);
 
 STATIC mp_obj_t tinysynth_freq(mp_obj_t self_in, mp_obj_t freq) {
     synth_tinysynth_obj_t *self = MP_OBJ_TO_PTR(self_in);
-    self->osc.freq = mp_obj_get_float(freq);
+    trad_osc_set_freq_Hz(&(self->osc), mp_obj_get_float(freq));
     return mp_const_none;
 }
 MP_DEFINE_CONST_FUN_OBJ_2(tinysynth_freq_obj, tinysynth_freq);
 
+STATIC mp_obj_t tinysynth_tone(mp_obj_t self_in, mp_obj_t tone) {
+    synth_tinysynth_obj_t *self = MP_OBJ_TO_PTR(self_in);
+    trad_osc_set_freq_semitone(&(self->osc), mp_obj_get_float(tone));
+    return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_2(tinysynth_tone_obj, tinysynth_tone);
+
+STATIC mp_obj_t tinysynth_waveform(mp_obj_t self_in, mp_obj_t waveform) {
+    synth_tinysynth_obj_t *self = MP_OBJ_TO_PTR(self_in);
+    trad_osc_set_waveform(&(self->osc), mp_obj_get_int(waveform));
+    return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_2(tinysynth_waveform_obj, tinysynth_waveform);
+
+STATIC mp_obj_t tinysynth_attack(mp_obj_t self_in, mp_obj_t attack) {
+    synth_tinysynth_obj_t *self = MP_OBJ_TO_PTR(self_in);
+    trad_osc_set_attack(&(self->osc), mp_obj_get_int(attack));
+    return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_2(tinysynth_attack_obj, tinysynth_attack);
+
+STATIC mp_obj_t tinysynth_decay(mp_obj_t self_in, mp_obj_t decay) {
+    synth_tinysynth_obj_t *self = MP_OBJ_TO_PTR(self_in);
+    trad_osc_set_decay(&(self->osc), mp_obj_get_int(decay));
+    return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_2(tinysynth_decay_obj, tinysynth_decay);
+
 STATIC mp_obj_t tinysynth_deinit(mp_obj_t self_in) {
     synth_tinysynth_obj_t *self = MP_OBJ_TO_PTR(self_in);
     remove_audio_source(self->source_index);
@@ -80,6 +106,10 @@ STATIC const mp_rom_map_elem_t tinysynth_locals_dict_table[] = {
     { MP_ROM_QSTR(MP_QSTR_start), MP_ROM_PTR(&tinysynth_start_obj) },
     { MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&tinysynth_stop_obj) },
     { MP_ROM_QSTR(MP_QSTR_freq), MP_ROM_PTR(&tinysynth_freq_obj) },
+    { MP_ROM_QSTR(MP_QSTR_tone), MP_ROM_PTR(&tinysynth_tone_obj) },
+    { MP_ROM_QSTR(MP_QSTR_waveform), MP_ROM_PTR(&tinysynth_waveform_obj) },
+    { MP_ROM_QSTR(MP_QSTR_attack), MP_ROM_PTR(&tinysynth_attack_obj) },
+    { MP_ROM_QSTR(MP_QSTR_decay), MP_ROM_PTR(&tinysynth_decay_obj) },
     { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&tinysynth_deinit_obj) },
 };
 
diff --git a/python_payload/cap_touch_demo.py b/python_payload/cap_touch_demo.py
index df4fd514c8..40db5303a6 100644
--- a/python_payload/cap_touch_demo.py
+++ b/python_payload/cap_touch_demo.py
@@ -6,6 +6,10 @@ synths = []
 for i in range(5):
     synths += [tinysynth(440,1)]
 
+for synth in synths:
+    synth.decay(300)
+    synth.waveform(3)
+
 chords = [[0,3,7,10,12],[-2,2,5,8,10],[-2,3,7,10,14],[-4,0,3,8,12],[-1,2,5,7,11]]
 
 chord = chords[3]
@@ -17,5 +21,5 @@ while True:
                 chord = chords[int((i-1)/2)]
             else:
                 i = int(i/2)
-                synths[i].freq(440*(2**(chord[i]/12)))
+                synths[i].tone(chord[i])
                 synths[i].start()
-- 
GitLab