Skip to content

Commit

Permalink
Merge pull request #83 from csboling/midi-tuning-ii
Browse files Browse the repository at this point in the history
midi: fix tuning behavior & ii leader functionality
  • Loading branch information
csboling authored Jul 8, 2020
2 parents 33f0c54 + 215706f commit f3a2acb
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 57 deletions.
2 changes: 1 addition & 1 deletion libavr32
Submodule libavr32 updated 3 files
+2 −2 .travis.yml
+5 −0 src/ii.h
+18 −14 src/music.c
22 changes: 16 additions & 6 deletions src/ansible_grid.c
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ void grid_keytimer(void) {
// reload factory default, don't immediately save it
for (uint8_t i = 0; i < 4; i++) {
for (uint8_t j = 0; j < 120; j ++) {
tuning_table[i][j] = ET[j] << 2;
tuning_table[i][j] = ET[j];
}
}
restore_grid_tuning();
Expand Down Expand Up @@ -948,7 +948,8 @@ static void kria_set_note(uint8_t trackNum) {
trackNum,
(int)cur_scale[noteInScale] +
scale_adj[noteInScale] +
(int)((oct[trackNum]+octaveBump) * 12));
(int)((oct[trackNum]+octaveBump) * 12),
0);
}

void clock_kria_track( uint8_t trackNum ) {
Expand Down Expand Up @@ -2826,6 +2827,15 @@ void handler_KriaKey(s32 data) {
view_clock = false;
break;
case 1:
if (view_tuning) {
view_tuning = false;
view_config = false;
view_clock = false;
restore_grid_tuning();
resume_kria();
break;
}

grid_refresh = &refresh_clock;
// print_dbg("\r\ntime: ");
// print_dbg_ulong(time_fine);
Expand Down Expand Up @@ -3695,7 +3705,7 @@ void mp_note_on(uint8_t n) {
if(mp_clock_count < 1) {
mp_clock_count++;
note_now[0] = n;
set_cv_note(0, (int)cur_scale[7-n] + scale_adj[7-n]);
set_cv_note(0, (int)cur_scale[7-n] + scale_adj[7-n], 0);
set_tr(TR1);
}
break;
Expand All @@ -3704,7 +3714,7 @@ void mp_note_on(uint8_t n) {
mp_clock_count++;
w = get_note_slot(2);
note_now[w] = n;
set_cv_note(w, (int)cur_scale[7-n] + scale_adj[7-n]);
set_cv_note(w, (int)cur_scale[7-n] + scale_adj[7-n], 0);
set_tr(TR1 + w);
}
break;
Expand All @@ -3713,7 +3723,7 @@ void mp_note_on(uint8_t n) {
mp_clock_count++;
w = get_note_slot(4);
note_now[w] = n;
set_cv_note(w, (int)cur_scale[7-n] + scale_adj[7-n]);
set_cv_note(w, (int)cur_scale[7-n] + scale_adj[7-n], 0);
set_tr(TR1 + w);
}
break;
Expand Down Expand Up @@ -4529,7 +4539,7 @@ static void es_note_on(s8 x, s8 y, u8 from_pattern, u16 timer, u8 voices) {
note_index = 0;
else if (note_index > 119)
note_index = 119;
set_cv_note(note, note_index);
set_cv_note(note, note_index, 0);
dac_update_now();
set_tr(TR1 + note);

Expand Down
10 changes: 5 additions & 5 deletions src/ansible_ii_leader.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,10 @@ static void ii_mode_jf(i2c_follower_t* follower, uint8_t track, uint8_t mode) {
static void ii_octave_jf(i2c_follower_t* follower, uint8_t track, int8_t octave) {
int16_t shift;
if (octave > 0) {
shift = ET[12*octave] << 2;
shift = ET[12*octave];
}
else if (octave < 0) {
shift = -(ET[12*(-octave)] << 2);
shift = -(ET[12*(-octave)]);
}
else {
shift = 0;
Expand Down Expand Up @@ -225,10 +225,10 @@ static void ii_octave_txo(i2c_follower_t* follower, uint8_t track, int8_t octave
}
case 1: { // gate / cv
if (octave > 0) {
shift = ET[12*octave] << 2;
shift = ET[12*octave];
}
else if (octave < 0) {
shift = -(ET[12*(-octave)] << 2);
shift = -ET[12*(-octave)];
}
else {
shift = 0;
Expand Down Expand Up @@ -284,7 +284,7 @@ static void ii_cv_txo(i2c_follower_t* follower, uint8_t track, uint16_t dac_valu

switch (follower->active_mode) {
case 0: { // enveloped oscillator
dac_value = (int)dac_value + (ET[12*(4+follower->oct)] << 2);
dac_value = (int)dac_value + (int)ET[12*(4+follower->oct)];
d[0] = 0x40; // TO_OSC
d[1] = track;
d[2] = dac_value >> 8;
Expand Down
72 changes: 33 additions & 39 deletions src/ansible_midi.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
#include "i2c.h"
#include "gpio.h"
#include "dac.h"
#include "music.h"
#include "util.h"

#include "init_common.h"
#include "conf_tc_irq.h"
Expand Down Expand Up @@ -65,7 +67,7 @@ typedef enum {
static void write_midi_standard(void);
static void write_midi_arp(void);

static uint16_t pitch_cv(u8 num, s16 offset);
static void midi_pitch(uint8_t n, uint16_t note, int16_t bend);
static uint16_t velocity_cv(u8 vel);
static uint16_t cc_cv(u8 value);

Expand Down Expand Up @@ -137,23 +139,6 @@ static void player_note_off(u8 ch, u8 num, u8 vel);
//-----------------------------
//----- globals

// step = 16384.0 / (10 octave * 12.0 semitones per octave)
// [int(n * step) for n in xrange(0,128)]
const u16 SEMI14[128] = {
0, 136, 273, 409, 546, 682, 819, 955, 1092, 1228, 1365, 1501, 1638,
1774, 1911, 2048, 2184, 2321, 2457, 2594, 2730, 2867, 3003, 3140,
3276, 3413, 3549, 3686, 3822, 3959, 4096, 4232, 4369, 4505, 4642,
4778, 4915, 5051, 5188, 5324, 5461, 5597, 5734, 5870, 6007, 6144,
6280, 6417, 6553, 6690, 6826, 6963, 7099, 7236, 7372, 7509, 7645,
7782, 7918, 8055, 8192, 8328, 8465, 8601, 8738, 8874, 9011, 9147,
9284, 9420, 9557, 9693, 9830, 9966, 10103, 10240, 10376, 10513, 10649,
10786, 10922, 11059, 11195, 11332, 11468, 11605, 11741, 11878, 12014,
12151, 12288, 12424, 12561, 12697, 12834, 12970, 13107, 13243, 13380,
13516, 13653, 13789, 13926, 14062, 14199, 14336, 14472, 14609, 14745,
14882, 15018, 15155, 15291, 15428, 15564, 15701, 15837, 15974, 16110,
16247, 16384, 16520, 16657, 16793, 16930, 17066, 17203, 17339
};

// step = 16384.0 / (10 octave * 12.0 semitones per octave)
// semi_per_octave = step * 12
// bend_step = semi_per_octave / 512.0
Expand Down Expand Up @@ -227,6 +212,7 @@ static arp_player_t player[4];

// shared state
static s16 pitch_offset[4];
static s16 pitch_shift[4];
static midi_clock_t midi_clock;
static key_state_t key_state;
static clock_source sync_source;
Expand Down Expand Up @@ -350,9 +336,8 @@ void handler_MidiFrontLong(s32 data) {

////////////////////////////////////////////////////////////////////////////////
///// common cv utilities

inline static uint16_t pitch_cv(u8 num, s16 offset) {
return SEMI14[num] + offset;
inline static void midi_pitch(uint8_t n, uint16_t note, int16_t bend) {
set_cv_note(n, sclip((int)note + pitch_shift[n], 0, 120), bend);
}

inline static uint16_t velocity_cv(u8 vel) {
Expand Down Expand Up @@ -473,25 +458,35 @@ static void set_voice_slew(voicing_mode v, s16 slew) {
}
}

static int ticks_to_semitones(int16_t shift) {
uint16_t mag = abs(shift);
for (int i = 0; i < 120; i++) {
if (mag <= ET[i]) {
return shift < 0 ? -i : i;
}
}
return 0;
}

static void set_voice_tune(voicing_mode v, s16 shift) {
u8 i;

switch (v) {
case eVoicePoly:
case eVoiceMulti:
for (i = 0; i < 4; i++) {
dac_set_off(i, shift);
pitch_shift[i] = ticks_to_semitones(shift);
}
break;
case eVoiceMono:
dac_set_off(0, shift); // pitch
dac_set_off(1, 0); // velocity
dac_set_off(2, 0); // channel pressure
dac_set_off(3, 0); // mod
pitch_shift[0] = ticks_to_semitones(shift); // pitch
pitch_shift[1] = 0; // velocity
pitch_shift[2] = 0; // channel pressure
pitch_shift[3] = 0; // mod
break;
default:
for (i = 0; i < 4; i++) {
dac_set_off(i, 0);
pitch_shift[i] = 0;
}
break;
}
Expand Down Expand Up @@ -691,8 +686,7 @@ static void poly_pitch_bend(u8 ch, u16 bend) {

for (u8 i = 0; i < voice_state.count; i++) {
if (voice_slot_active(&voice_state, i)) {
dac_set_value(i, pitch_cv(voice_slot_num(&voice_state, i),
pitch_offset[0]));
midi_pitch(i, voice_slot_num(&voice_state, i), pitch_offset[0]);
}
}
dac_update_now();
Expand Down Expand Up @@ -737,7 +731,7 @@ static void mono_note_on(u8 ch, u8 num, u8 vel) {

// keep track of held notes for legato and pitch bend
notes_hold(&notes[0], num, vel);
dac_set_value(MONO_PITCH_CV, pitch_cv(num, pitch_offset[0]));
midi_pitch(MONO_PITCH_CV, num, pitch_offset[0]);
dac_set_value_noslew(MONO_VELOCITY_CV, velocity_cv(vel));
dac_update_now();
set_tr(TR1);
Expand All @@ -753,7 +747,7 @@ static void mono_note_off(u8 ch, u8 num, u8 vel) {
notes_release(&notes[0], num);
prior = notes_get(&notes[0], kNotePriorityLast);
if (prior) {
dac_set_value(MONO_PITCH_CV, pitch_cv(prior->num, pitch_offset[0]));
midi_pitch(MONO_PITCH_CV, prior->num, pitch_offset[0]);
dac_set_value(MONO_VELOCITY_CV, velocity_cv(prior->vel));
dac_update_now();
}
Expand All @@ -780,7 +774,7 @@ static void mono_pitch_bend(u8 ch, u16 bend) {
// re-set pitch to pick up changed offset
const held_note_t *active = notes_get(&(notes[0]), kNotePriorityLast);
if (active) {
dac_set_value(MONO_PITCH_CV, pitch_cv(active->num, pitch_offset[0]));
midi_pitch(MONO_PITCH_CV, active->num, pitch_offset[0]);
dac_update_now();
}
}
Expand Down Expand Up @@ -921,7 +915,7 @@ static void multi_note_on(u8 ch, u8 num, u8 vel) {
return;

notes_hold(&notes[ch], num, vel);
dac_set_value(ch, pitch_cv(num, pitch_offset[ch]));
midi_pitch(ch, num, pitch_offset[ch]);
dac_update_now();
multi_tr_set(ch);
}
Expand All @@ -937,7 +931,7 @@ static void multi_note_off(u8 ch, u8 num, u8 vel) {
if (flags[ch].legato) {
prior = notes_get(&notes[ch], kNotePriorityLast);
if (prior) {
dac_set_value(ch, pitch_cv(prior->num, pitch_offset[ch]));
midi_pitch(ch, prior->num, pitch_offset[ch]);
dac_update_now();
}
else {
Expand Down Expand Up @@ -971,7 +965,7 @@ static void multi_pitch_bend(u8 ch, u16 bend) {
// re-set pitch to pick up changed offset
const held_note_t *active = notes_get(&(notes[ch]), kNotePriorityLast);
if (active) {
dac_set_value(ch, pitch_cv(active->num, pitch_offset[ch]));
midi_pitch(ch, active->num, pitch_offset[ch]);
dac_update_now();
}
}
Expand Down Expand Up @@ -1462,10 +1456,10 @@ void ii_midi_arp(uint8_t *d, uint8_t l) {

if (v == 0) {
for (i = 0; i < 4; i++)
dac_set_off(i, s);
pitch_shift[i] = ticks_to_semitones(s);
}
else {
dac_set_off(v-1, s);
pitch_shift[v-1] = ticks_to_semitones(s);
}
break;

Expand Down Expand Up @@ -1605,7 +1599,7 @@ void restore_midi_arp(void) {
arp_player_set_offset(p, arp_state.p[i].offset);
arp_player_set_fill(p, arp_state.p[i].fill);

dac_set_off(i, arp_state.p[i].shift);
pitch_shift[i] = ticks_to_semitones(arp_state.p[i].shift);
dac_set_slew(i, arp_state.p[i].slew);
}

Expand Down Expand Up @@ -1797,7 +1791,7 @@ static void player_note_on(u8 ch, u8 num, u8 vel) {
}
*/

dac_set_value(ch, SEMI14[num]);
midi_pitch(ch, num, 0);
multi_tr_set(ch);
}

Expand Down
10 changes: 5 additions & 5 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ void flash_read(void) {
void default_tuning(void) {
for (uint8_t i = 0; i < 4; i++) {
for (uint8_t j = 0; j < 120; j++) {
tuning_table[i][j] = ET[j] << 2;
tuning_table[i][j] = ET[j];
}
}
flashc_memcpy((void *)f.tuning_table, tuning_table, sizeof(tuning_table), true);
Expand All @@ -476,7 +476,7 @@ void fit_tuning(int mode) {
for (uint8_t i = 0; i < 4; i++) {
uint16_t offset = tuning_table[i][0];
for (uint8_t j = 0; j < 120; j++) {
tuning_table[i][j] = (ET[j] << 2) + offset;
tuning_table[i][j] = ET[j] + offset;
}
}
break;
Expand Down Expand Up @@ -549,13 +549,13 @@ uint8_t get_tr(uint8_t n) {
return gpio_get_pin_value(n);
}

void set_cv_note(uint8_t n, uint16_t note) {
dac_set_value(n, tuning_table[n][note]);
void set_cv_note(uint8_t n, uint16_t note, int16_t bend) {
dac_set_value(n, (int16_t)tuning_table[n][note] + bend);
for (uint8_t i = 0; i < I2C_FOLLOWER_COUNT; i++) {
bool play_follower = followers[i].active
&& followers[i].track_en & (1 << n);
if (play_follower) {
uint16_t cv_transposed = ET[note] << 2;
uint16_t cv_transposed = (int16_t)ET[note] + bend;
followers[i].cv(&followers[i], n, cv_transposed);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ void set_mode(ansible_mode_t m);
void update_leds(uint8_t m);
void set_tr(uint8_t n);
void clr_tr(uint8_t n);
void set_cv_note(uint8_t n, uint16_t cv);
void set_cv_note(uint8_t n, uint16_t cv, int16_t bend);
void set_cv_slew(uint8_t n, uint16_t s);
void reset_outputs(void);
void toggle_follower(uint8_t n);
Expand Down

0 comments on commit f3a2acb

Please sign in to comment.