usynth

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

fm.c (1451B)


      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <stdint.h>
      4 #include "operator.h"
      5 #include "wavetable.h"
      6 #include "fm.h"
      7 #include "machine.h"
      8 
      9 int16_t vol;
     10 
     11 int16_t
     12 clip(int64_t in)
     13 {
     14 	if (in > 0x7fff) return 0x7fff;
     15 	if (in < -0x7fff) return -0x7fff;
     16 	return in;
     17 }
     18 
     19 void
     20 fm_key_on(uint8_t *mm)
     21 {
     22 	int i;
     23 	int nmin, nmax;
     24 	Voice *v;
     25 	nmin = nmax = 0;
     26 	for (i = 0; i < 32; i++) {
     27 		if (fm_voices[i].id<fm_voices[nmin].id) nmin = i;
     28 		if (fm_voices[i].id>fm_voices[nmax].id) nmax = i;
     29 	}
     30 	v = &fm_voices[nmin];
     31 	v->id = fm_voices[nmax].id+1;
     32 	//v->channel = mm[1];
     33 	//v->key = mm[2];
     34 	//v->velocity = mm[3];
     35 	vms[nmin].status = 1;
     36 	vms[nmin].key = mm[2];
     37 	//v->pressure = 0;
     38 	vm_set(&vms[nmin], 0, 0);
     39 }
     40 
     41 void
     42 fm_key_off(uint8_t *mm)
     43 {
     44 	int i;
     45 	for (i=0; i<32; i++){
     46 		if (vms[i].key == mm[2]){
     47 			//fm_voices[i].velocity = mm[3];
     48 			vms[i].status = 0;
     49 			fm_voices[i].id = 0;
     50 		}
     51 	}
     52 }
     53 
     54 void
     55 fm_ctl_change(uint8_t *mm)
     56 {
     57 	fm_channels[mm[1]].control[mm[2]] = mm[3];
     58 }
     59 
     60 void
     61 fm_prog_change(uint8_t *mm)
     62 {
     63 	fm_channels[mm[1]].program = mm[2];
     64 }
     65 
     66 void
     67 fm_init(void)
     68 {
     69 	Channel *ch;
     70 	wt_init();
     71 	for (ch=fm_channels; ch<fm_channels+16; ch++){
     72 		ch->control[7]=0x7f;
     73 		ch->program = ch - fm_channels;
     74 	}
     75 }
     76 
     77 int16_t
     78 fm_mix(void)
     79 {
     80 	int64_t out;
     81 	int i;
     82 	out = 0;
     83 	for (i=0; i<32; i++) out += vm_run(&vms[i]);
     84 	return clip(out);
     85 }
     86 
     87 void
     88 fm_fillbuf(int16_t *buf, size_t nsamples)
     89 {
     90 	size_t i;
     91 	for (i=0; i < nsamples; i+=2){
     92 		buf[i] = buf[i+1] = fm_mix();
     93 	}
     94 }
     95