/* transcribe.c -- keyboard to adagio recorder */

/*****************************************************************************
*	    Change Log
*  Date	    | Change
*-----------+-----------------------------------------------------------------
* 23-Feb-86 | Created changelog
*	    | Use pedal information when computing durations
*  5-May-86 | Changed data structure for speed
* 21-May-86 | Use record.c to implement record functions
* 26-May-86 | Incorporate cmdline.c
*  6-Aug-86 | Adapted to Lattice V3.00
*****************************************************************************/

#include "cext.h"
#include "stdio.h"
#include "cmdline.h"
#include "mpu.h"
#include "userio.h"
#include "record.h"

#define STOP_CC 1
#define STOP_CBRK 2
#define STOP_KEY 3
#define STOP_SPACE 4

#define num_voices 16

#define stop_code ' '
char stop_explanation[] = "Space bar";

extern int musictrace;
extern int miditrace;
extern int CBREAK;
extern int debug_intr;
extern int debug_rec;
boolean poll = false;		/* true if poll, false if interrupt */

#define nswitches 8
char *switches[nswitches] =
    { "-debug", "-d", "-help", "-miditrace", "-m", "-trace", "-t", "-block" };

#define noptions 3
char *options[noptions] = { "-c", "-control", "-tune" };

/****************************************************************************
*	Routines local to this module
****************************************************************************/
private	void	cmdline_help();
private boolean stop_check();

/****************************************************************************
*				 cmdline_help
* Effect: 
*	Prints out command line help
****************************************************************************/

private void cmdline_help()
{
    fprintf(stderr,"transcri [options] filename [options]\n");
    fprintf(stderr,"	 Options are below.\n");
    fprintf(stderr,"	   -block	     disable MIDI thru\n");
    fprintf(stderr,"	   -control (-c) on  record control info\n");
    fprintf(stderr,"	   -control (-c) off do not record control info\n");
    fprintf(stderr,"	   -debug (-d)	     enable verbose debug mode\n");
    fprintf(stderr,"	   -help	     this message\n");
    fprintf(stderr,"	   -miditrace (-m)   turn on MIDI command trace\n");
    fprintf(stderr,"	   -trace (-t)	     trace music\n");
}

/****************************************************************
*			main
* Effect:
*	transcribe from keyboard
****************************************************************/

void main(argc,argv)
   int argc;
   char *argv[];
{
    long time;			/* current time */
    boolean done = false;	/* set when recording is finished */
    int stop_reason;		/* reason recording is finished */
    char score_na[100];		/* score name */
    int i;			/* used to scan command line */
    char *strptr;		/* string pointer used to get file name */
    int ctrlflag;		/* record control info? */

    score_na[0] = NULL;		/* null string */

    cl_init(switches, nswitches, options, noptions, argv, argc);

    if (cl_switch("-help")) {
	cmdline_help(); 
	return;
    }

    if ((strptr = cl_arg(1)) != NULL)
	strcpy(score_na, strptr);

    if ((strptr = cl_noption(options, noptions)) != NULL) {
	ctrlflag = (strcmp(strptr, "on") == 0);
    } else {
	ctrlflag = askbool("Pitch bend, etc. on", false);
    }
    musicinit();

    /* reset all channels to MIDI program 1: */
    for (i = 0; i < num_voices; i++) {
	midi_program(i, 1);
    }

    if (!rec_init(score_na, ctrlflag)) {
	printf("No space for recording, use a smaller adagio file.\n");
	musicterm();
	exit(1);
    }

    printf("Transcribe ready.  Type space bar to stop.\n");

    timereset();
    while (!done) {
	time = gettime()/* delay everything by offset */;
	if (rec_poll(time)) {	/* record anything that's there */
	    done = true;
	    stop_reason = STOP_SPACE;
	}
	if (CBREAK || kbhit()) {
	    done |= stop_check(&stop_reason);
	}
	mpu_error_check();	/* look for buffer overflow */
    }
    rec_final(false);	/* write out recorded data, */
			/* suppress time of first event*/
    musicterm();
}

/****************************************************************************
*				     stop_check
* Outputs:
*	*reason is set to reason for stop
*	true is returned iff play should stop
* Effect: 
*	Checks for break character or stop code from kbd
****************************************************************************/

private boolean stop_check(reason)
    int *reason;
{
    boolean done = false;
    switch(CBREAK) { /* stop reason */
	case 0: /* no stop code, try keyboard */
	    done = (getch() == stop_code);
	    if (done) *reason = STOP_KEY;
	    break;
	case 1: /* ctrl-break */
	    done = true;
	    if (kbhit()) getch();
	    *reason = STOP_CBRK;
	    break;
	case 2: /* ctrl-C */
	    done = true;
	    *reason = STOP_CC;
	    if (kbhit()) getch();
	    break;
    } /* stop reason */
    return done;
}
