diff --git a/MyCode/App_Auto.c b/MyCode/App_Auto.c index 245f85c..445aac2 100644 --- a/MyCode/App_Auto.c +++ b/MyCode/App_Auto.c @@ -59,10 +59,11 @@ static uint8_t s_seq_po; #define ARP_CH 12 /* 逐音琶音;垫音通道同一拍会叠多个音,不参与网格 */ static uint8_t s_seq_step[16]; static struct { uint8_t ch, in, out, used; } s_seq_slot[SEQ_SLOTS]; -/* 红圈:同一拍叠上来的音向右 1 个音(图上 1 tik = 两个格子 = 一个八分音符)。 */ +/* 第 5 拍会叠来一个多余触发。丢掉它,不占发音顺序,第 6 个音就落在下一拍。 */ static uint32_t s_grid_t0; static uint16_t s_grid_unit; static uint8_t s_grid_on; +static uint8_t s_seq_drop; static uint16_t s_pending_hold_ms; static uint8_t s_slot_hold4[SEQ_SLOTS]; static volatile uint16_t s_hold_report; @@ -181,6 +182,7 @@ static int App_Auto_MapSeq(int channel, int key, int is_on, int *out) int i; s_pending_hold_ms = 0; + s_seq_drop = 0; App_Auto_SeqRefresh(); if (!s_seq_on || channel == BASS_CH || channel == DRUM_CH) return 0; @@ -192,8 +194,13 @@ static int App_Auto_MapSeq(int channel, int key, int is_on, int *out) if (s_seq_slot[i].used && s_seq_slot[i].ch == (uint8_t)ch && s_seq_slot[i].in == (uint8_t)key) { - *out = s_seq_slot[i].out; - s_pending_hold_ms = (uint16_t)s_slot_hold4[i] * 4u; + if (s_seq_slot[i].used == 2u) + s_seq_drop = 1u; + else + { + *out = s_seq_slot[i].out; + s_pending_hold_ms = (uint16_t)s_slot_hold4[i] * 4u; + } s_seq_slot[i].used = 0; s_slot_hold4[i] = 0; return 1; @@ -203,21 +210,44 @@ static int App_Auto_MapSeq(int channel, int key, int is_on, int *out) return 1; } { - uint8_t step = (uint8_t)(s_seq_step[ch] & 7u); + uint8_t step; uint32_t now; - *out = s_seq[step]; - s_seq_step[ch] = (uint8_t)((step + 1u) & 7u); - /* 琶音通道同一拍里的后一个音,晚一个八分音符再发出 */ + uint8_t piled = 0; if (ch == ARP_CH) { now = wk_timebase_get(); - if (s_grid_on && (now - s_grid_t0) < (uint32_t)(s_grid_unit / 4u)) - s_pending_hold_ms = s_grid_unit; - else + if (!s_grid_on || s_grid_unit == 0u + || (now - s_grid_t0) >= (uint32_t)(s_grid_unit / 4u)) s_grid_unit = App_Auto_EighthMs(); + piled = (s_grid_on + && (now - s_grid_t0) < (uint32_t)(s_grid_unit / 4u)) ? 1u : 0u; s_grid_t0 = now; s_grid_on = 1u; } + if (piled) + { + /* 同一拍的后一个触发不发声,也不占用下一个顺序音 */ + s_seq_drop = 1u; + for (i = 0; i < SEQ_SLOTS; i++) + { + if (!s_seq_slot[i].used) + { + s_seq_slot[i].used = 2u; + s_seq_slot[i].ch = (uint8_t)ch; + s_seq_slot[i].in = (uint8_t)key; + s_seq_slot[i].out = 0; + return 1; + } + } + s_seq_slot[0].used = 2u; + s_seq_slot[0].ch = (uint8_t)ch; + s_seq_slot[0].in = (uint8_t)key; + s_seq_slot[0].out = 0; + return 1; + } + step = (uint8_t)(s_seq_step[ch] & 7u); + *out = s_seq[step]; + s_seq_step[ch] = (uint8_t)((step + 1u) & 7u); } for (i = 0; i < SEQ_SLOTS; i++) { @@ -556,6 +586,8 @@ static int App_Auto_MapNoteOn(int channel, int key) } out = App_Auto_MapNote(channel, key, &flags, 1); + if (s_seq_drop) + return out; if (channel >= 0 && channel < 16) { uint16_t bit = (uint16_t)(1u << channel); @@ -610,6 +642,8 @@ static void Func_CallBack_NoteOff(int channel,int key) MidiFifoItem_t midimsg = {0}; uint8_t flags = 0; int out_key = App_Auto_MapNote(channel, key, &flags, 0); + if (s_seq_drop) + return; midimsg.msg[0] = 0x80 | (channel & 0x0F); midimsg.msg[1] = (uint8_t)out_key; midimsg.msg[2] = 0; @@ -630,6 +664,8 @@ static void Func_CallBack_NoteOn(int channel,int key,int vel) } else out_key = App_Auto_MapNoteOn(channel, key); + if (s_seq_drop) + return; midimsg.msg[0] = 0x90 | (channel & 0x0F); midimsg.msg[1] = (uint8_t)out_key;