/***************************/
/* dyn.c                   */
/***************************/

#include <stdio.h>
#include <stdlib.h>
#include "maintypes.h"
#include "defines.h"
#include "dyn.h"

void dyn_init()
{
	int ii;

	global = 1;
	for (ii=0; ii < MAXTRACKS; ii++) {
		begin[ii] = NULL;
		remember[ii] = NULL;
	}
}

void ins_dyn_event(tnr, mark, phr, nn, dom, oct, pit, loud, beg, dur)
	char mark, *phr;
	int tnr, nn, dom, oct, pit, loud, beg, dur;
{
	/* insdmark1 */
	if ((dynhelp = (struct bind *) malloc (sizeof(struct bind))) == NULL) {
		fprintf(stderr, "malloc error\n");
		exit(10);
	}
	dynhelp->marker = mark;
	dynhelp->time = beg;

	/* insdmark2 */
	switch (mark) {
		case 'n': if ((not = (struct Note *) malloc (sizeof(struct Note))) == NULL) {
				fprintf(stderr, "malloc error\n");
				exit(10);
			  }
			  not->octave = oct;
			  not->pitch = pit;
			  not->loud = loud;
			  not->duration = dur;
			  not->end = 0;
			  not->flags = 0;
			  if (((not->octave) * 12 + (not->pitch)) < 0x20) not->flags = 0x0200;
			  if (((not->octave) * 12 + (not->pitch)) > 0x29) not->flags = 0x0100;
			  not->beam_nr = 0;
			  not->slur_nr = 0;
			  not->note_pos = 0;
			  not->slur_pos = 0;
			  not->beam_pos = 0;
			  not->treated = 0;
			  not->next_beamn_kind = 0;	/* type of next beam note */
			  not->accord_next = NULL;
			  dynhelp->data = (void *) not;
			  break;
		case 't': if ((ts = (struct TimeSig *) malloc (sizeof(struct TimeSig))) == NULL) {
				fprintf(stderr, "malloc error\n");
				exit(10);
			  }
			  ts->nom = nn;
			  ts->denom = dom;
			  dynhelp->data = (void *) ts;
			  break;
		case 'l': if ((ly = (struct Lyric *) malloc (sizeof(struct Lyric))) == NULL) {
				fprintf(stderr, "malloc error\n");
				exit(10);
			  }
			  if ((ly->text = (char *) malloc (strlen(phr)+1)) == NULL) {
			  	fprintf(stderr, "malloc error\n");
			  	exit(10);
			  }
			  strcpy(ly->text, phr);
			  dynhelp->data = (void *) ly;
			  break;
		case 'k': if ((ks = (struct KeySig *) malloc (sizeof(struct KeySig))) == NULL) {
				fprintf(stderr, "malloc error\n");
				exit(10);
			  }
			  ks->sign = nn;
			  dynhelp->data = (void *) ks;
			  break;
		case 'b': if ((bar = (struct Barre *) malloc (sizeof(struct Barre))) == NULL) {
				fprintf(stderr, "malloc error\n");
				exit(10);
			  }
			  bar->takt_duration = dur;
			  bar->number_of_voices = 1;
			  dynhelp->data = (void *) bar;
			  break;
	}

	dynhelp->next = NULL;

	/* insdmark3 */
	if (begin[tnr] == NULL) { 
		begin[tnr]=dynhelp;
		akt[tnr]=dynhelp;
	}
	else { 
		if ((remember[tnr] != NULL) && ((remember[tnr]->time) < beg))
			akt[tnr] = remember[tnr];
		else akt[tnr] = begin[tnr];
		prev[tnr] = NULL;
		while ((akt[tnr] != NULL) && ((akt[tnr]->time) < beg)) {
			prev[tnr] = akt[tnr];
			akt[tnr] = akt[tnr]->next;
		}
		if ((akt[tnr] == NULL) || ((akt[tnr]->time) > beg) || (mark == 'b')) {
			if (prev[tnr] != NULL) prev[tnr]->next = dynhelp;
			else begin[tnr] = dynhelp;
			dynhelp->next = akt[tnr];
		}
		else {	/* insert elements with equal time into list in correct permutation */
			if (akt[tnr]->marker == 'n') not = (struct Note *) akt[tnr]->data;
			while ( (akt[tnr] != NULL) && ((akt[tnr]->time) == beg) &&
				( ((akt[tnr]->marker) == 'b') ||
				  (((akt[tnr]->marker) == 'k') && (mark != 'k')) ||
				  (((akt[tnr]->marker) == 't') && ((mark == 'l') || (mark == 'n'))) ||
				  (((akt[tnr]->marker) == 'l') && (mark == 'n')) ||
				  (((akt[tnr]->marker) == 'n') && (mark == 'n') &&
				   ((((not->octave) * 12) + (not->pitch)) < ((oct * 12) + pit))) ) ) {
				prev[tnr] = akt[tnr];
				akt[tnr] = akt[tnr]->next;
				if ((akt[tnr]) && (akt[tnr]->marker == 'n')) not = (struct Note *) akt[tnr]->data;
			}
			if (prev[tnr] != NULL) prev[tnr]->next = dynhelp;
			else begin[tnr] = dynhelp;
			dynhelp->next = akt[tnr];
		}
	}
}

void split_notes(Track, pq)
	int Track;
	short int pq;
{
	int notend, h;
	unsigned long barrtime;

	/* splnmark1: initiation */
	dynhelp3 = begin[Track];
	dynhelp2 = dynhelp3;
	notend = 1;
	while (notend) {
		/* splnmark2: loop now */
		while ((dynhelp3 != NULL) && ((dynhelp3->marker) != 'b')) dynhelp3 = dynhelp3->next;
		if (dynhelp3 == NULL) {
			notend = 0; 
		}
		else {
			barrtime = dynhelp3->time;
			dynhelp3 = dynhelp3->next;
		}
		while (dynhelp2 && ((!dynhelp3) || (barrtime > (dynhelp2->time)))) {
	       	 if (dynhelp2->marker == 'n') {
	       	 	not = (struct Note *) dynhelp2->data;
	       	 	h = (dynhelp2->time) + (not->duration);

	       	 	/* note should be splited because of long time */
	       	 	if (((not->duration) > (4 * pq)) && ((!dynhelp3) || (((dynhelp2->time) + (4 * pq)) < barrtime))) {
	       	 		ins_dyn_event(Track, 'n', 0, 0, 0, not->octave, not->pitch,
	       	 		              not->loud, (dynhelp2->time) + (4 * pq), (not->duration) - (4 * pq));
	       	 		(not->duration) = 4 * pq;
	       	 	}
	       	 	else {
	       	 		/* note sounds about next barre */
	       	 		if ((dynhelp3) && (h > barrtime)) {
	       	 			(not->duration) = barrtime - (dynhelp2->time);
	       	 			ins_dyn_event(Track, 'n', 0, 0, 0, not->octave, not->pitch,
						not->loud, barrtime, h - barrtime);
				}
		 	}
		 }
		 dynhelp2 = dynhelp2->next;
		}
	}
}

/* the following funktion returns one in case of existing a note that begins	*/
/* on time timepoint, zero else							*/
/* right region was found -> okflag returns 1 else 0				*/

short note_with_time(bplocal, timepoint, bpp, okflag)
	struct bind *bplocal, **bpp;
	char *okflag;
	unsigned long timepoint;
{
	struct bind *bhelp;
	char remem;
	struct Note *nhelp;

	/* notes shorter than 1/4 allow for beams */
	if ((*okflag) > 4) remem = 0;
	else remem = 1;

	/* delete bit 4 */
	*okflag &= 0x3;

	while ((bplocal) && (((bplocal->time) < timepoint) || ((bplocal->marker) != 'n'))) bplocal = bplocal->next;
	if ((bplocal) && ((bplocal->time) == timepoint) && ((bplocal->marker) == 'n')) {
		if (*okflag) {
			nhelp = (struct Note *) bplocal->data;
			bhelp = bplocal;
			while ( (bhelp) && ((bhelp->time) == timepoint) &&
				(!((!((nhelp->flags) & 0x200)) && (*okflag == 1) &&
				 (remem || (!((nhelp->flags) & 0x20))) )) &&
			        (!((!((nhelp->flags) & 0x100)) && (*okflag == 2) &&
			         (remem || (!((nhelp->flags) & 0x20))) )) ) {
			       	bhelp = bhelp->next;
				if ((bhelp) && ((bhelp->time) == timepoint))
					nhelp = (struct Note *) bhelp->data;
			}
			if ((bhelp) && ((bhelp->time) == timepoint)) {
				*okflag = 1;
				*bpp = bhelp;
				return(1);
			}
			else {
				*okflag = 0;
				*bpp = bplocal;
				return(1);
			}
		}
		else {
			if (remem) {
				*okflag = 1;
				*bpp = bplocal;
				return(1);
			}
			else {
				nhelp = (struct Note *) bplocal->data;
				bhelp = bplocal;
				while ( (bhelp) && ((bhelp->time) == timepoint) && ((nhelp->flags) & 0x20)) {
					bhelp = bhelp->next;
					if ((bhelp) && ((bhelp->time) == timepoint))
						nhelp = (struct Note *) bhelp->data;
				}
				if ((bhelp) && ((bhelp->time) == timepoint)) {
					*okflag = 1;
					*bpp = bhelp;
					return(1);
				}
				else {
					*okflag = 0;
					*bpp = bplocal;
					return(1);
				}
			}
		}
	}
	else {
		*okflag = 0;
		return(0);
	}
}

short barre_between(bploc, reftime)
	struct bind *bploc;
	unsigned long reftime;
{
	short rem = 0;
	while ((bploc) && ((bploc->time) < reftime)) {
		if ((bploc->marker) == 'b') rem = 1;
		bploc = bploc->next;
	}
	return(rem);
}

void detect_note_value(reg, tr, notedurat, flagptr, endptr, begint, bindptr, slurnrpt, pq)
	int notedurat, *slurnrpt;
	short int pq, *flagptr, tr;
	unsigned long *endptr, begint;
	struct bind *bindptr;
	char reg;
{
	int i;
	char ok;	/* allow slur only to be in one region */
	char newslur;	/* for setting the slur-begin flag */
	short desicion;

	/* dnvmark1 */
	*flagptr = *flagptr | 0x80;
	i = 0;
	while ((i<21) && ((NORMFAKTOR * notedurat) > (faktors[i] * pq))) i++;
	if (i==21) {
		fprintf(stderr,"warning: cut very long note\n");
		*flagptr = *flagptr | note_codes[20];
		*endptr = begint + (7 * pq);
	}
	else {
		if ((NORMFAKTOR * notedurat) == (faktors[i] * pq)) {
			/* dnvmark2: input ok forces a special region */
			if (!reg && ((*flagptr) & 0x0100)) ok = 1;
			else	if (!reg && ((*flagptr) & 0x0200)) ok = 2;
				else ok = 0;
			desicion = note_with_time(bindptr, notedurat + begint, &dynhelp, &ok);
			/* dnvmark3 */
			if ((i<15) && (!desicion)) {
				if (barre_between(bindptr, begint + (notedurat * 4))) {
					/* call it a normal note */
					*flagptr = *flagptr | (note_codes[i]);
					*endptr = begint + notedurat;
				}
				else {
					/* staccato detected */
					*flagptr = *flagptr | ((note_codes[i+6]) + 4);
					*endptr = begint + (notedurat * 4);
				}
			}
			else {
				/* dnvmark4 */
				if (dynhelp) not = (struct Note *) dynhelp->data;
				if (((i>=15) && (!desicion)) ||
				    ((desicion) && (!ok)) || (not->slur_nr)) {
					/* call it a normal note */
					*flagptr = *flagptr | (note_codes[i]);
					*endptr = begint + notedurat;
				}
				else {
					/* legato detected */
					*flagptr = *flagptr | (note_codes[i]);
					*flagptr = *flagptr & 0xff7f;
					*endptr = begint + notedurat;
					newslur = 0;
					if (!(*slurnrpt)) {
						newslur = 1;
						*slurnrpt = global++;
					}
					*flagptr = *flagptr | ((not->flags) & 0x0300);
					not->flags = not->flags | ((*flagptr) & 0x0300);
					not->slur_nr = *slurnrpt;
					if (newslur) not->slur_pos |= 0x40;
				}
			}
		}
		else {
			/* normal note detected */
			*flagptr = *flagptr | (note_codes[i]);
			*endptr = begint + ((faktors[i] * pq) / NORMFAKTOR);
		}
	}
	if (!(*slurnrpt)) *flagptr = *flagptr & 0xff7f;
}

void insert_notetimes_and_slurs(reg, Track, pq)
	int Track;
	short int pq;
	char reg;
{
	akt[Track] = begin[Track];
	while (akt[Track]) {
		if ((akt[Track]->marker) == 'n') {
			not = (struct Note *) akt[Track]->data;
			detect_note_value(reg, Track, not->duration, &(not->flags), &(not->end), akt[Track]->time, akt[Track], &(not->slur_nr), pq);
		}
		akt[Track] = akt[Track]->next;
	}
}

void detect_accords(reg, Track)
	int Track;
	char reg;
{
	char attention;	/* remembers the region */

	/* deacmark1 */
	akt[Track] = begin[Track];

	while (akt[Track]) {
		/* deacmark2 */
		if ((akt[Track]->marker) == 'n') {
			not2 = (struct Note *) akt[Track]->data;
			dynhelp = akt[Track]->next;
			dynhelp2 = akt[Track];
			/* prevent accords over two regions */
			if ((((not2->octave) * 12 + (not2->pitch)) < 0x20) && (!reg)) attention = 1;
			else attention = 0;
			/* deacmark3 */
			while ((dynhelp) && ((dynhelp->time) == (akt[Track]->time))) {
				not = (struct Note *) dynhelp->data;
				if (((not->duration) == (not2->duration)) &&
				    ((!attention) || (((not->octave) * 12 + (not->pitch)) < 0x2a))) {
					while (not2->accord_next) not2 = not2->accord_next;
					not2->accord_next = not;
					dynhelp2->next = dynhelp->next;
					free(dynhelp);
					dynhelp = dynhelp2->next;
				}
				else {
					dynhelp2 = dynhelp;
					dynhelp = dynhelp->next;
				}
			}
		}
		akt[Track] = akt[Track]->next;
	}
}

void beam_detect(reg, Track)
	int Track;
	char reg;
{
	struct bind *found;
	char ok, remsign;
	unsigned long remtime;
	short helpshort;

	/* bdmark1 */
	akt[Track] = begin[Track];
	while (akt[Track]) {
		if (akt[Track]->marker == 'n') {
			not = (struct Note *) akt[Track]->data;
			if (!((not->flags) & 0x20)) {
				/* bdmark2: 1/8 or shorter found */
				dynhelp = akt[Track]->next;
				while ((dynhelp) && ((dynhelp->marker) != 'b'))
					dynhelp = dynhelp->next;
				if (((not->flags) & 0x100) && (!reg)) ok = 9;
				else	if (((not->flags) & 0x200) && (!reg)) ok = 10;
					else ok = 8;
				/* bdmark3 */
				if ((note_with_time(akt[Track], not->end, &found, &ok)) && (found) &&
				    (ok) && ((!dynhelp) || ((found->time) < (dynhelp->time)))) {
				    	not2 = (struct Note *) found->data;
				    	remsign = 0;
				    	if (((((not->slur_nr) && (!((not->flags) & 0x80))) || ((not2->slur_nr) && (!((not2->slur_pos) & 0x40)))) &&
				    	    ((not->slur_nr) != (not2->slur_nr))) || (not2->beam_nr)) {
				    		remtime = found->time;
				    		found = found->next;
				    		remsign = 1;
				    		/* while the restrictions of time and regions are not injured	*/
				    		/* try to search a valid beam_note				*/
				    		/* bdmark4 */
						while ((found) && ((found->time) == remtime) && (remsign) &&
						       (!(((not->flags) & 0x200) && (!reg) && ((not2->flags) & 0x100))) ) {
							not2 = (struct Note *) found->data;
							if ((!(not2->beam_nr)) && (not->slur_nr) && (!((not->flags) & 0x80)) &&
							    ((not2->slur_nr) == (not->slur_nr)) && (!((not2->flags) & 0x200))) remsign = 0;
							if ((!(not2->beam_nr)) && (!((not->slur_nr) && (!((not->flags) & 0x80)))) && (((not2->slur_nr)  &&
							    ((not2->slur_pos) & 0x40)) || (!not2->slur_nr)) && (!((not2->flags) & 0x200))) remsign = 0;
							if (remsign) found = found->next;
						}
					}
					/* bdmark5 */
					if (!remsign) {
				    		/* beam found */
				    		if (not->beam_nr) {
				    			not->flags &= 0xffbf;
				    			not2->beam_nr = not->beam_nr;
						}
						else {
							not->beam_nr = global;
							not2->beam_nr = global++;
						}
						not2->flags |= 0x40;
						helpshort = not->flags & 0x300;
						not->flags |= (not2->flags) & 0x300;
						not2->flags |= helpshort;
					}
				}
			}
		}
		akt[Track] = akt[Track]->next;
	}
}

void other_niveau(cr, of, pf, osp, psp)
	char cr;
	short of, pf, *osp, *psp;
{
	if (cr) {
		if (pf) {
			*psp = pf - 1;
			*osp = of;
		}
		else {
			*psp = 11;
			*osp = (of >> 1);
		}
	}
	else {
		if (pf != 11) {
			*psp = pf + 1;
			*osp = of;
		}
		else {
			*psp = 0;
			*osp = (of << 1);
		}
	}
}

void detect_note_positions_with_signs(track)
	int track;
{
	char cross;
	int signhelp;
	int i;
	short o, osecond, psecond, rem_o;
	int p;

	/* dnpsmark1 */
	akt[track] = begin[track];
	cross = 1;

	while (akt[track]) {
		switch (akt[track]->marker) {
			case 'n': /* dnpsmark2 */
				  not = (struct Note *) akt[track]->data;
				  do {
					  o = not->octave;
					  o = (1 << o);
					  p = not->pitch;
					  if (process[p] & 0x40) {
					  	/* hit whole tone */
						if (process[p] & o) {
							/* sign active */
							other_niveau(cross, o, p, &osecond, &psecond);
							if (process[psecond] & 0x40) {
								/* hit whole tone */
								if (process[psecond] & osecond) {
									/* sign active */
									osecond >>= 1;
									while (osecond) {
										osecond >>= 1;
										not->note_pos += 7;
									}
									not->note_pos += pitch_to_pos[psecond];
								}
								else {
									process[p] -= o;
									o >>= 1;
									while (o) {
										o >>= 1;
										not->note_pos += 7;
									}
									not->note_pos += pitch_to_pos[p];
									not->note_pos |= 0xc0;
								}
							}
							else {
								/* hit half tone */
								process[p] -= o;
								o >>= 1;
								while (o) {
									o >>= 1;
									not->note_pos += 7;
								}
								not->note_pos += pitch_to_pos[p];
								not->note_pos |= 0xc0;
							}
						}
						else {
							o >>= 1;
							while (o) {
								o >>= 1;
								not->note_pos += 7;
							}
							not->note_pos += pitch_to_pos[p];
						}
					  }
					  else {
						/* hit half tone */
						other_niveau(cross, o, p, &osecond, &psecond);
						rem_o = osecond;
						osecond >>= 1;
						while (osecond) {
							osecond >>= 1;
							not->note_pos += 7;
						}
						not->note_pos += pitch_to_pos[psecond];
						if (!(process[psecond] & rem_o)) {
							process[psecond] |= rem_o;
							if (cross) not->note_pos |= 0x40;
							else not->note_pos |= 0x80;
						}
					  }
					  not = not->accord_next;
				  } while (not);
				  break;
			case 'k': /* dnpsmark3 */
				  ks = (struct KeySig *) akt[track]->data;
				  if ((ks->sign) & 0x80) cross = 0;
				  else cross = 1;
				  for (i=0; i<12; i++) process[i] &= 0x40;
				  signhelp = (ks->sign) & 0x7;
				  while (signhelp--)
				  	if (cross) process[crosses[signhelp]] |= 0xbf;
				  	else process[bs[signhelp]] |= 0xbf;
				  break;
			case 'b': /* dnpsmark4 */
				  for(i=0; i<12; i++) {
					process[i] &= 0xc0;
					if (process[i] & 0x80) process[i] |= 0x3f;
				  }
				  break;
			default : break;
		}
		akt[track] = akt[track]->next;
	}
}

void slur_geometry(t)
	int t;
{
	unsigned long endtime;
	char used[42], sp, nothalt;
	int i;
	int minimum, maximum;
	char beginposmin, beginposmax, endposmin, endposmax;

	akt[t] = begin[t];
	while (akt[t]) {
		/* sgeomark1 */
		if ((akt[t]->marker) == 'n') {
			not = (struct Note *) akt[t]->data;
			if (((not->slur_nr) > 0) && (((not->slur_pos) & 0x3f) == 0)) {
				/* first slur note found */

				/* sgeomark2: next are for setting endtime */
				dynhelp = akt[t];
				not3 = not;
				while (!(((not3->flags) & 0x80) && ((not->slur_nr) == (not3->slur_nr)))) {
					dynhelp = dynhelp->next;
					while ((dynhelp->marker) != 'n') dynhelp = dynhelp->next;
					not3 = (struct Note *) dynhelp->data;
				}
				endtime = dynhelp->time;

				/* sgeomark3 */
				for (i=0; i<42; i++) used[i] = 0;
				maximum = 0;
				minimum = 41;
				not2 = not;
				dynhelp = akt[t];
				beginposmin = (not->note_pos) & 0x3f;
				not3 = not2;
				while (not3->accord_next) not3 = not3->accord_next;
				beginposmax = (not3->note_pos) & 0x3f;
				nothalt = 1;
				while (nothalt) {
					if ((not->slur_nr) == (not2->slur_nr)) {
						not3 = not2;
						while (not3->accord_next) not3 = not3->accord_next;
						if (minimum > ((not2->note_pos) & 0x3f)) minimum = (not2->note_pos) & 0x3f;
						if (maximum < ((not3->note_pos) & 0x3f)) maximum = (not3->note_pos) & 0x3f;
					}
					if (((dynhelp->time) != endtime) && ((dynhelp->time) != akt[t]->time)) {
						not3 = not2;
						while (not3->accord_next) not3 = not3->accord_next;
						for (i=((not2->note_pos) & 0x3f);i<=((not3->note_pos) & 0x3f);i++)
							used[i] = 1;
					}
					if (((not2->flags) & 0x80) && ((not->slur_nr) == (not2->slur_nr))) nothalt = 0;
					else {
						dynhelp = dynhelp->next;
						while ((dynhelp->marker) != 'n') dynhelp = dynhelp->next;
						not2 = (struct Note *) dynhelp->data;
					}
				}
				/* sgeomark4 */
				endposmin = (not2->note_pos) & 0x3f;
				not3 = not2;
				while (not3->accord_next) not3 = not3->accord_next;
				endposmax = (not3->note_pos) & 0x3f;
				if (maximum < 38) maximum += 3;
				else maximum = 41;
				if (minimum > 3) minimum -= 3;
				else minimum = 0;
				while ((maximum < 41) && (used[maximum])) maximum++;
				while ((minimum > 0) && (used[minimum])) minimum--;
				if ((((maximum - beginposmax) + (maximum - endposmax)) <=
				    ((beginposmin - minimum) + (endposmin - minimum))) && (maximum != 41)) {
					sp = maximum;
					sp |= 0x80;
				}
				else sp = minimum;
				/* sgeomark5 */
				dynhelp = akt[t];
				not2 = not;
				nothalt = 1;
				while (nothalt) {
					if (((not2->flags) & 0x80) && ((not->slur_nr) == (not2->slur_nr))) nothalt = 0;
					if ((not2->slur_nr) == (not->slur_nr)) {
						not3 = not2;
						while (not3->accord_next) {
							not3->slur_pos &= 0x40;
							not3->slur_pos |= sp;
							not3 = not3->accord_next;
						}
						not3->slur_pos &= 0x40;
						not3->slur_pos |= sp;

						if (((sp & 0x80) && ((sp & 0x3f) <= (LAMBDA + ((not3->note_pos) & 0x3f))))
						    || ((!(sp & 0x80)) && (((sp & 0x3f) + LAMBDA) <= ((not2->note_pos) & 0x3f)))) {
							/* set lower stem */
							not3 = not2;
							while (not3) {
								not3->flags |= 0x400;
								not3 = not3->accord_next;
							}
						}
					}
					else {
						not3 = not2;
						while (not3->accord_next) not3 = not3->accord_next;

						/* if neccesary set lower stems */
						if (((sp & 0x80) && (((sp & 0x3f) + SLURWIDE ) <= (LAMBDA + ((not3->note_pos) & 0x3f)))
						     && (((sp & 0x3f) + SLURWIDE ) > ((not2->note_pos) & 0x3f)))
						    || ((!(sp & 0x80)) && (((sp & 0x3f) - SLURWIDE ) <= (LAMBDA + ((not3->note_pos) & 0x3f)))
						     && (((sp & 0x3f) - SLURWIDE ) > ((not2->note_pos) & 0x3f)))) {
						     	not3 = not2;
						     	while (not3) {
						     		not3->flags |= 0x400;
						     		not3 = not3->accord_next;
						     	}
						}
					}

					if (nothalt) {
						dynhelp = dynhelp->next;
						while ((dynhelp->marker) != 'n') dynhelp = dynhelp->next;
						not2 = (struct Note *) dynhelp->data;
					}
				}
			}
		}
		akt[t] = akt[t]->next;
	}
}

void reset_treat_info(track)
	int track;
{
	akt[track] = begin[track];
	while (akt[track]) {
		if ((akt[track]->marker) == 'n') {
			not = (struct Note *) akt[track]->data;
			not->treated = 0;
		}
		akt[track] = akt[track]->next;
	}
}

void set_slur_regions(track)
	int track;
{
	short region, count, sum;

	akt[track] = begin[track];
	count = 1;
	sum = 0;
	while (akt[track]) {
		if ((akt[track]->marker) == 'n') {
			not = (struct Note *) akt[track]->data;
			if ((not->slur_nr) && (!(not->treated))) {
				/* now look forward and treat */
				dynhelp = akt[track];
				not2 = not;
				while (!(((not2->slur_nr) == (not->slur_nr)) && ((not2->flags) & 0x80))) {
					if ((not2->slur_nr) == (not->slur_nr)) {
						count++;
						sum += (not2->note_pos) & 0x3f;
					}
					dynhelp = dynhelp->next;
					while ((dynhelp->marker) != 'n') dynhelp = dynhelp->next;
					not2 = (struct Note *) dynhelp->data;
				}
				/* last note of current slur found */
				sum += (not2->note_pos) & 0x3f;
				region = (not2->flags) & 0x300;
				if ((!region) && ((sum / count) > 20)) region = 0x100;
				if (!region) region = 0x200;
				/* set slur-begin flag */
				not->slur_pos |= 0x40;
				dynhelp = akt[track];
				not2 = not;
				while (!(((not2->slur_nr) == (not->slur_nr)) && ((not2->flags) & 0x80))) {
					if ((not2->slur_nr) == (not->slur_nr)) {
						not2->treated = 1;
						not2->flags |= region;
						/* correct the begin flag */
						if (not2 != not) {
							while (not2) {
								not2->slur_pos &= 0xbf;
								not2 = not2->accord_next;
							}
						}
					}
					dynhelp = dynhelp->next;
					while ((dynhelp->marker) != 'n') dynhelp = dynhelp->next;
					not2 = (struct Note *) dynhelp->data;
				}
				/* set all value to the last note of slur */
				not2->treated = 1;
				not2->flags |= region;
				while (not2) {
					not2->slur_pos &= 0xbf;
					not2 = not2->accord_next;
				}
			}
		}
		akt[track] = akt[track]->next;
	}
}

void set_beam_regions(track)
	int track;
{
	short region, count, sum;

	akt[track] = begin[track];
	count = 0;
	sum = 0;
	while (akt[track]) {
		if ((akt[track]->marker) == 'n') {
			/* sbrmark1 */
			not = (struct Note *) akt[track]->data;
			if ((not->beam_nr) && (!(not->treated))) {
				/* now look forward and treat */
				dynhelp = akt[track];
				not2 = not;
				while (!(((not2->beam_nr) == (not->beam_nr)) && ((not2->flags) & 0x40))) {
					if ((not2->beam_nr) == (not->beam_nr)) {
						count++;
						sum += (not2->note_pos) & 0x3f;
					}
					dynhelp = dynhelp->next;
					while ((dynhelp->marker) != 'n') dynhelp = dynhelp->next;
					not2 = (struct Note *) dynhelp->data;
				}
				/* last note of current beam found */
				region = (not2->flags) & 0x300;
				if (!region) {
					/* last note has no concrete region -> set it! */
					if ((sum / count) > 20) region = 0x100;
					else region = 0x200;
					not2->flags |= region;
				}
				not2->treated = 1;
				
				/* sbrmark2 */
				/* set the region value to all other notes of current beam */
				dynhelp = akt[track];
				not2 = not;
				while (!(((not2->beam_nr) == (not->beam_nr)) && ((not2->flags) & 0x40))) {
					if ((not2->beam_nr) == (not->beam_nr)) {
						not2->treated = 1;
						not2->flags |= region;
					}
					dynhelp = dynhelp->next;
					while ((dynhelp->marker) != 'n') dynhelp = dynhelp->next;
					not2 = (struct Note *) dynhelp->data;
				}
			}
		}
		akt[track] = akt[track]->next;
	}
}

void ins_helprest(start, fine, callnumber)
	unsigned long start, fine;
	unsigned int callnumber;
{
	if ((start >= fine) || ((start + 0xffffff) < fine)) {
		fprintf(stderr, "warning: %d --> extreme rest found: start %lx end %lx\n", callnumber, start, fine);
	}

	hres1 = ank;
	hres2 = NULL;
	while ((hres1) && ((hres1->begin) <= start)) {
		hres2 = hres1;
		hres1 = hres1->next;
	}
	if ((hres3 = (struct helprest *) malloc (sizeof(struct helprest))) == NULL) {
		fprintf(stderr, "malloc error\n");
		exit(10);
	}
	hres3->begin = start;
	hres3->end = fine;
	hres3->next = hres1;

	if (hres2) hres2->next = hres3;
	else ank = hres3;
}


void deal_with_takt(tp, bt, attention, fac, reg)
	unsigned long bt;
	int tp;
	char attention, reg;
	short fac;
{
	int changes;
	struct Note *lastSnote;
	char sign, helpsign, nothing;
	unsigned long lastnotetime;

	changes = 1;
	nothing = 1;
	while (changes) {
		lastnotetime = bt;
		changes = 0;
		d2 = d;
		while ((d2) && ((d2->marker) != 'b')) {
			if ((d2->marker) == 'n') {
	        		not = (struct Note *) d2->data;
	        		sign = 0;	/* allow processing */
	        		if ((not->slur_nr) && (!((not->slur_pos) & 0x40)) && (bt != (d2->time))) sign = 1;
	        		if ((attention) && (!((not->flags) & 0x300))) {
	        			d3 = d2->next;
	        			helpsign = 1;
	        			while (d3 && ((d3->marker) != 'b') && helpsign) {
	        				if ((d3->marker) == 'n') {
	        					not2 = (struct Note *) d3->data;
	        					if ((not2->flags) & 0x200) {
	        						if ((not->end) > (d3->time)) sign = 1;
	        						helpsign = 0;
							}
							else d3 = d3->next;
						}
						else d3 = d3->next;
					}
				}
	                	if ((!(not->treated)) && ((attention == 0) || (!((not->flags) & 0x100))) && (!sign)) {
	                		if ((d2->time) > lastnotetime) {
	                			ins_helprest(lastnotetime, (d2->time), 1);
					}
	                		nothing = 0;
	                		not->treated = 1;
	                		if (attention || (reg == 2)) (not->flags) |= 0x200;
	                		else (not->flags) |= 0x100;
	                		lastnotetime = not->end;
	                		if ((not->slur_nr) && (!((not->flags) & 0x80))) {
	                			d2 = d2->next;
						lastSnote = not;
	                			helpsign = 1;
	                			while (d2 && ((d2->marker) != 'b') && helpsign) {
	                				if ((d2->marker) == 'n') {
	                					not2 = (struct Note *) d2->data;
	                					if ((not2->slur_nr) == (not->slur_nr)) {
	                						not2->treated = 1;
									lastSnote = not2;
	                						lastnotetime = not2->end;
									if (attention || (reg == 2)) (not2->flags) |= 0x200;
									else (not2->flags) |= 0x100;
									if ((not2->flags) & 0x80) helpsign = 0;
								}
							}
							d2 = d2->next;
						}
						if ((!(d2)) && (!((lastSnote->flags) & 0x80))) lastSnote->flags |= 0x80;
					}
					changes++;
	                        	while ((d2) && ((d2->marker) != 'b') && ((d2->time) < lastnotetime)) d2 = d2->next;
				}
                        	else d2 = d2->next;
			}
	        	else d2 = d2->next;
		}
		if ((d2) && (changes) && ((d2->time) > lastnotetime)) {
			ins_helprest(lastnotetime, (d2->time), 7);
		}
	}
	if (nothing) {
		if (d2) ins_helprest(bt, (d2->time), 2);
		else {
			uslonghelp = fac * tp;
			uslonghelp += bt;
			ins_helprest(bt, uslonghelp, 3);
		}
	}
}

void process_helprest(perq, tr, bt, tp, reg)
	short reg;
	int tp, tr, perq;
	unsigned long bt;
{
	unsigned long tphelp, dur, i;
	unsigned long b;

	/* debug output */
	hr1=ank;
	while (hr1) {
		hr1 = hr1->next;
	}

	/* first part realizes linking of rests */
	hr1 = ank;
	while (hr1) {
		hr2 = hr1->next;
		hr3 = hr1;
		while (hr2) {
			while (hr2 && ((hr2->begin) < (hr1->end))) {
				hr3 = hr2;
				hr2 = hr2->next;
			}
			if (hr2 && ((hr1->end) == (hr2->begin))) {
				/* link rests */
				hr1->end = hr2->end;
				hr3->next = hr2->next;
				free(hr2);
				hr2 = hr3->next;
			}
			else hr2 = NULL;
		}
		hr1 = hr1->next;
	}

	/* second part splits notes depending on tp */
	hr1 = ank;
	while (hr1) {
		b = bt;
		while (b < (hr1->begin)) b += tp;
		if ((b > (hr1->begin)) && (b < (hr1->end))) {
			ins_helprest(b, (hr1->end), 4);
			hr1->end = b;
		}
		else {
			if (b == (hr1->begin)) {
				tphelp = 4*tp;
				dur = (hr1->end) - (hr1->begin);
				while ((dur < tphelp) && (tphelp > tp)) tphelp = (tphelp >> 1);
				if (dur > tphelp) {
					uslonghelp = (hr1->begin) + tphelp;
					ins_helprest(uslonghelp, (hr1->end), 5);
					hr1->end = uslonghelp;
				}
			}
		}
		hr1 = hr1->next;
	}

	/* third part calculates rest-values and creates rest-events */
	hr1 = ank;
	dy2 = NULL;
	dy = begin[tr];
	while (hr1) {
		dur = (hr1->end) - (hr1->begin);
		i = 0;
		while ((i<6) && ((NORMFAKTOR * dur) > (faktors[i*3] * perq))) i++;
		if ((re = (struct Rest *) malloc (sizeof(struct Rest))) == NULL) {
			fprintf(stderr, "malloc error\n");
			exit(10);
		}
		re->flg = 0;
		re->position = reg;
		if ((NORMFAKTOR * dur) == (faktors[i*3] * perq)) re->kind = i;
		else {
			if (i) {
				re->kind = i-1;
				uslonghelp = (faktors[((i-1)*3)]) * perq;
				uslonghelp = uslonghelp / 16;
				uslonghelp += (hr1->begin);
				ins_helprest(uslonghelp, (hr1->end), 6);
			}
			else re->kind = 0;
		}
		while (dy && (((dy->time) < (hr1->begin)) ||
			(((dy->time) == (hr1->begin)) && ((dy->marker) != 'n')))) {
			dy2 = dy;
			dy = dy->next;
		}
		if ((bp = (struct bind *) malloc (sizeof(struct bind))) == NULL) {
			fprintf(stderr, "malloc error\n");
			exit(10);
		}
		bp->marker = 'r';
		bp->data = (void *) re;
		bp->time = (hr1->begin);
		if (dy2) dy2->next = bp;
		else begin[tr] = bp;
		bp->next = dy;
		dy2 = bp;
		hr1 = hr1->next;
	}

	/* fourth part deletes the helprest-list */
	hr1 = ank;
	while (hr1) {
		hr2 = hr1->next;
		free(hr1);
		hr1 = hr2;
	}
	ank = NULL;
}


void detect_rests(t, regio, pq)
	int t;	/* number of track */
	int pq;	/* per quarter */
	char regio;
{
	unsigned long barrtime;
	int taktpart;	/* logical part of takt, depends on nom */
	short factor;

	/* drmark1 */
	akt[t] = begin[t];
	dynhelp = akt[t];
	ank = NULL;
	factor = 4;	/* default is 4/4 */
	taktpart = pq;	/* default is 4/4 */
	barrtime = 0;	/* time of last barre */
	while (akt[t]) {
		/* jump to next bar */
		dynhelp2 = dynhelp;
		while ((dynhelp2) && ((dynhelp2->marker) != 'b')) {
			if ((dynhelp2->marker) == 't') {
				ts = (struct TimeSig *) dynhelp2->data;
				taktpart = pq * 4 /(ts->denom);
				factor = ts->nom;
			}
			dynhelp2 = dynhelp2->next;
		}
		if (dynhelp) {
			/* drmark2 */
			d = dynhelp;
			deal_with_takt(taktpart, barrtime, (regio == 0), factor, regio);
			if (regio == 1)
				process_helprest(pq, t, barrtime, taktpart, 0x40);
			else 
				process_helprest(pq, t, barrtime, taktpart, 0x80);
			if (!regio) {
				deal_with_takt(taktpart, barrtime, 0, factor, 1);
				process_helprest(pq, t, barrtime, taktpart, 0x40);
			}
		}
		akt[t] = dynhelp2;
		if (akt[t]) {
			dynhelp = akt[t]->next;
			barrtime = akt[t]->time;
		}
	}
}

void beam_geometry(tr)
	int tr;		/* number of track */
{
	char crit, usedpos[42], helpbpos;
	char maxone, helpmaxone, pos, maxb, minb, bestpos, besthigh, bestupperflag;
	int upp, low;
	short slope;
	short measurecounter;	/* for debugging with gdb */
	char orientflag, valid;
	char lowcut, uppcut, realpos, upperflag;
	short sl;
	long sbpos[42];		/* for storing beam and slur numbers */
	unsigned long remtime;
	short i, middle;
	unsigned short counter;
	int loop;
	double arg, helparg;
	struct bind *lastdealt, *last;
	struct Note *notehelp, *prev_note, *helpn, *nohe;

	/* bgmark1 */
	akt[tr] = begin[tr];
	measurecounter = 1;
	dynhelp3 = begin[tr];	/* first event in takt */
	while (akt[tr]) {
		if ((akt[tr]->marker) == 'b') {
			/* bgmark2 */
			dynhelp3 = akt[tr]->next;
			measurecounter++;
		}
		if ((akt[tr]->marker) == 'n') {
			/* bgmark3 */
			not = (struct Note *) akt[tr]->data;
			if ((!(not->treated)) && (not->beam_nr)) {
				/* bgmark4: found begin of beam */
				maxb = (not->note_pos) & 0x3f;
				minb = maxb;
				not->treated = 1;
				not->beam_pos = 0x40;
				/* reset sbpos-array */
				for (i=0; i<42; i++) sbpos[i] = 0;
				/* read until first beam note and set slur and beam positions */
				dynhelp2 = dynhelp3;
				dynhelp = akt[tr];
				while (dynhelp2 != dynhelp) {
					if ((dynhelp2->marker) == 'n') {
						not3 = (struct Note *) dynhelp2->data;
						if ((not3->slur_nr) && (!((not3->flags) & 0x80))) {
							for (loop= ((not3->slur_pos) & 0x3f) - 2;loop < ((not3->slur_pos) & 0x3f) + 3; loop++) 
								if ((loop >= 0) && (loop <=41)) sbpos[loop] = (not3->slur_nr);
						}
						else {
							if (not3->slur_nr) {
								for (loop= ((not3->slur_pos) & 0x3f) - 5;loop < ((not3->slur_pos) & 0x3f) + 5; loop++)
									if ((loop >= 0) && (loop <=41) && (sbpos[loop] == (not3->slur_nr))) sbpos[loop] = 0;
							}
						}
						if ((not3->beam_nr) && (not3->treated) && (!((not3->flags) & 0x40))) {
							helpbpos = (not3->beam_pos) & 0x3f;
							if ((not3->beam_pos) & 0x80) helpbpos += UPPLOWSHIFT;
							else {
								if (helpbpos > UPPLOWSHIFT) helpbpos -= UPPLOWSHIFT;
								else helpbpos = 0;
							}
							if (helpbpos > 41) helpbpos = 41;
							for (loop = helpbpos -2; loop < helpbpos + 3; loop++)
								if ((loop >= 0) && (loop <=41)) sbpos[loop] = (not3->beam_nr);
						}
						else 	if ((not3->beam_nr) && (not3->treated)) {
								helpbpos = (not3->beam_pos) & 0x3f;
								if ((not3->beam_pos) & 0x80) helpbpos += UPPLOWSHIFT;
								else {
									if (helpbpos > UPPLOWSHIFT) helpbpos -= UPPLOWSHIFT;
									else helpbpos = 0;
								}
								if (helpbpos > 41) helpbpos = 41;
								for (loop = helpbpos -5; loop < helpbpos + 6; loop++)
									if ((loop >= 0) && (loop <=41) && (sbpos[loop] == (not3->beam_nr))) sbpos[loop] = 0;
							}
					}
					dynhelp2 = dynhelp2->next;
				}

				/* bgmark5 */
				/* now start with processing the beam */
				lastdealt = akt[tr];
				/* reset the valid area array */
				for (i=0; i<42; i++) usedpos [i] = 0;

				/* specify the first valid region */
				upp = not->note_pos & 0x3f;
				while ((upp < 41) && (!(sbpos[upp]))) upp++;
				low = not->note_pos & 0x3f;
				while ((low > 0) && (!(sbpos[low]))) low--;
				for (i=low; i<=upp; i++) usedpos [i] = 1;
				usedpos [not->note_pos & 0x3f] = 2;

				remtime = dynhelp->time;
				counter = 0;

				/* bgmark6 */
				/* jump to last possible note of current beam */
				crit = 1;
				last = dynhelp2;
				nohe = (struct Note *) dynhelp2->data;
				if ((nohe->flags) & 0x40) crit = 0;
				while (crit) {
					dynhelp = dynhelp->next;
					if ((dynhelp) && ((dynhelp->time) > remtime) && ((dynhelp->marker == 'n') || (dynhelp->marker == 'r'))) {
						counter += 2;
						remtime = dynhelp->time;
					}
					if ((dynhelp) && ((dynhelp->marker) == 'n')) {
						not2 = (struct Note *) dynhelp->data;
						if ((not->beam_nr) == (not2->beam_nr)) {
							if (!usedpos[(not2->note_pos) & 0x3f]) {
								/* have to split beam */
								dynhelp = lastdealt;
								crit = 0;
								if (akt[tr] == lastdealt) {
									not->beam_nr = 0;
									not->beam_pos = 0;
									not2 = not;
								}
								else {
									not3 = (struct Note *) lastdealt->data;
									not3->flags |= 0x40;

									if (!((not2->flags) & 0x40)) {
										not2->beam_pos |= 0x40;
										global++;
										not2->beam_nr = global;
										lastdealt = lastdealt->next;
										while (lastdealt) {
											if ((lastdealt->marker) == 'n') {
												notehelp = (struct Note *) lastdealt->data;
												if ((notehelp->beam_nr) == (not->beam_nr)) {
													notehelp->beam_nr = global;
													if ((notehelp->flags) & 0x40) lastdealt = NULL;
												}
											}
											if (lastdealt) lastdealt = lastdealt->next;
										}
									}
									else {
										not2->flags &= 0xffbf;
										not2->beam_nr = 0;
									}
									not2 = not3;
								}
							}
							else {
								/* deal with printable beam note */
								last = dynhelp;
								lastdealt = dynhelp;
								helpn = not2;
								while (helpn->accord_next) helpn = helpn->accord_next;
								if (((helpn->note_pos) & 0x3f) > maxb) maxb = (helpn->note_pos) & 0x3f;
								if (((not2->note_pos) & 0x3f) < minb) minb = (not2->note_pos) & 0x3f;
								if ((not2->flags) & 0x40) crit = 0;
								not2->treated = 1;
								usedpos[(not2->note_pos) & 0x3f] = 2;
								if (not2->slur_nr) {
									if ((not2->slur_pos) & 0x80)
										for (i=((not2->slur_pos) & 0x3f) - 2; i<42; i++) usedpos[i] = 0;
									else
										for (i=((not2->slur_pos) & 0x3f) + 2; i>=0; i--) usedpos[i] = 0;
								}
							}
						}
						else {
							if (not2->slur_nr) {
								upp = 0;
								for (i=(not2->slur_pos & 0x3f); i<42; i++) if (usedpos[i]) upp++;
								low = 0;
								for (i=(not2->slur_pos & 0x3f); i>=0; i--) if (usedpos[i]) low++;
								if (upp > low)
									for (i=(not2->slur_pos & 0x3f); i>=0; i--) usedpos[i] = 0;
								else
									for (i=(not2->slur_pos & 0x3f); i<42; i++) usedpos[i] = 0;
							}
							if (not2->treated) {
								helpbpos = (not2->beam_pos) & 0x3f;
								if ((not2->beam_pos) & 0x80) helpbpos += UPPLOWSHIFT;
								else	if (helpbpos > UPPLOWSHIFT)
										helpbpos -= UPPLOWSHIFT;
									else helpbpos = 0;
								for (loop=helpbpos-2; loop < (helpbpos + 3); loop++)
									if ((loop >= 0) && (loop <= 41)) usedpos[loop] = 0;
							}
							usedpos[(not2->note_pos) & 0x3f] = 2;
						}
					}
					if (dynhelp == NULL) crit = 0;
				}

				if ((last == dynhelp2) && ((dynhelp == NULL) || ((nohe->flags) & 0x40))) {
					not->beam_nr = 0;
				}
				else {
					if ((dynhelp == NULL) && (last != dynhelp2)) {
						not2 = (struct Note *) last->data;
						not2->flags |= 0x40;
						dynhelp = last;
					}
				}

				/* bgmark7 */
				/* now dynhelp and not2 mark last note of current beam */

				if (not->beam_nr) {

					/* store the difference between the position of the last note	*/
					/* and the position of the first note				*/

					if (((not2->note_pos) & 0x3f) >= ((not->note_pos) & 0x3f)) {
						orientflag = 1;
						helpmaxone = (((not2->note_pos) & 0x3f) - ((not->note_pos) & 0x3f));
					}
					else {
						orientflag = 0;
						helpmaxone = (((not->note_pos) & 0x3f) - ((not2->note_pos) & 0x3f));
					}

					/* as a value for a middle position */
					middle = maxb + minb;

					/* set position */
					pos = 0x70;

					/* depending on middle search for a nice position */
					if ((((not->flags) & 0x100) && (middle > (2 * VIOLINEMID))) || (((not->flags) & 0x200) && (middle > (2 * BASSMID)))) {
						/* try to find a lower beam */
						upperflag = 0;
						i = minb -1;
						maxone = 0;
						if (maxb > BEAMDELTA) lowcut = maxb - BEAMDELTA;
						else lowcut = 0;
						if ((minb > BEAMTOLMAX) && (lowcut < (minb - BEAMTOLMAX))) lowcut = minb - BEAMTOLMAX;
						if (lowcut > helpmaxone) lowcut -= helpmaxone;
						else lowcut = 0;
						while ((usedpos[i] == 1) && (i > lowcut)) {
							maxone++;
							i--;
						}

						if (maxone > ((helpmaxone >> 1) + BEAMTOLERANCE)) {
							if (minb > BEAMTOLERANCE) realpos = minb - BEAMTOLERANCE;
							else realpos = 0;
							if (orientflag) {
								if (realpos > (helpmaxone >> 1)) realpos -= (helpmaxone >> 1);
								else realpos = 0;
							}
							pos = realpos + UPPLOWSHIFT;
							if (pos > 41) pos = 41;
						}
						else {
							/* try to find an upper beam */
							upperflag = 1;
							bestpos = minb - maxone;
							bestupperflag = 0;
							if (maxone > helpmaxone) realpos = bestpos + (helpmaxone >> 2);
							else realpos = bestpos;
							if (realpos > 41) realpos = 41;
							besthigh = maxone;
							i = maxb + 1;
							maxone = 0;
							uppcut = minb + BEAMDELTA;
							if (uppcut > 41) uppcut = 41;
							if (uppcut > (maxb + BEAMTOLMAX)) uppcut = maxb + BEAMTOLMAX;
							uppcut += helpmaxone;
							if (uppcut > 41) uppcut = 41;
							while ((usedpos[i] == 1) && (i < uppcut)) {
								maxone++;
								i++;
							}

							if (maxone > ((helpmaxone >> 1) + BEAMTOLERANCE)) {
								realpos = maxb + BEAMTOLERANCE;
								if (realpos > 41) realpos = 41;
								if (!orientflag) realpos += (helpmaxone >> 1);
								if (realpos > 41) realpos = 41;
								if (realpos > UPPLOWSHIFT) pos = realpos - UPPLOWSHIFT;
								else pos = 0;
							}
							else {
								if (maxone > besthigh) {
									besthigh = maxone;
									bestupperflag = 1;
									bestpos = maxb + maxone;
									if (maxone > helpmaxone) {
										if (bestpos > (helpmaxone >> 2)) realpos = bestpos - (helpmaxone >> 2);
										else realpos = 0;
									}
									else realpos = bestpos;
								}
							}
						}
					}
					else {
						/* try to find an upper beam */
						upperflag = 1;
						i = maxb + 1;
						maxone = 0;
						uppcut = minb + BEAMDELTA;
						if (uppcut > 41) uppcut = 41;
						if (uppcut > (maxb + BEAMTOLMAX)) uppcut = maxb + BEAMTOLMAX;
						uppcut += helpmaxone;
						if (uppcut > 41) uppcut = 41;
						while ((usedpos[i] == 1) && (i < uppcut)) {
							maxone++;
							i++;
						}

						if (maxone > ((helpmaxone >> 1) + BEAMTOLERANCE)) {
							realpos = maxb + BEAMTOLERANCE;
							if (realpos > 41) realpos = 41;
							if (!orientflag) realpos += (helpmaxone >> 1);;
							if (realpos > 41) realpos = 41;
							if (realpos > UPPLOWSHIFT) pos = realpos - UPPLOWSHIFT;
							else pos = 0;
						}
						else {
							/* try to find a lower beam */
							upperflag = 0;
							bestpos = maxb + maxone;
							bestupperflag = 1;
							if (maxone > helpmaxone) {
								if (bestpos > (helpmaxone >> 2)) realpos = bestpos - (helpmaxone >> 2);
								else realpos = 0;
							}
							else realpos = bestpos;
							besthigh = maxone;
							i = minb -1;
							maxone = 0;
							if (maxb > BEAMDELTA) lowcut = maxb - BEAMDELTA;
							else lowcut = 0;
							if ((minb > BEAMTOLMAX) && (lowcut < (minb - BEAMTOLMAX))) lowcut = minb - BEAMTOLMAX;
							if (lowcut > helpmaxone) lowcut -= helpmaxone;
							else lowcut = 0;
							while ((usedpos[i] == 1) && (i > lowcut)) {
								maxone++;
								i--;
							}
							if (maxone > ((helpmaxone >> 1) + BEAMTOLERANCE)) {
								if (minb > BEAMTOLERANCE) realpos = minb - BEAMTOLERANCE;
								else realpos = 0;
							        if (orientflag) {
							        	if (realpos > (helpmaxone >> 1)) realpos -= (helpmaxone >> 1);
							        	else realpos = 0;
								}
								pos = realpos + UPPLOWSHIFT;
								if (pos > 41) pos = 41;
							}
							else {
								if (maxone > besthigh) {
									besthigh = maxone;
									bestupperflag = 0;
									bestpos = minb - maxone;
									if (maxone > helpmaxone) realpos = bestpos + (helpmaxone >> 2);
									else realpos = bestpos;
									if (realpos > 41) realpos = 41;
								}
							}
						}
					}

					/* check middle region for setting the beam position	*/
					/* (only if not already found one)			*/

					valid = 1;
					if (pos == 0x70) {
						/* search a nice beam position between minb and maxb	*/
						/* only when MINBEAMBROAD is valid			*/
						if ((maxb - minb) < MINBEAMBROAD) valid = 0;

						if (valid) {
							if ((((not->note_pos) & 0x3f) <= bestpos) && orientflag) {
								if (bestpos > helpmaxone) bestpos -= helpmaxone;
								else bestpos = 0;
							}
							if ((((not->note_pos) & 0x3f) > bestpos) && (!orientflag)) {
								bestpos += helpmaxone;
								if (bestpos > 41) bestpos = 41;
							}
							maxone = 0;
							for (i=maxb; i>=minb; i--) {
								if (usedpos[i] == 1) maxone++;
								else {
									if (maxone > besthigh) {
										besthigh = maxone;
										bestpos = i;
										if (besthigh > helpmaxone) {
											bestpos += ((besthigh - helpmaxone) >> 1);
											realpos = bestpos + (helpmaxone >> 2);
											if (!orientflag) bestpos += helpmaxone;
											if (bestpos > 41) bestpos = 41;
											if (realpos > 41) realpos = 41;
										}
										else {
											realpos = bestpos + (besthigh >> 2);
											if (!orientflag) bestpos += besthigh;
										}
										if (((not->note_pos) & 0x3f) <= realpos)
											bestupperflag = 1;
										else bestupperflag = 0;
									}
									maxone = 0;
								}
							}
							pos = bestpos;
							if (bestupperflag) {
								if (pos > UPPLOWSHIFT) pos -= UPPLOWSHIFT;
								else pos = 0;
								upperflag = 1;
							}
							else {
								upperflag = 0;
								pos += UPPLOWSHIFT;
								if (pos > 41) pos = 41;
							}
							maxone = besthigh;
						}
					}

					/* bgmark8 */
					if (valid) {
						if (!counter) counter = 1;
						if (maxone >= helpmaxone) arg = helpmaxone;
						else arg = maxone;

						if (orientflag) slope = 1;
						else slope = -1;

						helparg = SLOPEFACTOR * counter;
						arg /= helparg;

						/* the following lines substitute a function atan */
						if (arg > 0.94) slope *= 9;
						else	if (arg > 0.77) slope *= 8;
							else	if (arg > 0.64) slope *= 7;
								else	if (arg > 0.52) slope *= 6;
									else	if (arg > 0.41) slope *= 5;
										else	if (arg > 0.31) slope *= 4;
											else	if (arg > 0.21) slope *= 3;
												else	if (arg > 0.12) slope *= 2;
													else	if (arg < 0.04) slope = 0;

						/* modify position */
						if (pos > 41) pos = 41;
						else {
							if (pos & 0x80) pos = 0;
						}

						/* setting of the upp/low-flag */
						if (upperflag) pos |= 0x80;

						/* generate a flag-mask for slope */
						if (slope < 0) {
							sl = 0;
							sl |= 0x8000;
							slope = slope * (-1);
						}
						else sl = 0;

						slope <<= 11;

						/* bgmark9 */
						/* set the values to all notes of current beam */
						sl |= slope;
						dynhelp = akt[tr];
						crit = 1;
						prev_note = NULL;
						while (crit) {
							if ((dynhelp->marker) == 'n') {
								not3 = (struct Note *) dynhelp->data;
								if ((not->beam_nr) == (not3->beam_nr)) {
									if (prev_note) {
										switch ((not3->flags) & 0x38) {
											case 0x0 : (prev_note->next_beamn_kind)++;
											case 0x8 : (prev_note->next_beamn_kind)++;
											case 0x10: (prev_note->next_beamn_kind)++;
											case 0x18: (prev_note->next_beamn_kind)++;
												   break;
											default  : break;
										}
									}
									prev_note = not3;
									not3->beam_pos |= pos;
									not3->flags |= sl;
									if ((not3->flags) & 0x40) {
										not3->next_beamn_kind = 0;
										crit = 0;
									}
								}
								else {
									if ((!(not3->slur_nr)) && ((!(not3->beam_nr) || (!(not3->treated)))) && (((not3->flags) & 0x38) != 0x30)) {
										helpn = not3;
										while (helpn->accord_next) helpn = helpn->accord_next;

										/* set lower stems if nessesary */
										if ((realpos > ((not3->note_pos) & 0x3f)) && ((LAMBDA + ((helpn->note_pos) & 0x3f) + 2) >= realpos)) {
											helpn = not3;
											while (helpn) {
												helpn->flags |= 0x400;
												helpn = helpn->accord_next;
											}
										}
									}
								}
							}
							if (crit) dynhelp = dynhelp->next;
						}
					}
					else {
						/* bgmark10 */
						/* sorry, this beam is unprintable	*/
						/* erase it				*/
						dynhelp = akt[tr]->next;
						crit = 1;
						while (crit && dynhelp) {
							if ((dynhelp->marker) == 'n') {
								not3 = (struct Note *) dynhelp->data;
								if ((not3->beam_nr) == (not->beam_nr)) {
									not3->beam_nr = 0;
									not3->beam_pos = 0;
									if ((not3->flags) & 0x40) crit = 0;
									not3->flags &= 0x7bf;
								}
							}
							if (crit) dynhelp = dynhelp->next;
						}
						not->beam_nr = 0;
						not->beam_pos = 0;
						not->flags &= 0x7bf;
					}
				}
			}
		}
		akt[tr] = akt[tr]->next;
	}
}

void calculate_rest_positions(tr)
	int tr;
{
	char full[42];				/* used positions */
	char bestpos;				/* for storing the best position */
	char highcount;				/* counts free positions */
	char to, mid, from1, to1, from2, to2;	/* variables for looping */
	int i;					/* for looping and indexing */
	long cur_slur[42], cur_beam[42];	/* positions used for slurs and beams */
	unsigned long rtime;			/* store time information */
	char goodpos, goodhigh;			/* temporal best */
	char minbeam, maxbeam;			/* to specify the region from beamed note to the beam itself */
	short restcount;			/* counts the rests of time rtime */
	char topos;				/* store the slope */
	char upperto;				/* setting a loopto value */
	short slope;				/* setting topos */
	short measurecounter;			/* is useful for gdb to stop at a given measure */

	/* crpmark1 */
	measurecounter = 1;
	akt[tr] = begin[tr];
	for (i=0; i<42; i++) {
		cur_slur[i] = 0;
		cur_beam[i] = 0;
	}
	while (akt[tr]) {
		if ((akt[tr]->marker) == 'b') measurecounter++;
		if ((akt[tr]->marker) == 'r') {
			/* crpmark2 */
			restcount = 1;
			rtime = akt[tr]->time;
			for (i=0; i<42; i++) {
				if (cur_slur[i] || cur_beam[i]) full[i] = 1;
				else full[i] = 0;
			}
			dynhelp = akt[tr];	/* store the begin of rest pointer */
			dynhelp3 = akt[tr];	/* indicates later the last rest of rtime */
			akt[tr] = akt[tr]->next;
			while ((akt[tr]) && (rtime == (akt[tr]->time))) {
				/* deal with rests and notes of time rtime */
				if ((akt[tr]->marker) == 'n') {
					not = (struct Note *) akt[tr]->data;
					not2 = not;
					while (not2->accord_next) not2 = not2->accord_next;

					if (!(not->beam_nr)) {
						if (((not->flags) & 0x30) == 0x30) {
							/* whole note without any stem */
							full[(not->note_pos) & 0x3f] = 1;
						}
						else {
							if ((not->flags) & 0x400) {
								/* lower stem */
								if (((not->note_pos) & 0x3f) > LAMBDA)
									to = ((not->note_pos) & 0x3f) - LAMBDA;
								else to = 0;
								for (i=((not2->note_pos) & 0x3f); i>=to; i-- ) full[i] = 1;
							}
							else {
								/* upper stem */
								to = ((not2->note_pos) & 0x3f) + LAMBDA;
								if (to > 41) to = 41;
								for (i=((not->note_pos) & 0x3f); i<=to; i++ ) full[i] = 1;
							}
						}
					}
					else {
						/* deal with beamed note */
						to = not->beam_pos & 0x3f;
						if ((not->beam_pos) & 0x80) to += UPPLOWSHIFT;
						else	if (to > UPPLOWSHIFT) to -= UPPLOWSHIFT;
							else to = 0;
						if (to > 41) to = 41;
						slope = (not->flags) & 0x7800;
						topos = (slope >> 11) & 0xf;
						if ((not->flags) & 0x8000) {
							/* falling beam */
							if (to > topos) minbeam = to - topos;
							else minbeam = 0;
							maxbeam = to;
						}
						else {
							/* raising beam */
							minbeam = to;
							maxbeam = to + topos;
							if (maxbeam > 41) maxbeam = 41;
						}
						if (((not2->note_pos) & 0x3f) > maxbeam) maxbeam = ((not2->note_pos) & 0x3f);
						if (((not->note_pos) & 0x3f) < minbeam) minbeam = ((not->note_pos) & 0x3f);
						for (i=minbeam; i<=maxbeam; i++) full[i] = 1; 
					}

					if ((not->slur_nr) && ((not->slur_pos) & 0x40)) {
						/* slur begins here */
						if (not->slur_pos & 0x80) {
							/* upper slur */
							to = SLURWIDE + ((not->slur_pos) & 0x3f);
							if (to > 41) to = 41;
							for (i=((not->slur_pos) & 0x3f); i<=to; i++) full[i] = 1;
						}
						else {
							/* lower slur */
							if (((not->slur_pos) & 0x3f) > SLURWIDE)
								to = ((not->slur_pos) & 0x3f) - SLURWIDE;
							else to = 0;
							for (i=to; i<=((not->slur_pos) & 0x3f); i++) full[i] = 1;
						}
					}
				}
				else {
					if ((akt[tr]->marker) == 'r') {
						restcount++;
						dynhelp3 = akt[tr];
					}
					else {
						/* after rests can only be notes of the same time */
						fprintf(stderr, "unknown element found\n");
						exit(10);
					}
				}
				akt[tr] = akt[tr]->next;
			}

			do {
				/* crpmark3 */
				re = (struct Rest *) dynhelp->data;
				if ((re->position) & 0x80) {
					/* it's a bass rest */
					mid = BASSMID;
					from1 = mid - halfresthigh[re->kind] -1;
					to1 = VIOLINEMID - 2;
					from2 = mid + halfresthigh[re->kind] + 6;
					to2 = 0;
				}

				if ((re->position) & 0x40) {
					/* it's a violine rest */
					mid = VIOLINEMID;
					from1 = mid - halfresthigh[re->kind] -1;
					to1 = 41;
					from2 = mid + halfresthigh[re->kind] + 6;
					to2 = BASSMID + 2;
				}

				/* crpmark4 */
				highcount = 0;
				goodhigh = 0;
				bestpos = 60;
				i = from1;
				while (i<to1) {
					if (!full[i]) {
						highcount++;
						if (highcount >= (resthigh[re->kind] + RESTTOLERANCE)) {
							bestpos = i - resthigh[re->kind] - HALFRESTTOLERANCE;
							i = 40;
						}
					}
					else {
						if (highcount > goodhigh) {
							goodhigh = highcount;
							goodpos = i - highcount;
						}
						highcount = 0;
					}
					i++;
				}

				/* rests (except of pause and hpause) can use */
				/* an small upper area because there is enough space */
				highcount = 0;
				if ((bestpos == 60) && ((re->kind) < 5)) {
					while (!full[i]) {
						i--;
						highcount++;
					}
					if (highcount > 2) bestpos = i + 2;
				}

				/* crpmark5 */
				highcount = 0;
				i = from2;
				while (i>to2) {
					if (!full[i]) {
						highcount++;
						if ((highcount > (resthigh[re->kind] + RESTTOLERANCE)) && 
						    ((abs(bestpos + (halfresthigh[re->kind]) - mid)) >
						     (abs((i + HALFRESTTOLERANCE) + (halfresthigh[re->kind]) - mid)))) {
						     	bestpos = i + HALFRESTTOLERANCE;
						     	i = 1;
						}
					}
					else {
						if (highcount > goodhigh) {
							goodhigh = highcount;
							goodpos = i;
						}
						highcount = 0;
					}
					i--;
				}

				/* crpmark6 */
				if (bestpos == 60) {
					bestpos = goodpos;
					re->flg = 1;
				}

				/* crpmark7 */
				/* half and whole rests needs an odd position */
				if ((re->kind) > 4) bestpos |= 0x1;
				re->position |= bestpos;

				upperto = bestpos + 2 + (resthigh[re->kind]);
				if (upperto > 41) upperto = 41;
				for (i=bestpos; i<=upperto; i++) full[i] = 1;
				restcount--;
				if (restcount) {
					dynhelp = dynhelp->next;
					if ((dynhelp->marker) != 'r') {
						fprintf(stderr, "error: deal non rest like rest\n");
						exit(10);
					}
				}
			} while (restcount);
			akt[tr] = dynhelp3;
		}
		if ((akt[tr]->marker) == 'n') {
			/* crpmark8 */
			not3 = (struct Note *) akt[tr]->data;
			if ((not3->beam_nr) && (((not3->beam_pos) & 0x40) || ((not3->flags) & 0x40))) {
				/* begin or end of beam */
				to = not3->beam_pos & 0x3f;
				if ((not3->beam_pos) & 0x80) to += UPPLOWSHIFT;
				else    if (to > UPPLOWSHIFT) to -= UPPLOWSHIFT;
					else to = 0;
				if (to > 41) to = 41;
				slope = (not3->flags) & 0x7800;
				topos = (slope >> 11) & 0xf;
				if ((not3->flags) & 0x8000) {
					/* falling beam */
					if (to > topos) topos = to - topos;
					else topos = 0;
					if (topos > 2) topos -= 2;
					else topos = 0;
					to += 2;
					if (to > 41) to = 41;
					if ((not3->beam_pos) & 0x40)
						for (i=topos; i<=to; i++) cur_beam[i] = not3->beam_nr;
					else {
						for (i=topos; i<=to; i++)
							if (cur_beam[i] == not3->beam_nr) cur_beam[i] = 0;
					}
				}
				else {
					/* raising beam */
					topos += to;
					if (topos > 41) topos = 41;
					if (to > 2) to -= 2;
					else to = 0;
					topos += 2;
					if (topos > 41) topos = 41;
					if ((not3->beam_pos) & 0x40)
						for (i=to; i<=topos; i++) cur_beam[i] = not3->beam_nr;
					else {
						for (i=to; i<=topos; i++)
							if (cur_beam[i] == not3->beam_nr) cur_beam[i] = 0;
					}
				}
			}
			if ((not3->slur_nr) && (((not3->slur_pos) & 0x40) || ((not3->flags) & 0x80))) {
				/* begin or end of slur */
				if (not3->slur_pos & 0x80) {
					/* upper slur */
					to = SLURWIDE + (not3->slur_pos & 0x3f);
					if (to > 41) to = 41;
					if ((not3->slur_pos) & 0x40)
						for (i=((not3->slur_pos) & 0x3f); i!=to; i++)
							cur_slur[i] = not3->slur_nr;
					else {
						for (i=((not3->slur_pos) & 0x3f); i!=to; i++)
							if (cur_slur[i] == not3->slur_nr) cur_slur[i] = 0;
					}
				}
				else {
					/* lower slur */
					if (((not3->slur_pos) & 0x3f) > SLURWIDE)
						to = (not3->slur_pos & 0x3f) - SLURWIDE;
					else to = 0;
					if ((not3->slur_pos) & 0x40)
						for (i=to; i!=((not3->slur_pos) & 0x3f); i++)
							cur_slur[i] = not3->slur_nr;
					else {
						for (i=to; i!=((not3->slur_pos) & 0x3f); i++)
							if (cur_slur[i] == not3->slur_nr) cur_slur[i] = 0;
					}
				}
			}
		}
		akt[tr] = akt[tr]->next;
	}
}

void ins_levent(tn, type, ltime, value)
	int tn;
	char type;
	unsigned long ltime;
	char value;
{
	/* this function requires the correct setting of dy to the begin of track */
	/* and of dy2 to NULL							  */

	while (dy && (((dy->time) < ltime) ||
	       (((dy->time) == ltime) && ((dy->marker) != 'n') && ((dy->marker) != 'r')))) {
		dy2 = dy;
		dy = dy->next;
	}

	if ((dynhelp3 = (struct bind *) malloc (sizeof(struct bind))) == NULL) {
		fprintf(stderr, "malloc error\n");
		exit(10);
	}
	if (dy2) dy2->next = dynhelp3;
	else begin[tn] = dynhelp3;
	dynhelp3->next = dy;
	dynhelp3->time = ltime;
	dynhelp3->marker = 'p';

	if ((lo = (struct Loudness *) malloc (sizeof(struct Loudness))) == NULL) {
		fprintf(stderr, "malloc error\n");
		exit(10);
	}
	dynhelp3->data = (void *) lo;
	if (type) {
		lo->dynamics = 0;
		lo->statics = value;
	}
	else {
		lo->dynamics = value;
		lo->statics = 0;
	}
}


void set_loudness_infos(tnr)
	int tnr;
{
	int i, j, k, l, m, n, sum, count, criterium, loop, loopto;
	unsigned long time, stime;
	char staticflag, dynamicflag, dval, sval;

	/* slimark1 */
	akt[tnr] = begin[tnr];
	dy = begin[tnr];
	dy2 = NULL;
	staticflag = 1;
	dynamicflag = 0;
	j = 0;
	for (i=0; i<6; i++) {
		if ((loudrecarr[i] = (struct loudrec *) malloc (sizeof(struct loudrec))) == NULL) {
			fprintf(stderr, "malloc error\n");
			exit(10);
		}
		loudrecarr[i]->time = 0;
	}
	/* slimark2 */
	while (akt[tnr]) {
		if ((akt[tnr]->marker) == 'n') {
			time = akt[tnr]->time;
			dynhelp = akt[tnr];
			sum = 0;
			count = 0;
			while (dynhelp && (time == (dynhelp->time))) {
				not = (struct Note *) dynhelp->data;
				sum += not->loud;
				count++;
				dynhelp = dynhelp->next;
			}
			criterium = sum / count;
			i = 0;
			while ((i < 7) && (loudarray[i] < criterium)) i++;
			if (staticflag) {
				ins_levent(tnr, 1, time, i + 1);
				staticflag = 0;
			}
			/* fill the record */
			loudrecarr[j]->time = time;
			loudrecarr[j]->criterium = criterium;
			loudrecarr[j]->range = i;

			/* slimark3 */
			j = modulo4pp[j];

			if (loudrecarr[j]->time) {
				k = modulo4pp[j];
				l = modulo4pp[k];
				m = modulo4pp[l];
				n = modulo4pp[m];
				i = modulo4pp[n];

				if ((loudrecarr[j]->criterium) < (loudrecarr[k]->criterium)) {
					if ((loudrecarr[k]->criterium) < (loudrecarr[l]->criterium)) {
						if ((loudrecarr[l]->criterium) < (loudrecarr[m]->criterium)) {
							if ((loudrecarr[m]->criterium) < (loudrecarr[n]->criterium)) {
								dval = 3;
								loopto = n;
								if ((loudrecarr[n]->criterium) == (loudrecarr[i]->criterium)) {
									staticflag = 1;
									stime = loudrecarr[n]->time;
									sval = loudrecarr[n]->range;
								}
							}
							else {
								dval = 2;
								loopto = m;
								if ((loudrecarr[m]->criterium) == (loudrecarr[n]->criterium)) {
									staticflag = 1;
									stime = loudrecarr[m]->time;
									sval = loudrecarr[m]->range;
								}
							}
						}
						else {
							dval = 1;
							loopto = l;
							if ((loudrecarr[l]->criterium) == (loudrecarr[m]->criterium)) {
								staticflag = 1;
								stime = loudrecarr[l]->time;
								sval = loudrecarr[l]->range;
							}
						}
					}
					else {
						dval = 0;
						loopto = k;
						if ((loudrecarr[k]->criterium) == (loudrecarr[l]->criterium)) {
							staticflag = 1;
							stime = loudrecarr[k]->time;
							sval = loudrecarr[k]->range;
						}
					}
					dynamicflag = 1;
				}
				else {
					if ((loudrecarr[j]->criterium) > (loudrecarr[k]->criterium)) {
						if ((loudrecarr[k]->criterium) > (loudrecarr[l]->criterium)) {
							if ((loudrecarr[l]->criterium) > (loudrecarr[m]->criterium)) {
								if ((loudrecarr[m]->criterium) > (loudrecarr[n]->criterium)) {
									dval = 7;
									loopto = n;
									if ((loudrecarr[n]->criterium) == (loudrecarr[i]->criterium)) {
										staticflag = 1;
										stime = loudrecarr[n]->time;
										sval = loudrecarr[n]->range;
									}
								}
								else {
									dval = 6;
									loopto = m;
									if ((loudrecarr[m]->criterium) == (loudrecarr[n]->criterium)) {
										staticflag = 1;
										stime = loudrecarr[m]->time;
										sval = loudrecarr[m]->range;
									}
								}
							}
							else {
								dval = 5;
								loopto = l;
								if ((loudrecarr[l]->criterium) == (loudrecarr[m]->criterium)) {
									staticflag = 1;
									stime = loudrecarr[l]->time;
									sval = loudrecarr[l]->range;
								}
							}
						}
						else {
							dval = 4;
							loopto = k;
							if ((loudrecarr[k]->criterium) == (loudrecarr[l]->criterium)) {
								staticflag = 1;
								stime = loudrecarr[k]->time;
								sval = loudrecarr[k]->range;
							}
						}
						dynamicflag = 1;
					}
					else {	/* loudness is equal */
						loop = j;
						while ((loop != i) && ((loudrecarr[loop]->criterium) == (loudrecarr[modulo4pp[loop]]->criterium))) {
							loop = modulo4pp[loop];
						}
						loopto = loop;
					}
				}

				if (dynamicflag) {
					ins_levent(tnr, 0, loudrecarr[j]->time, dval + 1);
					dynamicflag = 0;
				}
				if (staticflag) {
					loopto = modulo4pp[loopto];
					ins_levent(tnr, 1, stime, sval + 1);
					staticflag = 0;
				}
				/* slimark4 */
				loop = j;
				while (loop != loopto) {
					loudrecarr[loop]->time = 0;
					loop = modulo4pp[loop];
				}
			}
			akt[tnr] = dynhelp;
		}
		else akt[tnr] = akt[tnr]->next;
	}
}

void debug_out()
{
	int tnr, barrcounter;

	printf("\nListing the whole dynamic structure:\n");
	for (tnr = 0; tnr < MAXTRACKS; tnr++) {
		dynhelp = begin[tnr];
		barrcounter = 0;
		while (dynhelp != NULL) {
			printf("tnr: %i begin: %lx marker %c ",tnr, dynhelp->time, dynhelp->marker);
			switch (dynhelp->marker) {
				case 'n': not = (struct Note *) dynhelp->data;
					  printf("\tduration: %x oct: %i pit: %i\n", not->duration, not->octave, not->pitch);
					  printf("\tend: %lx loudness: %x flags: %x \n", not->end, not->loud, not->flags);
					  if (not->beam_nr) {
					  	printf("\t");
					  	if ((not->flags) & 0x40) printf("end\t");
					  	if ((not->beam_pos) & 0x40) printf("begin\t");
					  	printf("beam_number: %d beam_pos: %c orientation: ", not->beam_nr, positions[(not->beam_pos) & 0x3f]);
					  	if ((not->beam_pos) & 0x80) printf("upper\n");
					  	else printf("lower\n");
					  }
					  if (not->accord_next) printf("\taccorded: yes\n");
					  else printf("\taccorded: no\n");
					  if (not->slur_nr) {
					  	printf("\t");
					  	if ((not->flags) & 0x80) printf("end\t");
					  	if ((not->slur_pos) & 0x40) printf("begin\t");
					  	printf("slur_number: %d slur_pos: %c orientation: ", not->slur_nr, positions[(not->slur_pos) & 0x3f]);
					  	if ((not->slur_pos) & 0x80) printf("upper\n");
					  	else printf("lower\n");
					  }
					  printf("\tNotenausgabe: ");
					  if (((not->note_pos) & 0xc0) == 0xc0) printf("Aufhebung ");
					  else if (((not->note_pos) & 0xc0) == 0x80) printf("b ");
					       else if (((not->note_pos) & 0xc0) == 0x40) printf("Kreuz ");
					  if (((not->note_pos) & 0x3f) < 5) printf("'");
					  printf("%c\n", positions[(not->note_pos) & 0x3f]);
					  break;
				case 't': ts = (struct TimeSig *) dynhelp->data;
					  printf("nn: %i dom: %i\n",ts->nom, ts->denom);
					  break;
				case 'l': ly = (struct Lyric *) dynhelp->data;
					  printf("text: %s\n",ly->text);
					  break;
				case 'k': ks = (struct KeySig *) dynhelp->data;
					  printf("sign: %x\n",ks->sign);
					  break;
				case 'b': printf("end_of_measure: %d\n", ++barrcounter);
					  break;
				case 'r': re = (struct Rest *) dynhelp->data;
					  printf("kind: %x position: %x\n",re->kind, re->position);
					  break;
				case 'p': lo = (struct Loudness *) dynhelp->data;
					  if (lo->statics) printf("static with value: %x\n", lo->statics);
					  else printf("dynamic with value: %x\n", lo->dynamics);
					  break;
				default : printf("unknown marker\n");
					  break;
			}
			dynhelp = dynhelp->next;
		}
	}
}