usynth

simple midi synth for sndio
git clone git://nsmpr.xyz/usynth.git
Log | Files | Refs

commit 5546160a531d4245ff1defba20c565f7ffbc6c55
parent a2acd5f1c8acbcab54a64c00fddbda89b52c2e85
Author: prenev <an2qzavok@gmail.com>
Date:   Sat, 10 Apr 2021 16:09:57 +0300

rework machine into array from struct

Diffstat:
Mmachine.c | 164++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mmachine.h | 32++++++++++++++++----------------
Musynth.c | 22+++++++++++++---------
3 files changed, 111 insertions(+), 107 deletions(-)

diff --git a/machine.c b/machine.c @@ -2,28 +2,33 @@ #include <assert.h> #include <stdio.h> #include <stdint.h> +#include <string.h> #include "wavetable.h" #include "machine.h" #include "tune.h" -typedef void (*instruction)(VM*, uint8_t); - -void vm_fatal(VM*, char*); -void vm_adsr(VM*); - -void i_halt(VM*, uint8_t); -void i_lit(VM*, uint8_t); -void i_fetch(VM*, uint8_t); -void i_op(VM*, uint8_t); -void i_adsr(VM*, uint8_t); -void i_wave(VM*, uint8_t); -void i_note(VM*, uint8_t); -void i_2dt(VM*, uint8_t); -void i_dup(VM*, uint8_t); -void i_drop(VM*, uint8_t); -void i_swap(VM*, uint8_t); -void i_add(VM*, uint8_t); -void i_comb(VM*, uint8_t); +#define TOS(x) (x[VM_STACK + x[VM_SP] - 1]) +#define STOS(x) (x[VM_STACK + x[VM_SP] - 2]) +#define DATA(x) (x[x[VM_PC]]) + +typedef void (*instruction)(int16_t*, uint8_t); + +void vm_fatal(int16_t*, char*); +void vm_adsr(int16_t*); + +void i_halt(int16_t*, uint8_t); +void i_lit(int16_t*, uint8_t); +void i_fetch(int16_t*, uint8_t); +void i_op(int16_t*, uint8_t); +void i_adsr(int16_t*, uint8_t); +void i_wave(int16_t*, uint8_t); +void i_note(int16_t*, uint8_t); +void i_2dt(int16_t*, uint8_t); +void i_dup(int16_t*, uint8_t); +void i_drop(int16_t*, uint8_t); +void i_swap(int16_t*, uint8_t); +void i_add(int16_t*, uint8_t); +void i_comb(int16_t*, uint8_t); instruction instructions[128] = { [I_HALT] = i_halt, @@ -43,7 +48,7 @@ instruction instructions[128] = { /*** simple hard-coded program ***/ -int16_t sprog[] = { +int16_t sprog[1024*3] = { I_NOTE, I_2DT, I_OP|0x0000, @@ -60,141 +65,136 @@ int16_t sprog[] = { }; void -vm_set(VM *vm) +vm_set(int16_t *vm) { - vm->prog = sprog; - vm->active = 0; + memcpy(&vm[VM_PROG_START], sprog, 1024 * 3); + vm[VM_ACTIVE] = 0; } int16_t -vm_run(VM *vm) +vm_run(int16_t *vm) { instruction inst; - if (vm->prog == 0) return 0; - if (vm->active == 0) return 0; - vm->halted = 0; - vm->pc = 0; - vm->sp = 0; - vm_adsr(vm); - while (vm->halted == 0) { - inst = instructions[0xff & vm->prog[vm->pc]]; + if (vm[VM_ACTIVE] == 0) return 0; + vm[VM_PC] = VM_PROG_START; + vm[VM_HALTED] = 0; + vm[VM_SP] = 0; + //vm_adsr(vm); + while (vm[VM_HALTED] == 0) { + inst = instructions[0xff & DATA(vm)]; if (inst == 0) vm_fatal(vm, "illegal instruction"); - vm->pc++; - inst(vm, vm->prog[vm->pc]>>8); + vm[VM_PC]++; + inst(vm, DATA(vm)>>8); } - return vm->stack[vm->sp-1]; + return TOS(vm); } void -vm_adsr(VM *vm) +vm_adsr(int16_t *vm) { - int i; - for (i=0; i<16; i++) { - vm->adsr[i] = vm->status * 0x7fff; - } + //int i; + //for (i=0; i<16; i++) { + // vm->adsr[i] = vm->status * 0x7fff; + //} } void -vm_fatal(VM* vm, char *errstr) +vm_fatal(int16_t* vm, char *errstr) { - dprintf(2, "VM FATAL: %s\n", errstr); - dprintf(2, "pc = %d\n", vm->pc); + dprintf(2, "int16_t FATAL: %s\n", errstr); + dprintf(2, "pc = %d\n", vm[VM_PC]); exit(-1); } void -i_halt(VM *vm, uint8_t arg) +i_halt(int16_t *vm, uint8_t arg) { - vm->halted = 1; + vm[VM_HALTED] = 1; } void -i_lit(VM *vm, uint8_t arg) +i_lit(int16_t *vm, uint8_t arg) { - vm->stack[vm->sp] = vm->prog[vm->pc]; - vm->sp++; - vm->pc++; + vm[VM_SP]++; + vm[VM_PC]++; + TOS(vm) = DATA(vm); } void -i_fetch(VM *vm, uint8_t arg) +i_fetch(int16_t *vm, uint8_t arg) { - vm->stack[vm->sp-1] = vm->prog[vm->stack[vm->sp-1]]; + TOS(vm) = vm[TOS(vm)]; } void -i_op(VM *vm, uint8_t arg) +i_op(int16_t *vm, uint8_t arg) { - vm->op[arg] += vm->stack[vm->sp-1]; - vm->stack[vm->sp-1] = vm->op[arg]; + vm[VM_OPERATORS + arg] += TOS(vm); + TOS(vm) = vm[VM_OPERATORS + arg]; } void -i_adsr(VM *vm, uint8_t arg) +i_adsr(int16_t *vm, uint8_t arg) { - vm->stack[vm->sp] = vm->adsr[arg]; - vm->sp++; } void -i_wave(VM *vm, uint8_t arg) +i_wave(int16_t *vm, uint8_t arg) { uint16_t d; - d = ((uint16_t)vm->stack[vm->sp-1]) / WT_LENGTH; + d = ((uint16_t)TOS(vm)) / WT_LENGTH; d = d%WT_LENGTH; - vm->stack[vm->sp-1] = wavetable[arg][d]; + TOS(vm) = wavetable[arg][d]; } void -i_note(VM *vm, uint8_t arg) +i_note(int16_t *vm, uint8_t arg) { - vm->stack[vm->sp] = vm->key; - vm->sp++; + vm[VM_SP]++; + TOS(vm) = vm[VM_KEY]; } void -i_2dt(VM *vm, uint8_t arg) +i_2dt(int16_t *vm, uint8_t arg) { - uint8_t note = vm->stack[vm->sp-1]; + uint8_t note = TOS(vm); int16_t dt = tune[note%12] * (1 << (note/12)); - vm->stack[vm->sp-1] = dt; + TOS(vm) = dt; } void -i_dup(VM *vm, uint8_t arg) +i_dup(int16_t *vm, uint8_t arg) { - vm->stack[vm->sp] = vm->stack[vm->sp-1]; - vm->sp++; + vm[VM_SP]++; + TOS(vm) = STOS(vm); } void -i_drop(VM *vm, uint8_t arg) +i_drop(int16_t *vm, uint8_t arg) { - vm->sp--; + vm[VM_SP]--; } void -i_swap(VM *vm, uint8_t arg) +i_swap(int16_t *vm, uint8_t arg) { int16_t b; - b = vm->stack[vm->sp-1]; - vm->stack[vm->sp-1] = vm->stack[vm->sp-2]; - vm->stack[vm->sp-2] = b; + b = TOS(vm); + TOS(vm) = STOS(vm); + STOS(vm) = b; } void -i_add(VM *vm, uint8_t arg) +i_add(int16_t *vm, uint8_t arg) { - vm->stack[vm->sp-2] += vm->stack[vm->sp-2]; - vm->sp--; + STOS(vm) += TOS(vm); + vm[VM_SP]--; } void -i_comb(VM *vm, uint8_t arg) +i_comb(int16_t *vm, uint8_t arg) { - vm->stack[vm->sp-2] = - vm->stack[vm->sp-1] * vm->stack[vm->sp-2] - / 0x7fff; - vm->sp--; + STOS(vm) = TOS(vm) * STOS(vm) / 0x7fff; + vm[VM_SP]--; } diff --git a/machine.h b/machine.h @@ -1,3 +1,4 @@ +/* VM's instructions */ enum { I_HALT = 0, /* * * * * */ @@ -17,22 +18,21 @@ enum { I_COMB, }; -#define SDEPTH 256 - -typedef struct VM VM; -struct VM { - int active; - int halted; - int status; - uint8_t key; - int16_t stack[SDEPTH]; - int16_t op[16]; - int16_t adsr[16]; - int16_t sp; - int16_t *prog; - int16_t pc; +/* VM's memory state */ +enum { + VM_PC, + VM_ACTIVE, + VM_HALTED, + VM_KEY, + VM_KEY_ON, + VM_OPERATORS = 128, + VM_SP, + VM_STACK = 256, + VM_PROG_START = 1024, + VM_MEM_END = 4096, }; -void vm_set(VM*); -int16_t vm_run(VM*); +int16_t* vm_malloc(void); +void vm_set(int16_t*); +int16_t vm_run(int16_t*); diff --git a/usynth.c b/usynth.c @@ -11,7 +11,7 @@ struct sio_hdl *sh; size_t bs; int16_t *sbuf; -VM vm; +int16_t* vm; void note_on(uint8_t*); void note_off(uint8_t*); @@ -45,11 +45,10 @@ main(void) m_init("midithru/0"); m_vector.note_on = note_on; m_vector.note_off = note_off; - vm_set(&vm); - //vm.active = 1; - //vm.status = 1; - //vm.key = 45; + vm = malloc(4096); + + vm_set(vm); while (1){ size_t n; @@ -62,14 +61,19 @@ main(void) void note_on(uint8_t *m) { - vm.active = 1; - vm.status = 1; - vm.key = m[2]; + vm[VM_ACTIVE] = 1; + vm[VM_KEY] = m[2]; + vm[VM_KEY_ON] = 1; } void note_off(uint8_t *m) { + if (vm[VM_KEY] == m[2]) { + // temporary + vm[VM_KEY_ON] = 0; + vm[VM_ACTIVE] = 0; + } } void @@ -77,6 +81,6 @@ fillbuf(int16_t* buf, size_t n) { size_t i; for (i=0; i < n; i+=2) { - buf[i] = buf[i+1] = vm_run(&vm); + buf[i] = buf[i+1] = vm_run(vm); } }