/*
 * A sample program which dumps a Kawai K4 sysex dump to the
 * midi line (/dev/midi## version.).
 * Any incoming character aborts the dump.
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/soundcard.h>

#define BUFLEN 1024
#define MIDI_DEVICE_NUMBER	2	/* The third midi card in the system */
int fd;

main (int argc, char *argv[])
{
  unsigned char buf[BUFLEN];
  int i, tmp, n, p;

  if (argc != 2)
  {
  	fprintf(stderr, "usage: %s mididevice\n", argv[0]);
  	exit(-1);
  }

  if ((fd = open (argv[1], O_RDWR, 0)) == -1)
    {
      perror (argv[1]);
      exit (-1);
    }

  while ((n = read (0, buf, BUFLEN)) > 0)
    {
      if (write (fd, buf, n) != n)
      {
      	printf("/dev/sequencer: Write error\n");
      	exit(-1);
      }

      if (buf[n - 1] == 0xf7)	/* End of sysex */
	finished ();
    }

  fprintf (stderr, "Unexpected EOF\n");
  exit(-1);
}

int
die (char *s)
{
  fprintf (stderr, "%s", s);
  exit (-1);
}

int
finished ()
{
  int i, n;
  unsigned char buf[4];

  unsigned char reply[100];
  int replyp = 0;

  printf ("Ready\n");

  i = 100;	/* 1 sec */

   if (ioctl(fd, SNDCTL_MIDI_PRETIME, &i) == -1)
   {
   	perror("SNDCTL_MIDI_PRETIME");
   	exit(-1);
   }

  while (1)
    {
	if ((n=read(fd, buf, sizeof(buf)))==-1)
	{
		perror("midi dev");
		exit(-1);
	}

	for (i = 0; i < n; i++)
	  {
		if (buf[i] == 0xf0) /* Sysex start */
		   replyp=0;

		if (replyp < 100)
		  reply[replyp++] = buf[i];

		printf ("%02x ", buf[i]);
		fflush (stdout);
		if (buf[i] == 0xf7)	/* Sysex end */
		  {
		    printf ("\n");

		    if (reply[0] != 0xf0)
		      die ("Not sysex\n");
		    if (reply[1] != 0x40)
		      die ("Not Kawai sysex\n");
		    if (reply[2] != 0x00)
		      die ("Wrong reply channel\n");
		    if (reply[4] != 0x00)
		      die ("Kawai: Not a synthesizer\n");
		    if (reply[5] != 0x04)
		      die ("Kawai: Not K4/K4r\n");

		    if (reply[3] != 0x40)
		      {
			if (reply[3] == 0x41)
			  die ("Kawai: Write error\n");
			if (reply[3] == 0x42)
			  die ("Kawai: Write protect error\n");
			if (reply[3] == 0x42)
			  die ("Kawai: No card\n");
			die ("Kawai: Unknown error\n");
		      }
		    printf ("Uploaded OK\n");
		    exit (0);
		 }
	  }
     }
}
