/* $Id */
/* $Log */
/*********************************************************************

This software module was originally developed by

Eric D. Scheirer (MIT Media Laboratory)

in the course of development of the MPEG-2 NBC/MPEG-4 Audio standard
ISO/IEC 13818-7, 14496-1,2 and 3. This software module is an
implementation of a part of one or more MPEG-2 NBC/MPEG-4 Audio tools
as specified by the MPEG-2 NBC/MPEG-4 Audio standard.  ISO/IEC gives
users of the MPEG-2 NBC/MPEG-4 Audio standards free license to this
software module or modifications thereof for use in hardware or
software products claiming conformance to the MPEG-2 NBC/ MPEG-4 Audio
standards. Those intending to use this software module in hardware or
software products are advised that this use may infringe existing
patents. The original developer of this software module and his/her
company, the subsequent editors and their companies, and ISO/IEC have
no liability for use of this software module or modifications thereof
in an implementation.

This software module is hereby released into the public domain.

***********************************************************************/

#ifndef _SAOL_SCHED_H

#define _SAOL_SCHED_H

#include "saol_interp.h"
#include "saol.h"

typedef struct instr_handle_struct {
  char *label;
  context *cx;
  instr_decl *id;
  double **input;
  double **output;
  struct hostvar_list_struct *hvl;
  int turnoff_notified;
  int make_sound;
  int origin;
  int inchan;
} instr_handle;

#define ORIGIN_SEND 1
#define ORIGIN_SCORE 2
#define ORIGIN_INSTR 3

typedef struct hostvar_list_struct {
  char *name;
  symbol *sym;
  double *val;
  asig_frame **asig;
  struct hostvar_list_struct *next;
  int width;
} hostvar_list;

typedef struct handle_list_struct {
  instr_handle *h;
  struct handle_list_struct *next;
} handle_list;

typedef struct scheduler_struct {
  double time;
  handle_list *active;
  struct event_list_struct *pending;
  int running;
} scheduler;

typedef struct {
  char *name;
  char *label;
  double time;
  double dur;
  double *val;
  instr_handle *h;
  int numval;
  int type;
} event;

typedef struct event_list_struct {
  event *ev;
  struct event_list_struct *next;
} event_list;

instr_handle *register_inst(sa_decoder *sa,instr_decl *id, context *cx, double dur);
void instr_output(context *cx, double *pf, int pf_ct);
void finish_output(sa_decoder *sa);
void bus_output(char *busname, context *cx, double *pf, int pf_ct);
void clear_busses(sa_decoder *sa);
void instr_turnoff(context *cx); 
void instr_extend(context *cx, double time);
double get_host_value(instr_handle *id, symbol *sym, int idx);
void set_host_value(instr_handle *id, char *varname, int idx, double val);
asig_frame *get_host_asig(instr_handle *id, symbol *sym, int idx);
void set_host_asig(instr_handle *id, symbol *sym,
		    int idx, asig_frame *asig);
void new_host_var(instr_handle *h, char *name, int width, int type);
int has_host_var(instr_handle *h, char *varname);

void start_scheduler(sa_decoder *sa);
void start_send_instrs(sa_decoder *sa,int numch);
void sched_add_events(sa_decoder *sa,event events[],int num);
void sched_run_kcycle(sa_decoder *sa);
void schedule_event(sa_decoder *sa,event *event);

double *event_actparam_list(event *ev);
event_list *remove_event(event_list *, event_list *);
void zero_instr_output(instr_handle *h);
void output_sound(sa_decoder *sa);

event_list *find_event_handle(instr_handle *h,int type);
event *make_event(int type, double time);

void make_global_context(sa_decoder *sa);
void add_global_table(context *cx, char *name, double *val);
void destroy_global_table(context *cx, char *name);
void destroy_inst(sa_decoder *sa,instr_handle *h);
void free_context(context *cx);

int parse_score(sa_decoder *sa,char *fn);
event *new_event(char **words, int num);

#define INSTR_EVENT 1
#define CONTROL_EVENT 2
#define TURNOFF_EVENT 3
#define TABLE_EVENT 4
#define TEMPO_EVENT 5
#define END_EVENT 6
#define MIDI_ON_EVENT 7
#define MIDI_OFF_EVENT 8
#define MIDI_CONTROL_EVENT 9
#define PROGRAM_CHANGE_EVENT 10
#define MIDI_TEMPO_EVENT 11

#endif
