#ifndef _SYNTH_H
#define _SYNTH_H

#define PI 3.141592654f
#define TWOPI 6.283185308f

typedef unsigned char uint8;
typedef char int8;
typedef unsigned short uint16;
typedef short int16;
typedef unsigned int uint32;
typedef int int32;

#define Max4kChannels 16

__attribute__((packed)) struct T4kFileData {
 unsigned char WaveForm[Max4kChannels];
 unsigned char Link[Max4kChannels];
 float LinkFactor[Max4kChannels];
 float OutFactor[Max4kChannels];
 float StartVolume[Max4kChannels];
 float StartVolumeFactor[Max4kChannels];
 float StartPhaseFactor[Max4kChannels];
 unsigned char Panning[Max4kChannels];
 int EventOffset[Max4kChannels];
 int NoteOffset[Max4kChannels];
 int VolumeOffset[Max4kChannels];
};

__attribute__((packed)) struct T4kFilter {
 float FD1;
 float FD2;
 float FD3;
 float FD4;
 float FBLP;
 float FBHP;
 float CLP;
 float CHP;
 float RLP;
 float RHP; 
}; 

__attribute__((packed)) struct T4kADSRData {
 float AttackStep[Max4kChannels];
 float DecayStep[Max4kChannels];
 float DestDecay[Max4kChannels];
 unsigned char Sustain[Max4kChannels];
 float ReleaseStep[Max4kChannels];
};

__attribute__((packed)) struct T4kRealTimeData {
 unsigned char LinkFirst[Max4kChannels];
 float LinkValues[Max4kChannels];
 float Volume[Max4kChannels];
 float VolumeValue[Max4kChannels];
 float VolumeFactor[Max4kChannels];
 float ChannelLastLeft[Max4kChannels];
 float ChannelLastRight[Max4kChannels];
 int ADSRMode[Max4kChannels];
 float ADSRValue[Max4kChannels];
 float Phase[Max4kChannels];
 float PhaseIncrement[Max4kChannels];
 float PhaseFactor[Max4kChannels];
 struct T4kFilter Filter[Max4kChannels];
 float LastLeft;
 float LastRight;
 int TickCounter[Max4kChannels];
 unsigned char *EventOffset[Max4kChannels];
 unsigned char *NoteOffset[Max4kChannels];
 unsigned char *VolumeOffset[Max4kChannels];
 unsigned char *RestartEventOffset[Max4kChannels];
 unsigned char *RestartNoteOffset[Max4kChannels];
 unsigned char *RestartVolumeOffset[Max4kChannels];
 unsigned int BPMSamples;
 unsigned int CurrentBPMSamples;
 unsigned char ShouldExit;
};

__attribute__((packed)) struct T4kSynthData {
 struct T4kFileData FileData;
 struct T4kADSRData ADSRData;
 unsigned int InfoData;
 unsigned char EventData[0x200000];
 struct T4kRealTimeData RealtimeData;
};

#define SampleRate 44100
#define SampleRateFactor (float)(440.0f/SampleRate)
#define PortamentoFactor (float)(SampleRateFactor/16.0f)
#define Div8 (float)(1.0f/8.0f)
#define Div12 (float)(1.0f/12.0f)
#define Div64 (float)(1.0f/64.0f)
#define Div127 (float)(1.0f/127.0f)
#define Div255 (float)(1.0f/255.0f)
#define Div256 (float)(1.0f/256.0f)
#define Div65536 (float)(1.0f/65536.0f)
#define CutOffLowPassStartValue (float)(255.0f*Div256)
#define BufferSize 4096

void SynthInit(struct T4kSynthData *SynthData,unsigned char *TrackData,int TrackSize);
void SynthPoll(struct T4kSynthData *SynthData);
void SynthDone(struct T4kSynthData *SynthData);

#endif
