/*
  MidiSynth, MIDI synthesiser driver module for the MidiSupport system

  main.h - Common declarations and definitions

  created  19/01/10
  1.0      14/06/14
*/

#ifndef main_h
#define main_h

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "midi_spec.h"
#include "midi.h"
#include "instrument.h"

#ifndef FALSE
#define FALSE 0
#define TRUE !FALSE
#endif

#ifndef NULL
#define NULL 0
#endif

// Saturates 'x' to 'lo' or 'hi'
#define LIMIT(lo,x,hi) \
  if((x) < (lo)) (x) = (lo); \
  else if((x) > (hi)) (x) = (hi)

typedef unsigned long long int Uint64;
typedef signed long long int Int64;

// errors
enum
{
  NO_ERROR_,
  UNKNOWN_ERROR,
  CANNOT_ALLOCATE_MEMORY,
  PROBLEM_OPENING_FILE,
  INVALID_DATA,
  INVALID_SIZE,
  PROBLEM_READING_FILE,
  NO_INSTRUMENT,
  TOO_MANY_INSTRUMENTS,
  TOO_MANY_BANKS,
  TOO_MANY_WAVES,
  UNKNOWN_HEADING,
  NOT_EDITABLE,
  INVALID_CRC,
  NO_MELODICS_LINE,
  NO_BANK_LINE,
  NO_DRUM_LINE,
  NO_KIT_LINE,
  NO_PROGRAM_LINE,
  NO_KEY_LINE,
  INVALID_PROGRAM_NUMBER,
  INVALID_BANK_NUMBER,
  INVALID_KEY_NUMBER,
  INVALID_KIT_NUMBER,
  INVALID_INSTRUMENT_REF,
  NO_INSTRUMENT_NAME,
  INVALID_INSTRUMENT_NUMBER,
  INSTRUMENT_DELETED,
  WAVE_IN_USE,
  WAVE_OUT_OF_RANGE,
  NO_WAVEFORM,
  NUM_ERRORS
};

// shared sound audio buffer fill
typedef struct audio_s
{
  int size;                // length of circular buffer (samples not bytes)
  int read;                // read index (samples not bytes)
  int write;               // write index (samples not bytes)
  int rate_acc;            // fractional rate step accumulator (Q24)
  unsigned int *buffer;    // pointer to buffer of length 'size' samples (int's)
  int sys_base;            // system buffer base address
  int sys_end;             // system bufer end address
  int sys_rate;            // system sample rate (Q10)
  int sys_step;            // system fractional step (Q24)
  unsigned int sys_lr_vol; // system left/right volume (Q16 *2)
  int handler_id;          // shared sound handler id

} audio_t;

// general module data
#define AB_SIZE  2048 // audio buffer size in samples not bytes
typedef struct module_s
{
  // midi support
  int registered;     // true if we are registered with midi support
  int driver_number;
  int support_receive;
  int support_give;
  int support_pw;

  int sleep_timer;    // sleep when sleep_timer reaches sleep_timeout
  int sleep_timeout;  // activity timeout in centiseconds
  FILE *log;          // debugging log file handle
  unsigned int debug; // bitfield, see below
  unsigned int ticks; // current timestamp
  audio_t audio;      // audio data structure
  unsigned int buffer[AB_SIZE]; // audio buffer

} module_t;

// debug bitfield
#define DBG_MSG       0 // log midi messages
#define DBG_CALLBACKS 1 // log ticker callbacks

void inform_config(void);
extern module_t mod;

#endif
