/*
 * seq.c -- Main program for MIDI daemon, controls sequencing of low level  
 *          event transmission to the actual MIDI hardware.
 *  
 *  Copyright 1998 John E. Stone
 *                 j.stone@acm.org
 *                 johns@cs.umr.edu
 *
 * $Id: seq.c,v 1.16 1998/02/18 06:40:59 johns Exp $
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <unistd.h>

#include "seq.h"
#include "realtime.h"
#include "daemon.h"
#include "msgq.h"

#include "devices.h"


int midioutloop(MidiSystem * midisystem) {
  MidiIOEvent event;
  QHandle midiq;

  if ((midiq = midiq_create(MIDIQ_OUT)) == NULL) {
    daemonprint("Couldn't create MIDI output event queue, output daemon aborting.\n");
    return -1;
  }

  daemonprint("MIDI Output Daemon Running...\n");
  daemonize();

  while (1) {
    if (midiq_read(midiq, &event) != -1) {
      if (event.msglen == -1)
        break; 

      MIDIDeviceWrite(midisystem, &event);
    }
  }

  midiq_delete(midiq, MIDIQ_OUT);

  return 0;
}


int midiinloop(MidiSystem * midisystem) {
  MidiIOEvent event;
  QHandle midiq;

  if ((midiq = midiq_create(MIDIQ_IN)) == NULL) {
    daemonprint("Couldn't create MIDI input event queue, input daemon aborting.\n");
    return -1;
  }

  daemonprint("MIDI Input Daemon Running...\n");
  daemonize();

  while (1) {
    if (MIDIDeviceRead(midisystem, &event) == -1)
      break;

    midiq_write(midiq, &event, MIDI_PRIORITY_NORMAL);
  }

  midiq_delete(midiq, MIDIQ_IN);

  return 0;
}


int main(int argc, char **argv) {
  char * name;
  MidiSystem midisystem;
  pid_t pid;
 
  if (argc < 2) {
    printf("MIDI Daemon:  No configuration file specified.  Aborting.\n");
    return -1;
  } 

  name = malloc(strlen(argv[1])+1);
  strcpy(name, argv[1]);

  if (InitMIDIDrivers(&midisystem) == -1) {
    printf("Couldn't Initialize MIDI drivers.  Aborting.\n");
    return -1;
  }

  if (ConfigMIDIDevices(name, &midisystem) == -1) {
    printf("Couldn't Configure MIDI system.  Aborting.\n");
    return -1;
  }

  if (make_realtime() == 0)
    daemonprint("Executing at real-time priority.\n");
  else
    daemonprint("Couldn't jump to real-time, running at standard priority.\n");

  if ((pid = fork()) == 0)
    midiinloop(&midisystem);
  else 
    midioutloop(&midisystem);

  return 0;
}

