/***************************/ /* dyn.c */ /***************************/ #include #include #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= (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; } } }