/*
 * synth.c - main synthesizer control loops
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#include "synth.h"
#include "osc.h"
#include "loadsamples.h"

int synth_init(char * filename, instrument * synth) {
  waveform * wav;
  int i;

  wav = malloc(sizeof(waveform));

  if (readsample(filename, wav) != 0) {
    return -1;
  }
 
  for (i=0; i<NUMOSC; i++) {
    osc_init(&synth->osc[i], wav);
  }   

  synth_notesetup(synth);  
  synth_allnotesoff(synth);

  return 0;
} 


int synth_notesetup(instrument * synth) {
  int i;
  float freq;

  for (i=0; i<128; i++) {
    freq = 440.0 * pow(2.0, (i - 69) / 12.0);
    synth->note[i].freq = freq * ((float) FREQDIV);
  }

  return 0;
}

int synth_allnotesoff(instrument * synth) {
  int i;

  for (i=0; i<NUMOSC; i++) {
    osc_off(&synth->osc[i]);
    synth->oscnote[i] = -1;
  }
 
  for (i=0; i<128; i++) {
    synth->note[i].state = 0;
    synth->note[i].osc = -1;
  }
 
  return 0; 
}


int synth_note_on(instrument * synth, int midinote, unsigned char velocity) {
  int oscnum, i;

  if ((midinote < 0) || (midinote > 127))
    return 0;

  synth_note_off(synth, midinote); 

  oscnum = 0;
  for (i=0; i<NUMOSC; i++) {
    if (synth->oscnote[i] == -1) {
      oscnum = i;
      break;
    }
  }

  synth->note[midinote].state = 1;
  synth->note[midinote].osc = oscnum;
  synth->oscnote[oscnum] = midinote;
  osc_on(&synth->osc[oscnum], synth->note[midinote].freq, velocity);
    
  return 0;
}


int synth_note_off(instrument * synth, int midinote) {
  if (synth->note[midinote].state) {
    osc_off(&synth->osc[synth->note[midinote].osc]);    
    synth->oscnote[synth->note[midinote].osc] = -1;
  } 
  synth->note[midinote].state = 0; 
  synth->note[midinote].osc = -1; 
  
  return 0;
}


int synth_generate(instrument * synth, unsigned long len, long * outbuf) {
  int i;

  for (i=0; i<NUMOSC; i++) {
    osc_generate(&synth->osc[i], len, outbuf);
  }

  return 0;
}


