Skip to content

Commit

Permalink
Fix chained_osc in juno, amy; redo juno patches; fix parse_int_list c…
Browse files Browse the repository at this point in the history
…all in patches.
  • Loading branch information
dpwe committed Apr 15, 2024
1 parent 4fb865b commit 844e3b9
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 153 deletions.
28 changes: 9 additions & 19 deletions juno.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,19 +296,6 @@ def init_AMY(self):
self.amy_send(osc=self.lfo_osc, wave=amy.TRIANGLE, amp='1,0,0,1,0,0')
osc_setup = {'mod_source': self.lfo_osc}
self.amy_send(osc=self.pwm_osc, wave=amy.PULSE, **osc_setup)
# Setup chained_oscs
# All the oscs are the same, except:
# - only pulse needs duty (but OK if it's cloned, except sub)
# - wave is diff for each
# - chained osc is diff for each (but not cloned)
# - sub has different frequency, no duty
# So, to update for instance envelope:
# - we could run through each osc and update all params
# - or just update osc 0, then clone to 1,2,3, then restore
# their unique params
self.amy_send(osc=self.pwm_osc, chained_osc=self.sub_osc)
self.amy_send(osc=self.sub_osc, chained_osc=self.saw_osc)
self.amy_send(osc=self.saw_osc, chained_osc=self.nse_osc)
# Setup all the variable params.
self.update_lfo()
self.update_dco()
Expand Down Expand Up @@ -351,17 +338,20 @@ def clone_oscs(self):
base_osc = self.base_oscs[0]
pwm_osc = base_osc + self.pwm_osc
# Make the clones have their filters turned off.
amy.send(osc=pwm_osc, filter_type=amy.FILTER_NONE)
amy.send(osc=pwm_osc, filter_type=amy.FILTER_NONE,
chained_osc=base_osc + self.saw_osc)
amy.send(osc=base_osc + self.saw_osc, clone_osc=pwm_osc)
amy.send(osc=base_osc + self.saw_osc, wave=amy.SAW_UP,
amp=self._amp_coef_string(float(self.saw)))
amy.send(osc=base_osc + self.nse_osc, clone_osc=pwm_osc)
amy.send(osc=base_osc + self.nse_osc, wave=amy.NOISE,
amp=self._amp_coef_string(self.dco_noise))
amp=self._amp_coef_string(float(self.saw)),
chained_osc=base_osc + self.sub_osc)
amy.send(osc=base_osc + self.sub_osc, clone_osc=pwm_osc)
amy.send(osc=base_osc + self.sub_osc, wave=amy.PULSE,
amp=self._amp_coef_string(self.dco_sub),
freq=self.sub_freq)
freq=self.sub_freq,
chained_osc=base_osc + self.nse_osc)
amy.send(osc=base_osc + self.nse_osc, clone_osc=pwm_osc)
amy.send(osc=base_osc + self.nse_osc, wave=amy.NOISE,
amp=self._amp_coef_string(self.dco_noise)) # No chained_osc.
# Re-enable the filter on PWM osc.
amy.send(osc=pwm_osc, filter_type=amy.FILTER_LPF24)

Expand Down
5 changes: 3 additions & 2 deletions src/amy.c
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,7 @@ void amy_add_event_internal(struct event e, uint16_t base_osc) {
void clone_osc(uint16_t i, uint16_t f) {
// Set all the synth state to the values from another osc.
//fprintf(stderr, "cloning osc %d from %d\n", i, f);
reset_osc(i);
synth[i].wave = synth[f].wave;
synth[i].patch = synth[f].patch;
//synth[i].midi_note = synth[f].midi_note;
Expand Down Expand Up @@ -524,8 +525,8 @@ void clone_osc(uint16_t i, uint16_t f) {
//synth[i].mod_value = synth[f].mod_value;
//synth[i].substep = synth[f].substep;
//synth[i].status = synth[f].status;
//synth[i].chained_osc = synth[f].chained_osc; // RISKY - could make osc loops without knowing.
//synth[i].mod_source = synth[f].mod_source; // It's OK to have multiple oscs with the same mod source. But if we set it, then clone other params, we overwrite it.
//synth[i].chained_osc = synth[f].chained_osc + (f - i); // RISKY - could make osc loops without knowing.
synth[i].mod_source = synth[f].mod_source; // It's OK to have multiple oscs with the same mod source. But if we set it, then clone other params, we overwrite it.
synth[i].mod_target = synth[f].mod_target;
//synth[i].note_on_clock = synth[f].note_on_clock;
//synth[i].note_off_clock = synth[f].note_off_clock;
Expand Down
2 changes: 2 additions & 0 deletions src/amy.h
Original file line number Diff line number Diff line change
Expand Up @@ -460,8 +460,10 @@ void amy_live_stop();
void amy_reset_oscs();
void amy_print_devices();
void amy_set_custom(struct custom_oscillator* custom);
extern int parse_int_list_message(char *message, int16_t *vals, int max_num_vals, int16_t skipped_val);
extern void reset_osc(uint16_t i );


extern float render_am_lut(float * buf, float step, float skip, float incoming_amp, float ending_amp, const float* lut, int16_t lut_size, float *mod, float bandwidth);
extern void ks_init();
extern void ks_deinit();
Expand Down
6 changes: 2 additions & 4 deletions src/patches.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ uint16_t memory_patch_oscs[MEMORY_PATCHES];
uint8_t osc_to_voice[AMY_OSCS];
uint16_t voice_to_base_osc[MAX_VOICES];

extern int parse_int_list_message(char *message, int16_t *vals, int max_num_vals);


void patches_reset() {
for(uint8_t v=0;v<MAX_VOICES;v++) {
Expand Down Expand Up @@ -71,7 +69,7 @@ void patches_store_patch(char * message) {
// So i know that the patch / voice alloc already exists and the patch has already been set!
void patches_event_has_voices(struct event e) {
int16_t voices[MAX_VOICES];
uint8_t num_voices = parse_int_list_message(e.voices, voices, MAX_VOICES);
uint8_t num_voices = parse_int_list_message(e.voices, voices, MAX_VOICES, 0);
// clear out the voices and patch now from the event. If we didn't, we'd keep calling this over and over
e.voices[0] = 0;
AMY_UNSET(e.load_patch);
Expand All @@ -91,7 +89,7 @@ void patches_load_patch(struct event e) {
char sub_message[255];

int16_t voices[MAX_VOICES];
uint8_t num_voices = parse_int_list_message(e.voices, voices, MAX_VOICES);
uint8_t num_voices = parse_int_list_message(e.voices, voices, MAX_VOICES, 0);
char *message;
uint16_t patch_osc = 0;
if(e.load_patch > 1023) {
Expand Down
Loading

0 comments on commit 844e3b9

Please sign in to comment.