/*
  synth.h
  -------
  definitions of the synth data structures that the editor is allowed access to.
*/


#ifndef synth_h
#define synth_h

// Synth module SWIs

#define MIDISynth_Control 0xca340
// Reason codes
#define SYN_POLY          1  // number of generators (polyphony)
#define SYN_GLIDE         2  // Glide time scale factor
#define SYN_SLEEP         3  // Sleep timeout
#define SYN_FLAGS         4  // Flags  // see bits below
#define SYN_RESET         5  // Synthesiser reset
#define SYN_BANKS         6  // Bank Override
#define SYN_KITS          7  // Drum Kit Override
#define SYN_DRUM          8  // Percussion Channel, default & current
#define SYN_VOL           9  // Master Volume
#define SYN_BAL          10  // Master Balance
#define SYN_COARSE       11  // Master Tuning Coarse
#define SYN_FINE         12  // Master Tuning Fine
#define SYN_SAVE         13  // Save Choices
// SYN_FLAGS flag bits
#define MONO_AUDIO        0  // 0=stereo, 1=mono
#define L_R_SWAP          1  // 0=normal, 1=L/R swapped
#define ALL_BANKS         2  // 0=GM bank only, 1=Allow all Banks to be selected via MIDI
#define ALL_KITS          3  // 0=GM drum kit only, 1=Allow all Drum Kits to be selected via MIDI
#define BANK_SEL_DRUM     4  // 0=fixed percussion channel, 1=allow bank hi 127 to select chan
#define PRG_UPDATES_BANKS 5  // 0=Bank nsgs actioned when rcvd, 1=Bank msgs actioned on the next Program change
#define CSV_NO_NUMBER     6  // 0=CSV bank map includes instrument number, 1=CSV bank map excludes instrument number
#define PATCH_NO_KITS     7  // 0=Patch list includes drum kits, 1=Patch list excludes drum kits
#define PATCH_BY_BANK     8  // 0=Patch's listed by program then bank, 1=Patch's listed by bank then program
#define FLAG_MASK ((1<<9)-1) // bit mask for above flags


#define MIDISynth_Edit    0xca341
// Reason codes
#define SYN_NULL          0  // no action, just return data
#define SYN_LOAD_USER     1  // Load user from the given patch
#define SYN_LOAD_INSTR    2  // Load user from the given instrument number
#define SYN_SAVE_USER     3  // Save user to the given patch
#define SYN_SAVE_INST     4  // Save user as new instrument at the given location: Hi,Lo,Prg
#define SYN_SAVE_NEW      5  // Save user as new instrument in the next bank up
#define SYN_DELETE        6  // Delete the current instrument
#define SYN_SAVE_FULL     7  // Save Sound Set to file.
#define SYN_SAVE_SET      8  // Save Sound Set without waveforms to file.
#define SYN_SAVE_SRC      9  // Save Sound Set in a variety of formats, see flag bits below
#define SYN_LOAD_DEF     10  // Load the default Sound Set.
#define SYN_LOAD_SET     11  // Load the Sound Set from file.
#define SYN_LOAD_CSV     12  // Load a CSV file and create a Sound Set.
#define SYN_EDIT_WAVE    13  // Control the use of the edit waveform by the user instrument
#define SYN_SAVE_WAVE    14  // Save / Delete wave harmonic data
// SYN_SAVE_INSTR "flags" values.
enum{CREATE_NEW, COPY_INSTR, MOVE_INSTR};
// SYN_SAVE_SRC "flags" bit numbers
enum{C_SRC, TXT_PATCH, CSV_MAP, TXT_LST};
// SYN_EDIT_WAVE "flags"
enum{EDIT_WAVE_OSC1, EDIT_WAVE_OSC2, EDIT_WAVE_MOD};


#define NUM_GENS 128  // maximum number of note generators that can be defined
#define NAME_LEN  24  // maximum length of names for instruments, banks, sound set, and waves, including terminating null.

// Instrument definition
// -------------------------------

#define NUM_TONES  2  // number of tone sources per generator

// Delay-Attack-Hold-Decay-Sustain-Release envelope definition
typedef struct env_s
{
  short int          // range for all envelope parameters is 0 to 32767
    delay,           // (delay * 2) ms, envelope delay time
    attack_step,     // (16384 / step) ms, attack time (linear)
    attack_target,   // attack target, linear, max = 0dB
    hold,            // (hold * 2) ms, attack target hold time
    decay_step,      // (131072 / step) ms, decay time constant (exponential)
    decay_target,    // decay target, linear, max = 0dB
    sustain_step,    // (131072 / step) ms, sustain time constant (exponential)
    release_step;    // (131072 / step) ms, release time constant (exponential)
} env_t;

// Tone generator definition
typedef struct tone_s
{
  short int
    number,          // tone wavetable number
    pitch,           // final pitch offset from key, midi key number, can be negative
    initial_pitch,   // starting point for glide, signed offset, if 0 use last key pitch (useful for mono)
    glide;           // pitch glide time constant, 0 = fastest, 32767 = slowest

  env_t env;         // envelope
} tone_t;

// Instrument definition
typedef struct ins_s
{
  char name[NAME_LEN]; // instrument name

  tone_t
    wave[NUM_TONES]; // tone generators

  env_t
    noise_env,       // noise generator envelope
    filter_env;      // filter envelope

  unsigned int
    switches;        // see below

  short int
    filter_fc,       // filter cutoff, midi key number, can be negative
    filter_q,        // filter resonance, 1023 = oscilate to 0 = overdamped.
    retrig,          // retrigger count in envelope periods
    mod_wave,        // modulation wavetable number
    mod_rate,        // modulation rate
    mod_depth,       // modulation amplitude
    fm_depth,        // FM modulation depth, tone1 = modulator, tone2 = carrier
    detune,          // tone 1 to 2 detune, 0 = none, 1023 = approx. 1 semitone
    gain;            // overall gain, Q10, 1024 = x1 or 0dB

  unsigned char
    master_env,      // 0=none, 1=wave[0], 2=wave[1], 3=filter, 4=noise
    spare;           // (unused)

} ins_t;

// bit locations of switches
//                       bit      value       description
//                       ---    ----------    ----------------------------
#define LOWPASS           0  // 0x00000001    lowpass filter                     )
#define BANDPASS          1  // 0x00000002    bandpass filter                    )
#define HIGHPASS          2  // 0x00000004    highpass filter                    )
#define FILTERED_TONE     3  // 0x00000008    filtered tone generator            ) accessed by sample rate interrupt
#define TONE1_OUT         4  // 0x00000010    tone 1 output enable               )
#define TONE2_OUT         5  // 0x00000020    tone 2 output enable               )
#define TONE_RING_MOD     6  // 0x00000040    tone 1 and tone 2 ring modulation  )
#define PITCH1_MOD        7  // 0x00000080    tone 1 pitch modulation
#define PITCH2_MOD        8  // 0x00000100    tone 2 pitch modulation
#define AMP1_MOD          9  // 0x00000200    tone 1 amplitude modulation (unsigned, or DSB full carrier)
#define AMP1_RING        10  // 0x00000400    tone 1 amplitude modulation (signed, or DSB suppressed carrier)
#define AMP2_MOD         11  // 0x00000800    tone 2 amplitude modulation (unsigned, or DSB full carrier)
#define AMP2_RING        12  // 0x00001000    tone 2 amplitude modulation (signed, or DSB suppressed carrier)
#define NOISE_MOD        13  // 0x00002000    noise amplitude modulation
#define FILTER_MOD       14  // 0x00004000    filter pitch modulation
#define WAVE_RETRIGGER   15  // 0x00008000    tone envelope retrigger
#define NOISE_RETRIGGER  16  // 0x00010000    noise envelope retrigger
#define FILTER_RETRIGGER 17  // 0x00020000    filter envelope retrigger
#define PITCH_TRACK      18  // 0x00040000    tone pitch key track
#define FILTER_TRACK     19  // 0x00080000    filter frequency key track
#define WAVE_ENV_TRACK   20  // 0x00100000    tone envelope time constant pitch track
#define NOISE_ENV_TRACK  21  // 0x00200000    noise envelope time constant pitch track
#define FILTER_ENV_TRACK 22  // 0x00400000    filter envelope time constant pitch track
#define INV_FILTER_ENV   23  // 0x00800000    inverted filter envelope
#define DEFINED_LENGTH   24  // 0x01000000    defined length, no key up required
#define MONO_SCAN        25  // 0x02000000    monophonic keyboard scan


#define SIN_BITS         10  // log2 number of samples in waveforms, and points in fft for harmonics translation.

#define NUM_HARMS        32  // number of stored harmonics for waveform definitions
typedef struct harm_s
{
  char name[NAME_LEN];
  struct hrm_s
  {
    short int re;
    short int im;
  } hrm[NUM_HARMS];
} harm_t;

// special bank hi values used in the patch list
#define PERCUSSION_BANK 127  // percussion kit selection bank Hi
#define PERCUSSION_INST 128  // percussion instrument edit bank Hi

// returned error numbers from the MidiSynth module
#define ERROR_BASE                0x821800
#define INVALID_INSTRUMENT_REF    (ERROR_BASE + 23) // Instrument number has no bank references (is not being used)
#define NO_INSTRUMENT_NAME        (ERROR_BASE + 24) // An instrument must have a name or it is considered deleted
#define INVALID_INSTRUMENT_NUMBER (ERROR_BASE + 25) // Instrument number outside range of numbers in store
#define INSTRUMENT_DELETED        (ERROR_BASE + 26) // Empty slot in store

#endif
