/* Output from p2c, the Pascal-to-C translator */
/* From input file "tp_m2t13.pas" */


/*$R+,S+,D+,F+*/
/******************************************************************/
/* This is the C-version of MIDI2TeX. The majority of the source  */
/* is generated by P2C. Further adjustments were performed manually */
/*                                                                */
/*                                 19-9-93                        */
/******************************************************************/


#ifndef TP_DECL_H
#include "tp_decl.h"
#endif

#ifndef TP_MISC_H
#include "tp_misc.h"
#endif
#ifndef TP_DEBUG_H
#include "tp_debug.h"
#endif
#ifndef TP_M2TF4_H
#include "tp_m2tf4.h"
#endif
#ifndef TP_HEAP1_H
#include "tp_heap1.h"
#endif
#ifndef TP_MIDI_H
#include "tp_midi.h"
#endif

#include "tp_m2t16.h"

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>

#ifdef THINK_C
#include <console.h>
#include <Files.h>
FInfo fileInfo;
#endif

/* Set the stack size to be greater than the default. */
/* This declaration must go in the global data area.  */

#ifdef __TURBOC__
extern unsigned _stklen = 65536;
#endif


/*************************************************************/
static Void NewErrorExit()
{
/*************************************************************/
#ifdef __TURBOC__
Char Str1[128];

   if (_doserrno >0) {
     if (MidiFileOpened)
	fprintf(TexFile,"%% MIDI2TeX processing ended due to runtime error \n");
     sprintf(STR1, "...wait a minute, this was a runtime error, of type : %d ",_doserrno);
     ToBothEr(STR1);
     }

#endif
  if (MidiFileOpened) {
    if (MidiFile != NULL)
      fclose(MidiFile);
    MidiFile = NULL;
    if (TexFile != NULL)
		fclose(TexFile);
    TexFile = NULL;
#ifdef THINK_C
/* here we set the filetype and file creator of the TeX file for an easy switch to MSWord */
	CtoPstr(TeXFileName.p);
	GetFInfo(TeXFileName.p, 0, &fileInfo);
	fileInfo.fdType = *((unsigned long *) "TEXT");
	fileInfo.fdCreator = *((unsigned long *) "MSWD");
	SetFInfo(TeXFileName.p, 0, &fileInfo);
#endif
/*     freemem(TexBuf); /* this seems to be not necessary */
    WriteDebugInfo("Closing Midi & Tex File...");
  }
  if (DebugFileOpened) {
    if (DebugFile != NULL)
      fclose(DebugFile);
    DebugFile = NULL;
/*    freemem(DebBuf); /* this seems to be not necessary */
    if (Debug)
      printf("Closing up Debugging logger...\n");
  }
  /* free(Ms); */
  KillNotePool();
  KillNoteLists();
  for (i = 1; i <= NoTracks; i++)
    KillFilRec(&TrackArray[i - 1].FilRec);
}  /* NewErrorExit */


#define eps             3
#define eps_            0.1

boolean CheckChordNotes(Note1, Note2)
NoteRecord Note1, Note2;
{
  /*************************************************************/
  /*  This function checks if notes 1 and 2 form a chord       */
  /*************************************************************/
  boolean Result;

  switch (TimeDiff(Note1.StartTime, Note2.StartTime)) {

  case -3:
  case -2:
  case -1:
  case 0:
  case 1:
  case 2:
  case 3:
    if (Note1.NoteType == Note2.NoteType)
      Result = true;
    else
      Result = false;
    break;

  default:
    Result = false;
    break;
  }/* case */
  return Result;
}  /* CheckChordNotes */

#undef eps



/********************************************************/
 long NoteLength(ThisNote)
NoteRecord ThisNote;
{
  /********************************************************/
  return (TimeDiff(ThisNote.EndTime, ThisNote.StartTime));
}



/**************************************************************/
 Void ResetChordArray(ThisStack)
ChordRecord *ThisStack;
{
  /*************************************************************/
  memset(ThisStack, 0, sizeof(ChordArrayType));
}

/**************************************************************/
 Void ResetBeamArray(ThisArray)
BeamRecord *ThisArray;
{
  /*************************************************************/
  memset(ThisArray, 0, sizeof(BeamArrayType));
}

/**************************************************************/
 Void ResetAccKeys()
{
  /*************************************************************/
  long i, FORLIM;
  TrackRecord *WITH;

  FORLIM = ntracks;
  for (i = 0; i < FORLIM; i++) {
    WITH = &TrackArray[i];
    memset((&WITH->AccKey), 0, sizeof(AccKeyType));
  }
}


/******************************************************/
 Void SortChord(ThisTrack, ThisChord)
TrackRecord *ThisTrack;
ChordRecord *ThisChord;
{
  /******************************************************/
  long mn, mx, k, mean;
  NoteRecord *N, *P, *Nmx, *Nmn;
  long Border;
/*  Char STR1[256]; */

  mn = 32000;
  mx = 0;
  mean = 0;
  k = 0;
  N = ThisChord->StartNote;
  NextNote(ThisChord->EndNote, &P);
  do {
    mean += N->NoteVal;
    k++;
    if (N->NoteVal > mx) {
      mx = N->NoteVal;
      Nmx = N;
    }
    if (N->NoteVal < mn) {
      mn = N->NoteVal;
      Nmn = N;
    }
    NextNote(N, &N);
  } while (N != P);
  mean /= k;

  switch (ThisTrack->Clef) {

  case VIOLIN:
    Border = 70;
    break;

  case BASS:
    Border = 52;
    break;
  }

  if (mean > Border) {   /* put lowest last , staff should be down */
    if (ThisChord->EndNote == Nmn) {
      WriteDebugInfo("No sort necessary");
      return;
    }
    sprintf(STR1, "Exchanging note %3d with %3d",ThisChord->EndNote->NoteVal, Nmn->NoteVal);
    WriteDebugInfo(STR1);
    if (ThisChord->StartNote == Nmn)   /* else ???*/
      ThisChord->StartNote = ThisChord->EndNote;
    Exchange(&ThisTrack->NoteList, &Nmn, &ThisChord->EndNote);
    ThisChord->EndNote->ChordNote = true;
    Nmn->ChordNote = false;
    Nmn->Orient = DOWN;
    ThisChord->EndNote = Nmn;
    return;
  }
  /* with thistrack */
  if (ThisChord->EndNote == Nmx) {
    WriteDebugInfo("No sort necessary");
    return;
  }
  sprintf(STR1, "Exchanging note %3d with %3d",ThisChord->EndNote->NoteVal,Nmx->NoteVal);
  WriteDebugInfo(STR1);
  if (ThisChord->StartNote == Nmx)
    ThisChord->StartNote = ThisChord->EndNote;
  Exchange(&ThisTrack->NoteList, &Nmx, &ThisChord->EndNote);
  ThisChord->EndNote->ChordNote = true;
  Nmx->ChordNote = false;
  Nmx->Orient = UP;
  ThisChord->EndNote = Nmx;

  /* put highest note last, staff should be up */
}  /* SortChord */



/******************************************************/
 Void ChordFind(ThisTrack)
TrackRecord *ThisTrack;
{
  /******************************************************/
  long dstart;
  uchar VoidNotes;
  NoteRecord *N, *P, *Q_;
  boolean Chording;
  ChordRecord *WITH1;
/*   Char STR1[256]; */

  long FORLIM;

  WriteDebugInfo("Starting ChordFind");
  Chording = false;
  ThisTrack->ChStackPoint = 1;
  ThisTrack->ChStackEnd = 1;
  VoidNotes = 0;
  FirstNote(ThisTrack->NoteList, &N);
  FirstNote(ThisTrack->NoteList, &P);
  do {

    switch (N->Event) {

    case REST:   /* this should end any pending chords */
      break;

    case VOID:
      VoidNotes++;
      break;

    case NOTEON:
    case NOTEOFF:
      if (!Chording) {
	WITH1 = &ThisTrack->ChordArray[ThisTrack->ChStackPoint - 1];
	WITH1->StartNote = N;
	N->ChordNote = true;
	WITH1->NoNotes = 1;
	Chording = true;
      } else {  /* if Chording */
	PrevNote(N, &Q_);
	dstart = TimeDiff(N->StartTime, Q_->StartTime);
	if (N->NoteType == Q_->NoteType && dstart < QuantTime)
	{  /* notetypes and starttimes are equal */
	  WITH1 = &ThisTrack->ChordArray[ThisTrack->ChStackPoint - 1];
	  sprintf(STR1, "Note %3d in chord", N->NoteVal);
	  WriteDebugInfo(STR1);
	  N->ChordNote = true;
	  WITH1->EndNote = N;
	  WITH1->NoNotes++;
	} else {  /* note types or starttimes are not equal */
	  if (ThisTrack->ChordArray[ThisTrack->ChStackPoint - 1].NoNotes > 1)
	  {  /* there was a chord on the stack */
	    WriteDebugInfo("Finishing up a chord..");

	    ThisTrack->ChordArray[ThisTrack->ChStackPoint - 1].ChordFinished = true;
	    WITH1 = &ThisTrack->ChordArray[ThisTrack->ChStackPoint - 1];

	    /* start a possible beam at this chord's note */
	    WITH1->EndNote->ChordNote = false;
	    ThisTrack->ChStackPoint++;
	    WITH1 = &ThisTrack->ChordArray[ThisTrack->ChStackPoint - 1];
	    N->ChordNote = true;
	    WITH1->StartNote = N;
	    WITH1->NoNotes++;
	  } else {  /* there was no chord on the stack */
	    WITH1 = &ThisTrack->ChordArray[ThisTrack->ChStackPoint - 1];
	    WITH1->StartNote->ChordNote = false;
	    N->ChordNote = true;
	    WITH1->StartNote = N;
	    WITH1->NoNotes = 1;
	  }

	}
      }
      break;
      /* Event=NOTEON,NOTEOFF */
    }/* End Case */
    NextNote(N, &N);   /* repeat loop */
  } while (N != P);   /* FirstNote(NoteList) */

  WriteDebugInfo("Processed all events in the notelist");

  switch (ThisTrack->ChordArray[ThisTrack->ChStackPoint - 1].NoNotes) {
      /* WITH */

  case 2:
  case 3:
  case 4:
  case 5:
  case 6:
  case 7:
  case 8:
  case 9:
  case 10:  /* finish up chord */
    WITH1 = &ThisTrack->ChordArray[ThisTrack->ChStackPoint - 1];
    WITH1->ChordFinished = true;
    WITH1->EndNote->ChordNote = false;
    ThisTrack->ChStackEnd = ThisTrack->ChStackPoint;
    break;

  case 1:  /* Cancel the one-note-chord */
    WITH1 = &ThisTrack->ChordArray[ThisTrack->ChStackPoint - 1];
    WITH1->StartNote->ChordNote = false;
    WITH1->StartNote = NULL;
    ThisTrack->ChStackPoint--;
    ThisTrack->ChStackEnd = ThisTrack->ChStackPoint;
    break;

  case 0:  /* there are no notes in the stack */
    ThisTrack->ChStackPoint--;
    ThisTrack->ChStackEnd = ThisTrack->ChStackPoint;
    break;
  }/* CASE */

  sprintf(STR1, "Resorting %3d Chord(s) in this measure",ThisTrack->ChStackEnd);
  WriteDebugInfo(STR1);
  sprintf(STR1, "Before sort: %s",
	  ChordNoteList2String(STR1, ThisTrack->NoteList));
  /* WriteDebugInfo('Before sort: '+NoteList2String(NoteList)); */
  WriteDebugInfo(STR1);
  FORLIM = ThisTrack->ChStackEnd;
  for (i = 1; i <= FORLIM; i++)
    SortChord(ThisTrack, &ThisTrack->ChordArray[i - 1]);
  sprintf(STR1, "After sort: %s",
	  ChordNoteList2String(STR1, ThisTrack->NoteList));
  /* WriteDebugInfo('After sort: '+NoteList2String(NoteList)); */
  WriteDebugInfo(STR1);
  sprintf(STR1, "Number of void notes found in this measure by chordfind:%3d",
	  VoidNotes);
  WriteDebugInfo(STR1);
  WriteDebugInfo("ChordFind ready");
}  /* ChordFind */

#undef eps_

/******************************************************/
 long FindSlurrIndex()
{
  /******************************************************/
  long i;

  i = 0;
  while (SlurrIndexes[i]==true && i < MAXSLURR)
    i++;
  if (i >= MAXSLURR)
    ErrorExit(16L);
  SlurrIndexes[i] = true;
  return i;
}

/*********************************************************/
long IsSlurred(N, ThisTrack)
NoteRecord *N;
TrackRecord *ThisTrack;
{
  /******************************************************/
  long i, B, FORLIM;
  SlurrRecord *WITH;

  B = 0;
  FORLIM = ThisTrack->SlurrPt;
  for (i = 1; i <= FORLIM; i++) {
    WITH = &(ThisTrack->SlurrArray[i - 1]);
    if (WITH->Occupied==true && WITH->NotePnt == N)
      B = i;
  }
  return B;
}


/********************************************************/
 Void FindSlurrNote(ThisTrack, CurMeasure)
TrackRecord *ThisTrack;
long CurMeasure;
{
  /********************************************************/
  NoteRecord *N, *P;
  long SlurrI1, SlurrI2;
  MeasureTime TmpTime;
  SlurrRecord *WITH2;
/*   Char STR1[256]; */

  WriteDebugInfo("Starting SlurrFinder");
  SetTim(&TmpTime, (int)(CurMeasure + 1), 0);
  FirstNote(ThisTrack->NoteList, &N);
  P = N;
  do {   /* with TrackList */
    switch (N->Event) {

    case REST:   /* A rest occurred, their ought not to be any slurrs */
      break;

    case NOTEON:
    case NOTEOFF:
      if (TimeDiff(TmpTime, N->EndTime) < 0) {
	/* The EndTime of this note is beyond the end of current measure */
	/* So, slurr this note */
	SlurrI2 = IsSlurred(N, ThisTrack);
	if (SlurrI2 == 0) {   /* was not already slurred */
	  SlurrI1 = FindSlurrIndex();
	  ThisTrack->SlurrPt++;
	  WITH2 = &ThisTrack->SlurrArray[ThisTrack->SlurrPt - 1];
	  sprintf(STR1, "At note %3d a startslurr", N->NoteVal);
	  WriteDebugInfo(STR1);
	  WITH2->NotePnt = N;
	  WITH2->NoteVal = N->NoteVal;
	  WITH2->KindOf = STARTSLUR;
	  WITH2->Numb1 = SlurrI1;
	  WITH2->Occupied = true;
	  ThisTrack->Slurring = true;
	  /*Slurring:=FALSE;*/
	  /* this disables slurring for test purpose */
	}  /* If SlurrI2=0 */
	else {
	  /* Note was already slurred.  */
	  SlurrI1 = FindSlurrIndex();
	  WITH2 = &ThisTrack->SlurrArray[ThisTrack->SlurrPt - 1];
	  sprintf(STR1, "At note %3d a repeatslurr", N->NoteVal);
	  WriteDebugInfo(STR1);
	  WITH2->KindOf = REPEATSLUR;
	  WITH2->Numb2 = WITH2->Numb1;
	  WITH2->Numb1 = SlurrI1;
	}
      } else {
	/* The EndTime of this note is in current measure */
	if (ThisTrack->Slurring) {
	  SlurrI2 = IsSlurred(N, ThisTrack);
	  if (SlurrI2 > 0) {   /* this note was slurred */
	    WITH2 = &ThisTrack->SlurrArray[SlurrI2 - 1];
	    sprintf(STR1, "At note %3d end slurr", N->NoteVal);
	    WriteDebugInfo(STR1);
	    WITH2->KindOf = ENDSLUR;
	    WITH2->Numb2 = WITH2->Numb1;
	  }
	}
      }
      break;
    }/* case */
    NextNote(N, &N);
  } while (N != P);   /* FirstNote(NoteList) */
}  /* FindSlurrNote*/


/******************************************************************/
 Void ChopRest(N, ThisTrack, ThisMsre)
NoteRecord **N;
TrackRecord *ThisTrack;
long ThisMsre;
{
  /******************************************************************/
  NoteRecord *P;
  long dt;
  MeasureTime TmpTime;
  unsigned short DivTime, divider;
  uchar cnt;
/*  Char STR1[256]; */

  WriteDebugInfo("Starting ChopRest ");

  SetTim(&TmpTime, (int)(ThisMsre + 1), 0);
  dt = TimeDiff((*N)->EndTime, TmpTime);
  if (dt > 0) {   /* Rest is longer than and of current measure */
    WriteDebugInfo("Chopping rest off at end of this measure");
    P = GetFreeNote();
    Insert(&ThisTrack->NoteList, (*N)->Next, P);
    P->EndTime = (*N)->EndTime;
    P->StartTime = TmpTime;
    (*N)->EndTime = TmpTime;
    P->Event = REST;
  }
  dt = TimeDiff((*N)->EndTime, (*N)->StartTime);
  DivTime = PieceContr.Division * 8;
  cnt = 0;
  while (dt > PieceContr.Division / 8) {
    divider = 0;
    while (divider == 0) {
      DivTime >>= 1;
      divider = dt / DivTime;
      cnt++;
    }
    SetTim(&TmpTime, 0, DivTime);
    AddTime((*N)->StartTime, TmpTime, &TmpTime);
    (*N)->NoteType = (NoteTypes)cnt;
    dt -= divider * DivTime;
    if (dt <= PieceContr.Division / 16)
      continue;
    P = GetFreeNote();
    Insert(&ThisTrack->NoteList, (*N)->Next, P);
    P->Event = REST;
    P->EndTime = (*N)->EndTime;
    (*N)->EndTime = TmpTime;
    P->StartTime = TmpTime;
    sprintf(STR1, "Chopping rest into: [%3ld:%3ld-%3ld:%3ld]and [%3ld:%3ld-%3ld:%3ld]",
	    (*N)->StartTime.Measure,(*N)->StartTime.MPart,
	    (*N)->EndTime.Measure, (*N)->EndTime.MPart,
	    P->StartTime.Measure,  P->StartTime.MPart,
	    P->EndTime.Measure, P->EndTime.MPart);
    WriteDebugInfo(STR1);
    *N = P;
  }  /* while */
  WriteDebugInfo("End ChopRest");
}  /* ChopRest */


/******************************************************/
 Void FindNoteTypes(ThisTrack, ThisMsre)
TrackRecord *ThisTrack;
long ThisMsre;
{
  /******************************************************/
  NoteRecord *N, *P;
  long dt, Divisor, Rst;
  MeasureTime TmpTime;
  NoteRecord *WITH1;
/*  Char STR1[256]; */

  FirstNote(ThisTrack->NoteList, &N);
  P = N;
  do {   /* with TrackList */
    WITH1 = N;   /* WIth N^ */

    switch (WITH1->Event) {

    case NOTEON:
    case NOTEOFF:
      switch (ThisTrack->Clef) {

      case VIOLIN:
	if (WITH1->NoteVal > 70)
	  WITH1->Orient = DOWN;
	else
	  WITH1->Orient = UP;
	break;

      case BASS:
	if (WITH1->NoteVal > 52)
	  WITH1->Orient = DOWN;
	else
	  WITH1->Orient = UP;
	break;
      }
      break;
    }

    switch (WITH1->Event) {

    case NOTEON:
      WriteDebugInfo("Found a non-closed note");
      sprintf(STR1, "Starting at %3d:%3d",(int)WITH1->StartTime.Measure,
	      (int)WITH1->StartTime.MPart);
      WriteDebugInfo(STR1);
      sprintf(STR1, "Ending at %3d:%3d",(int)WITH1->EndTime.Measure,
	      (int)WITH1->EndTime.MPart);
      WriteDebugInfo(STR1);
      /* this prevent that the endtimes (1000) of non-closed notes */
      /* faul up the selection of the notetype */
      SetTim(&TmpTime, (int)(ThisMsre + 1), 0);
      break;

    /* if the note ends in this measure, check if its length is */
    /* longer than a whole note */
    /* check if a noteoff is shut off in this measure */
    default:
      SetTim(&TmpTime, (int)(ThisMsre + 1), 0);
      dt = TimeDiff(TmpTime, WITH1->EndTime);
      if (dt >= 0)   /* Note is closed in this measure ... */
	TmpTime = WITH1->EndTime;
      break;
    }/* case */


    if (Quantizing)
      Quantize(&N);

    /* DO not use EndTime but the previously defined TmpTime */
    dt = TimeDiff(TmpTime, WITH1->StartTime);
    if (dt < 0)
      WriteDebugInfo("Found an event with neg length !");
    if (dt > 0) {
      if (PieceContr.Division > dt) {
	Divisor = PieceContr.Division / dt;
	Rst = PieceContr.Division % dt * 10 / dt;
/* p2c: tp_m2t13.pas, line 546:
 * Note: Using % for possibly-negative arguments [317] */
	switch (Divisor) {

	case 1:
	  switch (Rst) {

	  case 0:
	  case 1:
	  case 2:
	    WITH1->NoteType = Q;
	    break;

	  case 3:
	  case 4:
	    WITH1->NoteType = CP;
	    break;

	  case 5:
	  case 6:
	  case 7:
	  case 8:
	  case 9:
	    WITH1->NoteType = C;
	    break;
	  }
	  break;

	case 2:
	  switch (Rst) {

	  case 0:
	  case 1:
	  case 2:
	  case 3:
	  case 4:
	    WITH1->NoteType = C;
	    break;

	  case 5:
	  case 6:
	  case 7:
	  case 8:
	    WITH1->NoteType = CCP;
	    break;

	  case 9:
	    WITH1->NoteType = C3;
	    break;
	  }
	  break;

	case 3:
	  switch (Rst) {

	  case 0:
	  case 1:
	  case 2:
	  case 3:
	  case 4:   /* 1/8 trioler */
	    WITH1->NoteType = C3;
	    break;

	  case 5:
	  case 6:
	  case 7:
	  case 8:
	  case 9:
	    WITH1->NoteType = CC;
	    break;
	  }
	  break;

	case 4:
	  WITH1->NoteType = CC;
	  break;

	case 5:
	case 6:   /* 1/16 trioler */
	  WITH1->NoteType = CC3;
	  break;

	case 7:
	case 8:
	case 9:
	case 10:
	case 11:
	case 12:
	  WITH1->NoteType = CCC;
	  break;

	default:
	  WITH1->NoteType = CCCC;
	  break;
	}
      } else {  /* if Division<dt */
	Divisor = dt / PieceContr.Division;
	Rst = dt % PieceContr.Division * 10 / PieceContr.Division;
/* p2c: tp_m2t13.pas, line 573:
 * Note: Using % for possibly-negative arguments [317] */
	switch (Divisor) {

	case 1:
	  switch (Rst) {

	  case 0:
	  case 1:
	    WITH1->NoteType = Q;
	    break;

	  case 2:
	  case 3:   /* These notes should be slurred  */
	    WITH1->NoteType = QPP;
	    break;

	  case 4:
	  case 5:
	  case 6:
	    WITH1->NoteType = QP;
	    break;

	  case 7:
	  case 8:   /* should be longer */
	    WITH1->NoteType = QP;
	    break;

	  case 9:
	    WITH1->NoteType = H;
	    break;
	  }
	  break;

	case 2:
	  switch (Rst) {   /* dit klopt nog niet ... */

	  case 0:
	  case 1:
	    WITH1->NoteType = H;
	    break;

	  case 2:
	  case 3:
	    WITH1->NoteType = HPPP;
	    break;

	  case 4:
	  case 5:
	  case 6:
	    WITH1->NoteType = HPP;
	    break;

	  case 7:
	  case 8:
	    WITH1->NoteType = HP;
	    break;

	  case 9:
	    WITH1->NoteType = HP;
	    break;
	  }
	  break;

	case 3:
	  switch (Rst) {

	  case 0:
	  case 1:
	  case 2:
	  case 3:
	  case 4:
	    WITH1->NoteType = HP;
	    break;

	  case 5:
	  case 6:
	  case 7:
	  case 8:
	  case 9:
	    WITH1->NoteType = WH;
	    break;
	  }
	  break;

	case 4:
	  switch (Rst) {

	  case 0:
	  case 1:
	  case 2:
	  case 3:
	    WITH1->NoteType = WH;
	    break;

	  case 4:
	  case 5:
	  case 6:
	  case 7:
	  case 8:
	  case 9:
	    WITH1->NoteType = WHPP;
	    break;
	  }
	  break;

	case 5:
	  WITH1->NoteType = WHPP;
	  break;

	case 6:
	  WITH1->NoteType = WHP;
	  break;
	}
      }
    } else {
      /* Do not show note, it has length zero ! */
      if (WITH1->Event == TXT)
	WriteDebugInfo("Hey, here is that metatext again..");
      else {
	WITH1->Event = VOID;
	WriteDebugInfo("Found a void note");
      }
    }
    /* If Event=REST Then ChopRest(N,ThisTrack,ThisMsre); */
    NextNote(N, &N);
  } while (N != P);   /* FirstNote(NoteList) */
}  /* FindNoteTypes */

/*********************************************************************/
 long NoteInChord(N, ThisTrack)
NoteRecord *N;
TrackRecord ThisTrack;
{
  /*********************************************************************/
  long Result;
  uchar i;

  Result = 0;
  for (i = 1; i <= ThisTrack.ChStackEnd; i++) {
    if (ThisTrack.ChordArray[i - 1].StartNote == N)
      Result = i;
  }
  return Result;
}

/*  variables for BeamFind:
struct LOC_BeamFind {
  TrackRecord *ThisTrack;
  uchar BeamPnt;
  NoteRecord *NotePnt;
  boolean Beaming;
} ; */

/*--------------------*/
 Void StartBeam(LINK)
struct LOC_BeamFind *LINK;
{
  /*--------------------*/
  BeamRecord *WITH;
/*  Char STR1[256]; */

  WITH = &LINK->ThisTrack->BeamArray[LINK->BeamPnt - 1];
  WITH->StartNote = LINK->NotePnt;
  WITH->EndNote = LINK->NotePnt;
  WITH->NoteType = LINK->NotePnt->NoteType;
  LINK->Beaming = true;
  WITH->NoNotes = 1;
  WITH->Numb = BeamIndex;
  BeamIndex++;
  sprintf(STR1, "Starting beam %3d at note %3d of type %3d",
	  WITH->Numb,LINK->NotePnt->NoteVal,(int)WITH->NoteType);
  WriteDebugInfo(STR1);
}

/*--------------------*/
 Void EndBeam(LINK)
struct LOC_BeamFind *LINK;
{
  /*--------------------*/
  unsigned short mn, i;
  uchar cnt, BPnt, max, min;
  NoteRecord *N, *P;
  boolean GoOn;
  BeamRecord *WITH;
  unsigned short FORLIM;
/*  Char STR1[256]; */

  WITH = &LINK->ThisTrack->BeamArray[LINK->BeamPnt - 1];

  LINK->Beaming = false;
  WITH->Chain2Next = false;
  mn = 0;
  max = 0;
  min = 127;
  cnt = 0;
  BPnt = LINK->BeamPnt;
  /* Pitch and slope should be determined over all chained beams */

  /* first, from the top find the first beam which has CHain2Next flag set */
  GoOn = false;
  if (BPnt > 1)
    BPnt--;
  while (!GoOn) {
    if (LINK->ThisTrack->BeamArray[BPnt - 1].Chain2Next ==true && BPnt > 1)
      BPnt--;
    else {
      if (!LINK->ThisTrack->BeamArray[BPnt - 1].Chain2Next) {
	if (BPnt < LINK->BeamPnt)
	  BPnt++;
      }
      GoOn = true;
    }
  }

  FORLIM = LINK->BeamPnt;
  /* The first Chain2Next Beam is pointed to by BPnt */
  /* We now have to process all the notes in the beams until BPnt=BeamPnt */

  for (i = BPnt - 1; i < FORLIM; i++) {
    WITH = &LINK->ThisTrack->BeamArray[i];   /* With */
    N = WITH->StartNote;
    NextNote(WITH->EndNote, &P);
    do {
      /*If NOT N^.ChordNote Then*/
      switch (N->Event) {

      case NOTEON:
      case NOTEOFF:
	mn += N->NoteVal;
	cnt++;
	if (N->NoteVal > max)
	  max = N->NoteVal;
	if (N->NoteVal < min)
	  min = N->NoteVal;
	break;
      }/* case */
      NextNote(N, &N);
    } while (N != P);
  }  /* For */

  WITH = &LINK->ThisTrack->BeamArray[BPnt - 1];
      /* with thistrack.beamarray */

  /* mn,cnt,Max and Min now have values  calculated over all Chained beams */
  /* We now have to fill the first beam record (Bpnt) with these values */

  /* This routine now does not take in account the orient of the note   */
  /* itself set by FindNotes and ChordFind. Look at this again...       */
  /* When handling chords, the mean only sees single notes of the chord.*/
  /* So that messes up a lot. */

  mn /= cnt;
  switch (LINK->ThisTrack->Clef) {

  case VIOLIN:
    if (mn < 70)
      WITH->Orient = UP;
    else
      WITH->Orient = DOWN;
    break;

  case BASS:
    if (mn < 52)
      WITH->Orient = UP;
    else
      WITH->Orient = DOWN;
    break;
  }
  if (WITH->Orient == UP)
    WITH->Pitch = max;
  else
    WITH->Pitch = min;

  if (WITH->EndNote->NoteVal > WITH->StartNote->NoteVal)
    WITH->Slope = (max - min) / cnt;
  else
    WITH->Slope = -((max - min) / cnt);
  /* WriteDebugInfo('Beam '+B2S(BeamPnt)+' has pitch '+B2S(Pitch)+
                 ',max='+B2S(max)+' min='+B2S(min)); */
  if (WITH->Orient == UP) {
    sprintf(STR1, "Ending beam %3d, beam is UP", WITH->Numb);
    WriteDebugInfo(STR1);
  } else {
    sprintf(STR1, "Ending beam %3d, beam is DOWN", WITH->Numb);
    WriteDebugInfo(STR1);
  }
  FORLIM = LINK->BeamPnt;
  /* Now Pitch,Orient & Slope must be copied to all Chained beams */
  for (i = BPnt + 1; i <= FORLIM; i++) {
    LINK->ThisTrack->BeamArray[i - 1].Orient =
      LINK->ThisTrack->BeamArray[i - 2].Orient;
    LINK->ThisTrack->BeamArray[i - 1].Slope =
      LINK->ThisTrack->BeamArray[i - 2].Slope;
    LINK->ThisTrack->BeamArray[i - 1].Pitch =
      LINK->ThisTrack->BeamArray[i - 2].Pitch;
  }

  LINK->BeamPnt++;
  if (LINK->BeamPnt > MAXBEAMS)
    ErrorExit(18L);
}

/*--------------------*/
 Void CancelBeam(LINK)
struct LOC_BeamFind *LINK;
{
  /*--------------------*/
  BeamRecord *WITH;
/*  Char STR1[256], STR2[256]; */

  LINK->Beaming = false;
  WITH = &LINK->ThisTrack->BeamArray[LINK->BeamPnt - 1];
  WITH->StartNote = NULL;
  WITH->EndNote = NULL;
  WITH->NoNotes = 0;
  sprintf(STR1, "Canceling beam %3d at note %3d",
	  WITH->Numb,LINK->NotePnt->NoteVal);
  WriteDebugInfo(STR1);
}

/*--------------------*/
 Void QuitBeam(LINK)
struct LOC_BeamFind *LINK;
{
  /*--------------------*/
  /* Close up the beams. Cancel Beam only if previous beam */
  /* has Chain2Next flag not set OR if BeamPnt=1 */
  TrackRecord *WITH;

  WITH = LINK->ThisTrack;
  if (WITH->BeamArray[LINK->BeamPnt - 1].NoNotes != 1) {
    EndBeam(LINK);
    return;
  }
  if (LINK->BeamPnt == 1) {
    CancelBeam(LINK);
    return;
  }
  if (WITH->BeamArray[LINK->BeamPnt - 2].Chain2Next)
    EndBeam(LINK);
  else
    CancelBeam(LINK);
}  /* QuitBeam */

/*--------------------*/
 Void Add2Beam(LINK)
struct LOC_BeamFind *LINK;
{
  /*--------------------*/
  BeamRecord *WITH;

  WITH = &LINK->ThisTrack->BeamArray[LINK->BeamPnt - 1];
  WITH->NoNotes++;
  WITH->EndNote = LINK->NotePnt;
}

/*--------------------------*/
 Void CreateUpChainBeam(LINK)
struct LOC_BeamFind *LINK;
{
  /*--------------------------*/
  BeamRecord *WITH;
/*  Char STR1[256], STR2[256]; */

  WITH = &LINK->ThisTrack->BeamArray[LINK->BeamPnt - 1];
  WITH->Chain2Next = true;
  WITH->EndNote = LINK->NotePnt;
  LINK->BeamPnt++;
  if (LINK->BeamPnt > MAXBEAMS)
    ErrorExit(18L);
  WITH = &LINK->ThisTrack->BeamArray[LINK->BeamPnt - 1];
  WITH->StartNote = LINK->NotePnt;
  WITH->EndNote = LINK->NotePnt;
  WITH->NoteType = LINK->NotePnt->NoteType;
  WITH->Numb = BeamIndex - 1;
  LINK->Beaming = true;
  WITH->NoNotes = 1;
  sprintf(STR1, "Chain  beam %3d at note %3d to type %3d",
	  WITH->Numb,LINK->NotePnt->NoteVal,(int)WITH->NoteType);
  WriteDebugInfo(STR1);
}  /* CreateUpChainBeam */

/*--------------------------*/
 Void CreateDnChainBeam(LINK)
struct LOC_BeamFind *LINK;
{
  /*--------------------------*/
  BeamRecord *WITH;
/*  Char STR1[256], STR2[256]; */

  WITH = &LINK->ThisTrack->BeamArray[LINK->BeamPnt - 1];
  WITH->Chain2Next = true;
  LINK->BeamPnt++;
  if (LINK->BeamPnt > MAXBEAMS)
    ErrorExit(18L);
  WITH = &LINK->ThisTrack->BeamArray[LINK->BeamPnt - 1];
  WITH->StartNote = LINK->NotePnt;
  WITH->EndNote = LINK->NotePnt;
  WITH->NoteType = LINK->NotePnt->NoteType;
  WITH->Numb = BeamIndex - 1;
  LINK->Beaming = true;
  WITH->NoNotes = 1;
  sprintf(STR1, "Chain beam %3d at note %3d to type %3d",
	  WITH->Numb,LINK->NotePnt->NoteVal,(int)WITH->NoteType);
  WriteDebugInfo(STR1);
}  /* CreateDnChainBeam */


/******************************************************/
 Void BeamFind(ThisTrack_)
TrackRecord *ThisTrack_;
{
  /******************************************************/
  struct LOC_BeamFind V;
  NoteRecord *FirstPnt;
  TrackRecord *WITH;
/*  Char STR1[256], STR2[256]; */


  V.ThisTrack = ThisTrack_;
  WriteDebugInfo("Starting BeamFind");
  V.BeamPnt = 1;
  V.Beaming = false;

  WITH = V.ThisTrack;   /* with thistrack */


  FirstNote(WITH->NoteList, &V.NotePnt);
  FirstPnt = NULL;   /* prevent early termination */

  while (V.NotePnt != FirstPnt) {  /* while */
    FirstNote(WITH->NoteList, &FirstPnt);
    switch (V.NotePnt->Event) {

    case NOTEON:
    case NOTEOFF:
      if (!V.NotePnt->ChordNote) {   /* exclude non-spacing notes */
	sprintf(STR1, "Note %3d is of type %3d",
		V.NotePnt->NoteVal,(int)V.NotePnt->NoteType);
	WriteDebugInfo(STR1);
	if (V.Beaming) {
	  switch (WITH->BeamArray[V.BeamPnt - 1].NoteType) {

	  case CPPP:
	  case CPP:
	  case C3:
	  case CP:
	  case C:
	    switch (V.NotePnt->NoteType) {

	    case CC3:
	    case CCP:
	    case CC:
	    case CCC3:
	    case CCCP:
	    case CCC:
	    case CCCC3:
	    case CCCCP:
	    case CCCC:
	      CreateUpChainBeam(&V);
	      break;

	    case CPPP:
	    case CPP:
	    case C3:
	    case CP:
	    case C:
	      Add2Beam(&V);
	      break;

	    default:
	      QuitBeam(&V);
	      break;
	    }
	    break;

	  case CC3:
	  case CCP:
	  case CC:
	    switch (V.NotePnt->NoteType) {

	    case CPPP:
	    case CPP:
	    case C3:
	    case CP:
	    case C:
	      CreateDnChainBeam(&V);
	      break;

	    case CCC3:
	    case CCCP:
	    case CCC:
	    case CCCC3:
	    case CCCCP:
	    case CCCC:
	      CreateUpChainBeam(&V);
	      break;

	    case CC3:
	    case CCP:
	    case CC:
	      Add2Beam(&V);
	      break;

	    default:
	      QuitBeam(&V);
	      break;
	    }
	    break;

	  case CCC3:
	  case CCCP:
	  case CCC:
	    switch (V.NotePnt->NoteType) {

	    case CPPP:
	    case CPP:
	    case C3:
	    case CP:
	    case C:
	    case CCPP:
	    case CC3:
	    case CCP:
	    case CC:
	      CreateDnChainBeam(&V);
	      break;

	    case CCCC3:
	    case CCCCP:
	    case CCCC:
	      CreateUpChainBeam(&V);
	      break;

	    case CCC3:
	    case CCCP:
	    case CCC:
	      Add2Beam(&V);
	      break;

	    default:
	      QuitBeam(&V);
	      break;
	    }
	    break;

	  case CCCC3:
	    switch (V.NotePnt->NoteType) {

	    case CCCC3:
	      Add2Beam(&V);
	      break;

	    default:
	      if ((long)V.NotePnt->NoteType >= (long)CPPP &&
		  (long)V.NotePnt->NoteType <= (long)CCC)
		CreateDnChainBeam(&V);
	      else
		QuitBeam(&V);
	      break;
	    }
	    break;

	  default:
	    QuitBeam(&V);
	    break;
	  }/* Case under If Beaming */

	} else {  /* not Beaming */
	  if ((long)V.NotePnt->NoteType > (long)CPP)
	    StartBeam(&V);
	}  /* not Beaming */

      }  /* NOTEON,NOTEOFF */
      break;
    }/* CASE N^.Event OF */
    NextNote(V.NotePnt, &V.NotePnt);
  }  /* WHILE */
  if (V.Beaming)
    QuitBeam(&V);

  WriteDebugInfo("BeamFind Ready");


}  /* BeamFind */



/**********************************************/
 Void InitFilePosns(N)
 long N;
{
  /**********************************************/
  uchar i, dummy;
  long cnt, NoOfBytes;
  Char TmpStr[256];
/*
  Char STR1[256];
  Char STR2[256];
*/
  TrackRecord *WITH;
  fpos_t OldPos;
  char *ptr;
  i = 1;
  fgetpos(MidiFile,&OldPos);
  
  do {

    ReadString(TmpStr, &HlpFilRec, 4L);
    sprintf(STR1, " Found start of track %3d with name:%s",i,TmpStr);
    WriteDebugInfo(STR1);
    NoOfBytes = ReadLongInt(&HlpFilRec);
    sprintf(STR1, "%3ld bytes in this track", NoOfBytes);
    WriteDebugInfo(STR1);
    sprintf(STR1,"FilePos : %ld",GetFilePos(&HlpFilRec));
    WriteDebugInfo(STR1);
    WITH = &TrackArray[i - 1];
    /* Copy the file info stuff into the currentr track file info */
    WITH->FilRec.FilePosition = HlpFilRec.FilePosition;
    memmove(WITH->FilRec.ReadBuf, HlpFilRec.ReadBuf,sizeof(BufType));
    WITH->EndOfTrackRead = false;
    WITH->FilRec.BytesProcessed = 0;
    WITH->FilRec.BufSemaphore = HlpFilRec.BufSemaphore;
    /* this is wrong, new BufPoint should be pointing in other buffer !!!
    WITH->FilRec.BufPoint = HlpFilRec.BufPoint; */
    ptr=HlpFilRec.ReadBuf;
    WITH->FilRec.BufPoint = WITH->FilRec.ReadBuf;
    while (ptr!=HlpFilRec.BufPoint){
      ptr++;
      WITH->FilRec.BufPoint++;
    }
    WITH->FilRec.LastBlockRead = HlpFilRec.LastBlockRead;
    SafetyCounter = 0;
    memset((&WITH->Curtime), 0, sizeof(MeasureTime));
    memset((&WITH->OldTime), 0, sizeof(MeasureTime));
    for (cnt = 1; cnt <= NoOfBytes; cnt++)
      dummy = ReadByte(&HlpFilRec);
    sprintf(STR1,"FilePos : %ld",GetFilePos(&HlpFilRec));
    WriteDebugInfo(STR1);
    i++;
  } while (i != N + 1);
  fsetpos(MidiFile,&OldPos);
}  /* InitFilePosns */

/**********************************************/
 boolean AllTracksRead(N)
long N;
{
  /**********************************************/
  boolean b;
  long i;

  b = true;
  for (i = 0; i < N; i++) {
    if (!EndOfTrackReached(&TrackArray[i]))
      b = false;
  }
  return b;
}

/*  variables for InitFileDebug: 
struct LOC_InitFileDebug {
  uchar FilesSel;
} ; */

/*--------------------------------------------------------------*/
Void SplitExtension(ThisFile,path,ext)
char *ThisFile,*path,*ext;
/*--------------------------------------------------------------*/
{
Char *pos;

pos=strrchr(ThisFile,'.');
if (pos==NULL)
   strcpy(path,ThisFile);
else{
   strncpy(path,ThisFile,strlen(ThisFile)-strlen(pos));
   strncpy(ext,pos,4);
   }
}

/*--------------------------------------------------------------*/
 Void ReadFileName(ThisFile, path, LINK)
FileNameType *ThisFile;
Char *path;
struct LOC_InitFileDebug *LINK;
{
  /*--------------------------------------------------------------*/
  Char *p;
  p=strrchr(path,'.');
  if (p==NULL) {
    if (LINK->FilesSel == 0)
      strcat(path, ".MID");
    else
      strcat(path, ".TEX");
  }
  /*
  _fullpath(ThisFile->p,path,80);
  _splitpath(ThisFile->p, ThisFile->r, ThisFile->d, ThisFile->n, ThisFile->e);
  */
  strcpy(ThisFile->p, path);
  SplitExtension(ThisFile->p,ThisFile->n,ThisFile->e);
  LINK->FilesSel++;
}  /* ReadFileName */


/**********************************************/
 Void InitFileDebug(P_argc,P_argv)
 int P_argc;
 char *P_argv[];
{
  /**********************************************/
  struct LOC_InitFileDebug V;
  uchar Pcnt, j;
  Char *PS,*p,*end;				/*  ,*S;   *S is not used */
  long Sint, Serr;
  
/*   Char STR1[256], STR2[256]; */

if ((PS = (char *) malloc(80*sizeof(char))) == NULL)
	{ printf("allocation error for PS - aborting\n");
	  exit(1);
	}
  V.FilesSel = 0;
  DebugOut = NODEB;
  Debug = false;

  for (Pcnt = 1; Pcnt < P_argc; Pcnt++) {
    /* WriteLn('Paramstring=',ParamStr(PCnt)); */
    /* printf("%s\n",P_argv[Pcnt]); */
    
    strcpy(PS, P_argv[Pcnt]);
    sprintf(STR1, "%.1s", PS);
    if (!strcmp(STR1, "-")) {

      sprintf(STR1, "%.2s", PS);
      if (!strcmp(STR1, "-?"))
	ErrorExit(0L);

#ifdef ST
      sprintf(STR1, "%.2s", PS);
      if (!strcmp(STR1, "-x"))
	BatchProcessing = true;
      sprintf(STR1, "%.2s", PS);
#endif

      sprintf(STR1, "%.2s", PS);
      if (!strcmp(STR1, "-i")) {  /* determine instrument staffs */
	if (ninstruments > 0) {ErrorExit(14L);};
	ninstruments++;
	if (strlen(PS) < 3){ ErrorExit(15L);};
	
	p=strtok((PS+2), ",");
	while (p != NULL) {
	  Sint = strtol(p,&end,10);
	  TrackArray[Sint - 1].Instrument = true;
	  nTracksInInstr++;
	  sprintf(STR1, "Track :%3ld is part of an instrument",Sint);
	  WriteDebugInfo(STR1);
	  p=strtok(NULL, ",");
	}
      }  /* if switch='-i' */

      sprintf(STR1, "%.2s", PS);
      if (!strcmp(STR1, "-f")) {  /* force zero beams for these staffs */
	
	p=strtok((PS+2), ",");
	while (p != NULL) {
	  Sint = strtol(p,&end,10);
	  TrackArray[Sint - 1].ForceZeroBeams= true;
	  sprintf(STR1, "Track :%3ld has beam slope forced to zero",Sint);
	  WriteDebugInfo(STR1);
	  p=strtok(NULL, ",");
	}
      }  /* if switch='-f' */

      sprintf(STR1, "%.2s", PS);
      if (!strcmp(STR1, "-h")) {  /* change horizontal size */
	
	if ((PS+2) != NULL) { /* wat doet deze voorwaarde */
	  Sint = strtol((PS+2),&end,10);
	  ScoreWidth = Sint;
	  SizingChanged = true;
	  sprintf(STR1, "Changing scorewidth from default to %3ld",ScoreWidth);
	  WriteDebugInfo(STR1);
	}
      }  /* if switch='-h' */

      sprintf(STR1, "%.2s", PS);
      if (!strcmp(STR1, "-v")) {  /* change vertical size */
	
	if ((PS+2) != NULL) {
	  Sint = strtol((PS+2),&end,10);
	  ScoreHeight = Sint;
	  SizingChanged = true;
	  sprintf(STR1, "Changing scoreheight from default to %3ld",ScoreHeight);
	  WriteDebugInfo(STR1);
	}
      }  /* if switch='-v' */

      sprintf(STR1, "%.2s", PS);
      if (!strcmp(STR1, "-e")) {  /* change elemskip size */
	
	if ((PS+2) != NULL) {
	  Sint = strtol((PS+2),&end,10);
	  ElemSkip = (long)(Sint * PT);
	  SizingChanged = true;
	  sprintf(STR1, "Changing Elemskip from default to %3ld",ElemSkip);
	  WriteDebugInfo(STR1);
	}
      }  /* if switch='-e' */

       sprintf(STR1, "%.2s", PS);
       if (!strcmp(STR1, "-m")) {  /* change magnitude of score */
	
	if ((PS+2) != NULL) {
	  Sint = strtol((PS+2),&end,10);
	  switch (Sint) {
	  case 20:
	    MusicSize = 20;
	    LineHeight = 160;
	    ScoreSep = 20;
	    Indent = 115;
	    CumLength = 215;
	    BarIndent = 40;
	    ElemSkip = (long)(10 * PT);
	    break;

	  case 16:
	    MusicSize = 16;
	    LineHeight = 125;
	    ScoreSep = 40;
	    Indent = 90;
	    CumLength = 190;
	    BarIndent = 30;
	    ElemSkip = (long)(8 * PT);
	    break;

	  default:
	    ErrorExit(20L);
	    break;
	  }/* case */
	  SizingChanged = true;
	  sprintf(STR1, "Changing magnitude from default to %3ld",Sint);
	  WriteDebugInfo(STR1);
	}
      }  /* if switch='-m' */

      sprintf(STR1, "%.2s", PS);
      if (!strcmp(STR1, "-k")) {  /* change keysign of score */
	
	if ((PS+2) != NULL) {
	  Sint = strtol((PS+2),&end,10);
	  if (Sint >= -8 && Sint <= 8)
	    PieceContr.KeySign = Sint;
	  else
	    ErrorExit(21L);
	  sprintf(STR1, "Changing keysign to %3ld",Sint);
	  WriteDebugInfo(STR1);
	}
      }  /* if switch='-k' */

      sprintf(STR1, "%.2s", PS);
      if (!strcmp(STR1, "-q")) {  /* quantization timing */
	
	if ((PS+2) != NULL) {
	  Sint = strtol((PS+2),&end,10);
	  if (Sint <= 64 && Sint > 0) {
	    Quantizing = true;
	    QuantTime = Sint;
	  } else
	    ErrorExit(13L);
	  sprintf(STR1, "Using quantization %3ld",Sint);
	  WriteDebugInfo(STR1);
	} 
      }  /* if switch='-q' */

      sprintf(STR1, "%.2s", PS);
      if (!strcmp(STR1, "-b")) {  /* force zero beams for these staffs */
	
	p=strtok((PS+2), ",");
	while (p != NULL) {
	  Sint = strtol(p,&end,10);
	  TrackArray[Sint - 1].Clef = BASS;
	  sprintf(STR1, "Track :%3ld notated with bass clef", Sint);
	  WriteDebugInfo(STR1);
	  p=strtok(NULL, ",");
	}  
      }  /* if switch='-b' */

      sprintf(STR1, "%.3s", PS);
      if (!strcmp(STR1, "-a1")) {  /* determine ALTO1 clefs */
	
	p=strtok((PS+3),",");
	while (p!= NULL) {
	  Sint = strtol(p,&end,10);
	  if (Sint > 0)
	    TrackArray[Sint - 1].Clef = ALTO1;
	  else
	    ErrorExit(22L);
	  sprintf(STR1, "Track :%3ld notated with ALTO1 clef", Sint);
	  WriteDebugInfo(STR1);
	  p=strtok(NULL, ",");
	}
      }  /* if switch='-a1' */

      sprintf(STR1, "%.3s", PS);
      if (!strcmp(STR1, "-a2")) {  /* determine ALTO2 clefs */
	
	p=strtok((PS+3),",");
	while (p!= NULL) {
	  Sint = strtol(p,&end,10);
	  if (Sint > 0)
	    TrackArray[Sint - 1].Clef = ALTO2;
	  else
	    ErrorExit(22L);
	  sprintf(STR1, "Track :%3ld notated with ALTO2 clef", Sint);
	  WriteDebugInfo(STR1);
	  p=strtok(NULL, ",");
	}
      }  /* if switch='-a2' */

      sprintf(STR1, "%.3s", PS);
      if (!strcmp(STR1, "-a3")) {  /* determine ALTO3 clefs */
	
	p=strtok((PS+3),",");
	while (p!= NULL) {
	  Sint = strtol(p,&end,10);
	  if (Sint > 0)
	    TrackArray[Sint - 1].Clef = ALTO3;
	  else
	    ErrorExit(22L);
	  sprintf(STR1, "Track :%3ld notated with ALTO3 clef", Sint);
	  WriteDebugInfo(STR1);
	  p=strtok(NULL, ",");
	}
      }  /* if switch='-a3' */

      sprintf(STR1, "%.3s", PS);
      if (!strcmp(STR1, "-a4")) {  /* determine ALTO4 clefs */
	
	p=strtok((PS+3),",");
	while (p!= NULL) {
	  Sint = strtol(p,&end,10);
	  if (Sint > 0)
	    TrackArray[Sint - 1].Clef = ALTO4;
	  else
	    ErrorExit(22L);
	  sprintf(STR1, "Track :%3ld notated with ALTO4 clef", Sint);
	  WriteDebugInfo(STR1);
	  p=strtok(NULL, ",");
	}
      }  /* if switch='-a4' */


      sprintf(STR1, "%.2s", PS);
      if (!strcmp(STR1, "-o")) {  /* order staffs */
	
	p=strtok((PS+2), ",");
	while (p != NULL ) {   /* now pointing at last item in orderarray */
	    Sint = strtol(p,&end,10);
	    TrackOrder[OrderIndex - 1] = Sint;
	    sprintf(STR1, "Ordering MIDI Track :%3ld at Staff %3ld",Sint,OrderIndex);
	    WriteDebugInfo(STR1);
	    OrderIndex++;
	    p=strtok(NULL,",");
	}
	OrderIndex--;
      }  /* if switch='-o' */

      sprintf(STR1, "%.2s", PS);
      if (!strcmp(STR1, "-s")) {  /* skipping tracks */
	
	p=strtok((PS+2), ",");
	while (p != NULL ) {   /* now pointing at last item in orderarray */
	    Sint = strtol(p,&end,10);
	    if (Sint == 1) {
	      TrackArray[Sint - 1].Skip = false;
	      NoOfSkips--;
	    } else {
	      TrackArray[Sint - 1].Skip++;
	      NoOfSkips++;
	    }
	    sprintf(STR1, "Skipping Track :%3ld", Sint);
	    WriteDebugInfo(STR1);
	    p=strtok(NULL,",");
	  }
      }  /* if switch='-s' */


      sprintf(STR1, "%.2s", PS);
      if (!strcmp(STR1, "-p")) {  /* part timing */
	
	if ((PS+2) != NULL ) {   /* now pointing at last item in orderarray */
	    Sint = strtol((PS+2),&end,10);
	    switch (Sint) {

	    case 1:
	    case 2:
	    case 4:
	    case 8:
	    case 16:
	    case 32:
	      PieceContr.PartType = Sint;
	      sprintf(STR1, "Part Timing =%3ld", Sint);
	      WriteDebugInfo(STR1);
	      PieceContr.PartOverRule = true;
	      break;

	    default:
	      ErrorExit(12L);
	      break;
	    }
	    sprintf(STR1, "Part time :%3ld", Sint);
	    WriteDebugInfo(STR1);
	  }
      }  /* if switch='-p' */
	
	sprintf(STR1, "%.2s", PS);
      if (!strcmp(STR1, "-d")) {
	
	if (!strcmp((PS+2), "FILE") || !strcmp((PS+2), "file")) {

	  DebugFile=fopen(DebugFileName.p,"w");
	  if (DebugFile == NULL)
	    DebugFile = tmpfile();
	  /*
	  else
	    rewind(DebugFile);
	  */
/*
	  DebBuf = (uchar *)malloc(sizeof(BufType));
	  if (DebBuf==NULL) ErrorExit(9L);
	  if (setvbuf(DebugFile, DebBuf , _IOFBF, sizeof(BufType))!=0)
	      {ErrorExit(9L);}
*/
	  DebugFileOpened = true;
	  DebugOut = DEBFILE;
	  Debug = true;
	}
	if (!strcmp((PS+2), "PRINTER")) {
	  DebugOut = PRINT;
	  Debug = true;
	}
	if (!strcmp((PS+2), "SCREEN")) {
	  DebugOut = SCREEN;
	  Debug = true;
	}
      } /* if -d switch */
    }  /* If this parameter is a switch */
    else {  /* this parameter is not a switch */
      if (V.FilesSel == 0) {
	ReadFileName(&MidiFileName, PS, &V);
	memcpy(&DebugFileName,&MidiFileName,sizeof(FileNameType));
	strcpy(DebugFileName.e, ".MLG");
	sprintf(DebugFileName.p, "%s%s",DebugFileName.n, DebugFileName.e);
      } else
	ReadFileName(&TeXFileName, PS, &V);
    }  /* else not a switch */
  }  /* for next loop */
  
  switch (V.FilesSel) {
     case 0 :  ErrorExit(1L); break;
     case 1 :  /* there was no TeXFilename selected */
	       memcpy(&TeXFileName,&MidiFileName,sizeof(FileNameType));
	       strcpy(TeXFileName.e, ".TEX");
	       sprintf(TeXFileName.p, "%s%s", TeXFileName.n, TeXFileName.e);
	       break;
     }

  if (MidiFile != NULL)
    MidiFile = freopen(MidiFileName.p, "rb", MidiFile);
  else
    MidiFile = fopen(MidiFileName.p, "rb");

  if (MidiFile == NULL)
    {
#ifdef __TURBOC__
     _doserrno=0; /* prevent DOS error */
#endif
     ErrorExit(1L);}
  else
    rewind(MidiFile);

  if (TexFile != NULL)
    TexFile = freopen(TeXFileName.p, "w", TexFile);
  else
    TexFile = fopen(TeXFileName.p, "w");

  if (TexFile == NULL)  ErrorExit(25L);

  if (TexFile == NULL)
    TexFile = tmpfile();
  /*
  else
    rewind(TexFile);
  */
/*
  TexBuf = (uchar *)malloc(sizeof(BufType));
  if (TexBuf==NULL) ErrorExit(9L);
  if (setvbuf(TexFile, TexBuf , _IOFBF, sizeof(BufType))!=0)
    {ErrorExit(9L);}
*/

  MidiFileOpened = true;
  printf("Translating %s into ",MidiFileName.p);
  printf("%s\n", TeXFileName.p);
  WriteDebugInfo("***********************************************");
  sprintf(STR1, "*   Midi2TeX translator %s *",VERSION);
  WriteDebugInfo(STR1);
  WriteDebugInfo("*                   by                        *");
  WriteDebugInfo("*       Hans Kuykens, Ad Verbruggen           *");
  sprintf(STR1, "* Translating %s", MidiFileName.p);
  WriteDebugInfo(STR1);
  WriteDebugInfo("*                  into ");
  sprintf(STR1, "*             %s", TeXFileName.p);
  WriteDebugInfo(STR1);
  WriteDebugInfo("***********************************************");
free((char *)PS);
}  /* InitFileDebug */

/**********************************************/
 void Initialize(P_argc,P_argv)
 int P_argc;
 char *P_argv[];
{
  /**********************************************/
  _TP_debug_init();
  _TP_Decl_init();
  _TP_Misc_init();
  _TP_Heap1_init();
  _TP_M2TF4_init();
  MidiFileOpened = false;
  DebugFileOpened = false;
  DebugFileOpened = false;
  /* if ((Ms = (MsArray *)malloc(sizeof(MsArray))==NULL)) ErrorExit(9L); */
  InitNotePool();
  memset((&PieceContr), 0, sizeof(ControlInfo));
  for (i = 1; i <= NoTracks; i++)
    memset((&TrackArray[i - 1]), 0, sizeof(TrackRecord));

  InitFilRec(&HlpFilRec);
  for (i = 1; i <= NoTracks; i++)
    InitFilRec(&TrackArray[i - 1].FilRec);

  for (i = 1; i <= NoTracks; i++)
    TrackOrder[i - 1] = i;
  for (i = 0; i <= MAXSLURR; i++)
    SlurrIndexes[i] = false;
  TrackArray[0].Skip = true;   /* Always  skip track 1 */
  OrderIndex = 1;
  NoOfSkips = 1;
  PieceContr.PartOverRule = false;
  Quantizing = false;
  TeXHeaderFinished = false;
  ChangedContext = FALSE;
  ninstruments = 0;
  nTracksInInstr = 0;
  ScoreWidth = 1600;   /* 0.1 mm */
  /* MusicTeX standard */
  ScoreHeight = 2400;   /* 0.1 mm */
  LineHeight = 160;   /* 0.1 mm */
  ElemSkip = (long)(10 * PT);    /* 3.5 mm */
  /* STandard \elemskip */
  CumLength = 220;   /* initialize cumulative length and height  */
  Indent = 115;
  BarIndent = 40;
  ScoreSep = 20;
  MeasureMaxCnt = 0;   /* Maximum number of notes in a measure     */
  MusicSize = 20;
  SizingChanged = false;
  BatchProcessing = false;
  NoOfPages = 1;
  QuantTime = 16;   /* default value */
  InitFileDebug(P_argc,P_argv);
}  /* Initialize */

/*****************************************************/
 Void CleanUpSlurrArrays()
{
  /*****************************************************/
  long i, j, TmpIndx, FORLIM;
  TrackRecord *WITH;
/*  Char STR1[256], STR2[256]; */

  TmpIndx = 0;
  FORLIM = ntracks;
  for (j = 0; j < FORLIM; j++) {
    WITH = &TrackArray[j];
    i = 1;
    while (i <= WITH->SlurrPt) {
      if (!WITH->SlurrArray[i - 1].Occupied) {   /* is processed, remove... */
	sprintf(STR1, "Removing slurr #%3ld",(long)WITH->SlurrArray[i - 1].Numb2);
	WriteDebugInfo(STR1);
	SlurrIndexes[WITH->SlurrArray[i - 1].Numb2] = false;
	if (i < MAXSLURR) {
	  memmove((&WITH->SlurrArray[i - 1]),
		  (&WITH->SlurrArray[i]),
		  (MAXSLURR - i) * sizeof(SlurrRecord));
	  i--;
	  WITH->SlurrPt--;   /* dit werkt niet !!! */
	} else {
	  memset((&WITH->SlurrArray[i - 1]), 0, sizeof(SlurrRecord));
	  WITH->SlurrPt--;
	}
      }
      i++;
    }
    if (WITH->SlurrPt < 0)   /* for safety */
      WITH->SlurrPt = 0;
    if (WITH->SlurrPt == 0)
      WITH->Slurring = false;
  }
}



/************************************************************/
 Void CleanUpTracks()
{
  /************************************************************/
  NoteRecord *N, *P;
  long All, i;
  uchar curtrack;
  MeasureTime TmpTime;
  uchar FORLIM;
  TrackRecord *WITH;
  /* Char STR1[256],STR2[256], STR3[256]; */

  SetTim(&TmpTime, (int)(MeasureCount + 1), 0);
  FORLIM = ntracks;
  for (curtrack = 0; curtrack < FORLIM; curtrack++) {   /* with thistrack */
    WITH = &TrackArray[curtrack];
    All = WITH->NoteList.Size;
    LastNote(WITH->NoteList, &N);
    PrevNote(N, &P);
    for (i = 1; i <= All; i++) {
      switch (N->Event) {

      case VOID:
	Re_move(&WITH->NoteList, N);
	BringFreeNote(N);
	break;
	/* if notearry */

      case REST:
      case NOTEOFF:
	if (TimeDiff(TmpTime, N->EndTime) < 0) {
	  sprintf(STR1, "Extending event %3d into next measure",N->NoteVal);
	  WriteDebugInfo(STR1);
	  SetTim(&N->StartTime, (int)(MeasureCount + 1), 0);
	} else {
	  Re_move(&WITH->NoteList, N);
	  BringFreeNote(N);
	}
	break;

      case NOTEON:
	SetTim(&N->StartTime, (int)(MeasureCount + 1), 0);
	break;

      case TXT:
	free(N->MetaTxt);
	Re_move(&WITH->NoteList, N);
	BringFreeNote(N);
	break;

      case PEDAL:
      case KEYSIGN:
      case SIGNATURE:
	if (TimeDiff(TmpTime, N->StartTime) < 0) {
	  sprintf(STR1, "META event %s still on stack...????", N->MetaTxt);
	  WriteDebugInfo(STR1);
	} else {
	  Re_move(&WITH->NoteList, N);
	  BringFreeNote(N);
	}
	break;

      }/* case */
      N = P;
      PrevNote(N, &P);
    }
    sprintf(STR1, "There are %3d notes which slurr to next measure",
	    WITH->NoteList.Size);
    WriteDebugInfo(STR1);
    /* If NoteList.Size>0 Then WriteDebugInfo('First note now has value :'+
                                        B2S(FirstNote(NoteList)^.NoteVal));
     */

    /* Clean up the BeamArray and ChordArray too */

    ResetBeamArray(WITH->BeamArray);
    ResetChordArray(WITH->ChordArray);
    ResetAccKeys();

  }
  CleanUpSlurrArrays();
}


/**************************************************/
 Char *RestString(Result, ValType, Clef)
Char *Result;
NoteTypes ValType;
ClefType Clef;
{
  /**************************************************/
  Char c1, c2;

  switch (Clef) {

  case VIOLIN:
    c1 = 'g';
    c2 = 'j';
    break;

  case BASS:
    c1 = 'J';
    c2 = 'K';
    break;
  }
  switch (ValType) {

  case WH:
    strcpy(Result, "\\pause ");
    break;

  case WHP:
    sprintf(Result, "\\rlap{\\qsk\\pt %c}\\pause ", c2);
    break;

  case WHPP:
    sprintf(Result, "\\rlap{\\qsk\\ppt %c}\\pause ", c2);
    break;

  case H:
    strcpy(Result, "\\hpause ");
    break;

  case HP:
    sprintf(Result, "\\rlap{\\qsk\\pt %c}\\hpause ", c2);
    break;

  case HPP:
    sprintf(Result, "\\rlap{\\qsk\\ppt %c}\\hpause ", c2);
    break;

  case HPPP:
    strcpy(Result, "\\pause ");
    break;

  case Q:
    strcpy(Result, "\\soupir ");
    break;

  case QP:
    sprintf(Result, "\\pt %c\\soupir ", c1);
    break;

  case QPP:
    sprintf(Result, "\\ppt %c\\soupir ", c1);
    break;

  case QPPP:
    sprintf(Result, "\\pppt %c\\soupir ", c1);
    break;

  case C:
    strcpy(Result, "\\ds ");
    break;

  case CP:
    sprintf(Result, "\\pt %c\\ds ", c1);
    break;

  case C3:
    strcpy(Result, "\\ds ");
    break;

  case CPP:
    sprintf(Result, "\\ppt %c\\ds ", c1);
    break;

  case CPPP:
    sprintf(Result, "\\pppt %c\\ds ", c1);
    break;

  case CC:
    strcpy(Result, "\\qs ");
    break;

  case CCP:
    sprintf(Result, "\\pt %c\\qs ", c1);
    break;

  case CCPP:
    sprintf(Result, "\\ppt %c\\qs ", c1);
    break;

  case CC3:
    strcpy(Result, "\\qs ");
    break;

  case CCC:
    strcpy(Result, "\\qs ");
    break;

  case CCCP:
    strcpy(Result, " ");
    break;

  case CCC3:
    strcpy(Result, " ");
    break;

  case CCCC:
    strcpy(Result, " ");
    break;

  case CCCCP:
    strcpy(Result, " ");
    break;

  case CCCC3:
    strcpy(Result, " ");
    break;
  }/* case */
  return Result;
}  /* RestString */


/**************************************/
uchar Index(uchar value)
{
  /**************************************/
  uchar Result, Modulo, TmpIndx;
  long Okt;

  if (value > 127) {
    Warning("Found a notevalue exceeding 127, replacing with 60 !");
    value = 60;
  }
  Okt = value - 60;
  Okt /= 12;
  /* WriteDebugInfo('Index->Okt='+I2S(Okt)); */
  Modulo = value % 12;
  /* WriteDebugInfo('Index->Modulo='+I2S(Modulo)); */
  TmpIndx = CPosition + Okt * 7;
  /* WriteDebugInfo('Index->TmpIndx='+I2S(TmpIndx)); */
  if (value > 60) {
    switch (Modulo) {

    case 0:
      Result = TmpIndx;
      break;

    case 2:
      Result = TmpIndx + 1;
      break;

    case 4:
      Result = TmpIndx + 2;
      break;

    case 5:
      Result = TmpIndx + 3;
      break;

    case 7:
      Result = TmpIndx + 4;
      break;

    case 9:
      Result = TmpIndx + 5;
      break;

    case 11:
      Result = TmpIndx + 6;
      break;

    default:
      Result = TmpIndx;
      break;
    }
    return Result;
  }
  switch (Modulo) {

  case 2:
    Result = TmpIndx - 6;
    break;

  case 4:
    Result = TmpIndx - 5;
    break;

  case 5:
    Result = TmpIndx - 4;
    break;

  case 7:
    Result = TmpIndx - 3;
    break;

  case 9:
    Result = TmpIndx - 2;
    break;

  case 11:
    Result = TmpIndx - 1;
    break;

  default:
    Result = TmpIndx;
    break;
  }

  return Result;
}  /* Index */



/************************************************************************/
Char *ValueString(char *Result,uchar value,ControlInfo Control,AccKeyType *AKey,boolean ChangeAKey)
/* Char *Result;
uchar value;
ControlInfo Control;
AccKeyType *AKey;
boolean ChangeAKey;*/
{
  /************************************************************************/
  unsigned int Modulo;

  Modulo = value % 12;

  /* The Accidental records should be in connection with each track, not with  */
  /* the control structure. In that case this function should include the      */
  /* track as a parameter.                                                     */

  switch (Modulo) {

  case 0:
    switch (Control.KeySign) {

    case -7:
    case -6:
      if (AKey->c == NON) {
	sprintf(Result, "{=%s}", Notes[Index(value) - 1]);
	if (ChangeAKey)
	  AKey->c = CORRECT;
      } else
	sprintf(Result, "%s", Notes[Index(value) - 1]);
      break;

    case 2:
    case 3:
    case 4:
    case 5:
    case 6:
    case 7:
    case 8:
      if (AKey->c == NON) {
	sprintf(Result, "{=%s}", Notes[Index(value) - 1]);
	if (ChangeAKey)
	  AKey->c = CORRECT;
      } else
	sprintf(Result, "%s", Notes[Index(value) - 1]);
      break;

    default:
      if (AKey->c != NON) {
	sprintf(Result, "{=%s}", Notes[Index(value) - 1]);
	if (ChangeAKey)
	  AKey->c = NON;
      } else
	sprintf(Result, "%s", Notes[Index(value) - 1]);
      break;
    }/* case */
    break;

  case 1:
    switch (Control.KeySign) {

    case 2:
    case 3:
    case 4:
    case 5:
    case 6:
    case 7:
    case 8:
      if (AKey->c == CORRECT) {
	sprintf(Result, "{^%s}", Notes[Index(value - 1) - 1]);
	if (ChangeAKey)
	  AKey->c = NON;
      } else
	sprintf(Result, "%s", Notes[Index(value - 1) - 1]);
      break;

    case -8:
    case -7:
    case -6:
    case -5:
    case -4:
      if (AKey->d == CORRECT) {
	sprintf(Result, "{_%s}", Notes[Index(value + 1) - 1]);
	if (ChangeAKey)
	  AKey->d = NON;
      } else
	sprintf(Result, "%s", Notes[Index(value + 1) - 1]);
      break;

    default:
      if (AKey->c == SHARP)
	sprintf(Result, "%s", Notes[Index(value - 1) - 1]);
      else if (AKey->d == FLAT)
	sprintf(Result, "%s", Notes[Index(value + 1) - 1]);
      else {
	switch (Control.KeySign) {

	case -8:
	case -7:
	case -6:
	case -5:
	case -4:
	case -3:
	case -2:
	case -1:
	  sprintf(Result, "{_%s}", Notes[Index(value + 1) - 1]);
	  if (ChangeAKey)
	    AKey->d = FLAT;
	  break;

	case 0:
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
	case 6:
	case 7:
	case 8:
	  sprintf(Result, "{^%s}", Notes[Index(value - 1) - 1]);
	  if (ChangeAKey)
	    AKey->c = SHARP;
	  break;
	}
      }
      break;
    }/* Case KeySign */
    break;

  case 2:
    switch (Control.KeySign) {

    case -8:
    case -7:
    case -6:
    case -5:
    case -4:
      if (AKey->d == NON) {
	sprintf(Result, "{=%s}", Notes[Index(value) - 1]);
	if (ChangeAKey)
	  AKey->d = CORRECT;
      } else
	sprintf(Result, "%s", Notes[Index(value) - 1]);
      break;

    case 4:
    case 5:
    case 6:
    case 7:
    case 8:
      if (AKey->d == NON) {
	sprintf(Result, "{=%s}", Notes[Index(value) - 1]);
	if (ChangeAKey)
	  AKey->d = CORRECT;
      } else
	sprintf(Result, "%s", Notes[Index(value) - 1]);
      break;

    default:
      if (AKey->d != NON) {
	sprintf(Result, "{=%s}", Notes[Index(value) - 1]);
	if (ChangeAKey)
	  AKey->d = NON;
      } else
	sprintf(Result, "%s", Notes[Index(value) - 1]);
      break;
    }/* case */
    break;

  case 3:
    switch (Control.KeySign) {

    case 4:
    case 5:
    case 6:
    case 7:
    case 8:
      if (AKey->d == CORRECT) {
	sprintf(Result, "{^%s}", Notes[Index(value - 1) - 1]);
	if (ChangeAKey)
	  AKey->d = NON;
      } else
	sprintf(Result, "%s", Notes[Index(value - 1) - 1]);
      break;

    case -8:
    case -7:
    case -6:
    case -5:
    case -4:
    case -3:
    case -2:
      if (AKey->e == CORRECT) {
	sprintf(Result, "{_%s}", Notes[Index(value + 1) - 1]);
	if (ChangeAKey)
	  AKey->e = NON;
      } else
	sprintf(Result, "%s", Notes[Index(value + 1) - 1]);
      break;

    default:
      if (AKey->d == SHARP)
	sprintf(Result, "%s", Notes[Index(value - 1) - 1]);
      else if (AKey->e == FLAT)
	sprintf(Result, "%s", Notes[Index(value + 1) - 1]);
      else {
	switch (Control.KeySign) {

	case -8:
	case -7:
	case -6:
	case -5:
	case -4:
	case -3:
	case -2:
	case -1:
	  sprintf(Result, "{_%s}", Notes[Index(value + 1) - 1]);
	  if (ChangeAKey)
	    AKey->e = FLAT;
	  break;

	case 0:
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
	case 6:
	case 7:
	case 8:
	  sprintf(Result, "{^%s}", Notes[Index(value - 1) - 1]);
	  if (ChangeAKey)
	    AKey->d = SHARP;
	  break;
	}
      }
      break;
    }/* Case KeySign */
    break;

  case 4:
    switch (Control.KeySign) {

    case -7:
    case -6:
    case -5:
    case -4:
    case -3:
    case -2:
      if (AKey->e == NON) {
	sprintf(Result, "{=%s}", Notes[Index(value) - 1]);
	if (ChangeAKey)
	  AKey->e = CORRECT;
      } else
	sprintf(Result, "%s", Notes[Index(value) - 1]);
      break;

    case 6:
    case 7:
    case 8:
      if (AKey->e == NON) {
	sprintf(Result, "{=%s}", Notes[Index(value) - 1]);
	if (ChangeAKey)
	  AKey->e = CORRECT;
      } else
	sprintf(Result, "%s", Notes[Index(value) - 1]);
      break;

    default:
      if (AKey->e != NON) {
	sprintf(Result, "{=%s}", Notes[Index(value) - 1]);
	if (ChangeAKey)
	  AKey->e = NON;
      } else
	sprintf(Result, "%s", Notes[Index(value) - 1]);
      break;
    }/* case */
    break;

  case 5:
    switch (Control.KeySign) {

    case -7:
      if (AKey->f == NON) {
	sprintf(Result, "{=%s}", Notes[Index(value) - 1]);
	if (ChangeAKey)
	  AKey->f = CORRECT;
      } else
	sprintf(Result, "%s", Notes[Index(value) - 1]);
      break;

    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
    case 6:
    case 7:
    case 8:
      if (AKey->f == NON) {
	sprintf(Result, "{=%s}", Notes[Index(value) - 1]);
	if (ChangeAKey)
	  AKey->f = CORRECT;
      } else
	sprintf(Result, "%s", Notes[Index(value) - 1]);
      break;

    default:
      if (AKey->f != NON) {
	sprintf(Result, "{=%s}", Notes[Index(value) - 1]);
	if (ChangeAKey)
	  AKey->f = NON;
      } else
	sprintf(Result, "%s", Notes[Index(value) - 1]);
      break;
    }/* case */
    break;

  case 6:
    switch (Control.KeySign) {

    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
    case 6:
    case 7:
    case 8:
      if (AKey->f == CORRECT) {
	sprintf(Result, "{^%s}", Notes[Index(value - 1) - 1]);
	if (ChangeAKey)
	  AKey->f = NON;
      } else
	sprintf(Result, "%s", Notes[Index(value - 1) - 1]);
      break;

    case -8:
    case -7:
    case -6:
    case -5:
      if (AKey->g == CORRECT) {
	sprintf(Result, "{_%s}", Notes[Index(value + 1) - 1]);
	if (ChangeAKey)
	  AKey->g = NON;
      } else
	sprintf(Result, "%s", Notes[Index(value + 1) - 1]);
      break;

    default:
      if (AKey->f == SHARP)
	sprintf(Result, "%s", Notes[Index(value - 1) - 1]);
      else if (AKey->g == FLAT)
	sprintf(Result, "%s", Notes[Index(value + 1) - 1]);
      else {
	switch (Control.KeySign) {

	case -8:
	case -7:
	case -6:
	case -5:
	case -4:
	case -3:
	case -2:
	case -1:
	  sprintf(Result, "{_%s}", Notes[Index(value + 1) - 1]);
	  if (ChangeAKey)
	    AKey->g = FLAT;
	  break;

	case 0:
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
	case 6:
	case 7:
	case 8:
	  sprintf(Result, "{^%s}", Notes[Index(value - 1) - 1]);
	  if (ChangeAKey)
	    AKey->f = SHARP;
	  break;
	}
      }
      break;
    }/* Case KeySign */
    break;

  case 7:
    switch (Control.KeySign) {

    case -7:
    case -6:
    case -5:
      if (AKey->g == NON) {
	sprintf(Result, "{=%s}", Notes[Index(value) - 1]);
	if (ChangeAKey)
	  AKey->g = CORRECT;
      } else
	sprintf(Result, "%s", Notes[Index(value) - 1]);
      break;

    case 3:
    case 4:
    case 5:
    case 6:
    case 7:
    case 8:
      if (AKey->g == NON) {
	sprintf(Result, "{=%s}", Notes[Index(value) - 1]);
	if (ChangeAKey)
	  AKey->g = CORRECT;
      } else
	sprintf(Result, "%s", Notes[Index(value) - 1]);
      break;

    default:
      if (AKey->g != NON) {
	sprintf(Result, "{=%s}", Notes[Index(value) - 1]);
	if (ChangeAKey)
	  AKey->g = NON;
      } else
	sprintf(Result, "%s", Notes[Index(value) - 1]);
      break;
    }/* case */
    break;

  case 8:
    switch (Control.KeySign) {

    case 3:
    case 4:
    case 5:
    case 6:
    case 7:
    case 8:
      if (AKey->g == CORRECT) {
	sprintf(Result, "{^%s}", Notes[Index(value - 1) - 1]);
	if (ChangeAKey)
	  AKey->g = NON;
      } else
	sprintf(Result, "%s", Notes[Index(value - 1) - 1]);
      break;

    case -8:
    case -7:
    case -6:
    case -5:
    case -4:
    case -3:
      if (AKey->a == CORRECT) {
	sprintf(Result, "{_%s}", Notes[Index(value + 1) - 1]);
	if (ChangeAKey)
	  AKey->a = NON;
      } else
	sprintf(Result, "%s", Notes[Index(value + 1) - 1]);
      break;

    default:
      if (AKey->g == SHARP)
	sprintf(Result, "%s", Notes[Index(value - 1) - 1]);
      else if (AKey->a == FLAT)
	sprintf(Result, "%s", Notes[Index(value + 1) - 1]);
      else {
	switch (Control.KeySign) {

	case -8:
	case -7:
	case -6:
	case -5:
	case -4:
	case -3:
	case -2:
	case -1:
	case 0:
	  sprintf(Result, "{_%s}", Notes[Index(value + 1) - 1]);
	  if (ChangeAKey)
	    AKey->a = FLAT;
	  break;

	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
	case 6:
	case 7:
	case 8:
	  sprintf(Result, "{^%s}", Notes[Index(value - 1) - 1]);
	  if (ChangeAKey)
	    AKey->g = SHARP;
	  break;
	}
      }
      break;
    }/* Case KeySign */
    break;

  case 9:
    switch (Control.KeySign) {

    case -7:
    case -6:
    case -5:
    case -4:
    case -3:
      if (AKey->a == NON) {
	sprintf(Result, "{=%s}", Notes[Index(value) - 1]);
	if (ChangeAKey)
	  AKey->a = CORRECT;
      } else
	sprintf(Result, "%s", Notes[Index(value) - 1]);
      break;

    case 5:
    case 6:
    case 7:
    case 8:
      if (AKey->a == NON) {
	sprintf(Result, "{=%s}", Notes[Index(value) - 1]);
	if (ChangeAKey)
	  AKey->a = CORRECT;
      } else
	sprintf(Result, "%s", Notes[Index(value) - 1]);
      break;

    default:
      if (AKey->a != NON) {
	sprintf(Result, "{=%s}", Notes[Index(value) - 1]);
	if (ChangeAKey)
	  AKey->a = NON;
      } else
	sprintf(Result, "%s", Notes[Index(value) - 1]);
      break;
    }/* case */
    break;

  case 10:
    switch (Control.KeySign) {

    case 5:
    case 6:
    case 7:
    case 8:
      if (AKey->a == CORRECT) {
	sprintf(Result, "{^%s}", Notes[Index(value - 1) - 1]);
	if (ChangeAKey)
	  AKey->a = NON;
      } else
	sprintf(Result, "%s", Notes[Index(value - 1) - 1]);
      break;

    case -8:
    case -7:
    case -6:
    case -5:
    case -4:
    case -3:
    case -2:
    case -1:
      if (AKey->b == CORRECT) {
	sprintf(Result, "{_%s}", Notes[Index(value + 1) - 1]);
	if (ChangeAKey)
	  AKey->b = NON;
      } else
	sprintf(Result, "%s", Notes[Index(value + 1) - 1]);
      break;

    default:
      if (AKey->a == SHARP)
	sprintf(Result, "%s", Notes[Index(value - 1) - 1]);
      else if (AKey->b == FLAT)
	sprintf(Result, "%s", Notes[Index(value + 1) - 1]);
      else {
	switch (Control.KeySign) {

	case -8:
	case -7:
	case -6:
	case -5:
	case -4:
	case -3:
	case -2:
	case -1:
	case 0:
	  sprintf(Result, "{_%s}", Notes[Index(value + 1) - 1]);
	  if (ChangeAKey)
	    AKey->b = FLAT;
	  break;

	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
	case 6:
	case 7:
	case 8:
	  sprintf(Result, "{^%s}", Notes[Index(value - 1) - 1]);
	  if (ChangeAKey)
	    AKey->a = SHARP;
	  break;
	}
      }
      break;
    }/* Case KeySign */
    break;

  case 11:
    switch (Control.KeySign) {

    case -8:
    case -7:
    case -6:
    case -5:
    case -4:
    case -3:
    case -2:
    case -1:
      if (AKey->b == NON) {
	sprintf(Result, "{=%s}", Notes[Index(value) - 1]);
	if (ChangeAKey)
	  AKey->b = CORRECT;
      } else
	sprintf(Result, "%s", Notes[Index(value) - 1]);
      break;

    case 8:
      if (AKey->b == NON) {
	sprintf(Result, "{=%s}", Notes[Index(value) - 1]);
	if (ChangeAKey)
	  AKey->b = CORRECT;
      } else
	sprintf(Result, "%s", Notes[Index(value) - 1]);
      break;

    default:
      if (AKey->b != NON) {
	sprintf(Result, "{=%s}", Notes[Index(value) - 1]);
	if (ChangeAKey)
	  AKey->b = NON;
      } else
	sprintf(Result, "%s", Notes[Index(value) - 1]);
      break;
    }/* case */
    break;

  }


  return Result;
}  /* ValueSTring */

/*  variables for Note2String: 
struct LOC_Note2String {
  NoteRecord ThisNote;
} ;*/

/*------------------------------*/
 Char HangOrBang(LINK)
struct LOC_Note2String *LINK;
{
  /*------------------------------*/
  if (LINK->ThisNote.Orient == UP)
    return 'u';
  else
    return 'l';
}


/**************************************************************************/
 Char *Note2String(Result, ThisNote_, Clef, AKey)
Char *Result;
NoteRecord ThisNote_;
ClefType Clef;
AccKeyType *AKey;
{
  /***************************************************************************/
  struct LOC_Note2String V;
  Char STR1[20]; /* STR2[256]; */

  V.ThisNote = ThisNote_;
  switch (V.ThisNote.Event) {

  case NOTEON:
  case NOTEOFF:
    switch (V.ThisNote.NoteType) {

    case WH:
      sprintf(Result, "\\wh %s",
	      ValueString(STR1, V.ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case WHP:
      sprintf(Result, "\\whp %s",
	      ValueString(STR1, V.ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case WHPP:
      sprintf(Result, "\\whpp %s",
	      ValueString(STR1, V.ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case WHPPP:
      sprintf(Result, "\\whppp %s",
	      ValueString(STR1, V.ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case H:
      sprintf(Result, "\\h%c %s",
	      HangOrBang(&V),
	      ValueString(STR1, V.ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case HP:
      sprintf(Result, "\\h%cp %s",
	      HangOrBang(&V),
	      ValueString(STR1, V.ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case HPP:
      sprintf(Result, "\\h%cpp %s",
	      HangOrBang(&V),
	      ValueString(STR1, V.ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case HPPP:
      sprintf(Result, "\\h%cppp %s",
	      HangOrBang(&V),
	      ValueString(STR1, V.ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case Q:
      sprintf(Result, "\\q%c %s",
	      HangOrBang(&V),
	      ValueString(STR1, V.ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case QP:
      sprintf(Result, "\\q%cp %s",
	      HangOrBang(&V),
	      ValueString(STR1, V.ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case QPP:
      sprintf(Result, "\\q%cpp %s",
	      HangOrBang(&V),
	      ValueString(STR1, V.ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case QPPP:
      sprintf(Result, "\\q%cppp %s",
	      HangOrBang(&V),
	      ValueString(STR1, V.ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case C:
      sprintf(Result, "\\c%c %s",
	      HangOrBang(&V),
	      ValueString(STR1, V.ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case CP:
      sprintf(Result, "\\c%cp %s",
	      HangOrBang(&V),
	      ValueString(STR1, V.ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case C3:
      sprintf(Result, "\\c%c %s",
	      HangOrBang(&V),
	      ValueString(STR1, V.ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case CPP:
      sprintf(Result, "\\c%cpp %s",
	      HangOrBang(&V),
	      ValueString(STR1, V.ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case CPPP:
      sprintf(Result, "\\c%cppp %s",
	      HangOrBang(&V),
	      ValueString(STR1, V.ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case CC:
      sprintf(Result, "\\cc%c %s",
	      HangOrBang(&V),
	      ValueString(STR1, V.ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case CCP:
      sprintf(Result, "\\pt %s\\cc%c %s",
	      ValueString(STR1, V.ThisNote.NoteVal, PieceContr, AKey, false),
	      HangOrBang(&V),
	      ValueString(STR2, V.ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case CC3:
      sprintf(Result, "\\cc%c %s",
	      HangOrBang(&V),
	      ValueString(STR1, V.ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case CCC:
      sprintf(Result, "\\ccc%c %s",
	      HangOrBang(&V),
	      ValueString(STR1, V.ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case CCCP:
      sprintf(Result, "\\pt %s\\ccc%c %s",
	      ValueString(STR1, V.ThisNote.NoteVal, PieceContr, AKey, false),
	      HangOrBang(&V),
	      ValueString(STR2, V.ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case CCC3:
      sprintf(Result, "\\ccc%c %s",
	      HangOrBang(&V),
	      ValueString(STR1, V.ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case CCCC:
      sprintf(Result, "\\cccc%c %s",
	      HangOrBang(&V),
	      ValueString(STR1, V.ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case CCCCP:
      sprintf(Result, "\\pt %s\\cccc%c %s",
	      ValueString(STR1, V.ThisNote.NoteVal, PieceContr, AKey, false),
	      HangOrBang(&V),
	      ValueString(STR2, V.ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case CCCC3:
      sprintf(Result, "\\cccc%c %s",
	      HangOrBang(&V),
	      ValueString(STR1, V.ThisNote.NoteVal, PieceContr, AKey, true));
      break;
    }/* case */
    break;

  case VOID:
    strcpy(Result, "");
    break;

  case TXT:
    sprintf(Result, "\\uptext{%s} ", V.ThisNote.MetaTxt);
    break;

  case REST:
    RestString(Result, V.ThisNote.NoteType, Clef);
    break;

  case PEDAL:
    if (V.ThisNote.Velocity > 0)
      strcpy(Result, "\\PED");
    else
      strcpy(Result, "\\DEP");
    break;
  }/* case */
  return Result;
}  /* Note2String */



/**************************************************************/
 Char *ChordNote2String(Result, ThisNote, Clef, AKey)
Char *Result;
NoteRecord ThisNote;
ClefType Clef;
AccKeyType *AKey;
{
  /**************************************************************/
  Char STR1[20];

  switch (ThisNote.Event) {

  case NOTEON:
  case NOTEOFF:
    switch (ThisNote.NoteType) {

    case WH:
      sprintf(Result, "\\zw %s",
	      ValueString(STR1, ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case H:
      sprintf(Result, "\\zh %s",
	      ValueString(STR1, ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case HP:
      sprintf(Result, "\\zhp %s",
	      ValueString(STR1, ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case HPP:
      sprintf(Result, "\\zhpp %s",
	      ValueString(STR1, ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case HPPP:
      sprintf(Result, "\\zhppp %s",
	      ValueString(STR1, ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case Q:
      sprintf(Result, "\\zq %s",
	      ValueString(STR1, ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case QP:
      sprintf(Result, "\\zqp %s",
	      ValueString(STR1, ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case QPP:
      sprintf(Result, "\\zqpp %s",
	      ValueString(STR1, ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case QPPP:
      sprintf(Result, "\\zqppp %s",
	      ValueString(STR1, ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case C:
      sprintf(Result, "\\zq %s",
	      ValueString(STR1, ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case CP:
      sprintf(Result, "\\zq %s",
	      ValueString(STR1, ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case C3:
      sprintf(Result, "\\zq %s",
	      ValueString(STR1, ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case CPP:
      sprintf(Result, "\\zqpp %s",
	      ValueString(STR1, ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case CPPP:
      sprintf(Result, "\\zqppp %s",
	      ValueString(STR1, ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case CC:
      sprintf(Result, "\\zq %s",
	      ValueString(STR1, ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case CCP:
      sprintf(Result, "\\zqp %s",
	      ValueString(STR1, ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case CC3:
      sprintf(Result, "\\zq %s",
	      ValueString(STR1, ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case CCC:
      sprintf(Result, "\\zq %s",
	      ValueString(STR1, ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case CCCP:
      sprintf(Result, "\\zqp %s",
	      ValueString(STR1, ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case CCC3:
      sprintf(Result, "\\zq %s",
	      ValueString(STR1, ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case CCCC:
      sprintf(Result, "\\zq %s",
	      ValueString(STR1, ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case CCCCP:
      sprintf(Result, "\\zqp %s",
	      ValueString(STR1, ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case CCCC3:
      sprintf(Result, "\\zq %s",
	      ValueString(STR1, ThisNote.NoteVal, PieceContr, AKey, true));
      break;
    }/* case */
    break;

  case VOID:
    strcpy(Result, "");
    break;

  case REST:
    RestString(Result, ThisNote.NoteType, Clef);
    break;

  case TXT:
    sprintf(Result, "\\uptext{%s}", ThisNote.MetaTxt);
    break;

  case PEDAL:
    if (ThisNote.Velocity > 0)
      strcpy(Result, "\\PED");
    else
      strcpy(Result, "\\DEP");
    break;
  }
  return Result;
}  /* ChordNote2String */

/*  variables for BeamNote2String:
struct LOC_BeamNote2String {
  BeamRecord ThisBeam;
} ; */

/*------------------------------*/
 Char HOrB(LINK)
struct LOC_BeamNote2String *LINK;
{
  /*------------------------------*/
  if (LINK->ThisBeam.Orient == UP)
    return 'h';
  else
    return 'b';
}

/*------------------------------*/
 Char BNo(LINK)
struct LOC_BeamNote2String *LINK;
{
  /*------------------------------*/
  Char Tmp[256];

  sprintf(Tmp, "%1d", LINK->ThisBeam.Numb);
  if (strlen(Tmp) > 1)
    WriteDebugInfo("Warning: found a beam number bigger than 9 !");
  return (Tmp[0]);
}



/**************************************************************/
 Char *BeamNote2String(Result, ThisNote, ThisBeam_, Clef, AKey)
Char *Result;
NoteRecord ThisNote;
BeamRecord ThisBeam_;
ClefType Clef;
AccKeyType *AKey;
{
  /**************************************************************/
  struct LOC_BeamNote2String V;
  Char TmpStr[26];
  Char STR1[25], STR3[25];

  V.ThisBeam = ThisBeam_;
  switch (ThisNote.Event) {

  case NOTEON:
  case NOTEOFF:
    switch (ThisNote.NoteType) {

    case C:
    case C3:
    case CC:
    case CC3:
    case CCC:
    case CCC3:
    case CCCC:
    case CCCC3:
      sprintf(TmpStr, "\\q%c%c%s",
	      HOrB(&V), BNo(&V),
	      ValueString(STR1, ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case CP:
    case CCP:
    case CCCP:
    case CCCCP:
      sprintf(TmpStr, "\\pt %s\\q%c%c%s",
	      ValueString(STR1, ThisNote.NoteVal, PieceContr, AKey, false),
	      HOrB(&V), BNo(&V),
	      ValueString(STR3, ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case CPP:
      sprintf(TmpStr, "\\ppt %s\\q%c%c%s",
	      ValueString(STR1, ThisNote.NoteVal, PieceContr, AKey, false),
	      HOrB(&V), BNo(&V),
	      ValueString(STR3, ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    case CPPP:
      sprintf(TmpStr, "\\pppt %s\\q%c%c%s",
	      ValueString(STR1, ThisNote.NoteVal, PieceContr, AKey, false),
	      HOrB(&V), BNo(&V),
	      ValueString(STR3, ThisNote.NoteVal, PieceContr, AKey, true));
      break;

    default:
      sprintf(TmpStr, "??%c%c%s",
	      HOrB(&V), BNo(&V),
	      ValueString(STR1, ThisNote.NoteVal, PieceContr, AKey, true));
      WriteDebugInfo(
	"Warning : found a note longer than an eighth note in a beam !");
      break;
    }/* case */
    break;

  case VOID:
    *TmpStr = '\0';
    break;

  case REST:
    RestString(TmpStr, ThisNote.NoteType, Clef);
    break;

  case TXT:
    sprintf(TmpStr, "\\uptext{%s}", ThisNote.MetaTxt);
    break;

  case PEDAL:
    if (ThisNote.Velocity > 0)
      strcpy(TmpStr, "\\PED");
    else
      strcpy(TmpStr, "\\DEP");
    break;
  }/* with thisnote */
  return strcpy(Result, TmpStr);
}  /* BeamNote2String */



/*****************************************************************/
 Char *InitBeam(Result, ThisBeam, ForceZero, AKey)
Char *Result;
BeamRecord ThisBeam;
boolean ForceZero;
AccKeyType *AKey;
{
  /*****************************************************************/
/*  Char TmpStr[26]; */
  Char IndxStr[3];
/*  Char STR1[256], STR2[42]; */

  sprintf(IndxStr, "%1d", ThisBeam.Numb);
  strcpy(TmpStr, "\\i");
  switch (ThisBeam.NoteType) {

  case C:
  case C3:
  case CP:
  case CPP:
  case CPPP:
    strcat(TmpStr, "b");
    break;

  case CC:
  case CC3:
  case CCP:
    strcat(TmpStr, "bb");
    break;

  case CCC:
  case CCC3:
  case CCCP:
    strcat(TmpStr, "bbb");
    break;

  case CCCC:
  case CCCC3:
  case CCCCP:
    strcat(TmpStr, "bbbb");
    break;
  }/* case */
  if (ThisBeam.Orient == UP)
    sprintf(TmpStr + strlen(TmpStr), "u%s", IndxStr);
  else
    sprintf(TmpStr + strlen(TmpStr), "l%s", IndxStr);

  sprintf(TmpStr + strlen(TmpStr), "%s{",
	  ValueString(STR1, ThisBeam.Pitch, PieceContr, AKey, false));

  /* determine the slope */
  if (ForceZero)
    strcpy(IndxStr, "0");
  else {
    switch (ThisBeam.Slope) {

    case -20:
    case -19:
    case -18:
      sprintf(IndxStr, "%2d", -8);
      break;

    case -17:
    case -16:
    case -15:
      sprintf(IndxStr, "%2d", -7);
      break;

    case -14:
    case -13:
    case -12:
      sprintf(IndxStr, "%2d", -6);
      break;

    case -11:
    case -10:
      sprintf(IndxStr, "%2d", -5);
      break;

    case -9:
    case -8:
      sprintf(IndxStr, "%2d", -4);
      break;

    case -7:
    case -6:
      sprintf(IndxStr, "%2d", -3);
      break;

    case -5:
    case -4:
      sprintf(IndxStr, "%2d", -2);
      break;

    case -3:
    case -2:
      sprintf(IndxStr, "%2d", -1);
      break;

    case -1:
    case 0:
    case 1:
      sprintf(IndxStr, "%1d", 0);
      break;

    case 2:
    case 3:
      sprintf(IndxStr, "%1d", 1);
      break;

    case 4:
    case 5:
      sprintf(IndxStr, "%1d", 2);
      break;

    case 6:
    case 7:
      sprintf(IndxStr, "%1d", 3);
      break;

    case 8:
    case 9:
      sprintf(IndxStr, "%1d", 4);
      break;

    case 10:
    case 11:
      sprintf(IndxStr, "%1d", 5);
      break;

    case 12:
    case 13:
    case 14:
      sprintf(IndxStr, "%1d", 6);
      break;

    case 15:
    case 16:
    case 17:
      sprintf(IndxStr, "%1d", 7);
      break;

    case 18:
    case 19:
    case 20:
      sprintf(IndxStr, "%1d", 8);
      break;

    default:
      if (ThisBeam.Slope >= -127 && ThisBeam.Slope <= -21)
	sprintf(IndxStr, "%2d", -9);
      else if (ThisBeam.Slope >= 21 && ThisBeam.Slope <= 127)
	sprintf(IndxStr, "%1d", 9);
      break;
    }
  }
  sprintf(TmpStr + strlen(TmpStr), "%s}", IndxStr);   /* With */
  sprintf(STR1, "Init beam with %s", TmpStr);
  WriteDebugInfo(STR1);
  return strcpy(Result, TmpStr);
}  /* InitBeam */

/*****************************************************/
 Char *PartialBeam(Result, ThisBeam)
Char *Result;
BeamRecord ThisBeam;
{
  /*****************************************************/
  Char IndxStr[3];
  Char TermBeam[26];
/*  Char STR1[54]; */

  sprintf(IndxStr, "%1d", ThisBeam.Numb);
  strcpy(TermBeam, "\\rlap{\\qsk\\t");
  switch (ThisBeam.NoteType) {

  case C:
  case C3:
  case CP:
  case CPP:
  case CPPP:
    strcat(TermBeam, "b");
    break;

  case CC:
  case CC3:
  case CCP:
    strcat(TermBeam, "bb");
    break;

  case CCC:
  case CCC3:
  case CCCP:
    strcat(TermBeam, "bbb");
    break;

  case CCCC:
  case CCCC3:
  case CCCCP:
    strcat(TermBeam, "bbbb");
    break;
  }/* case */

  if (ThisBeam.Orient == UP)
    sprintf(TermBeam + strlen(TermBeam), "u%s}", IndxStr);
  else
    sprintf(TermBeam + strlen(TermBeam), "l%s}", IndxStr);
  sprintf(STR1, "Partial terminate beam with %s", TermBeam);
  WriteDebugInfo(STR1);
  return strcpy(Result, TermBeam);
}  /* PartialBeam */


/*****************************************************/
 Char *TerminateBeam(Result, ThisBeam)
Char *Result;
BeamRecord ThisBeam;
{
  /*****************************************************/
  Char IndxStr[3];
  Char TermBeam[26];
/*  Char STR1[48]; */

  if (ThisBeam.Orient == UP)
    sprintf(TermBeam, "\\tbu%1d", ThisBeam.Numb);
  else
    sprintf(TermBeam, "\\tbl%1d", ThisBeam.Numb);
  sprintf(STR1, "Terminating beam with %s", TermBeam);
  WriteDebugInfo(STR1);
  return strcpy(Result, TermBeam);
}  /* Terminate Beam */

/***********************************************************/
 Char *ChainBeam(Result, ThisBeam, NextBeam)
Char *Result;
BeamRecord ThisBeam, NextBeam;
{
  /***********************************************************/
  Char IndxStr[3];
/*  Char TmpStr[26];
  Char STR1[46]; */

  if ((long)NextBeam.NoteType > (long)ThisBeam.NoteType) {   /* With */
    sprintf(IndxStr, "%1d", NextBeam.Numb);

    if (NextBeam.NoNotes == 1)
	  /* there is only one note of higher type in next beam */
	    strcpy(TmpStr, "\\t");
	  /* instead of initializing higher order beam we insert */
    else  /* a terminate beam which draws the flags at the back  */
      strcpy(TmpStr, "\\n");
    /* of the note                                         */

    switch (NextBeam.NoteType) {

    case C:
    case C3:
    case CP:
    case CPP:
    case CPPP:
      strcat(TmpStr, "b");
      break;

    case CC:
    case CC3:
    case CCP:
      strcat(TmpStr, "bb");
      break;

    case CCC:
    case CCC3:
    case CCCP:
      strcat(TmpStr, "bbb");
      break;

    case CCCC:
    case CCCC3:
    case CCCCP:
      strcat(TmpStr, "bbb");
      break;
    }/* case */
    if (ThisBeam.Orient == UP)   /* With */
      sprintf(TmpStr + strlen(TmpStr), "u%s", IndxStr);
    else
      sprintf(TmpStr + strlen(TmpStr), "l%s", IndxStr);

  } else {
    sprintf(IndxStr, "%1d", NextBeam.Numb);
    strcpy(TmpStr, "\\t");
    switch (NextBeam.NoteType) {

    case C:
    case C3:
    case CP:
    case CPP:
    case CPPP:
      strcat(TmpStr, "bb");
      break;

    case CC:
    case CC3:
    case CCP:
      strcat(TmpStr, "bbb");
      break;

    case CCC:
    case CCC3:
    case CCCP:
      strcat(TmpStr, "bbbb");
      break;

    case CCCC:
    case CCCC3:
    case CCCCP:
      WriteDebugInfo("This cannot happen...!, error in CHaining beam");
      break;
    }/* case */
    if (ThisBeam.Orient == UP)
      sprintf(TmpStr + strlen(TmpStr), "u%s", IndxStr);
    else
      sprintf(TmpStr + strlen(TmpStr), "l%s", IndxStr);
  }

  sprintf(STR1, "Chaining beam with %s", TmpStr);
  WriteDebugInfo(STR1);
  return strcpy(Result, TmpStr);


}  /* ChainBeam */


/*****************************************************************/
 Char *InitSlurr(Result, ThisSlurr, AKey)
Char *Result;
SlurrRecord ThisSlurr;
AccKeyType *AKey;
{
  /*****************************************************************/
/*  Char TmpStr[26]; */
  Char IndxStr[3];
/*  Char STR1[256];
  Char STR2[256]; */

  sprintf(IndxStr, "%1d", ThisSlurr.Numb1);
  sprintf(TmpStr, "\\itenu%s%s",
	  IndxStr,
	  ValueString(STR2, ThisSlurr.NoteVal, PieceContr, AKey, false));
  sprintf(STR1, "Init slurr with %s", TmpStr);
  WriteDebugInfo(STR1);
  return strcpy(Result, TmpStr);
}  /* InitSlurr*/

/***********************************************************/
 Char *TerminateSlurr(Result, ThisSlurr)
Char *Result;
SlurrRecord *ThisSlurr;
{
  /***********************************************************/
  Char IndxStr[3];
/*  Char TmpStr[26];
  Char STR1[50]; */

  sprintf(IndxStr, "%1d", ThisSlurr->Numb2);
  sprintf(TmpStr, "\\tten%s", IndxStr);
  sprintf(STR1, "Terminating slurr with %s", TmpStr);
  WriteDebugInfo(STR1);
  if (ThisSlurr->KindOf == ENDSLUR)
    ThisSlurr->Occupied = false;
  return strcpy(Result, TmpStr);
}  /* Terminate Slurr */





/****************************************************/
 Void FindMeasureParts(ThisMeasure)
unsigned int ThisMeasure;
{
  /****************************************************/
  MeasureTime ST, ET, TET, DT;
  long i, curtrack;
  NoteRecord *N, *P, *Q_;
  boolean Done, PartEmpty;
  long t1, t2, FORLIM;
  TrackRecord *WITH;
/*  Char STR1[256], STR2[256];
  Char STR3[28]; */
  long FORLIM1;

  FORLIM = ntracks;
  for (curtrack = 1; curtrack <= FORLIM; curtrack++) {   /* with curtrack */
    WITH = &TrackArray[curtrack - 1];
    sprintf(STR1, "Finding parts in track %3ld", curtrack);
    WriteDebugInfo(STR1);
    FirstNote(WITH->NoteList, &N);
    Q_ = N;
    LastNote(WITH->NoteList, &P);
    SetTim(&ST, ThisMeasure, 0);
    SetTim(&ET, ThisMeasure, (int)PieceContr.TicksPerMeasure);
    SetTim(&DT, 0, PieceContr.PartTime);
    AddTime(ST, DT, &TET);
    if (N == P) {
      WriteDebugInfo("Only one event in this track and measure ");
      switch (N->Event) {

      case NOTEON:
      case NOTEOFF:
	sprintf(STR1, "Note %3d", N->NoteVal);
	WriteDebugInfo(STR1);
	break;

      case REST:
	sprintf(STR1, "Rest of type %3ld", (long)N->NoteType);
	WriteDebugInfo(STR1);
	break;

      case TXT:
	sprintf(STR1, "Text : %s", N->MetaTxt);
	WriteDebugInfo(STR1);
	break;

      case VOID:
	WriteDebugInfo("Void event ");
	break;

      case PEDAL:
	WriteDebugInfo("Pedal event");
	break;
      }

      switch (N->Event) {

      case NOTEON:
      case NOTEOFF:
      case TXT:
	WITH->PartStart[0] = N;
	WITH->PartEnd[0] = N;
	FORLIM1 = PieceContr.nparts;
	for (i = 1; i < FORLIM1; i++) {
	  /* Reset further starts and ends..., but why here ... ? */
	  WITH->PartStart[i] = NULL;
	  WITH->PartEnd[i] = NULL;
	}
	break;

      case REST:
	FORLIM1 = PieceContr.nparts;
	for (i = 0; i < FORLIM1; i++) {
	  WITH->PartStart[i] = NULL;
	  WITH->PartEnd[i] = NULL;
	}
	i = PieceContr.nparts / 2;
	WITH->PartStart[i - 1] = N;
	WITH->PartEnd[i - 1] = N;
	break;

      case VOID:
	FORLIM1 = PieceContr.nparts;
	for (i = 0; i < FORLIM1; i++) {
	  WITH->PartStart[i] = NULL;
	  WITH->PartEnd[i] = NULL;
	}
	break;
      }/* case */
    } else {  /* N<>P */
      FORLIM1 = PieceContr.nparts;
      for (i = 0; i < FORLIM1; i++) {
	sprintf(STR1, "In part %3ld following events:", i + 1);
	WriteDebugInfo(STR1);
	PartEmpty = true;
	WITH->PartStart[i] = NULL;
	WITH->PartEnd[i] = NULL;
	Done = false;
	t1 = TimeDiff(ST, N->StartTime);
	t2 = TimeDiff(TET, N->StartTime);
	/* does not stop at end of measure */
	while (t1 <= 0 && t2 > 0 && !Done) {   /* Else */
	  switch (PartEmpty) {

	  case true:
	    WITH->PartStart[i] = N;
	    WITH->PartEnd[i] = N;
	    PartEmpty = false;
	    break;

	  case false:
	    WITH->PartEnd[i] = N;
	    break;
	  }/* case */
	  switch (N->Event) {

	  case NOTEON:
	  case NOTEOFF:
	    sprintf(STR1, "Note %3d", N->NoteVal);
	    WriteDebugInfo(STR1);
	    break;

	  case REST:
	    sprintf(STR1, "Rest of type %3ld", (long)N->NoteType);
	    WriteDebugInfo(STR1);
	    break;

	  case TXT:
	    sprintf(STR1, "Text : %s", N->MetaTxt);
	    WriteDebugInfo(STR1);
	    break;
	    /* VOID           : Warning('Whoops, a void event in part....'); */
	  }
	  NextNote(N, &N);
	  if (N == Q_)
	    Done = true;
	  t1 = TimeDiff(ST, N->StartTime);
	  t2 = TimeDiff(TET, N->StartTime);
	}  /* while */
	memmove(&ST,&TET, sizeof(MeasureTime));
	AddTime(ST, DT, &TET);
      }  /* for next i */
    }  /* Else: N<>P */
  }
  WriteDebugInfo("Ready finding parts in this measure");
}  /* FindMeasureParts */

/*  variables for PartCreateMeasure: 
struct LOC_PartCreateMeasure {
  NoteRecord *N;
  long curtr, EventCnt;
  boolean BeamsOccured;
} ; */


/*-------------------------------*/
 Char *Seperator(Result, LINK)
Char *Result;
struct LOC_PartCreateMeasure *LINK;
{
  /*-------------------------------*/
  Char TmpStr[256];

  *TmpStr = '\0';
  if (LINK->curtr == ntracks) {
	/* we are at the end of the current range ...*/
	  if (ntracks <= 1) {  /* curtr=ntracks */
      *TmpStr = '\0';
      return strcpy(Result, TmpStr);
    }
    if (TrackArray[TrackOrder[ntracks - 1] - 1].Skip== true ||
	TrackArray[TrackOrder[ntracks - 2] - 1].Skip == true)
      return strcpy(Result, TmpStr);
    if (TrackArray[TrackOrder[ntracks - 1] - 1].Instrument==true &&
	TrackArray[TrackOrder[ntracks - 2] - 1].Instrument==true)
      strcpy(TmpStr, "|");
    else
      strcpy(TmpStr, "&");
    return strcpy(Result, TmpStr);
  }
  if (LINK->curtr == 1) {  /* curtr=1 */
    *TmpStr = '\0';
    return strcpy(Result, TmpStr);
  }
  if (TrackArray[TrackOrder[LINK->curtr - 2] - 1].Skip)
    return strcpy(Result, TmpStr);
  if (TrackArray[TrackOrder[LINK->curtr - 1] - 1].Instrument == true&&
      TrackArray[TrackOrder[LINK->curtr - 2] - 1].Instrument ==true)
    strcpy(TmpStr, "|");
  else
    strcpy(TmpStr, "&");
  return strcpy(Result, TmpStr);

  /* curtr>1 & curtr<ntracks */
}  /* Seperator */


/*--------------------------------------------------------*/
 Char *GetNoteStr(Result, ThisTrack, LINK)
Char *Result;
TrackRecord *ThisTrack;
struct LOC_PartCreateMeasure *LINK;
{
  /*--------------------------------------------------------*/
  Char Astring[256];
  long j;
  MeasureTime TmpTime;
  SlurrRecord *WITH1;
/*  Char STR1[256]; */

  *Astring = '\0';
  SetTim(&TmpTime, (int)(MeasureCount + 1), 0);

  if (ThisTrack->Slurring) {
    j = IsSlurred(LINK->N, ThisTrack);
    if (j > 0) {
      WITH1 = &ThisTrack->SlurrArray[j - 1];
      switch (WITH1->KindOf) {

      case STARTSLUR:
	strcat(Astring, InitSlurr(STR1, ThisTrack->SlurrArray[j - 1],
				  &ThisTrack->AccKey));
	break;

      case REPEATSLUR:
	strcat(Astring, TerminateSlurr(STR1, &ThisTrack->SlurrArray[j - 1]));
	strcat(Astring, InitSlurr(STR1, ThisTrack->SlurrArray[j - 1],
				  &ThisTrack->AccKey));
	break;

      case ENDSLUR:
	strcat(Astring, TerminateSlurr(STR1, &ThisTrack->SlurrArray[j - 1]));
	break;
      }/* case */
    }
  }  /* slurring */


  if (ThisTrack->Beam) {
    LINK->BeamsOccured = true;
    if (LINK->N == ThisTrack->BeamArray[ThisTrack->BeamPt - 1].EndNote) {
      if (ThisTrack->BeamArray[ThisTrack->BeamPt - 1].Chain2Next) {
	strcat(Astring,
	       ChainBeam(STR1, ThisTrack->BeamArray[ThisTrack->BeamPt - 1],
			 ThisTrack->BeamArray[ThisTrack->BeamPt]));

	ThisTrack->BeamPt++;

	if (LINK->N == ThisTrack->BeamArray[ThisTrack->BeamPt - 1].EndNote)
	      /* end this beam immediately */
		strcat(Astring, TerminateBeam(STR1,
			 ThisTrack->BeamArray[ThisTrack->BeamPt - 1]));

      } else
	strcat(Astring,
	  TerminateBeam(STR1, ThisTrack->BeamArray[ThisTrack->BeamPt - 1]));
    }
  }  /* if beam */
  else {
    if (LINK->N == ThisTrack->BeamArray[ThisTrack->BeamPt - 1].StartNote) {
      LINK->BeamsOccured = true;
      if (ThisTrack->BeamArray[ThisTrack->BeamPt - 1].NoNotes == 1 &&
	  ThisTrack->BeamArray[ThisTrack->BeamPt - 1].Chain2Next  == true &&
	  (long)ThisTrack->BeamArray[ThisTrack->BeamPt - 1].NoteType >
	  (long)ThisTrack->BeamArray[ThisTrack->BeamPt].NoteType) {
	strcat(Astring,
	       InitBeam(STR1, ThisTrack->BeamArray[ThisTrack->BeamPt],
			ThisTrack->ForceZeroBeams, &ThisTrack->AccKey));
	strcat(Astring,
	       PartialBeam(STR1, ThisTrack->BeamArray[ThisTrack->BeamPt - 1]));
	ThisTrack->BeamPt++;
      } else
	strcat(Astring,
	       InitBeam(STR1, ThisTrack->BeamArray[ThisTrack->BeamPt - 1],
			ThisTrack->ForceZeroBeams, &ThisTrack->AccKey));
      ThisTrack->Beam = true;
    }
  }


  if (ThisTrack->Chord) {   /* With thistrack */
    if (LINK->N != ThisTrack->ChordArray[ThisTrack->ChordPt - 1].EndNote) {
      strcat(Astring, ChordNote2String(STR1, *LINK->N, ThisTrack->Clef,
				       &ThisTrack->AccKey));
      return strcpy(Result, Astring);
    }
    ThisTrack->Chord = false;
    WriteDebugInfo("Hit the end of the chord");
    ThisTrack->ChordPt++;
    if (!ThisTrack->Beam) {
      strcat(Astring, Note2String(STR1, *LINK->N, ThisTrack->Clef,
				  &ThisTrack->AccKey));
      LINK->EventCnt++;
      return strcpy(Result, Astring);
    }
    LINK->BeamsOccured = true;
    strcat(Astring, BeamNote2String(STR1, *LINK->N,
	     ThisTrack->BeamArray[ThisTrack->BeamPt - 1], ThisTrack->Clef,
	     &ThisTrack->AccKey));
    LINK->EventCnt++;
    if (LINK->N == ThisTrack->BeamArray[ThisTrack->BeamPt - 1].EndNote) {
      ThisTrack->Beam = false;
      ThisTrack->BeamPt++;
    }
    return strcpy(Result, Astring);
  }  /* If NtArPoint... */

  if (LINK->N == ThisTrack->ChordArray[ThisTrack->ChordPt - 1].StartNote) {
    WriteDebugInfo("Hit start of chord ");
    ThisTrack->Chord = true;
    strcat(Astring, ChordNote2String(STR1, *LINK->N, ThisTrack->Clef,
				     &ThisTrack->AccKey));
    return strcpy(Result, Astring);
  }
  if (!ThisTrack->Beam) {
    strcat(Astring,
	   Note2String(STR1, *LINK->N, ThisTrack->Clef, &ThisTrack->AccKey));
    LINK->EventCnt++;
    return strcpy(Result, Astring);
  }
  LINK->BeamsOccured = true;
  strcat(Astring, BeamNote2String(STR1, *LINK->N,
				  ThisTrack->BeamArray[ThisTrack->BeamPt - 1],
				  ThisTrack->Clef, &ThisTrack->AccKey));
  LINK->EventCnt++;
  LINK->BeamsOccured = true;
  if (LINK->N == ThisTrack->BeamArray[ThisTrack->BeamPt - 1].EndNote &&
      !ThisTrack->BeamArray[ThisTrack->BeamPt - 1].Chain2Next) {
    ThisTrack->Beam = false;
    ThisTrack->BeamPt++;
  }
  return strcpy(Result, Astring);


  /* Else */
}  /* GetNoteStr */

/****************************************************/
 Void PartCreateMeasure()
{
  /****************************************************/
  struct LOC_PartCreateMeasure V;
  long i;
  static Char Ms[MAXPARTS][512];
  long CurLength;
  static long MaxCnts[MAXPARTS];
  long FORLIM;
  TrackRecord *WITH;
/*  Char STR1[256], STR2[512]; */


  FORLIM = ntracks;
  for (i = 0; i < FORLIM; i++) {
    WITH = &TrackArray[i];
    WITH->Chord = false;
    WITH->Beam = false;
    WITH->ChordPt = 1;
    WITH->BeamPt = 1;
  }

  CurLength = 0;

  FORLIM = PieceContr.nparts;
  for (i = 0; i < FORLIM; i++) {
    MaxCnts[i] = 0;
    V.BeamsOccured = false;
    strcpy(Ms[i],"");
    for (V.curtr = ntracks; V.curtr >= 1; V.curtr--) {
      WITH = &TrackArray[TrackOrder[V.curtr - 1] - 1];
      V.EventCnt = 0;
      if (WITH->NoteList.Size > MeasureMaxCnt)
	MeasureMaxCnt = WITH->NoteList.Size;
      if (!WITH->Skip) {
	V.N = WITH->PartStart[i];
	if (V.N != NULL) {
	  strcat(Ms[i],
		 GetNoteStr(STR1, &TrackArray[TrackOrder[V.curtr - 1] - 1],
			    &V));
	  while (V.N != WITH->PartEnd[i]) {
	    NextNote(V.N, &V.N);
	    strcat(Ms[i],
		   GetNoteStr(STR1, &TrackArray[TrackOrder[V.curtr - 1] - 1],
			      &V));
	  }
	}
      }
      strcat(Ms[i], Seperator(STR1, &V));

      if (V.EventCnt > MaxCnts[i])
	MaxCnts[i] = V.EventCnt;

    }

    /* MaxCnts[i] contains the maximum number of notes in any of the tracks' parts */
    /* we use it to update the total         */
    /* cumulative length of the score line */


    if (V.BeamsOccured) {
      sprintf(STR2, "\\NOtes%s\\enotes\\relax", Ms[i]);
      strcpy(Ms[i], STR2);
      CurLength += MaxCnts[i] * ElemSkip * 2;
    } else {
      switch (MaxCnts[i]) {

      case 0:
	break;
	/* empty parts are not written ... */

      case 1:
      case 2:
	sprintf(STR1, "\\NOtes%s\\enotes\\relax", Ms[i]);
	strcpy(Ms[i], STR1);
	CurLength += MaxCnts[i] * ElemSkip * 2;
	break;

      case 3:
      case 4:
      case 5:
	sprintf(STR2, "\\Notes%s\\enotes\\relax", Ms[i]);
	strcpy(Ms[i], STR2);
	CurLength += (long)floor(1.4 * MaxCnts[i] * ElemSkip + 0.5);
	break;

      case 6:
      case 7:
      case 8:
      case 9:
      case 10:
	sprintf(STR1, "\\notes%s\\enotes\\relax", Ms[i]);
	strcpy(Ms[i], STR1);
	CurLength += MaxCnts[i] * ElemSkip;
	break;

      case 11:
      case 12:
      case 13:
      case 14:
      case 15:
	sprintf(STR2, "\\notes%s\\enotes\\relax", Ms[i]);
	strcpy(Ms[i], STR2);
	CurLength += MaxCnts[i] * ElemSkip;
	break;

      case 16:
      case 17:
      case 18:
      case 19:
      case 20:
	sprintf(STR1, "\\notes%s\\enotes\\relax", Ms[i]);
	strcpy(Ms[i], STR1);
	CurLength += MaxCnts[i] * ElemSkip;
	break;

      default:
	sprintf(STR2, "\\notes%s\\enotes\\relax", Ms[i]);
	strcpy(Ms[i], STR2);
	CurLength += MaxCnts[i] * ElemSkip;
	break;
      }/* case */
    }

    if (i + 1 > 1) {
      if (!V.BeamsOccured) {
	sprintf(STR2, "\\temps%s", Ms[i]);
	strcpy(Ms[i], STR2);
      }
    }

  }  /* For Next nparts */

  /* All parts are processed, a full measure has been written to disk   */
  /* Now we must find out if we have to write a \alapage and \alaligne  */
  /* CumLength now contains the length of the total lines               */
  if (MeasureCount > 0) {
    sprintf(STR1, "Curlength=%3ldpt, Cumlength=%3ldpt, Cumheight=%3ld",
	    CurLength,CumLength,CumHeight);
    WriteDebugInfo(STR1);
    if (CumLength + CurLength >= ScoreWidth) {
      if (CumHeight + ScoreSep + LineHeight * (ntracks - NoOfSkips) >= ScoreHeight) {
	fprintf(TexFile, "\\alapage\n");
	NoOfPages++;
	CumHeight = ScoreSep + LineHeight * (ntracks - NoOfSkips) + 200;
	CumLength = Indent + CurLength;
	WriteDebugInfo("so... inserting \\alapage");
      } else {
	fprintf(TexFile, "\\alaligne\n");
	CumHeight += ScoreSep + LineHeight * (ntracks - NoOfSkips);
	CumLength = Indent + CurLength;
	WriteDebugInfo("so... inserting \\aligne");
      }
    } else
      if (!ChangedContext) {
	 fprintf(TexFile, "\\barre\n");
	 CumLength += BarIndent + CurLength;
	 WriteDebugInfo("so... inserting \\barre");
      }
  }  /* If MeasureCount>0 */
  else  /* MeasureCOunt=0 */
    CumLength += ElemSkip + CurLength;

  /* Reset the ChangedCOntext flag to disable its effect in writing the \barre */
  ChangedContext=FALSE;


  FORLIM = PieceContr.nparts;
  for (i = 0; i < FORLIM; i++) {
    if (MaxCnts[i] > 0) {
      fprintf(TexFile, "%s\n", Ms[i]);
      sprintf(STR1, "Tail of MeasureString : %s", Ms[i]);
      WriteDebugInfo(STR1);
    } else
      WriteDebugInfo("Empty part ");
  }

}  /* PartCreateMeasure */

/**********************************************/
 Void CheckControls(ThisMsre)
long ThisMsre;
{   /* TrackArray record 1 contains META events */
  /**********************************************/
  NoteRecord *N;
  TrackRecord *WITH;

  WITH = TrackArray;
  if (WITH->NoteList.Size <= 0)
      /* we assume that there is only one control */
      {  /* per measure                              */
    return;
  }  /* If */
  FirstNote(WITH->NoteList, &N);
  if (N->StartTime.Measure != ThisMsre)
    return;
  switch (N->Event) {

  case KEYSIGN:
  case SIGNATURE:
    ChangeContext(N);
    break;
  }/* case */
}


/*************************************************************/
static Void InstallNewErrorExit()
{
/*************************************************************/
atexit(NewErrorExit);
}

  /**********************************************/
  /*                                            */
  /*           MAIN BLOCK                       */
  /*                                            */
  /**********************************************/
  long FORLIM;
  TrackRecord *WITH;

main(argc,argv)
int argc;
char *argv[];
{
#ifdef THINK_C
argc = ccommand(&argv);
#endif

  InstallNewErrorExit();
  DisplayLicense();
  Initialize(argc,argv);
  ReadString(TmpStr, &HlpFilRec, 4L);
  WriteDebugInfo(TmpStr);
  if (strcmp(TmpStr, "MThd"))
    ErrorExit(2L);
  ALongInt = ReadLongInt(&HlpFilRec);
  sprintf(STR1, "HeaderNo=%3ld", ALongInt);
  WriteDebugInfo(STR1);
  if (ALongInt != 6)
    ErrorExit(2L);
  FileFormat = ReadInteger(&HlpFilRec);
  sprintf(STR1, "MidiFile is in format type : %3d", (int)FileFormat);
  WriteDebugInfo(STR1);   /* this is OK */
  switch (FileFormat) {

  case 0:
    Warning("This is a type 0 MIDI file, no warranties about the result...");
    break;

  case 1:
    break;
  case 2:
    ErrorExit(5L);
    break;
  default:
    ErrorExit(5L);
    break;
  }

  ntracks = ReadInteger(&HlpFilRec);
  sprintf(STR1, " Found %3ld tracks in this file", ntracks);
  WriteDebugInfo(STR1);
  if (NoOfSkips > 0) {
    sprintf(STR1, "Skipping %3d of them", (int)NoOfSkips);
    WriteDebugInfo(STR1);
  }
  if (OrderIndex > 1) {
    if (OrderIndex != ntracks)
      ErrorExit(7L);
  }
  CumHeight = ScoreSep + LineHeight * (ntracks - NoOfSkips) + 300;

  WriteTexHeader();
  PieceContr.Division = ReadInteger(&HlpFilRec);
  sprintf(STR1, " Division : %3ld", PieceContr.Division);
  WriteDebugInfo(STR1);
  PieceContr.Num = 4;
  PieceContr.Den = 2;
  PieceContr.TicksPerMeasure = PieceContr.Division * PieceContr.Num * 4 /
			       Power(2, PieceContr.Den);
  sprintf(STR1, "Ticks per Measure :%3ld", PieceContr.TicksPerMeasure);
  WriteDebugInfo(STR1);
  PieceContr.PartTime = PieceContr.TicksPerMeasure / PieceContr.Num;
  PieceContr.nparts = PieceContr.TicksPerMeasure / PieceContr.PartTime;
  PieceContr.Twindow = PieceContr.Division / 16;

  InitFilePosns(ntracks);   /* find the starts of the tracks in the file */
#ifdef THINK_C
setvbuf(stdout,NULL,_IONBF,0);
#endif
  MeasureCount = -1;
  do {
    MeasureCount++;
    sprintf(STR1, " starting to read Measure %3d",(int)MeasureCount);
    WriteDebugInfo(STR1);
    printf("[%ld]",MeasureCount);
    if (MeasureCount > 0 && MeasureCount % 19 == 0)
      putchar('\n');
    FORLIM = ntracks;
/* p2c: tp_m2t13.pas, line 2958:
 * Note: Using % for possibly-negative arguments [317] */
    for (CurTrack = 1; CurTrack <= FORLIM; CurTrack++) {
      WITH = &TrackArray[CurTrack - 1];   /* With TrackArray */
      if (!EndOfTrackReached(&TrackArray[CurTrack - 1])) {
	sprintf(STR1, "Starting to read from track :%3ld", CurTrack);
	WriteDebugInfo(STR1);
	/* LastNoteOffTime.Measure:=MeasureCount; */
	/* to get a correct rest */
	/* LastNoteOffTime.Mpart:=0; */

	QuitTrack = false;

	/* Transfer all spilled events back to the note stack */
	if (WITH->SpillList.Size > 0) {
	  sprintf(STR1, "Transfering %3d notes from spillist",
		  WITH->SpillList.Size);
	  WriteDebugInfo(STR1);
	}
	while (WITH->SpillList.Size > 0) {
	  LastNote(WITH->SpillList, &N);
	  Re_move(&WITH->SpillList, N);
	  Append(&WITH->NoteList, N);
	  sprintf(STR1, "Note : %3d from %3d:%3ld to %3d:%3ld",
		  N->NoteVal,(int)N->StartTime.Measure,
		  N->StartTime.MPart,
		  (int)N->EndTime.Measure,
		  N->EndTime.MPart);
	  WriteDebugInfo(STR1);

	  if (WITH->SpillList.Size == 0) {
	    if (N->StartTime.Measure > MeasureCount)
	      QuitTrack = true;
	  }
	}


	if (!QuitTrack && !WITH->EndOfTrackRead) {
	  sprintf(STR1,"FilePos for this track : %ld",GetFilePos(&TrackArray[CurTrack-1].FilRec));
	  WriteDebugInfo(STR1);
	  do {
	    ReadDeltaTime(&TrackArray[CurTrack - 1]);
	    if (WITH->Curtime.Measure > MeasureCount + 1 ||
		(WITH->Curtime.Measure == MeasureCount + 1 &&
		 WITH->Curtime.MPart > QuantTime / 2))
	      QuitTrack = true;
	    ReadEvent(&TrackArray[CurTrack - 1]);
	    SafetyCounter++;
	  } while (!(QuitTrack== true || WITH->EndOfTrackRead == true));
	}

	/* Transfer SpillEvents to SpillList */
	/* only NoteOn can be transferred...*/
	/* a NoteOff can be maintained, but */
	/* note must than be slurred to     */
	/* next measure                     */

	/* removing notes to spillist not correct yet.... */
	/*  Hans : 24-3-92 */

	if (WITH->NoteList.Size > 0) {
	  SetTim(&TempTime, (int)(MeasureCount + 1), 0);
	  LastNote(WITH->NoteList, &N);
	  while ((WITH->NoteList.Size > 0) &
		 (TimeDiff(TempTime, N->StartTime) <= 0)) {
	    sprintf(STR1, "Transfering note %3d to spillist",N->NoteVal);
	    WriteDebugInfo(STR1);
	    Re_move(&WITH->NoteList, N);
	    Append(&WITH->SpillList, N);
	    if (WITH->NoteList.Size > 0) {
	      LastNote(WITH->NoteList, &N);
	      sprintf(STR1, "Last note now : %3d", N->NoteVal);
	      WriteDebugInfo(STR1);
	    }
	  }
	}

      } else {
	sprintf(STR1, "Track %3ld was already empty", CurTrack);
	WriteDebugInfo(STR1);
      }


      /* see if there was any note at all in the track ... */
      /* this is not OK....????? 26-3-'92 */
      if (WITH->NoteList.Size == 0) {
	SetTim(&WITH->Curtime, (int)MeasureCount,
		(int)PieceContr.TicksPerMeasure);
	InsertRest(&TrackArray[CurTrack - 1]);
      }

    }  /* For loop curtrack */


    /* Process the current measure in the Track's note arrays */
    fprintf(TexFile, "%%measure %1ld\n", MeasureCount + 1);

    /* see if there are any control events to start in this measure */

    CheckControls(MeasureCount);

    BeamIndex = 0;
    for (CurTrack = ntracks; CurTrack >= 1; CurTrack--) {
      WITH = &TrackArray[CurTrack - 1];
      if (!WITH->Skip && WITH->NoteList.Size > 0) {
	sprintf(STR1, "Start handling events in track :%3ld",CurTrack);
	WriteDebugInfo(STR1);
	FindNoteTypes(&TrackArray[TrackOrder[CurTrack - 1] - 1], MeasureCount);
	ChordFind(&TrackArray[TrackOrder[CurTrack - 1] - 1]);
	FindSlurrNote(&TrackArray[TrackOrder[CurTrack - 1] - 1], MeasureCount);
	BeamFind(&TrackArray[TrackOrder[CurTrack - 1] - 1]);
      }
    }

    FindMeasureParts((int)MeasureCount);

    PartCreateMeasure();

    CleanUpTracks();

  } while (!(AllTracksRead(ntracks)== true || SafetyCounter > 10000));

  fprintf(TexFile, "\\finmorceau\n");
  fprintf(TexFile, "\\bye\n");
  printf("\r\nTotal : %ld pages coded\r\n", NoOfPages);
  exit(0);
}

