chiark / gitweb /
Import upstream version 5.3.
[mup] / mup / mup / trantab.c
1 /* Copyright (c) 1997, 1998, 2000, 2001, 2002, 2004 by Arkkra Enterprises */
2 /* All rights reserved */
3 /*
4  * Name:        trantab.c
5  *
6  * Description: This file contains functions for translating tablature staffs
7  *              to their corresponding tabnote staffs.
8  */
9
10 #include "defines.h"
11 #include "structs.h"
12 #include "globals.h"
13
14 /*
15  * Define a temp structure for holding info about the note generated from a
16  * NOTE on a tablature staff.
17  */
18 struct TABNOTENOTE {
19         char letter;            /* 'a' to 'g' */
20         char accidental;        /* '\0', 'x', '#', 'n', '&', 'B'(double flat)*/
21         int octave;             /* 0 to 9 */
22         int hs;                 /* half steps above c0 */
23         int strno;              /* the string this note is played on */
24         struct NOTE *note_p;    /* point to the NOTE this is derived from */
25 };
26
27 static void tabv2tabnotev P((struct MAINLL *mainll_p, int vidx));
28 static void fixprevmeas P((struct GRPSYL *ngs_p, struct MAINLL *mll_p));
29 static int hasprebend P((struct GRPSYL *gs_p));
30 static int cancombine P((struct MAINLL *mll_p, struct GRPSYL *tgs_p,
31                 RATIONAL *comp_p));
32 static RATIONAL calctime P((struct GRPSYL *gs_p));
33 static void translate_group P((struct GRPSYL *tgs_p, struct GRPSYL *pregs_p,
34                 struct GRPSYL *ngs_p, struct MAINLL *mll_p, int combine));
35 static void calcnote P((struct STRINGINFO *sinfo_p, int fretno, RATIONAL bend,
36                 int sharps, struct TABNOTENOTE *note_p, struct GRPSYL *tgs_p));
37 static int findfret P((struct GRPSYL *tgs_p, struct MAINLL *mll_p, int strno));
38 static void popnotes P((struct GRPSYL *gs_p, struct TABNOTENOTE tnn[],
39                 int ntnn, struct GRPSYL *tgs_p, struct MAINLL *mll_p,
40                 int is_prebend, int combine, int sharps));
41 static int neighbor P((struct TABNOTENOTE *high_p, struct TABNOTENOTE *low_p));
42 static int inkeysig P((struct TABNOTENOTE *note_p, int sharps));
43 static int upletter P((struct TABNOTENOTE *note_p));
44 static int downletter P((struct TABNOTENOTE *note_p));
45 static void cleanaccs P((struct GRPSYL *gs_p, struct MAINLL *mll_p));
46 \f
47 /*
48  * Name:        tab2tabnote()
49  *
50  * Abstract:    Populate tabnote staffs' voices from corresponding tab voices.
51  *
52  * Returns:     void
53  *
54  * Description: This function loops through the MLL looking for tab staffs.
55  *              For each it does some work, but the main thing is that it loops
56  *              through each voice and calls tabv2tabnotev() for each GRPSYL
57  *              list.  That function populates the corresponding tabnote voice.
58  */
59
60 void
61 tab2tabnote()
62
63 {
64         struct MAINLL *mainll_p;        /* point along main linked list */
65         struct STAFF *nstaff_p;         /* tabnote STAFF */
66         struct GRPSYL *ngs_p;           /* tabnote GRPSYL */
67         int vidx;
68
69
70         debug(2, "tab2tabnote");
71         initstructs();
72
73         for (mainll_p = Mainllhc_p; mainll_p != 0; mainll_p = mainll_p->next) {
74
75                 if (mainll_p->str == S_SSV) {
76                         asgnssv(mainll_p->u.ssv_p); /* keep SSVs up to date */
77                         continue;
78                 }
79
80                 /* if not a tab staff, there's nothing to do */
81                 if (mainll_p->str != S_STAFF ||
82                     is_tab_staff(mainll_p->u.staff_p->staffno) == NO) {
83                         continue;
84                 }
85
86                 /*
87                  * The previous staff must be a tabnote staff.  Set pointers to
88                  * this tabnote staff and its first voice's first GRPSYL.
89                  */
90                 nstaff_p = mainll_p->prev->u.staff_p;
91                 ngs_p = nstaff_p->groups_p[0];
92
93                 /*
94                  * If this is a multirest, adjust any octave marks in progress.
95                  */
96                 if (ngs_p->basictime < -1 &&
97                                 Octave_bars[nstaff_p->staffno] > 0) {
98
99                         /* add negative bars plus 1; barline will count as 1 */
100                         Octave_bars[nstaff_p->staffno] += ngs_p->basictime + 1;
101
102                         /* if whole octave stuff is done, re-init */
103                         if (Octave_bars[nstaff_p->staffno] < 0) {
104                                 Octave_bars[nstaff_p->staffno] = 0;
105                                 Octave_count[nstaff_p->staffno] = 0.0;
106                                 Octave_adjust[nstaff_p->staffno] = 0;
107                         }
108                 }
109
110                 /* loop through all possible voices, populating tabnote */
111                 for (vidx = 0; vidx < MAXVOICES; vidx++) {
112                         tabv2tabnotev(mainll_p, vidx);
113                 }
114         }
115 }
116 \f
117 /*
118  * Name:        tabv2tabnotev()
119  *
120  * Abstract:    Populate a tabnote voice from its corresponding tab voice.
121  *
122  * Returns:     void
123  *
124  * Description: This function populates a tabnote GRPSYL list based on its
125  *              corresponding tab GRPSYL list, after making sure that the voice
126  *              exists for each.
127  */
128
129 static void
130 tabv2tabnotev(mainll_p, vidx)
131
132 struct MAINLL *mainll_p;        /* main LL struct for this staff */
133 int vidx;                       /* voice index, 0 to MAXVOICES-1 */
134
135 {
136         struct STAFF *tstaff_p;         /* tablature STAFF */
137         struct STAFF *nstaff_p;         /* tabnote STAFF */
138         struct GRPSYL *tgs_p;           /* tablature GRPSYL */
139         struct GRPSYL *ngs_p;           /* tabnote GRPSYL */
140         struct GRPSYL *nngs_p;          /* next tabnote GRPSYL */
141         struct GRPSYL *gs_p;            /* newly allocated GRPSYL */
142         struct GRPSYL *pregs_p;         /* GRPSYL for prebend's grace group */
143         int combine;                    /* should two groups be combined? */
144         RATIONAL totdur;                /* total duration of combined groups */
145         int n;                          /* loop variable */
146         char *acc_p;                    /* pointer to accidental string */
147
148
149         /*
150          * Set pointers to the tablature staff's STAFF structure and the first
151          * GRPSYL in the voice we're working on.
152          */
153         tstaff_p = mainll_p->u.staff_p;
154         tgs_p = tstaff_p->groups_p[vidx];
155
156         /* if this voice doesn't exist, there is nothing to copy to tabnote */
157         if (tgs_p == 0) {
158                 return;
159         }
160
161         /*
162          * The previous staff must be a tabnote staff.  Set pointers to this
163          * tabnote staff and the first GRPSYL of the given voice.
164          */
165         nstaff_p = mainll_p->prev->u.staff_p;
166         ngs_p = nstaff_p->groups_p[vidx];
167
168         /* tabnote staff must have at least as many voices as tab staff */
169         if (ngs_p == 0) {
170                 l_ufatal(tgs_p->inputfile, tgs_p->inputlineno,
171                         "tab staff %d has a voice %d, but tabnote staff %d doesn't; change vscheme for tabnote staff",
172                         nstaff_p->staffno + 1, vidx + 1, nstaff_p->staffno);
173         }
174
175         /*
176          * If the tabnote staff/voice doesn't have a measure space, it was
177          * manually entered, and we will leave it alone.  However, it is
178          * possible that this staff/voice in the previous measure was
179          * generated, and that the last GRPSYL there had note(s) that were to
180          * slide to our GRPSYL.  If so, that slurtolist needs to be adjusted.
181          */
182         if (ngs_p->is_meas == NO || ngs_p->grpcont != GC_SPACE) {
183                 fixprevmeas(ngs_p, mainll_p->prev);
184                 return;
185         }
186
187         FREE(ngs_p);            /* throw away the measure space */
188
189         /*
190          * Loop once for each GRPSYL in this measure on the tablature staff/
191          * voice.  Usually, for each one found, we allocate one for the tabnote
192          * staff/voice.  But in cases involving prebends, we allocate a second
193          * one, since they translate to a grace note (in parentheses) and a
194          * normal note.  And in certain cases of bends of <= 1/4 step, we don't
195          * allocate any, since we combine the two notes into one.
196          */
197         combine = NO;
198         for ( ; tgs_p != 0; tgs_p = tgs_p->next) {
199                 /*
200                  * If this group was combined into the previous group because
201                  * of 1/4 step bends, we don't allocate any group now.
202                  */
203                 if (combine) {
204                         combine = NO;
205                         continue;
206                 }
207
208                 /*
209                  * Check whether any of the notes in this tab group have
210                  * prebends.  If so, allocate a special GRPSYL for the grace
211                  * note(s) in parentheses before the main group.  Link it and
212                  * set its fields.
213                  */
214                 if (hasprebend(tgs_p)) {
215                         CALLOC(GRPSYL, pregs_p, 1);
216                         if (tgs_p == tstaff_p->groups_p[vidx]) {
217                                 /* first GRPSYL in list; no previous one, */
218                                 /*  staff points at us */
219                                 pregs_p->prev = 0;
220                                 nstaff_p->groups_p[vidx] = pregs_p;
221                         } else {
222                                 /* a later one; set both links */
223                                 pregs_p->prev = ngs_p;
224                                 ngs_p->next = pregs_p;
225                         }
226                         pregs_p->next = 0;      /* last one so far */
227                         ngs_p = pregs_p;
228
229                         /* set fields unless they'd be just hardcoded 0 */
230                         pregs_p->inputlineno = tgs_p->inputlineno;
231                         pregs_p->inputfile = tgs_p->inputfile;
232                         pregs_p->staffno = nstaff_p->staffno;
233                         pregs_p->vno = vidx + 1;
234                         pregs_p->grpsyl = GS_GROUP;
235                         pregs_p->basictime = 4; /* stemless 1/4 note */
236                         pregs_p->is_meas = NO;
237                         pregs_p->tuploc = NOITEM;
238                         pregs_p->fulltime = Zero;
239                         pregs_p->grpcont = GC_NOTES;
240                         pregs_p->grpvalue = GV_ZERO;
241                         pregs_p->grpsize = GS_SMALL;
242                         pregs_p->headshape = HS_UNKNOWN;
243                         pregs_p->clef = NOCLEF;
244                         pregs_p->beamloc = NOITEM;
245                         pregs_p->beamto = CS_SAME;
246                         pregs_p->stemto = CS_SAME;
247                         pregs_p->tie = NO;
248                         pregs_p->roll = NOITEM;
249                         pregs_p->ho_usage = HO_NONE;
250                         /* nnotes and notelist get set later */
251                 } else {
252                         pregs_p = 0;            /* no prebend grace */
253                 }
254
255                 /*
256                  * Allocate a GRPSYL.  Initialize it to be the same as the tab
257                  * GRPSYL, since most fields are the same.  Later we'll change
258                  * the ones that are different.  Link it appropriately to the
259                  * staff (if it's the first one) or else the previous GRPSYL.
260                  */
261                 CALLOC(GRPSYL, gs_p, 1);
262                 *gs_p = *tgs_p;
263                 if (tgs_p == tstaff_p->groups_p[vidx] && pregs_p == 0) {
264                         /* first one; no previous one, staff points at us */
265                         gs_p->prev = 0;
266                         nstaff_p->groups_p[vidx] = gs_p;
267                 } else {
268                         /* later one; set both links */
269                         gs_p->prev = ngs_p;
270                         ngs_p->next = gs_p;
271                 }
272                 gs_p->next = 0;         /* last one so far */
273                 ngs_p = gs_p;           /* use ngs_p var for new one */
274
275                 /* set the correct staff number */
276                 ngs_p->staffno = nstaff_p->staffno;
277
278                 /* can't share same withlist because fonts may be */
279                 /*  changed in them differently later */
280                 clone_withlist(ngs_p, tgs_p);
281
282                 /* notelist will be reset later; nnotes might change */
283
284                 combine = cancombine(mainll_p, tgs_p, &totdur);
285                 if (combine) {
286                         /* calc basictime and dots of combined note */
287                         ngs_p->basictime = reconstruct_basictime(totdur);
288                         ngs_p->dots = recalc_dots(totdur, ngs_p->basictime);
289
290                         /* combine fulltime (works even for tuplets) */
291                         ngs_p->fulltime = radd(tgs_p->fulltime,
292                                         tgs_p->next->fulltime);
293                 }
294
295                 if (tgs_p->grpcont == GC_NOTES && ! is_mrpt(ngs_p)) {
296                         translate_group(tgs_p, pregs_p, ngs_p,
297                                         mainll_p, combine);
298                 }
299         }
300
301         /*
302          * For measure repeats, mark the staff and get out.  If there is more
303          * than one voice, each will hit this code, but that's okay.
304          */
305         if (is_mrpt(ngs_p)) {
306                 nstaff_p->mrptnum = tstaff_p->mrptnum;
307                 return;
308         }
309
310         /* blow away unneeded accidentals */
311         cleanaccs(nstaff_p->groups_p[vidx], mainll_p->prev);
312
313         /*
314          * Because we may have combined some groups, we might have lost the
315          * STARTITEM or ENDITEM of some beamed groups.  So find this situation
316          * and fix it.  This can only affect nongrace groups, so ignore grace
317          * groups.
318          */
319         ngs_p = nstaff_p->groups_p[vidx];       /* first group in measure */
320         if (ngs_p->grpvalue == GV_ZERO) /* if grace, */
321                 ngs_p = nextnongrace(ngs_p);    /* get first nongrace*/
322
323         for ( ; ngs_p != 0; ngs_p = nngs_p) {
324                 /* get the next group, if any, excluding graces */
325                 nngs_p = nextnongrace(ngs_p);
326
327                 /*
328                  * For this and the next group, if it's a quarter or longer,
329                  * make sure it won't get beamed.
330                  */
331                 if (ngs_p->basictime <= 4)
332                         ngs_p->beamloc = NOITEM;
333                 if (nngs_p != 0 && nngs_p->basictime <= 4)
334                         nngs_p->beamloc = NOITEM;
335
336                 /* based on this and next group, change this group */
337                 switch (ngs_p->beamloc) {
338                 case STARTITEM:
339                         if (nngs_p == 0 ||
340                             nngs_p->beamloc == STARTITEM ||
341                             nngs_p->beamloc == NOITEM)
342                                 ngs_p->beamloc = NOITEM;
343                         break;
344                 case INITEM:
345                         if (nngs_p == 0 ||
346                             nngs_p->beamloc == STARTITEM ||
347                             nngs_p->beamloc == NOITEM)
348                                 ngs_p->beamloc = ENDITEM;
349                         break;
350                 case ENDITEM:
351                 case NOITEM:
352                         if (nngs_p != 0) {
353                                 if (nngs_p->beamloc == INITEM)
354                                         nngs_p->beamloc = STARTITEM;
355                                 else if (nngs_p->beamloc == ENDITEM)
356                                         nngs_p->beamloc = NOITEM;
357                         }
358                         break;
359                 }
360         }
361
362         /*
363          * Now we have start and end items on every beamed set, but it is
364          * possible that some of them are rests (if there were rests embedded
365          * in the original set).  So revise to get them out of there.
366          */
367         ngs_p = nstaff_p->groups_p[vidx];       /* first group in measure */
368         if (ngs_p->grpvalue == GV_ZERO) /* if grace, */
369                 ngs_p = nextnongrace(ngs_p);    /* get first nongrace*/
370
371         for ( ; ngs_p != 0; ngs_p = nextnongrace(ngs_p)) {
372                 int notegroups;         /* number in this set */
373                 struct GRPSYL *end_p;   /* point at the enditem */
374
375                 if (ngs_p->beamloc != STARTITEM)
376                         continue;
377                 /*
378                  * We found a startitem; count how many note groups in the set.
379                  * Also set end_p to point at the end item in case we need it
380                  * later.
381                  */
382                 notegroups = 0;
383                 end_p = 0;      /* avoid useless warnings */
384                 for (nngs_p = ngs_p; nngs_p != 0 &&
385                                 (nngs_p->prev == 0 ||
386                                 nngs_p->prev->beamloc != ENDITEM);
387                                 nngs_p = nextnongrace(nngs_p)) {
388                         if (nngs_p->grpcont == GC_NOTES)
389                                 notegroups++;
390                         end_p = nngs_p;
391                 }
392
393                 if (notegroups <= 1) {
394                         /* 0 or 1 note groups; blow away the set */
395                         for (nngs_p = ngs_p; nngs_p != 0 &&
396                                         (nngs_p->prev == 0 ||
397                                         nngs_p->prev->beamloc!=ENDITEM);
398                                         nngs_p = nextnongrace(nngs_p)) {
399                                 nngs_p->beamloc = NOITEM;
400                         }
401                 } else {
402                         /*
403                          * There are at least two note groups, so we will keep
404                          * the set, but we may need to move the endpoints to
405                          * avoid rests.
406                          */
407                         /* remove any rests at the start */
408                         for (nngs_p = ngs_p; nngs_p->grpcont == GC_REST;
409                                         nngs_p = nextnongrace(nngs_p)) {
410                                 nngs_p->beamloc = NOITEM;
411                         }
412                         nngs_p->beamloc = STARTITEM;
413                         /* remove any rests at the end */
414                         for (nngs_p = end_p; nngs_p->grpcont == GC_REST;
415                                         nngs_p = prevnongrace(nngs_p)) {
416                                 nngs_p->beamloc = NOITEM;
417                         }
418                         nngs_p->beamloc = ENDITEM;
419                 }
420         }
421
422         /* do beaming of tabnote staff based on beamstyle */
423         if (has_cust_beaming(nstaff_p->groups_p[vidx]) == NO) {
424                 do_beaming(nstaff_p->groups_p[vidx], GS_NORMAL,
425                                         nstaff_p->staffno, vidx + 1);
426                 do_beaming(nstaff_p->groups_p[vidx], GS_SMALL,
427                                         nstaff_p->staffno, vidx + 1);
428         }
429
430         /*
431          * When there are octave marks on the tabnote staff, adjust the notes
432          * the opposite way so that the result is correct.  Then check to make
433          * sure nothing is out of range.
434          */
435         octave_transpose(nstaff_p, mainll_p, vidx, NO);
436
437         for (ngs_p = nstaff_p->groups_p[vidx]; ngs_p != 0; ngs_p = ngs_p->next){
438                 for (n = 0; n < ngs_p->nnotes; n++) {
439                         if (ngs_p->notelist[n].octave < MINOCTAVE ||
440                             ngs_p->notelist[n].octave > MAXOCTAVE) {
441
442                                 acc_p = ngs_p->notelist[n].accidental == '\0' ?
443                                         "" : Acctostr[strchr(Acclets, ngs_p->
444                                         notelist[n].accidental) - Acclets];
445
446                                 l_ufatal(ngs_p->inputfile,
447                                         ngs_p->inputlineno,
448                                         "'octave' string on tabnote staff transposes note %c%s to out of range octave %d",
449                                         ngs_p->notelist[n].letter,
450                                         acc_p,
451                                         ngs_p->notelist[n].octave);
452                         }
453                 }
454         }
455 }
456 \f
457 /*
458  * Name:        fixprevmeas()
459  *
460  * Abstract:    Fixed unresolved slides in the previous tabnote measure.
461  *
462  * Returns:     void
463  *
464  * Description: This function is called for the first GRPSYL of a manually
465  *              entered tabnote measure.  If the previous tabnote measure was
466  *              generated, it might be trying to slide to a note in our GRPSYL.
467  *              If so, its slurtolist would have a string number in place of a
468  *              letter and NOFRET for the octave.  This function resolves this
469  *              to the true letter and octave.
470  */
471
472 static void
473 fixprevmeas(ngs_p, mll_p)
474
475 struct GRPSYL *ngs_p;           /* tabnote GRPSYL */
476 struct MAINLL *mll_p;           /* MLL for this GRPSYL */
477
478 {
479         struct GRPSYL *prevngs_p;       /* previous GRPSYL */
480         struct SLURTO *s_p;             /* point at a SLURTO structure */
481         int j, k;                       /* for looping through notes */
482
483
484         /* find previous GRPSYL, if any; if not notes, nothing to do */
485         prevngs_p = prevgrpsyl(ngs_p, &mll_p);
486         if (prevngs_p == 0 || prevngs_p->grpcont != GC_NOTES)
487                 return;
488
489         /*
490          * Check every note in the preceding group.  Don't break out after
491          * finding one, since multiple ones could slide to our note.  But there
492          * is a max of one slur/bend coming from each note.
493          */
494         s_p = 0;                /* prevent useless 'used before set' warning */
495         for (k = 0; k < prevngs_p->nnotes; k++) {
496                 /* check every slur from that note */
497                 for (j = 0; j < prevngs_p->notelist[k].nslurto; j++) {
498                         s_p = &prevngs_p->notelist[k].slurtolist[j];
499
500                         /* only deal with unresolved tabslurs */
501                         if (s_p->letter < MAXTABLINES && s_p->octave == NOFRET)
502                                 break;
503                 }
504                 /* if found a tabslur to our GRPSYL */
505                 if (j < prevngs_p->notelist[k].nslurto) {
506                         /* if our GRPSYL has no notes, this is no good */
507                         if (ngs_p->grpcont != GC_NOTES) {
508                                 l_warning(prevngs_p->inputfile,
509                                 prevngs_p->inputlineno,
510                                 "no note on tabnote staff to slide to from %c%s%d",
511                                 prevngs_p->notelist[k].letter,
512                                 prevngs_p->notelist[k].accidental == '\0' ? "" :
513                                 Acctostr[ strchr(Acclets, prevngs_p->notelist[k]
514                                                 .accidental) - Acclets ],
515                                 prevngs_p->notelist[k].octave);
516
517                                 prevngs_p->notelist[k].nslurto = 0;
518
519                         /* if our GRPSYL has >= 2 notes, this is no good */
520                         } else if (ngs_p->nnotes >= 2) {
521                                 l_warning(prevngs_p->inputfile,
522                                 prevngs_p->inputlineno,
523                                 "can't slide from %c%s%d because multiple notes in the next group",
524                                 prevngs_p->notelist[k].letter,
525                                 prevngs_p->notelist[k].accidental == '\0' ? "" :
526                                 Acctostr[ strchr(Acclets, prevngs_p->notelist[k]
527                                                 .accidental) - Acclets ],
528                                 prevngs_p->notelist[k].octave);
529
530                                 prevngs_p->notelist[k].nslurto = 0;
531                         /* there is one note, so we can do the slide */
532                         } else {
533                                 s_p->letter = ngs_p->notelist[0].letter;
534                                 s_p->octave = ngs_p->notelist[0].octave;
535                         }
536                 }
537         }
538 }
539 \f
540 /*
541  * Name:        hasprebend()
542  *
543  * Abstract:    Check whether any of the notes in this group have a prebend.
544  *
545  * Returns:     YES or NO
546  *
547  * Description: This function checks whether any of the notes in this group
548  *              have a prebend.  That's the case where a NOTE structure has
549  *              both a fret number and a bend other than "".  A bend of "" is
550  *              the release of a bend.  It will also return NO if this group
551  *              is a rest or space.
552  */
553
554 static int
555 hasprebend(tgs_p)
556
557 struct GRPSYL *tgs_p;
558
559 {
560         int n;                  /* for looping through notes */
561
562
563         for (n = 0; n < tgs_p->nnotes; n++) {
564                 /* check for a fret with a nonnull bend */
565                 if (tgs_p->notelist[n].FRETNO != NOFRET &&
566                     HASREALBEND(tgs_p->notelist[n])) {
567                         return (YES);
568                 }
569         }
570
571         return (NO);
572 }
573 \f
574 /*
575  * Name:        cancombine()
576  *
577  * Abstract:    Check two groups can be joined into one on the tabnote staff.
578  *
579  * Returns:     YES or NO
580  *
581  * Description: This function checks whether the two given groups are joined
582  *              by 1/4 step or less bends and should be combined into one group
583  *              on the tabnote staff.  There are a number of other conditions
584  *              that must be met for this to be allowed.  If the answer is YES,
585  *              it sets *comb_p to the total duration, ignoring the effect of
586  *              tuplets.
587  */
588
589 static int
590 cancombine(mll_p, tgs_p, comb_p)
591
592 struct MAINLL *mll_p;   /* main linked list structure we are hanging off of */
593 struct GRPSYL *tgs_p;   /* tablature GRPSYL for the first of the two groups */
594 RATIONAL *comb_p;       /* for returning total time if combinable */
595
596 {
597         struct GRPSYL *nexttgs_p;       /* the second GRPSYL */
598         struct GRPSYL *next2tgs_p;      /* the next one after that */
599         int n;                          /* for looping through note lists */
600
601
602         /* must be a note group */
603         if (tgs_p->grpcont != GC_NOTES)
604                 return (NO);
605
606         /* must not be grace */
607         if (tgs_p->grpvalue == GV_ZERO)
608                 return (NO);
609
610         for (n = 0; n < tgs_p->nnotes; n++) {
611                 /* no note can be the destination of a nonnull bend */
612                 if (HASREALBEND(tgs_p->notelist[n]))
613                         return (NO);
614         }
615
616         nexttgs_p = tgs_p->next;        /* find the next group */
617
618         /* first group must not be at the end of a measure */
619         if (nexttgs_p == 0)
620                 return (NO);
621
622         /* first and second group must have same number of notes */
623         if (tgs_p->nnotes != nexttgs_p->nnotes)
624                 return (NO);
625
626         /* each pair of notes must be joined by a bend of <= 1/4 step */
627         for (n = 0; n < nexttgs_p->nnotes; n++) {
628                 if ( ! HASBEND(nexttgs_p->notelist[n]) ||
629                    GT(ratbend(&nexttgs_p->notelist[n]), One_fourth))
630                         return (NO);
631         }
632
633         /* find the following (3rd) group, if there is one */
634         next2tgs_p = nextgrpsyl(nexttgs_p, &mll_p);
635
636         /* no notes in the second group are allowed to bend into the third */
637         if (next2tgs_p != 0) {
638                 for (n = 0; n < next2tgs_p->nnotes; n++) {
639                         if (HASBEND(next2tgs_p->notelist[n]))
640                                 return (NO);
641                 }
642         }
643
644         /* first group must not be at the end of a tuplet */
645         if (tgs_p->tuploc == ENDITEM || tgs_p->tuploc == LONEITEM)
646                 return (NO);
647
648         /* second group must not be at the start of a tuplet */
649         if (nexttgs_p->tuploc == STARTITEM || nexttgs_p->tuploc == LONEITEM)
650                 return (NO);
651
652         /* get total duration of the two groups */
653         *comb_p = radd(calctime(tgs_p), calctime(nexttgs_p));
654
655         /* total must be double whole, or else numerator must be 2**n - 1 */
656         if (NE(*comb_p, Two) && (comb_p->n & (comb_p->n + 1)) != 0)
657                 return (NO);
658
659         return (YES);
660 }
661 \f
662 /*
663  * Name:        calctime()
664  *
665  * Abstract:    Calculate time duration, considering basictime and dots.
666  *
667  * Returns:     The rational number answer.
668  *
669  * Description: This function, given a GRPSYL structure, returns the duration
670  *              as a rational number.  It considers basictime and dots, but it
671  *              does not include the effect of tuplets.  It assumes nongrace,
672  *              it assumes GC_NOTES (thus no quadruple wholes), and it assumes
673  *              not multirest.
674  */
675
676 static RATIONAL
677 calctime(gs_p)
678
679 struct GRPSYL *gs_p;
680
681 {
682         RATIONAL base;
683
684
685         if (gs_p->basictime == 0) {
686                 /* double whole note is 2 */
687                 base.n = 2;
688                 base.d = 1;
689         } else {
690                 /* anything else is 1/basictime */
691                 base.n = 1;
692                 base.d = gs_p->basictime;
693         }
694
695         /* return  ( base * (2 - (1/2)**dots) )   */
696         return (rmul(base, rsub(Two, rrai(One_half, gs_p->dots))));
697 }
698 \f
699 /*
700  * Name:        translate_group()
701  *
702  * Abstract:    Translate tablature group notes to tabnote group notes.
703  *
704  * Returns:     void
705  *
706  * Description: This function is given a tablature staff group.  It normally
707  *              translates the notes in this one group to the notes in the
708  *              corresponding tabnote staff group.  But in the case where the
709  *              tab staff group has note(s) that are prebends, it also creates
710  *              the notes for the tabnote grace group.  And in the case where
711  *              this tab group is to be combined with the following one, it
712  *              translates the two together into one tabnote group.
713  */
714
715 static void
716 translate_group(tgs_p, pregs_p, ngs_p, mll_p, combine)
717
718 struct GRPSYL *tgs_p;           /* tablature GRPSYL */
719 struct GRPSYL *ngs_p;           /* corresponding main tabnote GRPSYL */
720 struct GRPSYL *pregs_p;         /* GRPSYL for prebend's grace group */
721 struct MAINLL *mll_p;           /* main LL struct we come from */
722 int combine;                    /* combining two tab groups into one tabnote?*/
723
724 {
725         struct TABNOTENOTE notes[MAXTABLINES];    /* notes in the main group */
726         struct TABNOTENOTE prenotes[MAXTABLINES]; /* notes in prebend group */
727         struct TABNOTENOTE tempnote;    /* temporary storage for sorting */
728         struct STRINGINFO *strinfo;     /* info about the strings */
729         int fret;               /* fret number */
730         int idx, pidx;          /* indices into regular and prebend arrays */
731         int n, k;               /* loop variables */
732         int strno;              /* string number */
733         RATIONAL bend;          /* bend distance as a rational number */
734         int sharps;             /* number of sharps in tabnote staff's keysig*/
735
736
737         /* find the key signature; flats count negative */
738         sharps = svpath(ngs_p->staffno, SHARPS)->sharps;
739
740         /* point to the array of structures describing the strings */
741         strinfo = svpath(tgs_p->staffno, STAFFLINES)->strinfo;
742
743         /*
744          * Loop through the note structures in the tab staff's GRPSYL, filling
745          * the prebend and regular note arrays.
746          */
747         idx = pidx = 0;
748         for (n = 0; n < tgs_p->nnotes; n++) {
749
750                 /* get string and fret number */
751                 strno = tgs_p->notelist[n].STRINGNO;
752                 fret = tgs_p->notelist[n].FRETNO;
753
754                 /*
755                  * If this note is a prebend note, put the original (unbent)
756                  * note in the prenotes array.  Link this to the tab staff's
757                  * GRPSYL.  Keep the array sorted so that the highest notes
758                  * come first.
759                  */
760                 if (fret != NOFRET && HASREALBEND(tgs_p->notelist[n])) {
761                         calcnote(&strinfo[strno], fret, Zero, sharps,
762                                         &prenotes[pidx++], tgs_p);
763                         prenotes[pidx-1].strno = strno;
764                         prenotes[pidx-1].note_p = &tgs_p->notelist[n];
765                         for (k = pidx - 1; k > 0; k--) {
766                                 if (prenotes[k].hs > prenotes[k-1].hs) {
767                                         tempnote = prenotes[k-1];
768                                         prenotes[k-1] = prenotes[k];
769                                         prenotes[k] = tempnote;
770                                 }
771                         }
772                 }
773
774                 /* find the bend amount; if none we will get Zero */
775                 bend = ratbend(&tgs_p->notelist[n]);
776
777                 /*
778                  * If there is no fret number in this note, it must be the
779                  * destination of a bend.  Call findfret to search backwards
780                  * through earlier notes on this string, until we find the fret
781                  * number, which is where the bend started.
782                  */
783                 if (fret == NOFRET)
784                         fret = findfret(tgs_p, mll_p, strno);
785                 if (fret == NOFRET)
786                         pfatal("cannot find fret number for tablature note");
787
788                 /*
789                  * Now we have the fret, and maybe a bend too.  Calculate what
790                  * note this comes out to, and put it in the notes array.
791                  * Link this to the GRPSYL it was derived from.  Keep the
792                  * array sorted so that the highest notes come first.
793                  */
794                 calcnote(&strinfo[strno], fret, bend, sharps, &notes[idx++],
795                                 tgs_p);
796                 notes[idx-1].note_p = &tgs_p->notelist[n];
797                 notes[idx-1].strno = strno;
798                 for (k = idx - 1; k > 0; k--) {
799                         if (notes[k].hs > notes[k-1].hs) {
800                                 tempnote = notes[k-1];
801                                 notes[k-1] = notes[k];
802                                 notes[k] = tempnote;
803                         }
804                 }
805         }
806
807         /*
808          * If we are generating a prebend group, populate NOTE structures for
809          * it.  Then, in any case, populate NOTE structures for the main group.
810          */
811         if (pregs_p != 0)
812                 popnotes(pregs_p, prenotes, pidx, tgs_p, mll_p, YES, NO,sharps);
813
814         popnotes(ngs_p, notes, idx, tgs_p, mll_p, NO, combine, sharps);
815 }
816 \f
817 /*
818  * Name:        calcnote()
819  *
820  * Abstract:    Calculate note info for a tabnote NOTE structure.
821  *
822  * Returns:     void
823  *
824  * Description: This function is given the info about the string in question,
825  *              the fret number on that string, and the amount of bend (which
826  *              might be zero).  From this it calculates what note that results
827  *              in, and how best to represent it, which depends on what the
828  *              key sig is.  Bends are rounded to the nearest half step,
829  *              rounding downward when they fall on an exact quarter step.
830  *              The results are put in the TABNOTENOTE structure provided.
831  */
832
833 static void
834 calcnote(sinfo_p, fret, bend, sharps, note_p, tgs_p)
835
836 struct STRINGINFO *sinfo_p;     /* pointer to info about the string */
837 int fret;                       /* fret number on the string */
838 RATIONAL bend;                  /* bend distance */
839 int sharps;                     /* number of sharps in tabnote staff's keysig*/
840 struct TABNOTENOTE *note_p;     /* note structure to be filled */
841 struct GRPSYL *tgs_p;           /* pointer to tab group */
842
843 {
844         /*
845          * The following table, indexed by a note letter minus 'a', tells how
846          * many half steps that note is above C.
847          */
848         static int hstab[] = { 9, 11, 0, 2, 4, 5, 7 };
849                             /* a   b  c  d  e  f  g */
850         /*
851          * The following table, given the number of sharps in a major key
852          * (flats count negative), is to be indexed by (sharps + 7).  The
853          * result is the number of half steps the key note is above C.
854          */
855         static int sh2keyhs[] = { 11,6, 1, 8, 3,10, 5, 0, 7, 2, 9, 4,11, 6, 1 };
856                                /* c& g& d& a& e& b& f  c  g  d  a  e  b  f# c#*/
857                                /* -7 -6 -5 -4 -3 -2 -1 0  1  2  3  4  5  6  7 */
858         /*
859          * The following table, given the number of sharps in a major key
860          * (flats count negative), is to be indexed by (sharps + 7).  The
861          * result is the number of letters the key note is above C.
862          */
863         static int sh2keylet[] ={ 0, 4, 1, 5, 2, 6, 3, 0, 4, 1, 5, 2, 6, 3, 0 };
864                                /* c& g& d& a& e& b& f  c  g  d  a  e  b  f# c#*/
865                                /* -7 -6 -5 -4 -3 -2 -1 0  1  2  3  4  5  6  7 */
866
867         /*
868          * The following table, given the number of half steps a note is above
869          * the key note, tells how many letters above the key note letter the
870          * given note should be written as.  For example, in the key of C, the
871          * note 6 half steps up (augmented 4th, f#), should be written with
872          * the letter 3 letters above c (c + 3 = f), thus f# and not g&.
873          */
874         static int hs2s[] = { 0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6 };
875         /* intervals:         P1 A1 M2 m3 M3 P4 A4 P5 A5 M6 m7 M7 */
876         /* key of C example:  c  c# d  e& e  f  f# g  g# a  b& b  */
877
878
879         int hs;                 /* half steps above c0 */
880         RATIONAL bendqs;        /* bend quarter steps */
881         int keyhs;              /* hs above C the key note is */
882         int intervhs;           /* hs above key note the given note is */
883         int intervlet;          /* letters above key note the given note is */
884         int keyletidx;          /* the key letter (c=1, d=1, etc.) */
885         int octacc;             /* half steps due to octave & accidental */
886         int accoffset;          /* resulting note's acc (&=-1, #=1, etc.) */
887
888
889         /*
890          * Convert the bend to quarter steps.  If the result is an odd integer,
891          * dividing by 2 will give the number of half steps we want (we are
892          * rounding downward).  Otherwise, we round to the nearest half step.
893          */
894         bendqs = rmul(bend, Four);
895         if (bendqs.n % 2 == 1 && bendqs.d == 1) {
896                 hs = bendqs.n / 2;
897         } else {
898                 bendqs = radd(bendqs, One);
899                 hs = bendqs.n / bendqs.d / 2;
900         }
901
902         /* add on the half steps due to letter, octave, and fret */
903         hs += hstab[ sinfo_p->letter - 'a' ] + 12 * sinfo_p->octave + fret;
904
905         /* adjust if string has an accidental; only '#' and '&' are allowed */
906         switch (sinfo_p->accidental) {
907         case '#':
908                 hs++;           /* sharp */
909                 break;
910         case '&':
911                 hs--;           /* flat */
912                 break;
913         }
914
915         /* hs is now the correct note, in half steps above c0 */
916         note_p->hs = hs;
917
918         /*
919          * Now that we know the note, we still have to decide how to represent
920          * it, like G# versus A&.  If the note falls within the key signature,
921          * we go with that.  Otherwise, we take our best shot at which way to
922          * do it.
923          *
924          * For C major, for example, it seems clear that F# and C# are more
925          * likely to be appropriate than G& and D&, due to borrowed dominant
926          * chords.  G# is probably better than A&, since it's in the dominant
927          * of the relative minor, though it's not good for the flat 6 chord.
928          * But D# is getting a little extreme, and E& is probably better.
929          * Certainly B& is better than A#.
930          *
931          * For A minor, a similar analysis shows that the same note choices
932          * are good, except that D# is probably better than E&.  We could use
933          * the is_minor flag from the key sig to make this difference.  But
934          * since it's only one note, which is questionable anyway, and since
935          * people wouldn't normally bother to set that flag except for some
936          * unknown MIDI purpose, we elect not to differentiate, but rather
937          * simply go with the "major" analysis.  Of course, we have to
938          * transpose this to the appropriate major key.
939          */
940
941         /*
942          * Find how many half steps above a C the key note is, assuming major.
943          * Then find how many half steps higher the given note is, being
944          * careful to add 12 in there because hs could be as small as -1.
945          */
946         keyhs = sh2keyhs[sharps + 7];
947         intervhs = (hs + 12 - keyhs) % 12;
948
949         /* find how many letters above the key letter this note should be */
950         intervlet = hs2s[intervhs];
951
952         /* find the key letter (c = 0, d = 1, etc.) */
953         keyletidx = sh2keylet[sharps + 7];
954
955         /* find the letter that should be used for this note */
956         note_p->letter = "cdefgab"[(keyletidx + intervlet) % 7];
957
958         /*
959          * Subtract out the half steps due to letter (half steps the letter is
960          * above C).  This leaves the half steps due to the octave & accidental.
961          */
962         octacc = hs - hstab[ note_p->letter - 'a' ];
963
964         /*
965          * The nearest multiple of 12 gives the octave.  What's left gives the
966          * accidental from -2 to 2 (double flat to double sharp).  Index a
967          * character array by that plus 2 to get the right character.
968          */
969         note_p->octave = (octacc + 12 + 6) / 12 - 1;
970         accoffset = octacc - 12 * note_p->octave;
971         note_p->accidental = Acclets[accoffset + 2];
972
973         if (note_p->octave < MINOCTAVE || note_p->octave > MAXOCTAVE) {
974                 l_ufatal(tgs_p->inputfile, tgs_p->inputlineno,
975                 "the indicated note on the %s string is out of range, too %s",
976                 format_string_name(sinfo_p->letter, sinfo_p->accidental,
977                 sinfo_p->nticks), note_p->octave > MAXOCTAVE ? "high" : "low");
978         }
979 }
980 \f
981 /*
982  * Name:        findfret()
983  *
984  * Abstract:    Find fret number that applies to the given GRPSYL.
985  *
986  * Returns:     The fret number, or NOFRET if none found.
987  *
988  * Description: This function starts at the given GRPSYL and works backwards
989  *              through that voice until it find a GRPSYL containing a fret
990  *              number.  This is needed since when there is a bend (other than
991  *              a prebend), the fret number does not exist in this GRPSYL, but
992  *              in some earlier GRPSYL which is "bent" to this GRPSYL by a
993  *              series of one or more bends.  Every intervening GRPSYL must
994  *              have a "note" for this string.  If the function hits an
995  *              invalid GRPSYL or the beginning of the MLL, it returns NOFRET.
996  *              This should never happen.
997  */
998
999 static int
1000 findfret(tgs_p, mll_p, strno)
1001
1002 struct GRPSYL *tgs_p;           /* tab GRPSYL to start from */
1003 struct MAINLL *mll_p;           /* MLL struct it hangs off of */
1004 int strno;                      /* string number */
1005
1006 {
1007         int n;                  /* for looping through notelist */
1008
1009
1010         /* loop until we find the fret or something goes wrong */
1011         for (;;) {
1012                 /* the GRPSYL must contain notes */
1013                 if (tgs_p->grpcont != GC_NOTES)
1014                         return (NOFRET);
1015
1016                 /* find the note for the string in question; it must exist */
1017                 for (n = 0; n < tgs_p->nnotes; n++) {
1018                         if (tgs_p->notelist[n].STRINGNO == strno)
1019                                 break;
1020                 }
1021                 if (n == tgs_p->nnotes)
1022                         return (NOFRET);
1023
1024                 /* if this note (string) has a valid fret, return it */
1025                 if (tgs_p->notelist[n].FRETNO != NOFRET)
1026                         return (tgs_p->notelist[n].FRETNO);
1027
1028                 /* search backwards for the next GRPSYL, which must exist */
1029                 tgs_p = prevgrpsyl(tgs_p, &mll_p);
1030                 if (tgs_p == 0)
1031                         return (NOFRET);
1032         }
1033 }
1034 \f
1035 /*
1036  * Name:        popnotes()
1037  *
1038  * Abstract:    Adjust the desired notes and populate the NOTE structures.
1039  *
1040  * Returns:     void
1041  *
1042  * Description: This function is given the notes desired for one tabnote
1043  *              GRPSYL.  If too many notes are too close together to print, it
1044  *              throws some away, with warnings.  Then it allocates NOTE
1045  *              structures and fills them in.
1046  */
1047
1048 static void
1049 popnotes(ngs_p, tnn, ntnn, tgs_p, mll_p, is_prebend, combine, sharps)
1050
1051 struct GRPSYL *ngs_p;           /* tabnote GRPSYL */
1052 struct TABNOTENOTE tnn[];       /* array of TABNOTENOTE structures */
1053 int ntnn;                       /* number of the above structures */
1054 struct GRPSYL *tgs_p;           /* tablature GRPSYL we came from */
1055 struct MAINLL *mll_p;           /* main LL structure we came from */
1056 int is_prebend;                 /* is this a prebend group? */
1057 int combine;                    /* this group formed by combining tab grps? */
1058 int sharps;                     /* current key signature */
1059
1060 {
1061         struct NOTE *newnote_p; /* handy pointer to an allocated NOTE */
1062         struct GRPSYL *nexttgs_p; /* the tab GRPSYL following ours */
1063         struct GRPSYL *prevngs_p; /* the tabnote GRPSYL preceding ours */
1064         struct SLURTO *s_p;     /* point at a SLURTO structure */
1065         struct MAINLL *mainll_p;/* place to store mll_p */
1066         int hightight, lowtight;/* are notes next to a conflict neighboring? */
1067         int remnote;            /* should a note be removed? */
1068         int keysigidx;          /* index to the note that is in the key sig */
1069         int nonkeysigidx;       /* index to the note not in the key sig */
1070         int n, k, j;            /* loop variables */
1071
1072
1073         /*
1074          * Loop through the notes, throwing away duplicates.  They are already
1075          * in order, highest note first.
1076          */
1077         for (n = 1; n < ntnn; n++) {
1078                 if (tnn[n - 1].hs == tnn[n].hs) {
1079                         l_warning(tgs_p->inputfile, tgs_p->inputlineno,
1080                         "throwing away duplicate note %c%c%d on tabnote staff",
1081                         tnn[n].letter, tnn[n].accidental, tnn[n].octave);
1082
1083                         for (k = n; k < ntnn; k++)
1084                                 tnn[k - 1] = tnn[k];
1085                         ntnn--;
1086                         n--;
1087                 }
1088         }
1089
1090         /*
1091          * Loop through the remaining notes, looking for conflicts, such as f
1092          * versus f#.  Because of the way the notes were generated, and because
1093          * of the previous loop, at this point any remaining conflicts will
1094          * consist of two notes, one fitting the key signature and one not.
1095          * Try to rewrite enharmonically the one that is not in the key sig.
1096          * The only problem that can arise is if there is a neighoring note in
1097          * the way.  Like, with f and f# in the key of 0 sharps, we'd like to
1098          * change f# to g&, but we can't if there's already a g.  So if this
1099          * happens, try to rewrite the other note (in this case, we'd get e#
1100          * and f#).  If there's already an e, give up and throw one note away.
1101          * Yes, we could rewrite g as a&& to make room, but this is so rare
1102          * that it's not worth the effort.
1103          */
1104         for (n = 1; n < ntnn; n++) {
1105                 if (tnn[n - 1].letter == tnn[n].letter &&
1106                     tnn[n - 1].octave == tnn[n].octave) {
1107                         /*
1108                          * We have a conflict.  See whether the notes next to
1109                          * the conflicting notes (if any) are on neighboring
1110                          * steps.
1111                          */
1112                         if (n > 1 && neighbor(&tnn[n - 2], &tnn[n - 1]) == YES)
1113                                 hightight = YES;
1114                         else
1115                                 hightight = NO;
1116
1117                         if (n < ntnn-1 && neighbor(&tnn[n], &tnn[n + 1]) == YES)
1118                                 lowtight = YES;
1119                         else
1120                                 lowtight = NO;
1121
1122                         /* remember which of the notes is in the key sig */
1123                         if (inkeysig(&tnn[n], sharps) == YES) {
1124                                 keysigidx = n;
1125                                 nonkeysigidx = n - 1;
1126                         } else {
1127                                 keysigidx = n - 1;
1128                                 nonkeysigidx = n;
1129                         }
1130
1131                         remnote = NO;   /* init to not remove any note */
1132
1133                         if (hightight == YES && lowtight == YES) {
1134                                 /* no room to move either note */
1135                                 remnote = YES;
1136                         } else if (hightight == YES) {
1137                                 /* no room to move high note; move low note */
1138                                 if (downletter(&tnn[n]) == NO) {
1139                                         /* can't move it */
1140                                         remnote = YES;
1141                                 }
1142                         } else if (lowtight == YES) {
1143                                 /* no room to move low note; move high note */
1144                                 if (upletter(&tnn[n - 1]) == NO) {
1145                                         /* can't move it */
1146                                         remnote = YES;
1147                                 }
1148                         } else {
1149                                 /* room on both sides */
1150                                 if (keysigidx == n) {
1151                                         /* try moving nonkeysig note first */
1152                                         if (upletter(&tnn[n - 1]) == NO &&
1153                                                 downletter(&tnn[n]) == NO) {
1154                                                         /* can't move either */
1155                                                         remnote = YES;
1156                                         }
1157                                 } else {
1158                                         /* try moving nonkeysig note first */
1159                                         if (downletter(&tnn[n]) == NO &&
1160                                                 upletter(&tnn[n - 1]) == NO) {
1161                                                         /* can't move either */
1162                                                         remnote = YES;
1163                                         }
1164                                 }
1165                         }
1166
1167                         /*
1168                          * We have to remove one of the two notes in this
1169                          * conflict.  Arbitrarily, remove the one that doesn't
1170                          * fit the key signature.
1171                          */
1172                         if (remnote == YES) {
1173                                 l_warning(tgs_p->inputfile, tgs_p->inputlineno,
1174                                 "throwing away note %c%c%d on tabnote staff due to conflict with %c%c%d",
1175                                                 tnn[nonkeysigidx].letter,
1176                                                 tnn[nonkeysigidx].accidental,
1177                                                 tnn[nonkeysigidx].octave,
1178                                                 tnn[keysigidx].letter,
1179                                                 tnn[keysigidx].accidental,
1180                                                 tnn[keysigidx].octave);
1181
1182                                 for (k = nonkeysigidx + 1; k < ntnn; k++)
1183                                         tnn[k - 1] = tnn[k];
1184                                 ntnn--;
1185                                 n--;
1186                         }
1187                 }
1188         }
1189
1190         /* find the tab GRPSYL following our tab GRPSYL, if there is one */
1191         mainll_p = mll_p;       /* save mll_p */
1192         nexttgs_p = nextgrpsyl(tgs_p, &mll_p);
1193
1194         /* find the tabnote GRPSYL preceding ours, if there is one */
1195         mll_p = mainll_p;       /* restore mll_p in case it was changed */
1196         prevngs_p = prevgrpsyl(ngs_p, &mll_p);
1197
1198         CALLOC(NOTE, ngs_p->notelist, ntnn);
1199         ngs_p->nnotes = (short)ntnn;
1200
1201         /*
1202          * Loop through the newly allocated notes, setting all their fields.
1203          */
1204         for (n = 0; n < ntnn; n++) {
1205                 newnote_p = &ngs_p->notelist[n];   /* set short cut pointer */
1206
1207                 /* allocate the array of coordinates */
1208                 MALLOCA(float, ngs_p->notelist[n].c, NUMCTYPE);
1209
1210                 /* copy the calculated letter/accidental/octave */
1211                 newnote_p->letter = tnn[n].letter;
1212                 newnote_p->accidental = tnn[n].accidental;
1213                 newnote_p->octave = tnn[n].octave;
1214
1215                 /* copy note size, except that prebend graces are always small*/
1216                 newnote_p->notesize = is_prebend == YES ?
1217                                 GS_SMALL : tnn[n].note_p->notesize;
1218
1219                 newnote_p->headshape = tnn[n].note_p->headshape;
1220                 newnote_p->tie = tnn[n].note_p->tie;
1221                 newnote_p->tiestyle = tnn[n].note_p->tiestyle;
1222
1223                 /* flag to draw curved line after notes */
1224                 if (combine)
1225                         newnote_p->smallbend = YES;
1226
1227                 /* copy whether note has paren; but if prebend, always set it*/
1228                 newnote_p->note_has_paren = tnn[n].note_p->note_has_paren;
1229                 if (is_prebend)
1230                         newnote_p->note_has_paren = YES;
1231
1232                 /*
1233                  * If this note has slur(s), allocate a slur-to list.  If a
1234                  * slur is to real frets, set the string number in the letter
1235                  * for now, and fix it up later when we know the true letter
1236                  * and octave.  If it's a slur to or from nowhere, copy over
1237                  * the "octave" (pseudo fret) as is.  The letter on these is
1238                  * meaningless.  Note:  a maximum of one slur can be to a real
1239                  * fret and a maximum of two slurs can exist.
1240                  */
1241                 if (tnn[n].note_p->nslurto != 0) {
1242                         newnote_p->nslurto = tnn[n].note_p->nslurto;
1243                         CALLOC(SLURTO, newnote_p->slurtolist,
1244                                         newnote_p->nslurto);
1245
1246                         for (k = 0; k < newnote_p->nslurto; k++) {
1247                                 s_p = &tnn[n].note_p->slurtolist[k];
1248
1249                                 if (IS_NOWHERE(s_p->octave)) {
1250                                         /* slur to or from nowhere */
1251                                         /* letter is meaningless */
1252                                         newnote_p->slurtolist[k].octave =
1253                                                         s_p->octave;
1254                                 } else {        /* real fret number */
1255                                         newnote_p->slurtolist[k].letter =
1256                                                         tnn[n].strno;
1257                                         newnote_p->slurtolist[k].octave =
1258                                                         NOFRET; /* unknown */
1259                                 }
1260
1261                                 /* always copy slur style */
1262                                 newnote_p->slurtolist[k].slurstyle =
1263                                         s_p->slurstyle;
1264                         }
1265                 }
1266
1267                 /*
1268                  * If we are a prebend note, allocate a slur-to list.
1269                  */
1270                 if (is_prebend) {
1271                         CALLOC(SLURTO, newnote_p->slurtolist, 1);
1272                         newnote_p->is_bend = YES;
1273                         newnote_p->nslurto = 1;
1274                         /*
1275                          * Although the bent-to note has been calculated, at
1276                          * this point in the code we don't know what it is.
1277                          * For now, we store the string number in the letter.
1278                          * When we are doing the next GRPSYL on this staff, we
1279                          * will change this to be the true bent-to letter, and
1280                          * set the octave too.
1281                          */
1282                         newnote_p->slurtolist[0].letter = tnn[n].strno;
1283                         newnote_p->slurtolist[0].octave = NOFRET;
1284                 }
1285
1286                 /*
1287                  * If we are not a prebend group (those are handled elsewhere)
1288                  * and our group was not formed by combining two tab groups
1289                  * and there is a next GRPSYL on the tablature staff (in this
1290                  * or the next measure), our note might be bent to a note in
1291                  * that next GRPSYL.  So search it to see if it contains a note
1292                  * that our current note is bent to.  If so, allocate a slur-to
1293                  * list.
1294                  */
1295                 if ( ! is_prebend && ! combine && nexttgs_p != 0) {
1296                         for (k = 0; k < nexttgs_p->nnotes; k++) {
1297                                 /*
1298                                  * Find matching string with a bend but either
1299                                  * no fret or else it has to be a null bend.
1300                                  * This eliminates finding a prebend.
1301                                  */
1302                                 if (nexttgs_p->notelist[k].STRINGNO == tnn[n].
1303                                     strno && HASBEND(nexttgs_p->notelist[k]) &&
1304                                     (nexttgs_p->notelist[k].FRETNO == NOFRET ||
1305                                     HASNULLBEND(nexttgs_p->notelist[k])))
1306                                         break;
1307                         }
1308                         if (k < nexttgs_p->nnotes) {
1309                                 if (newnote_p->nslurto != 0)
1310                                         pfatal("slur and bend on the same note [popnotes]");
1311
1312                                 CALLOC(SLURTO, newnote_p->slurtolist, 1);
1313                                 newnote_p->is_bend = YES;
1314                                 newnote_p->nslurto = 1;
1315                                 /*
1316                                  * We don't yet know what the bent-to note is
1317                                  * going to be.  For now, we store the string
1318                                  * number in the letter.  When we are doing the
1319                                  * next GRPSYL on this staff, we will change
1320                                  * this to be the true bent-to letter, and set
1321                                  * the octave too.
1322                                  */
1323                                 newnote_p->slurtolist[0].letter = tnn[n].strno;
1324                         }
1325                 }
1326
1327                 /*
1328                  * If we are not a prebend note and there is a previous GRPSYL
1329                  * on the tabnote staff (in this or the previous measure), our
1330                  * note may be the destination of a bend or a slur.  Try to
1331                  * find the note in the previous GRPSYL that bends or slurs to
1332                  * our note, if any.  If found, set its slur-to list correctly,
1333                  * now that we know what should be put in it.
1334                  */
1335                 if ( ! is_prebend && prevngs_p != 0) {
1336                         /*
1337                          * Check every note in the preceding group.  Don't
1338                          * break out after finding one, since multiple ones
1339                          * could slide to our note if our note was a duplicate
1340                          * (derived from multiple strings).  But there is a
1341                          * max of one slur/bend coming from each note.
1342                          */
1343                         for (k = 0; k < prevngs_p->nnotes; k++) {
1344                                 /* check every slur from that note */
1345                                 s_p = 0;        /* avoid 'used before set' */
1346                                 for (j = 0; j < prevngs_p->notelist[k].nslurto;
1347                                                 j++) {
1348                                         s_p = &prevngs_p->notelist[k].
1349                                                         slurtolist[j];
1350                                         if (s_p->letter == tnn[n].strno &&
1351                                             ! IS_NOWHERE(s_p->octave))
1352                                                 break;
1353                                 }
1354                                 /* if found a slur to our note */
1355                                 if (j < prevngs_p->notelist[k].nslurto) {
1356                                         s_p->letter = ngs_p->notelist[n].letter;
1357                                         s_p->octave = ngs_p->notelist[n].octave;
1358                                 }
1359                         }
1360                 }
1361         }
1362 }
1363 \f
1364 /*
1365  * Name:        neighbor()
1366  *
1367  * Abstract:    Find whether the given notes are on neighboring letters.
1368  *
1369  * Returns:     YES or NO
1370  *
1371  * Description: This function figures out whether the given notes are on
1372  *              neighboring letter, taking octaves into account.
1373  */
1374
1375 static int
1376 neighbor(high_p, low_p)
1377
1378 struct TABNOTENOTE *high_p;     /* the higher note */
1379 struct TABNOTENOTE *low_p;      /* the lower note */
1380
1381 {
1382         /* if the letter themselves aren't right, return NO */
1383         if (low_p->letter == 'g') {
1384                 if (high_p->letter != 'a')
1385                         return (NO);
1386         } else {
1387                 if (high_p->letter != low_p->letter + 1)
1388                         return (NO);
1389         }
1390
1391         /* if the octaves aren't right, return NO */
1392         if (low_p->letter == 'b') {
1393                 if (high_p->octave != low_p->octave + 1)
1394                         return (NO);
1395         } else {
1396                 if (high_p->octave != low_p->octave)
1397                         return (NO);
1398         }
1399
1400         return (YES);
1401 }
1402 \f
1403 /*
1404  * Name:        inkeysig()
1405  *
1406  * Abstract:    Find whether the given note fits the key signature.
1407  *
1408  * Returns:     YES or NO
1409  *
1410  * Description: This function figures out whether the given note fits the key
1411  *              signature, and returns the answer.
1412  */
1413
1414 static int
1415 inkeysig(note_p, sharps)
1416
1417 struct TABNOTENOTE *note_p;     /* note contained in a TABNOTENOTE structure */
1418 int sharps;                     /* current key signature */
1419
1420 {
1421         int circnum;            /* position in the circle of 5ths */
1422         int accnum;             /* B = 0, & = 1, n = 2, # = 3, x = 4 */
1423         int sharpness;          /* how "sharp" is the note */
1424
1425
1426         circnum = strchr(Circle, note_p->letter) - Circle;
1427         accnum = strchr(Acclets, note_p->accidental) - Acclets;
1428         sharpness = circnum + 7 * (accnum - 2);
1429
1430         if (sharpness >= sharps && sharpness <= sharps + 6)
1431                 return (YES);
1432         else
1433                 return (NO);
1434 }
1435 \f
1436 /*
1437  * Name:        upletter()
1438  *
1439  * Abstract:    Alter note enharmonically, incrementing the letter.
1440  *
1441  * Returns:     void
1442  *
1443  * Description: This function alters the given note enharmonically.  It raises
1444  *              the letter, and adjusts the accidental and octave as needed.
1445  */
1446
1447 static int
1448 upletter(note_p)
1449
1450 struct TABNOTENOTE *note_p;     /* note contained in a TABNOTENOTE structure */
1451
1452 {
1453         int accnum;             /* B = 0, & = 1, n = 2, # = 3, x = 4 */
1454
1455
1456         accnum = strchr(Acclets, note_p->accidental) - Acclets;
1457
1458         /*
1459          * If the old letter is e or b, the next higher white note is only a
1460          * half step away, so the accidental has to be a half step flatter.
1461          * Otherwise, it's a whole step.  If the result would be flatter than
1462          * a double flat, we can't do this, so return NO.
1463          */
1464         if (note_p->letter == 'e' || note_p->letter == 'b') {
1465                 if (accnum == 0)        /* double flat */
1466                         return (NO);
1467                 accnum--;
1468         } else {
1469                 if (accnum <= 1)        /* flat or double flat */
1470                         return (NO);
1471                 accnum -= 2;
1472         }
1473
1474         /* if the note is b, increment the octave; fail if impossible */
1475         if (note_p->letter == 'b') {
1476                 if (note_p->octave == MAXOCTAVE)
1477                         return (NO);
1478                 note_p->octave++;
1479         }
1480
1481         /* increment the letter; g wraps around to a */
1482         if (note_p->letter == 'g')
1483                 note_p->letter = 'a';
1484         else
1485                 note_p->letter++;
1486
1487         note_p->accidental = Acclets[accnum];
1488
1489         return (YES);
1490 }
1491 \f
1492 /*
1493  * Name:        downletter()
1494  *
1495  * Abstract:    Alter note enharmonically, decrementing the letter.
1496  *
1497  * Returns:     void
1498  *
1499  * Description: This function alters the given note enharmonically.  It lowers
1500  *              the letter, and adjusts the accidental and octave as needed.
1501  */
1502
1503 static int
1504 downletter(note_p)
1505
1506 struct TABNOTENOTE *note_p;     /* note contained in a TABNOTENOTE structure */
1507
1508 {
1509         int accnum;             /* B = 0, & = 1, n = 2, # = 3, x = 4 */
1510
1511
1512         accnum = strchr(Acclets, note_p->accidental) - Acclets;
1513
1514         /*
1515          * If the old letter is f or c, the next lower white note is only a
1516          * half step away, so the accidental has to be a half step sharper.
1517          * Otherwise, it's a whole step.  If the result would be sharper than
1518          * a double sharp, we can't do this, so return NO.
1519          */
1520         if (note_p->letter == 'f' || note_p->letter == 'c') {
1521                 if (accnum == 4)        /* double sharp */
1522                         return (NO);
1523                 accnum++;
1524         } else {
1525                 if (accnum >= 3)        /* sharp or double sharp */
1526                         return (NO);
1527                 accnum += 2;
1528         }
1529
1530         /* if the note is c, decrement the octave; fail if impossible */
1531         if (note_p->letter == 'c') {
1532                 if (note_p->octave == MINOCTAVE)
1533                         return (NO);
1534                 note_p->octave--;
1535         }
1536
1537         /* decrement the letter; a wraps around to g */
1538         if (note_p->letter == 'a')
1539                 note_p->letter = 'g';
1540         else
1541                 note_p->letter--;
1542
1543         note_p->accidental = Acclets[accnum];
1544
1545         return (YES);
1546 }
1547 \f
1548 /*
1549  * Name:        cleanaccs()
1550  *
1551  * Abstract:    Remove unnecessary accidentals from a tabnote staff measure.
1552  *
1553  * Returns:     void
1554  *
1555  * Description: This function removes all the unnecessary accidentals from one
1556  *              measure of a tabnote staff.  It takes into consideration the
1557  *              key signature and the fact that accidentals last for the
1558  *              duration of the measure unless changed by another accidental.
1559  *              Also, if a note in the first group was tied from the previous
1560  *              measure, any accidental is carried over to this note and
1561  *              any series of notes it ties into, but if the note occurs again
1562  *              in this measure it reverts to the key signature; so the bottom
1563  *              line is we can ignore this and pretend that the tied note is in
1564  *              the key signature.
1565  */
1566
1567 static void
1568 cleanaccs(gs_p, mll_p)
1569
1570 struct GRPSYL *gs_p;            /* starts at first tabnote GRPSYL */
1571 struct MAINLL *mll_p;           /* main LL struct that tabnote staff hangs off*/
1572
1573 {
1574         /* current accidental for letter and octave */
1575         char curacc[7][MAXOCTAVE + 1];  /* assumes MINOCTAVE == 0 */
1576
1577         int oct;                /* octave number */
1578         char let;               /* note letter */
1579         int sharps;             /* number of sharps in tabnote staff's keysig*/
1580         int cidx;               /* index into circle of fifths */
1581         struct GRPSYL *prevgs_p;/* pointer to preceding GRPSYL */
1582         struct NOTE *note_p;    /* pointer to a NOTE structure */
1583         int n, k;               /* loop variables */
1584
1585
1586
1587         /*
1588          * Initialize the table to say that for all octaves of all letters,
1589          * the accidental is a natural.
1590          */
1591         for (oct = 0; oct <= MAXOCTAVE; oct++) {
1592                 for (let = 'a'; let <= 'g'; let++) {
1593                         curacc[let - 'a'] [oct] = 'n';
1594                 }
1595         }
1596
1597         /* find the key signature; flats count negative */
1598         sharps = svpath(gs_p->staffno, SHARPS)->sharps;
1599
1600         /*
1601          * Load the key signature's accidentals into the array for every
1602          * octave.
1603          */
1604         for (oct = 0; oct <= 9; oct++) {
1605                 for (cidx = 0; cidx < sharps; cidx++) {
1606                         curacc[ Circle[cidx] - 'a' ] [oct] = '#';
1607                 }
1608                 for (cidx = 0; cidx > sharps; cidx--) {
1609                         curacc[ Circle[6 + cidx] - 'a' ] [oct] = '&';
1610                 }
1611         }
1612
1613         /*
1614          * Loop through every note group and every note in them, clearing
1615          * accidentals when that accidental is already in force, and updating
1616          * the table when not.
1617          */
1618         for ( ; gs_p != 0; gs_p = gs_p->next) {
1619                 if (gs_p->grpcont != GC_NOTES)
1620                         continue;
1621
1622                 /* find previous group; could be in previous measure if any */
1623                 prevgs_p = prevgrpsyl(gs_p, &mll_p);
1624
1625                 for (n = 0; n < gs_p->nnotes; n++) {
1626                         note_p = &gs_p->notelist[n];
1627
1628                         /*
1629                          * If the note is the destination of a tie, blow away
1630                          * its accidental.  This wouldn't have to be a special
1631                          * check if it weren't for ties across bar lines.
1632                          */
1633                         if (prevgs_p != 0 && prevgs_p->grpcont == GC_NOTES) {
1634                                 for (k = 0; k < prevgs_p->nnotes; k++) {
1635                                         if (prevgs_p->notelist[k].tie == YES &&
1636                                             prevgs_p->notelist[k].letter ==
1637                                             note_p->letter && prevgs_p->notelist
1638                                             [k].octave == note_p->octave) {
1639                                                 note_p->accidental = '\0';
1640                                                 break;
1641                                         }
1642                                 }
1643                                 /* if we found it was tied, continue to next */
1644                                 if (k < prevgs_p->nnotes)
1645                                         continue;
1646                         }
1647                         /*
1648                          * If this note's accidental agrees with the accidental
1649                          * already in force for this letter and octave, wipe it
1650                          * out.  If it doesn't, leave it alone, and update the
1651                          * table to show the new accidental that is in force.
1652                          */
1653                         if (note_p->accidental == curacc[ note_p->letter - 'a' ]
1654                                          [ note_p->octave ]) {
1655                                 note_p->accidental = '\0';
1656                         } else {
1657                                 curacc[ note_p->letter - 'a' ] [ note_p->
1658                                                 octave ] = note_p->accidental;
1659                         }
1660                 }
1661         }
1662 }