/* mm.c -- midi monitor */

/*****************************************************************************
*	    Change Log
*  Date	    | Change
*-----------+-----------------------------------------------------------------
*  7-Apr-86 | Created changelog
*****************************************************************************/

#include "cext.h"
#include "stdio.h"
#include "midicode.h"
#include "mpu.h"
#include "cmdline.h"

int bender;	/* record pitch bend etc.? */

/****************************************************************************
* Data for command line parsing
****************************************************************************/
#define nswitches 8
private char *switches[nswitches] = 
    { "-help", "-miditrace", "-m", "-trace", "-t", "-block", "-d", "-debug"};

#define noptions 1
private char *options[noptions] = { "-tune" };

/*****************************************************************************
*	Routines local to this module
*****************************************************************************/
private	void	output(); 
private	void	put_pitch();
private	void	showhelp();

/****************************************************************************
*				main
* Effect: prompts for parameters, starts monitor
****************************************************************************/

void main(argc, argv)
    int argc;
    char *argv[];
{
    int done = false;
    byte data[4];	/* midi input data buffer */

    cl_init(switches, nswitches, options, noptions, argv, argc);
    if (cl_switch("-help")) showhelp();

    bender = askbool("pitch bend etc. on", false);

    musicinit();
    while (getkey(false) != -1) ;
    midi_cont(bender);
    printf("Midi Monitor ready.	 Type Q to stop.\n");

    while (!done) {
	char c;
	if (kbhit()) {
	    c = getch();
	    if (tolower(c) == 'q') done = true;
	    else printf("type q to quit\n");
	}
	if (getbuf(false, data)) {
	    output(data);
	}
    }
    musicterm();
}

/****************************************************************************
*				output
* Inputs:
*	byte data[]: midi data buffer holding one command
* Effect: format and print  midi data
****************************************************************************/

private void output(data)
    byte data[];
{
    int command;	/* the current command */
    int chan;		/* the midi channel of the current event */

    command = data[0] & MIDI_CODE_MASK;
    chan = data[0] & MIDI_CHN_MASK;

    if (command == MIDI_ON_NOTE && data[2] != 0) {
	printf("Note On,  Chan %2d, Key %2d (", chan, data[1]);
	put_pitch(data[1] - 12);
	printf("), Vel %d\n", data[2]);
    } else if (command == MIDI_ON_NOTE /* && data[2] == 0 */) {
	printf("Note Off, Chan %2d, Key %2d (", chan, data[1]);
	put_pitch(data[1] - 12);
	printf("), Vel %d\n", data[2]);
    } else if (command == MIDI_CH_PROGRAM) {
	printf("Prog Chg, Chan %2d, Prog %2d\n", chan, data[1]);
    } else if (command == MIDI_CTRL) {
	printf("Ctrl Chg, Chan %2d, Ctrl %2d, Val %2d\n",
	       chan, data[1], data[2]);
    } else if (command == MIDI_TOUCH) {
	printf("A. Touch, Chan %2d, Val %2d\n", chan, data[1]);
    } else if (command == MIDI_BEND) {
	printf("P. Bend,  Chan %2d, Val %2d\n", chan,
	       (data[1] + (data[2]<<7)));
    }
}

/****************************************************************************
*				put_pitch
* Inputs:
*	int p: pitch number
* Effect: write out the pitch name for a given number
****************************************************************************/

private void put_pitch(p)
    int p;
{
    static char *ptos[] = {"c", "cs", "d", "ef", "e", "f", "fs", "g",
			   "gs", "a", "bf", "b"};
    printf("%s%d", ptos[p % 12], p / 12);
}

/****************************************************************************
*				showhelp
* Effect: print help text
****************************************************************************/

private void showhelp()
{
    fprintf(stderr,"mm is a midi monitor program, switches are:");
    fprintf(stderr,"       -block            disable MIDI thru\n");
    fprintf(stderr,"       -help             this message\n");
    fprintf(stderr,"       -miditrace (-m)   turn on MIDI command trace\n");
    fprintf(stderr,"       -trace (-t)       trace music\n");
    fprintf(stderr,"       -debug (-d)	     debug flag for cintr.c\n");
}
