Browse Source

Add start of midi events

master
cancel 6 years ago
parent
commit
9af409de76
  1. 19
      bank.c
  2. 29
      bank.h
  3. 5
      cli_main.c
  4. 109
      sim.c
  5. 3
      sim.h
  6. 10
      tui_main.c

19
bank.c

@ -96,3 +96,22 @@ fail:
*cursor = offset; *cursor = offset;
return 0; return 0;
} }
void oevent_list_init(Oevent_list* olist) {
olist->buffer = NULL;
olist->count = 0;
olist->capacity = 0;
}
void oevent_list_deinit(Oevent_list* olist) { free(olist->buffer); }
void oevent_list_clear(Oevent_list* olist) { olist->count = 0; }
Oevent* oevent_list_alloc_item(Oevent_list* olist) {
Usz count = olist->count;
if (olist->capacity == count) {
Usz capacity = count < 16 ? 16 : orca_round_up_power2(count);
olist->buffer = realloc(olist->buffer, capacity * sizeof(Oevent));
olist->capacity = capacity;
}
Oevent* result = olist->buffer + count;
olist->count = count + 1;
return result;
}

29
bank.h

@ -29,3 +29,32 @@ Usz bank_append(Bank* restrict bank, Usz cur_size, Usz index,
Usz bank_read(char const* restrict bank_data, Usz bank_size, Usz bank_read(char const* restrict bank_data, Usz bank_size,
Bank_cursor* restrict cursor, Usz index, I32* restrict dest, Bank_cursor* restrict cursor, Usz index, I32* restrict dest,
Usz dest_count); Usz dest_count);
typedef enum {
Oevent_type_midi,
} Oevent_types;
typedef struct {
U8 oevent_type;
U8 channel;
U8 octave;
U8 note;
U8 velocity;
U8 bar_divisor;
} Oevent_midi;
typedef union {
U8 oevent_type;
Oevent_midi midi;
} Oevent;
typedef struct {
Oevent* buffer;
Usz count;
Usz capacity;
} Oevent_list;
void oevent_list_init(Oevent_list* olist);
void oevent_list_deinit(Oevent_list* olist);
void oevent_list_clear(Oevent_list* olist);
Oevent* oevent_list_alloc_item(Oevent_list* olist);

5
cli_main.c

@ -101,13 +101,16 @@ int main(int argc, char** argv) {
markmap_reusable_ensure_size(&markmap_r, field.height, field.width); markmap_reusable_ensure_size(&markmap_r, field.height, field.width);
Bank bank; Bank bank;
bank_init(&bank); bank_init(&bank);
Oevent_list oevent_list;
oevent_list_init(&oevent_list);
Usz max_ticks = (Usz)ticks; Usz max_ticks = (Usz)ticks;
for (Usz i = 0; i < max_ticks; ++i) { for (Usz i = 0; i < max_ticks; ++i) {
orca_run(field.buffer, markmap_r.buffer, field.height, field.width, i, orca_run(field.buffer, markmap_r.buffer, field.height, field.width, i,
&bank, ORCA_PIANO_BITS_NONE); &bank, &oevent_list, ORCA_PIANO_BITS_NONE);
} }
markmap_reusable_deinit(&markmap_r); markmap_reusable_deinit(&markmap_r);
bank_deinit(&bank); bank_deinit(&bank);
oevent_list_deinit(&oevent_list);
field_fput(&field, stdout); field_fput(&field, stdout);
field_deinit(&field); field_deinit(&field);
return 0; return 0;

109
sim.c

@ -87,6 +87,50 @@ ORCA_PURE static bool oper_has_neighboring_bang(Glyph const* gbuf, Usz h, Usz w,
return false; return false;
} }
static U8 midi_note_number_of(Glyph g) {
switch (g) {
case 'C':
return 0;
case 'c':
return 1;
case 'D':
return 2;
case 'd':
return 3;
case 'E':
return 4;
case 'F':
return 5;
case 'f':
return 6;
case 'G':
return 7;
case 'g':
return 8;
case 'A':
return 9;
case 'a':
return 10;
case 'B':
return 11;
default:
return UINT8_MAX;
}
}
static ORCA_FORCE_NO_INLINE U8 midi_velocity_of(Glyph g) {
Usz n = index_of(g);
// scale [0,9] to [0,127]
if (n < 10) return (U8)(n * 14 + 1);
n -= 10;
// scale [0,25] to [0,127]
// js seems to send 1 when original n is < 10, and 0 when n is 11. Is that
// the intended behavior?
if (n == 0) return UINT8_C(0);
if (n >= 26) return UINT8_C(127);
return (U8)(n * 5 - 3);
}
ORCA_FORCE_NO_INLINE ORCA_FORCE_NO_INLINE
static void oper_movement_phase0(Gbuffer gbuf, Mbuffer mbuf, Usz const height, static void oper_movement_phase0(Gbuffer gbuf, Mbuffer mbuf, Usz const height,
Usz const width, Usz const y, Usz const x, Usz const width, Usz const y, Usz const x,
@ -127,6 +171,7 @@ typedef struct {
Bank_cursor cursor; Bank_cursor cursor;
Glyph const* vars_slots; Glyph const* vars_slots;
Piano_bits piano_bits; Piano_bits piano_bits;
Oevent_list* oevent_list;
} Oper_phase1_extras; } Oper_phase1_extras;
static void oper_bank_store(Oper_phase0_extras* extra_params, Usz width, Usz y, static void oper_bank_store(Oper_phase0_extras* extra_params, Usz width, Usz y,
@ -145,6 +190,9 @@ static Usz oper_bank_load(Oper_phase1_extras* extra_params, Usz width, Usz y,
&extra_params->cursor, index, out_vals, out_count); &extra_params->cursor, index, out_vals, out_count);
} }
// ORCA_FORCE_NO_INLINE
// static void oper_add_midi_event(Oper_phase1_extras* extra_params,
ORCA_FORCE_STATIC_INLINE ORCA_FORCE_STATIC_INLINE
Usz usz_clamp(Usz val, Usz min, Usz max) { Usz usz_clamp(Usz val, Usz min, Usz max) {
if (val < min) if (val < min)
@ -290,7 +338,8 @@ Usz usz_clamp(Usz val, Usz min, Usz max) {
#define ORCA_SOLO_OPERATORS(_) \ #define ORCA_SOLO_OPERATORS(_) \
_('!', keys) \ _('!', keys) \
_('#', comment) \ _('#', comment) \
_('*', bang) _('*', bang) \
_(':', midi)
#define ORCA_DUAL_OPERATORS(_) \ #define ORCA_DUAL_OPERATORS(_) \
_('A', 'a', add) \ _('A', 'a', add) \
@ -374,6 +423,36 @@ END_PHASE
BEGIN_SOLO_PHASE_1(bang) BEGIN_SOLO_PHASE_1(bang)
END_PHASE END_PHASE
BEGIN_SOLO_PHASE_0(midi)
BEGIN_ACTIVE_PORTS
for (Usz i = 1; 1 < 6; ++i) {
PORT(0, (Isz)i, IN);
}
END_PORTS
END_PHASE
BEGIN_SOLO_PHASE_1(midi)
STOP_IF_NOT_BANGED;
Glyph channel_g = PEEK(0, 1);
Glyph octave_g = PEEK(0, 2);
Glyph note_g = PEEK(0, 3);
Glyph velocity_g = PEEK(0, 4);
Glyph length_g = PEEK(0, 5);
U8 octave_num = (U8)index_of(octave_g);
if (octave_num == 0) return;
if (octave_num > 9) octave_num = 9;
U8 note_num = midi_note_number_of(note_g);
if (note_num == UINT8_MAX) return;
Usz channel_num = index_of(channel_g);
if (channel_num > 15) channel_num = 15;
Oevent_midi* oe = (Oevent_midi*)oevent_list_alloc_item(extra_params->oevent_list);
oe->oevent_type = (U8)Oevent_type_midi;
oe->channel = (U8)channel_num;
oe->octave = (U8)usz_clamp(index_of(channel_g), 1, 9);
oe->note = note_num;
oe->velocity = midi_velocity_of(velocity_g);
oe->bar_divisor = (U8)usz_clamp(index_of(length_g), 1, 16);
END_PHASE
BEGIN_DUAL_PHASE_0(add) BEGIN_DUAL_PHASE_0(add)
REALIZE_DUAL; REALIZE_DUAL;
BEGIN_DUAL_PORTS BEGIN_DUAL_PORTS
@ -960,20 +1039,22 @@ static void sim_phase_1(Gbuffer gbuf, Mbuffer mbuf, Usz height, Usz width,
} }
void orca_run(Gbuffer gbuf, Mbuffer mbuf, Usz height, Usz width, void orca_run(Gbuffer gbuf, Mbuffer mbuf, Usz height, Usz width,
Usz tick_number, Bank* bank, Piano_bits piano_bits) { Usz tick_number, Bank* bank, Oevent_list* oevent_list,
Piano_bits piano_bits) {
Glyph vars_slots[('Z' - 'A' + 1) + ('z' - 'a' + 1)]; Glyph vars_slots[('Z' - 'A' + 1) + ('z' - 'a' + 1)];
memset(vars_slots, '.', sizeof(vars_slots)); memset(vars_slots, '.', sizeof(vars_slots));
mbuffer_clear(mbuf, height, width); mbuffer_clear(mbuf, height, width);
Oper_phase0_extras bank_write_params; oevent_list_clear(oevent_list);
bank_write_params.bank = bank; Oper_phase0_extras phase0_extras;
bank_write_params.bank_size = 0; phase0_extras.bank = bank;
bank_write_params.vars_slots = &vars_slots[0]; phase0_extras.bank_size = 0;
sim_phase_0(gbuf, mbuf, height, width, tick_number, &bank_write_params); phase0_extras.vars_slots = &vars_slots[0];
Oper_phase1_extras bank_read_params; sim_phase_0(gbuf, mbuf, height, width, tick_number, &phase0_extras);
bank_read_params.bank = bank; Oper_phase1_extras phase1_extras;
bank_read_params.bank_size = bank_write_params.bank_size; phase1_extras.bank = bank;
bank_cursor_reset(&bank_read_params.cursor); phase1_extras.bank_size = phase0_extras.bank_size;
bank_read_params.vars_slots = &vars_slots[0]; bank_cursor_reset(&phase1_extras.cursor);
bank_read_params.piano_bits = piano_bits; phase1_extras.vars_slots = &vars_slots[0];
sim_phase_1(gbuf, mbuf, height, width, tick_number, &bank_read_params); phase1_extras.piano_bits = piano_bits;
sim_phase_1(gbuf, mbuf, height, width, tick_number, &phase1_extras);
} }

3
sim.h

@ -16,4 +16,5 @@ static inline Piano_bits piano_bits_of(Glyph g) {
} }
void orca_run(Gbuffer gbuf, Mbuffer markmap, Usz height, Usz width, void orca_run(Gbuffer gbuf, Mbuffer markmap, Usz height, Usz width,
Usz tick_number, Bank* bank, Piano_bits piano_bits); Usz tick_number, Bank* bank, Oevent_list* oevent_list,
Piano_bits piano_bits);

10
tui_main.c

@ -386,7 +386,8 @@ static Usz adjust_humanized_snapped(Usz ruler, Usz in, Isz delta_rulers) {
return delta_rulers > 0 ? ruler * (Usz)delta_rulers : 1; return delta_rulers > 0 ? ruler * (Usz)delta_rulers : 1;
} }
// could overflow if inputs are big // could overflow if inputs are big
if (delta_rulers < 0) in += ruler - 1; if (delta_rulers < 0)
in += ruler - 1;
Isz n = ((Isz)in - 1) / (Isz)ruler + delta_rulers; Isz n = ((Isz)in - 1) / (Isz)ruler + delta_rulers;
if (n < 0) if (n < 0)
n = 0; n = 0;
@ -508,6 +509,8 @@ int main(int argc, char** argv) {
bank_init(&bank); bank_init(&bank);
Undo_history undo_hist; Undo_history undo_hist;
undo_history_init(&undo_hist); undo_history_init(&undo_hist);
Oevent_list oevent_list;
oevent_list_init(&oevent_list);
// Enable UTF-8 by explicitly initializing our locale before initializing // Enable UTF-8 by explicitly initializing our locale before initializing
// ncurses. // ncurses.
@ -587,7 +590,7 @@ int main(int argc, char** argv) {
field_resize_raw_if_necessary(&scratch_field, field.height, field.width); field_resize_raw_if_necessary(&scratch_field, field.height, field.width);
field_copy(&field, &scratch_field); field_copy(&field, &scratch_field);
orca_run(field.buffer, markmap_r.buffer, field.height, field.width, orca_run(field.buffer, markmap_r.buffer, field.height, field.width,
tick_num, &bank, piano_bits); tick_num, &bank, &oevent_list, piano_bits);
field_copy(&scratch_field, &field); field_copy(&scratch_field, &field);
needs_remarking = false; needs_remarking = false;
} }
@ -724,7 +727,7 @@ int main(int argc, char** argv) {
case AND_CTRL('f'): case AND_CTRL('f'):
undo_history_push(&undo_hist, &field, tick_num); undo_history_push(&undo_hist, &field, tick_num);
orca_run(field.buffer, markmap_r.buffer, field.height, field.width, orca_run(field.buffer, markmap_r.buffer, field.height, field.width,
tick_num, &bank, piano_bits); tick_num, &bank, &oevent_list, piano_bits);
++tick_num; ++tick_num;
piano_bits = ORCA_PIANO_BITS_NONE; piano_bits = ORCA_PIANO_BITS_NONE;
needs_remarking = true; needs_remarking = true;
@ -786,5 +789,6 @@ quit:
field_deinit(&field); field_deinit(&field);
field_deinit(&scratch_field); field_deinit(&scratch_field);
undo_history_deinit(&undo_hist); undo_history_deinit(&undo_hist);
oevent_list_deinit(&oevent_list);
return 0; return 0;
} }

Loading…
Cancel
Save