/*
 * This software is released under GPL. If you don't know what that is
 * immediately point your webbrowser to  http://www.gnu.org and read
 * all about it.
 *
 * The short version: You can modify the sources for your own purposes
 * but you must include the new source if you distribute a derived  work.
 *
 * (C) 2002, 2003, 2004, 2005 Jens M Andreasen <ja@linux.nu>
 *
 *
 *
 *    (
 *     )
 *   c[]
 * 
 */ 


/*
// binary pattern 

#define oooo 0
#define oooi 1
#define ooio 2
#define ooii 3
#define oioo 4
#define oioi 5
#define oiio 6
#define oiii 7
#define iooo 8
#define iooi 9
#define ioio A
#define ioii B
#define iioo C
#define iioi D
#define iiio E
#define iiii F

#define B16_PASTE(a,b,c,d) 0x ## a ## b ## c ## d
#define B16(a,b,c,d)  B16_PASTE(a,b,c,d)
*/


#ifndef MX44_H
#define MX44_H

#include "mmx.h"
#include <pthread.h>

//#define OMNIMODE 


#ifdef OMNIMODE
// Tim suggested a smaller footprint
#define MIDICHANNELS 1 
#define CHANNELMASK 0x0   
#else
// Elsewise we are multitimbral
#define MIDICHANNELS 16
#define CHANNELMASK 0x0F
#endif

#define SAMPLES 32 // number of samples to produce before polling midi
#define ENVLOOP 2  // number of envelope updates during sample production

#define OPLOOP SAMPLES/ENVLOOP
#define OUTBUF SAMPLES * 2 // stereo == 2

/* 
 * Data for a running envelope
 * 
 */
typedef struct 
{
  // Each envelope has a current value ..
  mmx_t state02;  // d 
  mmx_t state13;  // d
 
  // .. and a precalculated +/- value to be added .. 
  mmx_t delta02; // d
  mmx_t delta13; // d
  // .. for exactly x samples ..
  int time[4][8];     // [op][step]
  int time_count[4];  // [op]

  // .. before being replaced by the next precalculated delta value
  int delta_value[4][9]; // [op][step]
  int step[4]; // op

  int sustain[4]; // middle level in the sustain loop
  int release[4]; // the release deltas cannot be precalculated

  int running; // bit 0 - 3 set while env still running
  int audible; // bit 0 - 3 set if this voice is in the mix
}Mx44env;

/*
 * Data for a single running voice
 *
 */
typedef struct _mx44voice
{

  // mmx_t samples[SAMPLES];
  //    mmx_t delay[1024]; // Delay on am/pm feedback;

  // intonation parameters
  int intonation[4][2]; // w (op) [amount | decay]

  // state of oscillators
  mmx_t state02;  // d (op 0, op 2) 
  mmx_t state13;  // d (op 1, op3)
  // frequency of oscillators
  mmx_t delta02;  // d 
  mmx_t delta13;  // d


  // Each oscillator is phase- and amplitude modulated
  // by every other oscillators previous output

  // Modulaton arguments are skewed diagonally as in:

  // x[3](op2,op1,op0,op3)
  // x[2](op1,op0,op3,op2)
  // x[1](op0,op3,op2,op1)
  // x[0](op3,op2,op1,op0)

  mmx_t pm[4]; // w
  mmx_t am[4]; // w

  // pseudo sin is averaged from two bumpy approximations
  // running 60 degrees apart at the same frequency. 
  // Optionally one part can be "octave doubled" and
  // crossmodulated to a second set of waweshapes.
  mmx_t od; // w (op)
  mmx_t complexwawe;

  // Magic Number Modulation
  mmx_t magicnumber;
  mmx_t magicmodulation;
  mmx_t magicmodulation2;

  // some switches
  mmx_t lowpass;
  mmx_t waweshape;

  // Stereo mix
  mmx_t mixL;     // w
  mmx_t mixR;     // w

  mmx_t wheel;    // w 

  // Final utput of oscillator 0,1,2,3
  mmx_t out;      // w


  short delay_index;
  short delay_time;
  int delay_osc_state;
  int delay_osc_delta;
  int delay_osc_amount;
  // Next voice in an asignment que (running, hold, released, silent)
  struct _mx44voice *next; 
  struct _mx44voice *previous; 
  
  // envelopes
  Mx44env env;
  

  unsigned char channel; // channel number
  unsigned char key;
  short padding[3];
}Mx44voice;

// The patch sets up the initial state according to
// key and velocity etc
#define WAWEBUTTON 1
#define WHEELBUTTON 2
#define INVERTWHEELBUTTON 4
#define LOWPASSBUTTON 8
#define WAWESHAPEBUTTON 16
#define PHASEFOLLOWKEYBUTTON 32
#define MAGICBUTTON 64

typedef struct // Mx44patch
{
  short  pm[4][4]; // [destination] [source]
  short  am[4][4];

  short mix[4][2]; // [op] [left | right]
  
  short  env_level[4][8]; // [op] [stage]
  short  env_time[4][8];

  short harmonic[4];

  short intonation[4][2]; // [op] [amount | decay]

  short detune[4];

  short velocityfollow[4];

  unsigned char od[4]; // octave doubling
  unsigned char button[4]; // WAWE, WHEEL, LOWPASS and WAWESHAPE

  // key bias
  short breakpoint[4];   // [op]
  short keybias[4][2];   // [op] [hi | lo value]
  // env keyfollow
  short keyfollow[4][2]; // [op] [attack | sustain-loop]
  // key velocity
  short velocity[4]; // [op]

  short phase[4][2]; // [op] [offset | velocityfollow]
  char name[32];

  short fx_delay[5]; // delay time, spread, feedback, modulation and outlevel
  short fx_overdrive; // distortion

  char lfo_button[2]; // loop, aftertouch .
  short lfo[6]; // lfo rate 1,  rate 2,  level 1, level 2, time 1 and time 2
  
  // unused //----------
  short mod_delay;
  short mod_keyfollow;
  short mod_freq;
  short mod_freq_keyfollow;
  short mod_freg_amount;
  short unused[46];
}
Mx44patch;


typedef struct { // Mx44state
  mmx_t mmxtmp[2];
  mmx_t wheel;


  Mx44voice *voices;
  Mx44voice *que[5]; // assigned, held, released, silent, excess held
  Mx44voice *last[4]; 
  Mx44voice *keyboard[MIDICHANNELS][128][4];
  int keyTable[128];
  // some controllers
  char holdpedal[MIDICHANNELS];
  short pitchbend[MIDICHANNELS];
  char modulation[MIDICHANNELS];
  char mod_now[MIDICHANNELS];


  pthread_mutex_t busy;
  pthread_t midi_thread; 
  pthread_attr_t midi_thread_attr; 
  struct sched_param midi_thread_param;



  int lfo_env_state[MIDICHANNELS];
  int lfo_rate_state[MIDICHANNELS];


  int current; // number of prerendered samples already delivered

  int isGraphic;
  int maxpoly;
  int samplerate;

  Mx44patch patch[128]; // preset patches
  Mx44patch tmpPatch[MIDICHANNELS]; // actual editable and sounding patch
  char patchNo[MIDICHANNELS]; // chosen preset number 
  char monomode[MIDICHANNELS];

}Mx44state;

extern  Mx44state* mx44_new(int maxpolyphony,char* patch_path); 
 // middle A == 440.0
extern  void mx44_reset(Mx44state* mx44,double tuningfork,int samplerate);
extern  void mx44_pgmchange(Mx44state* mx44,int channel,int patchnumber);
extern  void mx44_noteon(Mx44state* mx44,int channel,int key,int velocity);
extern  void mx44_noteoff(Mx44state* mx44,int channel,int key,int velocity);
extern  void mx44_pitchbend(Mx44state* mx44,int channel,int data1,int data2);
extern  void mx44_control(Mx44state* mx44,int channel,int control,int data);
extern  void mx44_chanpress(Mx44state* mx44,int channel,int data);

extern  void mx44_dispose(Mx44state * mx44);

#ifdef OMNIMODE
// syntax checking only ... 
// use with debugger at your own risk ..
extern void omni(Mx4state* mx4, int request,float* port_left, float* port_right)
#endif

extern  int mx44_play(Mx44state* mx44,short * stereo_out);

#endif

/*
Table comparing ratios between Thomas Young 
1799 well temperament to equal temperament

C 	1.0 	        1.0
C# 	1.055730636 	1.059463094
D 	1.119771437 	1.122462048
Eb 	1.187696971 	1.189207115
E 	1.253888072 	1.259921050
F 	1.334745462 	1.334839854
F# 	1.407640848 	1.414213562
G 	1.496510232 	1.498307077
Ab 	1.583595961 	1.587401052
A 	1.675749414 	1.681792831
Bb 	1.781545449 	1.781797436
B 	1.878842233 	1.887748625
C 	2.0	        2.0


    cent  == 1.0005777895  == 2^(1/1200)
100 cent  == cent^100 == one semitone


A table for Pythagorian tuning:

Pitch:	C	C#	D	Eb	E	F 	F#	G	G#	A	A#	B 	C
Cents:	0	113.7	203.9	294.1 	407.8	498	611.7	702	792.2 	905.9	996.1	1109.8	1200
Ratios:	1/1	2187    9/8	32/27 	81/64	4/3	729/512	3/2	128/81 	27/16	16/9	243/128	2/1
                / 2048	



A table for  meantone tuning by Pietro Aaron (1523).

Pitch:	C	C#	D	Eb	E	F 	F#	G	G#	A	A#	B 	C
Cents:	0	76.0	193.2	310.3	386.3 	503.4	579.5	696.8	772.6 	889.7	1006.8	1082.9	1200




A table for Werckmeister III (1691) is as follows:

Pitch:	C	C#	D	Eb	E	F 	F#	G	G#	A	A#	B 	C
Cents:	0	90.225	192.18	294.135	390.225 498.045	588.27	696.09	792.18 	888.27	996.09	1092.18	1200



A table for Young (1799):

Pitch:	C	C#	D	Eb	E	F 	F#	G	G#	A	A#	B 	C
Cents:	0	93.9	195.8	297.8	391.7 	499.9	591.9	697.9	795.8 	893.8	999.8	1091.8	1200




(new tuning :name 'just
     :ratios '((1 c)
               (16/15 cs)
               (9/8 d)
               (6/5 ds )
               (5/4 e)
               (4/3 f)
               (45/32 fs )
               (3/2 g)
               (8/5 gs )
               (5/3 a)
               (16/9 as)
               (15/8 b)
                 2/1))

(new tuning :name 'werckmeister3
     :cents '((0 c)
              (94 cs)
              (192 d)
              (278 ds)
              (390 e)
              (475 f)
              (588 fs)
              (696 g)
              (790 gs)
              (888 a)
              (975 as)
              (1092 b)
               1200))

*/




