PageRenderTime 72ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/branch/robo-ops/contrib/libmodplug/src/load_abc.cpp

#
C++ | 2649 lines | 2431 code | 110 blank | 108 comment | 614 complexity | a6147e7c023578ae49fe217a8371621b MD5 | raw file
Possible License(s): GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. MikMod Sound System
  3. By Jake Stine of Divine Entertainment (1996-2000)
  4. Support:
  5. If you find problems with this code, send mail to:
  6. air@divent.org
  7. Distribution / Code rights:
  8. Use this source code in any fashion you see fit. Giving me credit where
  9. credit is due is optional, depending on your own levels of integrity and
  10. honesty.
  11. -----------------------------------------
  12. Module: LOAD_ABC
  13. ABC module loader.
  14. by Peter Grootswagers (2006)
  15. <email:pgrootswagers@planet.nl>
  16. Portability:
  17. All systems - all compilers (hopefully)
  18. */
  19. #include <stdlib.h>
  20. #include <time.h>
  21. #include <string.h>
  22. #include <math.h>
  23. #include <ctype.h>
  24. #ifdef NEWMIKMOD
  25. #include "mikmod.h"
  26. #include "uniform.h"
  27. typedef UBYTE BYTE;
  28. typedef UWORD WORD;
  29. #else
  30. #include "stdafx.h"
  31. #include "sndfile.h"
  32. #endif
  33. #include "load_pat.h"
  34. #define MAXABCINCLUDES 8
  35. #define MAXCHORDNAMES 80
  36. #define ABC_ENV_DUMPTRACKS "MMABC_DUMPTRACKS"
  37. #define ABC_ENV_NORANDOMPICK "MMABC_NO_RANDOM_PICK"
  38. // gchords use tracks with vpos 1 thru 7
  39. // drums use track with vpos 8
  40. // voice chords use vpos 0 and vpos from 11 up
  41. #define GCHORDBPOS 1
  42. #define GCHORDFPOS 2
  43. #define GCHORDCPOS 3
  44. #define DRUMPOS 8
  45. #define DRONEPOS1 9
  46. #define DRONEPOS2 10
  47. // in the patterns a whole note at unmodified tempo is 16 rows
  48. #define ROWSPERNOTE 16
  49. // a 1/64-th note played in triool equals a 1/96-th note, to be able
  50. // to play them and also to play the 1/64-th we need a resolution of 192
  51. // because 2/192 = 1/96 and 3/192 = 1/64
  52. #define RESOLUTION 192
  53. #pragma pack(1)
  54. /**************************************************************************
  55. **************************************************************************/
  56. #ifdef NEWMIKMOD
  57. static char ABC_Version[] = "ABC+2.0 (draft IV)";
  58. #endif
  59. typedef enum {
  60. note,
  61. octave,
  62. smpno,
  63. volume,
  64. effect,
  65. effoper
  66. } ABCEVENT_X_NOTE;
  67. typedef enum {
  68. none,
  69. trill,
  70. bow,
  71. accent
  72. } ABCEVENT_X_EFFECT;
  73. typedef enum {
  74. cmdflag,
  75. command,
  76. chordnum,
  77. chordnote,
  78. chordbase,
  79. jumptype
  80. } ABCEVENT_X_CMD;
  81. typedef enum {
  82. cmdsegno = '$',
  83. cmdcapo = 'B',
  84. cmdchord = 'C',
  85. cmdfine = 'F',
  86. cmdhide = 'H',
  87. cmdjump = 'J',
  88. cmdloop = 'L',
  89. cmdcoda = 'O',
  90. cmdpartbrk = 'P',
  91. cmdsync = 'S',
  92. cmdtempo = 'T',
  93. cmdvariant = 'V',
  94. cmdtocoda = 'X'
  95. } ABCEVENT_CMD;
  96. typedef enum {
  97. jumpnormal,
  98. jumpfade,
  99. jumpdacapo,
  100. jumpdcfade,
  101. jumpdasegno,
  102. jumpdsfade,
  103. jumpfine,
  104. jumptocoda,
  105. jumpvariant,
  106. jumpnot
  107. } ABCEVENT_JUMPTYPE;
  108. typedef struct _ABCEVENT
  109. {
  110. struct _ABCEVENT *next;
  111. ULONG tracktick;
  112. union {
  113. BYTE par[6];
  114. struct {
  115. BYTE flg;
  116. BYTE cmd;
  117. ULONG lpar; // for variant selections, bit pattern
  118. };
  119. };
  120. BYTE part;
  121. BYTE tiednote;
  122. } ABCEVENT;
  123. typedef struct _ABCTRACK
  124. {
  125. struct _ABCTRACK *next;
  126. ABCEVENT *head;
  127. ABCEVENT *tail;
  128. ABCEVENT *capostart;
  129. ABCEVENT *tienote;
  130. int transpose;
  131. int octave_shift;
  132. ULONG slidevoltime; // for crescendo and diminuendo
  133. int slidevol; // -2:fade away, -1:diminuendo, 0:none, +1:crescendo
  134. BYTE vno; // 0 is track is free for use, from previous song in multi-songbook
  135. BYTE vpos; // 0 is main voice, other is subtrack for gchords, gchords or drumnotes
  136. BYTE tiedvpos;
  137. BYTE mute;
  138. BYTE chan; // 10 is percussion channel, any other is melodic channel
  139. BYTE volume;
  140. BYTE instr; // current instrument for this track
  141. BYTE legato;
  142. char v[22]; // first twenty characters are significant
  143. } ABCTRACK;
  144. typedef struct _ABCMACRO
  145. {
  146. struct _ABCMACRO *next;
  147. char *name;
  148. char *subst;
  149. char *n;
  150. } ABCMACRO;
  151. /**************************************************************************
  152. **************************************************************************/
  153. typedef struct _ABCHANDLE
  154. {
  155. #ifdef NEWMIKMOD
  156. MM_ALLOC *allochandle;
  157. MM_ALLOC *macrohandle;
  158. MM_ALLOC *trackhandle;
  159. MM_ALLOC *ho;
  160. #endif
  161. ABCMACRO *macro;
  162. ABCMACRO *umacro;
  163. ABCTRACK *track;
  164. long int pickrandom;
  165. unsigned int len;
  166. int speed;
  167. char *line;
  168. char *beatstring;
  169. BYTE beat[4]; // a:first note, b:strong notes, c:weak notes, n:strong note every n
  170. char gchord[80]; // last setting for gchord
  171. char drum[80]; // last setting for drum
  172. char drumins[80]; // last setting for drum
  173. char drumvol[80]; // last setting for drum
  174. ULONG barticks;
  175. // parse variables, declared here to avoid parameter pollution
  176. int abcchordvol, abcchordprog, abcbassvol, abcbassprog;
  177. int ktrans;
  178. int drumon, gchordon, droneon;
  179. int dronegm, dronepitch[2], dronevol[2];
  180. ABCTRACK *tp, *tpc, *tpr;
  181. ULONG tracktime;
  182. } ABCHANDLE;
  183. static int global_voiceno, global_octave_shift, global_tempo_factor, global_tempo_divider;
  184. static char global_part;
  185. static ULONG global_songstart;
  186. /* Named guitar chords */
  187. static char chordname[MAXCHORDNAMES][8];
  188. static int chordnotes[MAXCHORDNAMES][6];
  189. static int chordlen[MAXCHORDNAMES];
  190. static int chordsnamed = 0;
  191. static const char *sig[] = {
  192. " C D EF G A Bc d ef g a b", // 7 sharps C#
  193. " C D EF G AB c d ef g ab ", // 6 sharps F#
  194. " C DE F G AB c de f g ab ", // 5 sharps B
  195. " C DE F GA B c de f ga b ", // 4 sharps E
  196. " CD E F GA B cd e f ga b ", // 3 sharps A
  197. " CD E FG A B cd e fg a b ", // 2 sharps D
  198. " C D E FG A Bc d e fg a b", // 1 sharps G
  199. " C D EF G A Bc d ef g a b", // 0 sharps C
  200. " C D EF G AB c d ef g ab ", // 1 flats F
  201. " C DE F G AB c de f g ab ", // 2 flats Bb
  202. " C DE F GA B c de f ga b ", // 3 flats Eb
  203. " CD E F GA B cd e f ga b ", // 4 flats Ab
  204. " CD E FG A B cd e fg a b ", // 5 flats Db
  205. "C D E FG A Bc d e fg a b ", // 6 flats Gb
  206. "C D EF G A Bc d ef g a b ", // 7 flats Cb
  207. // 0123456789012345678901234
  208. };
  209. static const char *keySigs[] = {
  210. /* 0....:....1....:....2....:....3....:....4....:....5. */
  211. "7 sharps: C# A#m G#Mix D#Dor E#Phr F#Lyd B#Loc ",
  212. "6 sharps: F# D#m C#Mix G#Dor A#Phr BLyd E#Loc ",
  213. "5 sharps: B G#m F#Mix C#Dor D#Phr ELyd A#Loc ",
  214. "4 sharps: E C#m BMix F#Dor G#Phr ALyd D#Loc ",
  215. "3 sharps: A F#m EMix BDor C#Phr DLyd G#Loc ",
  216. "2 sharps: D Bm AMix EDor F#Phr GLyd C#Loc ",
  217. "1 sharp : G Em DMix ADor BPhr CLyd F#Loc ",
  218. "0 sharps: C Am GMix DDor EPhr FLyd BLoc ",
  219. "1 flat : F Dm CMix GDor APhr BbLyd ELoc ",
  220. "2 flats : Bb Gm FMix CDor DPhr EbLyd ALoc ",
  221. "3 flats : Eb Cm BbMix FDor GPhr AbLyd DLoc ",
  222. "4 flats : Ab Fm EbMix BbDor CPhr DbLyd GLoc ",
  223. "5 flats : Db Bbm AbMix EbDor FPhr GbLyd CLoc ",
  224. "6 flats : Gb Ebm DbMix AbDor BbPhr CbLyd FLoc ",
  225. "7 flats : Cb Abm GbMix DbDor EbPhr FbLyd BbLoc ",
  226. 0
  227. };
  228. // local prototypes
  229. static int abc_getnumber(const char *p, int *number);
  230. static ABCTRACK *abc_locate_track(ABCHANDLE *h, const char *voice, int pos);
  231. static void abc_add_event(ABCHANDLE *h, ABCTRACK *tp, ABCEVENT *e);
  232. static void abc_add_setloop(ABCHANDLE *h, ABCTRACK *tp, ULONG tracktime);
  233. static void abc_add_setjumploop(ABCHANDLE *h, ABCTRACK *tp, ULONG tracktime, ABCEVENT_JUMPTYPE j);
  234. static ULONG abc_pattracktime(ABCHANDLE *h, ULONG tracktime);
  235. static int abc_patno(ABCHANDLE *h, ULONG tracktime);
  236. static void abc_message(const char *s1, const char *s2)
  237. {
  238. char txt[256];
  239. if( strlen(s1) + strlen(s2) > 255 ) return;
  240. sprintf(txt, s1, s2);
  241. #ifdef NEWMIKMOD
  242. _mmlog(txt);
  243. #else
  244. fprintf(stderr, "load_abc > %s\n", txt);
  245. #endif
  246. }
  247. static ULONG modticks(ULONG abcticks)
  248. {
  249. return abcticks / RESOLUTION;
  250. }
  251. static ULONG abcticks(ULONG modticks)
  252. {
  253. return modticks * RESOLUTION;
  254. }
  255. static ULONG notelen_notediv_to_ticks(int speed, int len, int div)
  256. {
  257. ULONG u;
  258. u = (ROWSPERNOTE * RESOLUTION * speed * len * global_tempo_factor) / (div * global_tempo_divider);
  259. return u;
  260. }
  261. static void abc_dumptracks(ABCHANDLE *h, const char *p)
  262. {
  263. ABCTRACK *t;
  264. ABCEVENT *e;
  265. int n,pat,row,tck;
  266. char nn[3];
  267. if( !h ) return;
  268. for( t=h->track; t; t=t->next ) {
  269. printf("track %d.%d chan=%d %s\n", (int)(t->vno), (int)(t->vpos),
  270. (int)(t->chan), (char *)(t->v));
  271. if( strcmp(p,"nonotes") )
  272. n = 1;
  273. else
  274. n = 0;
  275. for( e=t->head; e; e=e->next ) {
  276. tck = modticks(e->tracktick);
  277. row = tck / h->speed;
  278. pat = row / 64;
  279. tck = tck % h->speed;
  280. row = row % 64;
  281. nn[0] = ( e->tracktick % abcticks(h->speed * 64) ) ? ' ': '-';
  282. if( e->flg == 1 ) {
  283. printf(" %6d.%02d.%d%c%c %d.%d %s ",
  284. pat, row, tck, nn[0], (int)(e->part), (int)(t->vno),
  285. (int)(t->vpos), (char *)(t->v));
  286. if( e->cmd == cmdchord ) {
  287. nn[0] = "CCCDDEFFGGAABccddeffggaabb"[e->par[chordnote]];
  288. nn[1] = "b # # # # # # # # # # #"[e->par[chordnote]];
  289. nn[2] = '\0';
  290. if( isspace(nn[1]) ) nn[1] = '\0';
  291. printf("CMD %c: gchord %s%s",
  292. (char)(e->cmd), nn, chordname[e->par[chordnum]]);
  293. if( e->par[chordbase] != e->par[chordnote] ) {
  294. nn[0] = "CCCDDEFFGGAABccddeffggaabb"[e->par[chordbase]];
  295. nn[1] = "b # # # # # # # # # # #"[e->par[chordbase]];
  296. nn[2] = '\0';
  297. printf("/%s", nn);
  298. }
  299. printf("\n");
  300. }
  301. else
  302. printf("CMD %c @%p 0x%08lX\n",
  303. (char)(e->cmd), e,
  304. (unsigned long)(e->lpar));
  305. if( strcmp(p,"nonotes") )
  306. n = 1;
  307. else
  308. n = 0;
  309. }
  310. else if( n ) {
  311. printf(" %6d.%02d.%d%c%c %d.%d %s ", pat, row, tck, nn[0], e->part, t->vno, t->vpos, t->v);
  312. if( e->par[note] ) {
  313. nn[0] = "CCCDDEFFGGAABccddeffggaabb"[e->par[note]-23];
  314. nn[1] = "b # # # # # # # # # # #"[e->par[note]-23];
  315. nn[2] = '\0';
  316. }
  317. else strcpy(nn,"--");
  318. printf("NOTE %s octave %d inst %s vol %03d\n",
  319. nn, e->par[octave], pat_gm_name(pat_smptogm(e->par[smpno])),e->par[volume]);
  320. if( strcmp(p,"all") )
  321. n = 0;
  322. }
  323. }
  324. }
  325. }
  326. #ifdef NEWMIKMOD
  327. #define MMFILE MMSTREAM
  328. #define mmfgetc(x) _mm_read_SBYTE(x)
  329. #define mmfeof(x) _mm_feof(x)
  330. #define mmfgets(buf,sz,f) _mm_fgets(f,buf,sz)
  331. #define mmftell(x) _mm_ftell(x)
  332. #define mmfseek(f,p,w) _mm_fseek(f,p,w)
  333. #define mmfopen(s,m) _mm_fopen(s,m)
  334. #define mmfclose(f) _mm_fclose(f)
  335. #else
  336. #define MMSTREAM FILE
  337. #define _mm_fopen(name,mode) fopen(name,mode)
  338. #define _mm_fgets(f,buf,sz) fgets(buf,sz,f)
  339. #define _mm_fseek(f,pos,whence) fseek(f,pos,whence)
  340. #define _mm_ftell(f) ftell(f)
  341. #define _mm_read_UBYTES(buf,sz,f) fread(buf,sz,1,f)
  342. #define _mm_read_SBYTES(buf,sz,f) fread(buf,sz,1,f)
  343. #define _mm_feof(f) feof(f)
  344. #define _mm_fclose(f) fclose(f)
  345. #define DupStr(h,buf,sz) strdup(buf)
  346. #define _mm_calloc(h,n,sz) calloc(n,sz)
  347. #define _mm_recalloc(h,buf,sz,elsz) realloc(buf,sz)
  348. #define _mm_free(h,p) free(p)
  349. typedef struct {
  350. char *mm;
  351. int sz;
  352. int pos;
  353. } MMFILE;
  354. static MMFILE *mmfopen(const char *name, const char *mode)
  355. {
  356. FILE *fp;
  357. MMFILE *mmfile;
  358. long len;
  359. if( *mode != 'r' ) return NULL;
  360. fp = fopen(name, mode);
  361. if( !fp ) return NULL;
  362. fseek(fp, 0, SEEK_END);
  363. len = ftell(fp);
  364. mmfile = (MMFILE *)malloc(len+sizeof(MMFILE));
  365. if( !mmfile ) return NULL;
  366. fseek(fp, 0, SEEK_SET);
  367. fread(&mmfile[1],1,len,fp);
  368. fclose(fp);
  369. mmfile->mm = (char *)&mmfile[1];
  370. mmfile->sz = len;
  371. mmfile->pos = 0;
  372. return mmfile;
  373. }
  374. static void mmfclose(MMFILE *mmfile)
  375. {
  376. free(mmfile);
  377. }
  378. static bool mmfeof(MMFILE *mmfile)
  379. {
  380. if( mmfile->pos < 0 ) return TRUE;
  381. if( mmfile->pos < mmfile->sz ) return FALSE;
  382. return TRUE;
  383. }
  384. static int mmfgetc(MMFILE *mmfile)
  385. {
  386. int b;
  387. if( mmfeof(mmfile) ) return EOF;
  388. b = mmfile->mm[mmfile->pos];
  389. mmfile->pos++;
  390. if( b=='\r' && mmfile->mm[mmfile->pos] == '\n' ) {
  391. b = '\n';
  392. mmfile->pos++;
  393. }
  394. return b;
  395. }
  396. static void mmfgets(char buf[], unsigned int bufsz, MMFILE *mmfile)
  397. {
  398. int i,b;
  399. for( i=0; i<(int)bufsz-1; i++ ) {
  400. b = mmfgetc(mmfile);
  401. if( b==EOF ) break;
  402. buf[i] = b;
  403. if( b == '\n' ) break;
  404. }
  405. buf[i] = '\0';
  406. }
  407. static long mmftell(MMFILE *mmfile)
  408. {
  409. return mmfile->pos;
  410. }
  411. static void mmfseek(MMFILE *mmfile, long p, int whence)
  412. {
  413. switch(whence) {
  414. case SEEK_SET:
  415. mmfile->pos = p;
  416. break;
  417. case SEEK_CUR:
  418. mmfile->pos += p;
  419. break;
  420. case SEEK_END:
  421. mmfile->pos = mmfile->sz + p;
  422. break;
  423. }
  424. }
  425. #endif
  426. // =====================================================================================
  427. static ABCEVENT *abc_new_event(ABCHANDLE *h, ULONG abctick, const char data[])
  428. // =====================================================================================
  429. {
  430. ABCEVENT *retval;
  431. int i;
  432. retval = (ABCEVENT *)_mm_calloc(h->trackhandle, 1,sizeof(ABCEVENT));
  433. retval->next = NULL;
  434. retval->tracktick = abctick;
  435. for( i=0; i<6; i++ )
  436. retval->par[i] = data[i];
  437. retval->part = global_part;
  438. retval->tiednote = 0;
  439. return retval;
  440. }
  441. // =============================================================================
  442. static ABCEVENT *abc_copy_event(ABCHANDLE *h, ABCEVENT *se)
  443. // =============================================================================
  444. {
  445. ABCEVENT *e;
  446. e = (ABCEVENT *)_mm_calloc(h->trackhandle, 1,sizeof(ABCEVENT));
  447. e->next = NULL;
  448. e->tracktick = se->tracktick;
  449. e->flg = se->flg;
  450. e->cmd = se->cmd;
  451. e->lpar = se->lpar;
  452. e->part = se->part;
  453. return e;
  454. }
  455. // =============================================================================
  456. static void abc_new_macro(ABCHANDLE *h, const char *m)
  457. // =============================================================================
  458. {
  459. ABCMACRO *retval;
  460. const char *p;
  461. char buf[256],*q;
  462. for( p=m; *p && isspace(*p); p++ ) ;
  463. for( q=buf; *p && *p != '='; p++ )
  464. *q++ = *p;
  465. if( q != buf )
  466. while( isspace(q[-1]) ) q--;
  467. *q = '\0';
  468. retval = (ABCMACRO *)_mm_calloc(h->macrohandle, 1,sizeof(ABCTRACK));
  469. retval->name = DupStr(h->macrohandle, buf,strlen(buf));
  470. retval->n = strrchr(retval->name, 'n'); // for transposing macro's
  471. for( p++; *p && isspace(*p); p++ ) ;
  472. strncpy(buf,p,200);
  473. for( q=&buf[strlen(buf)-1]; q!=buf && isspace(*q); q-- ) *q = '\0';
  474. retval->subst = DupStr(h->macrohandle, buf, strlen(buf));
  475. retval->next = h->macro;
  476. h->macro = retval;
  477. }
  478. // =============================================================================
  479. static void abc_new_umacro(ABCHANDLE *h, const char *m)
  480. // =============================================================================
  481. {
  482. ABCMACRO *retval, *mp;
  483. const char *p;
  484. char buf[256], let[2], *q;
  485. for( p=m; *p && isspace(*p); p++ ) ;
  486. for( q=buf; *p && *p != '='; p++ )
  487. *q++ = *p;
  488. if( q != buf )
  489. while( isspace(q[-1]) ) q--;
  490. *q = '\0';
  491. if( strlen(buf) > 1 || strchr("~HIJKLMNOPQRSTUVWXY",toupper(buf[0])) == 0 || strchr("xy",buf[0]) ) return;
  492. strcpy(let,buf);
  493. for( p++; *p && isspace(*p); p++ ) ;
  494. strncpy(buf,p,200);
  495. for( q=&buf[strlen(buf)-1]; q!=buf && isspace(*q); q-- ) *q = '\0';
  496. for( q=buf; *q; q++ ) if( *q == '!' ) *q = '+'; // translate oldstyle to newstyle
  497. if( !strcmp(buf,"+nil+") ) { // delete a macro
  498. mp = NULL;
  499. for( retval=h->umacro; retval; retval = retval->next ) {
  500. if( retval->name[0] == let[0] ) { // delete this one
  501. if( mp ) mp->next = retval->next;
  502. else h->umacro = retval->next;
  503. _mm_free(h->macrohandle, retval);
  504. return;
  505. }
  506. mp = retval;
  507. }
  508. return;
  509. }
  510. retval = (ABCMACRO *)_mm_calloc(h->macrohandle, 1,sizeof(ABCTRACK));
  511. retval->name = DupStr(h->macrohandle, let,1);
  512. retval->subst = DupStr(h->macrohandle, buf, strlen(buf));
  513. retval->n = 0;
  514. retval->next = h->umacro; // by placing it up front we mask out the old macro until we +nil+ it
  515. h->umacro = retval;
  516. }
  517. // =============================================================================
  518. static ABCTRACK *abc_new_track(ABCHANDLE *h, const char *voice, int pos)
  519. // =============================================================================
  520. {
  521. ABCTRACK *retval;
  522. if( !pos ) global_voiceno++;
  523. retval = (ABCTRACK *)_mm_calloc(h->trackhandle, 1,sizeof(ABCTRACK));
  524. retval->next = NULL;
  525. retval->vno = global_voiceno;
  526. retval->vpos = pos;
  527. retval->tiedvpos = pos;
  528. retval->instr = 1;
  529. strncpy(retval->v, voice, 20);
  530. retval->v[20] = '\0';
  531. retval->head = NULL;
  532. retval->tail = NULL;
  533. retval->capostart = NULL;
  534. retval->tienote = NULL;
  535. retval->mute = 0;
  536. retval->chan = 0;
  537. retval->transpose = 0;
  538. retval->volume = h->track? h->track->volume: 120;
  539. retval->slidevoltime = 0;
  540. retval->slidevol = 0;
  541. retval->legato = 0;
  542. return retval;
  543. }
  544. static int abc_numtracks(ABCHANDLE *h)
  545. {
  546. int n;
  547. ABCTRACK *t;
  548. n=0;
  549. for( t = h->track; t; t=t->next )
  550. n++;
  551. return n;
  552. }
  553. static int abc_interval(const char *s, const char *d)
  554. {
  555. const char *p;
  556. int i,j,k;
  557. int n,oct,m[2];
  558. for( j=0; j<2; j++ ) {
  559. if( j ) p = d;
  560. else p = s;
  561. switch(p[0]) {
  562. case '^':
  563. n = p[1];
  564. i = 2;
  565. break;
  566. case '_':
  567. n = p[1];
  568. i = 2;
  569. break;
  570. case '=':
  571. n = p[1];
  572. i = 2;
  573. break;
  574. default:
  575. n = p[0];
  576. i = 1;
  577. break;
  578. }
  579. for( k=0; k<25; k++ )
  580. if( n == sig[7][k] )
  581. break;
  582. oct = 4; // ABC note pitch C is C4 and pitch c is C5
  583. if( k > 12 ) {
  584. oct++;
  585. k -= 12;
  586. }
  587. while( p[i] == ',' || p[i] == '\'' ) {
  588. if( p[i] == ',' )
  589. oct--;
  590. else
  591. oct++;
  592. i++;
  593. }
  594. m[j] = k + 12 * oct;
  595. }
  596. return m[0] - m[1];
  597. }
  598. static int abc_transpose(const char *v)
  599. {
  600. int i,j,t;
  601. const char *m = "B", *mv = "";
  602. t = 0;
  603. global_octave_shift = 99;
  604. for( ; *v && *v != ']'; v++ ) {
  605. if( !strncasecmp(v,"t=",2) ) {
  606. v+=2;
  607. if( *v=='-' ) {
  608. j = -1;
  609. v++;
  610. }
  611. else j = 1;
  612. v+=abc_getnumber(v,&i);
  613. t += i * j;
  614. global_octave_shift = 0;
  615. }
  616. if( !strncasecmp(v,"octave=",7) ) {
  617. v+=7;
  618. if( *v=='-' ) {
  619. j = -1;
  620. v++;
  621. }
  622. else j = 1;
  623. v+=abc_getnumber(v,&i);
  624. t += i * j * 12;
  625. global_octave_shift = 0;
  626. }
  627. if( !strncasecmp(v,"transpose=",10) ) {
  628. v+=10;
  629. if( *v=='-' ) {
  630. j = -1;
  631. v++;
  632. }
  633. else j = 1;
  634. v+=abc_getnumber(v,&i);
  635. t += i * j;
  636. global_octave_shift = 0;
  637. }
  638. if( !strncasecmp(v,"octave=",7) ) { // used in kv304*.abc
  639. v+=7;
  640. if( *v=='-' ) {
  641. j = -1;
  642. v++;
  643. }
  644. else j = 1;
  645. v+=abc_getnumber(v,&i);
  646. t += i * j * 12;
  647. global_octave_shift = 0;
  648. }
  649. if( !strncasecmp(v,"m=",2) ) {
  650. v += 2;
  651. mv = v; // get the pitch for the middle staff line
  652. while( *v && *v != ' ' && *v != ']' ) v++;
  653. global_octave_shift = 0;
  654. }
  655. if( !strncasecmp(v,"middle=",7) ) {
  656. v += 7;
  657. mv = v; // get the pitch for the middle staff line
  658. while( *v && *v != ' ' && *v != ']' ) v++;
  659. global_octave_shift = 0;
  660. }
  661. if( !strncasecmp(v,"clef=",5) )
  662. v += 5;
  663. j = 1;
  664. if( !strncasecmp(v,"treble",6) ) {
  665. j = 0;
  666. v += 6;
  667. switch( *v ) {
  668. case '1': v++; m = "d"; break;
  669. case '2': v++;
  670. default: m = "B"; break;
  671. case '3': v++; m = "G"; break;
  672. case '4': v++; m = "E"; break;
  673. case '5': v++; m = "C"; break;
  674. }
  675. global_octave_shift = 0;
  676. }
  677. if( j && !strncasecmp(v,"bass",4) ) {
  678. m = "D,";
  679. j = 0;
  680. v += 4;
  681. switch( *v ) {
  682. case '1': v++; m = "C"; break;
  683. case '2': v++; m = "A,"; break;
  684. case '3': v++; m = "F,"; break;
  685. case '4': v++;
  686. default: m = "D,"; break;
  687. case '5': v++; m = "B,,"; break;
  688. }
  689. if( global_octave_shift == 99 )
  690. global_octave_shift = -2;
  691. }
  692. if( j && !strncasecmp(v,"tenor",5) ) {
  693. j = 0;
  694. v += 5;
  695. switch( *v ) {
  696. case '1': v++; m = "G"; break;
  697. case '2': v++; m = "E"; break;
  698. case '3': v++; m = "C"; break;
  699. case '4': v++;
  700. default: m = "A,"; break;
  701. case '5': v++; m = "F,"; break;
  702. }
  703. if( global_octave_shift == 99 )
  704. global_octave_shift = 1;
  705. }
  706. if( j && !strncasecmp(v,"alto",4) ) {
  707. j = 0;
  708. v += 4;
  709. switch( *v ) {
  710. case '1': v++; m = "G"; break;
  711. case '2': v++; m = "E"; break;
  712. case '3': v++;
  713. default: m = "C"; break;
  714. case '4': v++; m = "A,"; break;
  715. case '5': v++; m = "F,"; break;
  716. }
  717. if( global_octave_shift == 99 )
  718. global_octave_shift = 1;
  719. }
  720. if( j && strchr("+-",*v) && *v && v[1]=='8' ) {
  721. switch(*v) {
  722. case '+':
  723. t += 12;
  724. break;
  725. case '-':
  726. t -= 12;
  727. break;
  728. }
  729. v += 2;
  730. if( !strncasecmp(v,"va",2) ) v += 2;
  731. global_octave_shift = 0;
  732. j = 0;
  733. }
  734. if( j ) {
  735. while( *v && *v != ' ' && *v != ']' ) v++;
  736. }
  737. }
  738. if( strlen(mv) > 0 ) // someone set the middle note
  739. t += abc_interval(mv, m);
  740. if( global_octave_shift == 99 )
  741. global_octave_shift = 0;
  742. return t;
  743. }
  744. // =============================================================================
  745. static ABCTRACK *abc_locate_track(ABCHANDLE *h, const char *voice, int pos)
  746. // =============================================================================
  747. {
  748. ABCTRACK *tr, *prev, *trunused;
  749. char vc[21];
  750. int i, trans=0, voiceno=0, instrno = 1, channo = 0;
  751. for( ; *voice == ' '; voice++ ) ; // skip leading spaces
  752. for( i=0; *voice && *voice != ']' && *voice != '%' && !isspace(*voice); voice++ ) // can work with inline voice instructions
  753. vc[i++] = *voice;
  754. vc[i] = '\0';
  755. prev = NULL;
  756. trunused = NULL;
  757. if( !pos ) trans = abc_transpose(voice);
  758. for( tr=h->track; tr; tr=tr->next ) {
  759. if( tr->vno == 0 ) {
  760. if( !trunused ) trunused = tr; // must reuse mastertrack (h->track) as first
  761. }
  762. else {
  763. if( !strncasecmp(tr->v, vc, 20) ) {
  764. if( tr->vpos == pos )
  765. return tr;
  766. trans = tr->transpose;
  767. global_octave_shift = tr->octave_shift;
  768. voiceno = tr->vno;
  769. instrno = tr->instr;
  770. channo = tr->chan;
  771. }
  772. }
  773. prev = tr;
  774. }
  775. if( trunused ) {
  776. tr = trunused;
  777. if( pos ) {
  778. tr->vno = voiceno;
  779. tr->instr = instrno;
  780. tr->chan = channo;
  781. }
  782. else {
  783. global_voiceno++;
  784. tr->vno = global_voiceno;
  785. tr->instr = 1;
  786. tr->chan = 0;
  787. }
  788. tr->vpos = pos;
  789. tr->tiedvpos = pos;
  790. strncpy(tr->v, vc, 20);
  791. tr->v[20] = '\0';
  792. tr->mute = 0;
  793. tr->transpose = trans;
  794. tr->octave_shift = global_octave_shift;
  795. tr->volume = h->track->volume;
  796. tr->tienote = NULL;
  797. tr->legato = 0;
  798. return tr;
  799. }
  800. tr = abc_new_track(h, vc, pos);
  801. if( pos ) {
  802. tr->vno = voiceno;
  803. tr->instr = instrno;
  804. tr->chan = channo;
  805. }
  806. tr->transpose = trans;
  807. tr->octave_shift = global_octave_shift;
  808. if( prev ) prev->next = tr;
  809. else h->track = tr;
  810. return tr;
  811. }
  812. // =============================================================================
  813. static ABCTRACK *abc_check_track(ABCHANDLE *h, ABCTRACK *tp)
  814. // =============================================================================
  815. {
  816. if( !tp ) {
  817. tp = abc_locate_track(h, "", 0); // must work for voiceless abc too...
  818. tp->transpose = h->ktrans;
  819. }
  820. return tp;
  821. }
  822. static void abc_add_capo(ABCHANDLE *h, ABCTRACK *tp, ULONG tracktime)
  823. {
  824. ABCEVENT *e;
  825. char d[6];
  826. d[0] = d[1] = d[2] = d[3] = d[4] = d[5] = 0;
  827. d[cmdflag] = 1;
  828. d[command] = cmdcapo;
  829. e = abc_new_event(h, tracktime, d);
  830. tp->capostart = e;
  831. abc_add_event(h, tp, e); // do this last (recursion danger)
  832. }
  833. static void abc_add_segno(ABCHANDLE *h, ABCTRACK *tp, ULONG tracktime)
  834. {
  835. ABCEVENT *e;
  836. char d[6];
  837. d[0] = d[1] = d[2] = d[3] = d[4] = d[5] = 0;
  838. d[cmdflag] = 1;
  839. d[command] = cmdsegno;
  840. e = abc_new_event(h, tracktime, d);
  841. abc_add_event(h, tp, e);
  842. }
  843. static void abc_add_coda(ABCHANDLE *h, ABCTRACK *tp, ULONG tracktime)
  844. {
  845. ABCEVENT *e;
  846. char d[6];
  847. d[0] = d[1] = d[2] = d[3] = d[4] = d[5] = 0;
  848. d[cmdflag] = 1;
  849. d[command] = cmdcoda;
  850. e = abc_new_event(h, tracktime, d);
  851. abc_add_event(h, tp, e);
  852. }
  853. static void abc_add_fine(ABCHANDLE *h, ABCTRACK *tp, ULONG tracktime)
  854. {
  855. ABCEVENT *e;
  856. char d[6];
  857. d[0] = d[1] = d[2] = d[3] = d[4] = d[5] = 0;
  858. d[cmdflag] = 1;
  859. d[command] = cmdfine;
  860. e = abc_new_event(h, tracktime, d);
  861. abc_add_event(h, tp, e);
  862. }
  863. static void abc_add_tocoda(ABCHANDLE *h, ABCTRACK *tp, ULONG tracktime)
  864. {
  865. ABCEVENT *e;
  866. char d[6];
  867. d[0] = d[1] = d[2] = d[3] = d[4] = d[5] = 0;
  868. d[cmdflag] = 1;
  869. d[command] = cmdtocoda;
  870. e = abc_new_event(h, tracktime, d);
  871. abc_add_event(h, tp, e);
  872. }
  873. // first track is dirigent, remove all control events from other tracks
  874. // to keep the information where the events should be relative to note events
  875. // in the same tick the ticks are octated and four added for note events
  876. // the control events that come before the note events get a decremented tick,
  877. // those that come after get an incremented tick, for example:
  878. // ctrl ctrl note ctrl ctrl note
  879. // original: t t t t t+1 t+1
  880. // recoded: 8t+1 8t+2 8t+4 8t+5 8t+11 8t+12
  881. static void abc_remove_unnecessary_events(ABCHANDLE *h)
  882. {
  883. ABCTRACK *tp,*ptp;
  884. ABCEVENT *ep, *el;
  885. ULONG ct, et;
  886. int d;
  887. ptp = NULL;
  888. for( tp=h->track; tp; tp=tp->next ) {
  889. el = NULL;
  890. ep = tp->head;
  891. ct = 0;
  892. d = -3;
  893. while( ep ) {
  894. et = ep->tracktick;
  895. ep->tracktick <<= 3;
  896. ep->tracktick += 4;
  897. if( ep->flg == 1 ) {
  898. ep->tracktick += d;
  899. d++;
  900. if( d == 0 ) d = -1;
  901. if( d == 4 ) d = 3;
  902. if( tp!=h->track ) ep->cmd = cmdhide;
  903. switch( ep->cmd ) {
  904. case cmdhide:
  905. case cmdsync:
  906. if( el ) {
  907. el->next = ep->next;
  908. _mm_free(h->trackhandle,ep);
  909. ep = el->next;
  910. }
  911. else {
  912. tp->head = ep->next;
  913. _mm_free(h->trackhandle,ep);
  914. ep = tp->head;
  915. }
  916. break;
  917. default:
  918. el = ep;
  919. ep = ep->next;
  920. break;
  921. }
  922. }
  923. else {
  924. el = ep;
  925. ep = ep->next;
  926. d = 1;
  927. }
  928. if( et > ct )
  929. d = -3;
  930. ct = et;
  931. }
  932. if( !tp->head ) { // no need to keep empty tracks...
  933. if( ptp ) {
  934. ptp->next = tp->next;
  935. _mm_free(h->trackhandle,tp);
  936. tp = ptp;
  937. }
  938. else {
  939. h->track = tp->next;
  940. _mm_free(h->trackhandle,tp);
  941. tp = h->track;
  942. }
  943. }
  944. ptp = tp; // remember previous track
  945. }
  946. }
  947. // set ticks back, and handle partbreaks
  948. static void abc_retick_events(ABCHANDLE *h)
  949. {
  950. ABCTRACK *tp;
  951. ABCEVENT *ep;
  952. ULONG et, tt=0, at = abcticks(64 * h->speed);
  953. for( tp=h->track; tp; tp=tp->next ) {
  954. // make ticks relative
  955. tt = 0;
  956. for( ep=tp->head; ep; ep=ep->next ) {
  957. et = ep->tracktick >> 3;
  958. ep->tracktick = et - tt;
  959. tt = et;
  960. }
  961. // make ticks absolute again, skipping no-op partbreaks
  962. tt = 0;
  963. for( ep=tp->head; ep; ep=ep->next ) {
  964. ep->tracktick += tt;
  965. tt = ep->tracktick;
  966. if( ep->flg == 1 && ep->cmd == cmdpartbrk ) {
  967. if( tt % at ) {
  968. tt += at;
  969. tt /= at;
  970. tt *= at;
  971. ep->tracktick -= abcticks(h->speed); // break plays current row
  972. }
  973. else ep->cmd = cmdhide;
  974. }
  975. }
  976. }
  977. }
  978. // make sure every track has the control events it needs, this way it is not
  979. // necessary to have redundant +segno+ +D.C.+ etc in the voices, the first voice
  980. // is the master, it is pointed to by the member 'track' in the ABCHANDLE
  981. static void abc_synchronise_tracks(ABCHANDLE *h)
  982. {
  983. ABCTRACK *tp;
  984. ULONG tm; // tracktime in master
  985. ABCEVENT *em, *es, *et, *ec; // events in master, slave, slave temporary and copied event
  986. if( !h || !h->track ) return;
  987. abc_remove_unnecessary_events(h);
  988. for( tp = h->track->next; tp; tp = tp->next ) {
  989. for( em=h->track->head; em; em=em->next ) {
  990. if( em->flg == 1 ) { // some kind of control event
  991. switch( em->cmd ) {
  992. case cmdchord:
  993. case cmdhide:
  994. case cmdtempo:
  995. case cmdsync:
  996. break;
  997. default: // check to see if copy is necessary
  998. ec = abc_copy_event(h, em);
  999. tm = em->tracktick;
  1000. es = tp->head; // allways search from the begin...
  1001. for( et=es; et && et->tracktick <= tm; et=et->next )
  1002. es = et;
  1003. if( es == NULL || es->tracktick > tm ) { // special case: head of track
  1004. ec->next = es;
  1005. tp->head = ec;
  1006. }
  1007. else {
  1008. ec->next = es->next;
  1009. es->next = ec;
  1010. }
  1011. break;
  1012. }
  1013. }
  1014. }
  1015. }
  1016. abc_retick_events(h);
  1017. }
  1018. static void abc_add_event(ABCHANDLE *h, ABCTRACK *tp, ABCEVENT *e)
  1019. {
  1020. if( !tp->capostart ) abc_add_capo(h, tp, global_songstart);
  1021. if( tp->tail ) {
  1022. tp->tail->next = e;
  1023. tp->tail = e;
  1024. }
  1025. else {
  1026. tp->head = e;
  1027. tp->tail = e;
  1028. }
  1029. }
  1030. static void abc_add_partbreak(ABCHANDLE *h, ABCTRACK *tp, ULONG tracktime)
  1031. {
  1032. ABCEVENT *e;
  1033. char d[6];
  1034. d[0] = d[1] = d[2] = d[3] = d[4] = d[5] = 0;
  1035. d[cmdflag] = 1;
  1036. d[command] = cmdpartbrk;
  1037. e = abc_new_event(h, tracktime, d);
  1038. abc_add_event(h, tp, e);
  1039. }
  1040. static void abc_add_tempo_event(ABCHANDLE *h, ABCTRACK *tp, ULONG tracktime, int tempo)
  1041. {
  1042. ABCEVENT *e;
  1043. char d[6];
  1044. d[0] = d[1] = d[2] = d[3] = d[4] = d[5] = 0;
  1045. d[cmdflag] = 1;
  1046. d[command] = cmdtempo;
  1047. e = abc_new_event(h, tracktime, d);
  1048. e->lpar = tempo;
  1049. abc_add_event(h, tp, e);
  1050. }
  1051. static void abc_add_noteoff(ABCHANDLE *h, ABCTRACK *tp, ULONG tracktime)
  1052. {
  1053. ABCEVENT *e;
  1054. char d[6];
  1055. d[note] = 0;
  1056. d[octave] = 0;
  1057. d[smpno] = pat_gmtosmp(tp->instr);
  1058. d[volume] = 0;
  1059. d[effect] = 0;
  1060. d[effoper] = 0;
  1061. e = abc_new_event(h, tracktime, d);
  1062. abc_add_event(h, tp, e);
  1063. }
  1064. static int abc_dynamic_volume(ABCTRACK *tp, ULONG tracktime, int vol)
  1065. {
  1066. ULONG slidetime;
  1067. int voldelta;
  1068. if( tp->mute ) return 0;
  1069. if( tp->slidevol == 0 ) return vol;
  1070. if( tracktime < tp->slidevoltime ) return vol;
  1071. slidetime = modticks(tracktime - tp->slidevoltime);
  1072. voldelta = (slidetime * 15) / 64 / 6; // slide from say mf up to f in one pattern's time
  1073. if( tp->slidevol > -2 && voldelta > 15 ) voldelta = 15; // never to much dynamics
  1074. if( tp->slidevol > 0 ) vol += voldelta;
  1075. else vol -= voldelta;
  1076. if( vol < 2 ) vol = 2; // xmms divides this by 2....
  1077. if( vol > 127 ) vol = 127;
  1078. return vol;
  1079. }
  1080. static void abc_track_untie_short_chordnotes(ABCHANDLE *h)
  1081. {
  1082. ABCTRACK *tp;
  1083. int vn;
  1084. tp = h->tp;
  1085. vn = tp->vno;
  1086. for( tp = h->track; tp; tp = tp->next )
  1087. if( tp != h->tp && tp->vno == vn && tp->tienote ) {
  1088. abc_message("short notes in chord can not be tied:\n%s", h->line);
  1089. tp->tienote = 0;
  1090. }
  1091. }
  1092. static void abc_track_clear_tiednote(ABCHANDLE *h)
  1093. {
  1094. ABCTRACK *tp;
  1095. int vn;
  1096. tp = h->tp;
  1097. vn = tp->vno;
  1098. for( tp = h->track; tp; tp = tp->next )
  1099. if( tp->vno == vn ) tp->tienote = 0;
  1100. }
  1101. static void abc_track_clear_tiedvpos(ABCHANDLE *h)
  1102. {
  1103. ABCTRACK *tp;
  1104. int vn;
  1105. tp = h->tp;
  1106. vn = tp->vno;
  1107. for( tp = h->track; tp; tp = tp->next )
  1108. if( tp->vno == vn ) tp->tiedvpos = tp->vpos;
  1109. }
  1110. static ABCTRACK *abc_track_with_note_tied(ABCHANDLE *h, ULONG tracktime, int n, int oct)
  1111. {
  1112. int vn, vp;
  1113. ABCTRACK *tp;
  1114. ABCEVENT *e;
  1115. tp = h->tp;
  1116. vn = tp->vno;
  1117. vp = tp->vpos;
  1118. for( tp = h->track; tp; tp = tp->next ) {
  1119. if( tp->vno == vn ) {
  1120. e = tp->tienote;
  1121. if( e && e->tracktick < tracktime
  1122. && e->par[octave] == oct && abs(e->par[note] - n) < 3 ) {
  1123. if( tp->vpos != vp ) tp->tiedvpos = vp;
  1124. h->tp = tp;
  1125. return tp;
  1126. }
  1127. }
  1128. }
  1129. tp = h->tp;
  1130. vp = tp->tiedvpos;
  1131. if( tp->vpos != vp ) {
  1132. // chord note track allready returned in previous call
  1133. for( tp = h->track; tp; tp = tp->next ) {
  1134. if( tp->vno == vn && tp->vpos == vp ) {
  1135. tp->tiedvpos = h->tp->vpos;
  1136. h->tp = tp;
  1137. return tp;
  1138. }
  1139. }
  1140. }
  1141. return h->tp;
  1142. }
  1143. static int abc_add_noteon(ABCHANDLE *h, int ch, const char *p, ULONG tracktime, char *barkey, int vol, ABCEVENT_X_EFFECT fx, int fxop)
  1144. {
  1145. ABCEVENT *e;
  1146. ABCTRACK *tp;
  1147. int i,j,k;
  1148. int n,oct;
  1149. char d[6];
  1150. tp = h->tp;
  1151. switch(ch) {
  1152. case '^':
  1153. if( p[0] == '^' ) {
  1154. n = p[1];
  1155. i = 2;
  1156. ch = 'x';
  1157. }
  1158. else {
  1159. n = p[0];
  1160. i = 1;
  1161. }
  1162. break;
  1163. case '_':
  1164. if( p[0] == '_' ) {
  1165. n = p[1];
  1166. i = 2;
  1167. ch = 'b';
  1168. }
  1169. else {
  1170. n = p[0];
  1171. i = 1;
  1172. }
  1173. break;
  1174. case '=':
  1175. n = p[0];
  1176. i = 1;
  1177. break;
  1178. default:
  1179. n = ch;
  1180. i = 0;
  1181. break;
  1182. }
  1183. for( k=0; k<51; k++ ) {
  1184. if( n == barkey[k] )
  1185. break;
  1186. }
  1187. j = k;
  1188. if( k > 24 )
  1189. k -= 25; // had something like A# over Bb key F signature....
  1190. if( i ) {
  1191. // propagate accidentals if necessary
  1192. // DON'T do redundant accidentals they're always relative to C-scale
  1193. for( k=0; k<25; k++ ) {
  1194. if( n == sig[7][k] )
  1195. break;
  1196. }
  1197. if( k < 25 ) { // only do real notes...
  1198. switch(ch) {
  1199. case 'x':
  1200. k++;
  1201. case '^':
  1202. k++;
  1203. break;
  1204. case 'b':
  1205. k--;
  1206. case '_':
  1207. k--;
  1208. break;
  1209. case '=':
  1210. break;
  1211. }
  1212. if( j < 25 ) // was it not A# over Bb?
  1213. barkey[j] = ' ';
  1214. barkey[k] = n;
  1215. }
  1216. }
  1217. oct = 3; // ABC note pitch C is C4 and pitch c is C5
  1218. if( k < 25 ) {
  1219. k += tp->transpose;
  1220. while( k > 12 ) {
  1221. oct++;
  1222. k -= 12;
  1223. }
  1224. while( k < 0 ) {
  1225. oct--;
  1226. k += 12;
  1227. }
  1228. d[note] = 23 + k; // C0 is midi notenumber 24
  1229. }
  1230. else
  1231. d[note] = 0; // someone has doen ^X3 or something like it...
  1232. while( p[i] && strchr(",'",p[i]) ) {
  1233. if( p[i]==',' ) oct--;
  1234. else oct++;
  1235. i++;
  1236. tp->octave_shift = 0; // forget we ever had to look at it
  1237. }
  1238. if( tp->octave_shift )
  1239. tp->transpose += 12 * tp->octave_shift;
  1240. oct += tp->octave_shift;
  1241. tp->octave_shift = 0; // after the first note we never have to look at it again
  1242. if( oct < 0 ) oct = 0;
  1243. if( oct > 9 ) oct = 9;
  1244. d[octave] = oct;
  1245. d[smpno] = pat_gmtosmp(tp->instr);
  1246. d[volume] = abc_dynamic_volume(tp, tracktime, vol);
  1247. d[effect] = fx; // effect
  1248. d[effoper] = fxop;
  1249. tp = abc_track_with_note_tied(h, tracktime, d[note], oct);
  1250. if( tp->tienote ) {
  1251. if( tp->tienote->par[note] != d[note] ) {
  1252. if( abs(tp->tienote->par[note] - d[note]) < 3 ) {
  1253. // may be tied over bar symbol, recover local accidental to barkey
  1254. k = tp->tienote->par[note] - 23 - tp->transpose;
  1255. while( k < 0 ) k += 12;
  1256. while( k > 12 ) k -= 12;
  1257. if( (isupper(n) && barkey[k+12] == ' ') || (islower(n) && barkey[k] == ' ') ) {
  1258. barkey[j] = ' ';
  1259. if( isupper(n) )
  1260. barkey[k] = n;
  1261. else
  1262. barkey[k+12] = n;
  1263. d[note] = tp->tienote->par[note];
  1264. d[octave] = tp->tienote->par[octave];
  1265. }
  1266. }
  1267. }
  1268. }
  1269. if( tp->tienote
  1270. && tp->tienote->par[note] == d[note]
  1271. && tp->tienote->par[octave] == d[octave] ) {
  1272. for( e = tp->tienote; e; e = e->next ) {
  1273. if( e->par[note] == 0 && e->par[octave] == 0 ) { // undo noteoff
  1274. e->flg = 1;
  1275. e->cmd = cmdhide;
  1276. e->lpar = 0;
  1277. break;
  1278. }
  1279. }
  1280. tp->tienote->tiednote = 1; // mark him for the pattern writers
  1281. for( j=i; isdigit(p[j]) || p[j]=='/'; j++ ) ; // look ahead to see if this one is tied too
  1282. if( p[j] != '-' ) // is this note tied too?
  1283. tp->tienote = NULL; // if not the tie ends here...
  1284. return i;
  1285. }
  1286. tp->tienote = NULL;
  1287. if( tp->tail
  1288. && tp->tail->tracktick == tracktime
  1289. && tp->tail->par[note] == 0
  1290. && tp->tail->par[octave] == 0 ) {
  1291. for( j=0; j<6; j++ )
  1292. tp->tail->par[j] = d[j];
  1293. }
  1294. else {
  1295. e = abc_new_event(h, tracktime, d);
  1296. abc_add_event(h, tp, e);
  1297. }
  1298. if( i > 0 && p[i-1] == '"' ) {
  1299. i--; // someone coded a weird note like ^"E"
  1300. abc_message("strange note encountered scanning %s", h->line);
  1301. }
  1302. return i;
  1303. }
  1304. static void abc_add_dronenote(ABCHANDLE *h, ABCTRACK *tp, ULONG tracktime, int nnum, int vol)
  1305. {
  1306. ABCEVENT *e;
  1307. int j,k;
  1308. int oct;
  1309. char d[6];
  1310. oct = -1; // ABC note pitch C is C4 and pitch c is C5
  1311. k = nnum + 1;
  1312. while( k > 12 ) {
  1313. oct++;
  1314. k -= 12;
  1315. }
  1316. while( k < 0 ) {
  1317. oct--;
  1318. k += 12;
  1319. }
  1320. if( oct < 0 ) oct = 0;
  1321. d[note] = 23 + k; // C0 is midi notenumber 24
  1322. d[octave] = oct;
  1323. d[smpno] = pat_gmtosmp(tp->instr);
  1324. d[volume] = abc_dynamic_volume(tp, tracktime, vol);
  1325. d[effect] = 0; // effect
  1326. d[effoper] = 0;
  1327. if( tp->tail
  1328. && tp->tail->tracktick == tracktime
  1329. && tp->tail->par[note] == 0
  1330. && tp->tail->par[octave] == 0 ) {
  1331. for( j=0; j<6; j++ )
  1332. tp->tail->par[j] = d[j];
  1333. }
  1334. else {
  1335. e = abc_new_event(h, tracktime, d);
  1336. abc_add_event(h, tp, e);
  1337. }
  1338. }
  1339. static void abc_add_chordnote(ABCHANDLE *h, ABCTRACK *tp, ULONG tracktime, int nnum, int vol)
  1340. {
  1341. abc_add_dronenote(h, tp, tracktime, nnum + 23, tp->mute? 0: vol);
  1342. }
  1343. static void abc_add_drumnote(ABCHANDLE *h, ABCTRACK *tp, ULONG tracktime, int nnum, int vol)
  1344. {
  1345. abc_add_dronenote(h, tp, tracktime, nnum, tp->mute? 0: vol);
  1346. }
  1347. static void abc_add_variant_start(ABCHANDLE *h, ABCTRACK *tp, ULONG tracktime, int n)
  1348. {
  1349. ABCEVENT *e;
  1350. char d[6];
  1351. d[0] = d[1] = d[2] = d[3] = d[4] = d[5] = 0;
  1352. d[cmdflag] = 1;
  1353. d[command] = cmdvariant;
  1354. e = abc_new_event(h, tracktime, d);
  1355. e->lpar = 1<<n;
  1356. abc_add_event(h, tp, e);
  1357. }
  1358. static void abc_add_variant_choise(ABCTRACK *tp, int n)
  1359. {
  1360. tp->tail->lpar |= 1<<n;
  1361. }
  1362. static void abc_add_chord(const char *p, ABCHANDLE *h, ABCTRACK *tp, ULONG tracktime)
  1363. {
  1364. ABCEVENT *e;
  1365. char d[6];
  1366. char s[8];
  1367. int i;
  1368. const char *n = " C D EF G A Bc d ef g a b";
  1369. d[0] = d[1] = d[2] = d[3] = d[4] = d[5] = 0;
  1370. d[cmdflag] = 1;
  1371. d[command] = cmdchord;
  1372. if( p[0] == '(' ) p++; // chord between parens like: (C)
  1373. for( i=0; n[i]; i++ )
  1374. if( *p == n[i] ) {
  1375. d[chordnote] = i;
  1376. break;
  1377. }
  1378. p++;
  1379. switch(*p) {
  1380. case 'b':
  1381. d[chordnote]--;
  1382. p++;
  1383. break;
  1384. case '#':
  1385. d[chordnote]++;
  1386. p++;
  1387. break;
  1388. }
  1389. d[chordbase] = d[chordnote];
  1390. for( i=0; p[i] && p[i] != '"' && p[i] != '/' && p[i] != '(' && p[i] != ')' && p[i] != ' '; i++ ) s[i] = p[i];
  1391. s[i] = '\0';
  1392. p = &p[i];
  1393. if( *p=='/' ) {
  1394. p++;
  1395. for( i=0; n[i]; i++ )
  1396. if( *p == n[i] ) {
  1397. d[chordbase] = i;
  1398. break;
  1399. }
  1400. p++;
  1401. switch(*p) {
  1402. case 'b':
  1403. d[chordbase]--;
  1404. p++;
  1405. break;
  1406. case '#':
  1407. d[chordbase]++;
  1408. p++;
  1409. break;
  1410. }
  1411. }
  1412. for( i=0; i<chordsnamed; i++ )
  1413. if( !strcmp(s, chordname[i]) ) {
  1414. d[chordnum] = i;
  1415. break;
  1416. }
  1417. if( i==chordsnamed ) {
  1418. abc_message("Failure: unrecognized chordname %s",s);
  1419. return;
  1420. }
  1421. e = abc_new_event(h, tracktime, d);
  1422. abc_add_event(h, tp, e);
  1423. }
  1424. static void abc_add_setloop(ABCHANDLE *h, ABCTRACK *tp, ULONG tracktime)
  1425. {
  1426. ABCEVENT *e;
  1427. char d[6];
  1428. d[0] = d[1] = d[2] = d[3] = d[4] = d[5] = 0;
  1429. d[cmdflag] = 1;
  1430. d[command] = cmdloop;
  1431. e = abc_new_event(h, tracktime, d);
  1432. abc_add_event(h, tp, e);
  1433. }
  1434. static void abc_fade_track(ABCTRACK *tp, ABCEVENT *e)
  1435. {
  1436. while(e) {
  1437. if( e->flg != 1 && e->par[note] != 0 )
  1438. e->par[volume] = abc_dynamic_volume(tp, e->tracktick, e->par[volume]);
  1439. e = e->next;
  1440. }
  1441. }
  1442. static void abc_add_setjumploop(ABCHANDLE *h, ABCTRACK *tp, ULONG tracktime, ABCEVENT_JUMPTYPE j)
  1443. {
  1444. ABCEVENT *e;
  1445. char d[8];
  1446. d[0] = d[1] = d[2] = d[3] = d[4] = d[5] = 0;
  1447. d[cmdflag] = 1;
  1448. d[command] = cmdjump;
  1449. d[jumptype] = j;
  1450. e = abc_new_event(h, tracktime, d);
  1451. abc_add_event(h, tp, e);
  1452. }
  1453. static void abc_add_sync(ABCHANDLE *h, ABCTRACK *tp, ULONG tracktime)
  1454. {
  1455. ABCEVENT *e;
  1456. char d[6];
  1457. e = tp->tail;
  1458. if( e && e->tracktick == tracktime ) return;
  1459. if( e && e->flg == 1 && e->cmd == cmdsync ) {
  1460. e->tracktick = tracktime;
  1461. return;
  1462. }
  1463. d[0] = d[1] = d[2] = d[3] = d[4] = d[5] = 0;
  1464. d[cmdflag] = 1;
  1465. d[command] = cmdsync;
  1466. e = abc_new_event(h, tracktime, d);
  1467. abc_add_event(h, tp, e);
  1468. }
  1469. static void abc_add_gchord_syncs(ABCHANDLE *h, ABCTRACK *tpc, ULONG tracktime)
  1470. {
  1471. ABCTRACK *tp;
  1472. int i;
  1473. for( i = GCHORDBPOS; i < DRUMPOS; i++ ) {
  1474. tp = abc_locate_track(h, tpc->v, i);
  1475. abc_add_sync(h,tp,tracktime);
  1476. }
  1477. }
  1478. static void abc_add_drum_sync(ABCHANDLE *h, ABCTRACK *tpr, ULONG tracktime)
  1479. {
  1480. ABCTRACK *tp;
  1481. tp = abc_locate_track(h, tpr->v, DRUMPOS);
  1482. abc_add_sync(h,tp,tracktime);
  1483. }
  1484. static int abc_getnumber(const char *p, int *number)
  1485. {
  1486. int i,h;
  1487. i = 0;
  1488. h = 0;
  1489. while( isdigit(p[i]) ) {
  1490. h = 10 * h + p[i] - '0';
  1491. i++;
  1492. }
  1493. if( i==0 )
  1494. *number = 1;
  1495. else
  1496. *number = h;
  1497. return i;
  1498. }
  1499. static int abc_getexpr(const char *p, int *number)
  1500. {
  1501. int i, term, total;
  1502. i = 0;
  1503. while( isspace(p[i]) )
  1504. i++;
  1505. if( p[i] == '(' ) {
  1506. i += abc_getexpr(p+i+1, number);
  1507. while( p[i] && (p[i] != ')') )
  1508. i++;
  1509. return i;
  1510. }
  1511. i += abc_getnumber(p+i, &total);
  1512. while( isspace(p[i]) )
  1513. i++;
  1514. while( p[i] == '+' ) {
  1515. i += abc_getexpr(p+i+1, &term);
  1516. total += term;
  1517. while( isspace(p[i]) )
  1518. i++;
  1519. }
  1520. *number = total;
  1521. return i;
  1522. }
  1523. static int abc_notelen(const char *p, int *len, int *div)
  1524. {
  1525. int i,h,k;
  1526. i = abc_getnumber(p,len);
  1527. h = 1;
  1528. while( p[i] == '/' ) {
  1529. h *= 2;
  1530. i++;
  1531. }
  1532. if( isdigit(p[i]) ) {
  1533. h /= 2;
  1534. i += abc_getnumber(p+i,&k);
  1535. }
  1536. else k = 1;
  1537. *div = h * k;
  1538. return i;
  1539. }
  1540. static int abc_brokenrithm(const char *p, int *nl, int *nd, int *b, int hornpipe)
  1541. {
  1542. switch( *b ) {
  1543. case '<':
  1544. *nl *= 3;
  1545. *nd *= 2;
  1546. hornpipe = 0;
  1547. break;
  1548. case '>':
  1549. *nd *= 2;
  1550. hornpipe = 0;
  1551. break;
  1552. }
  1553. *b = *p;
  1554. switch( *b ) {
  1555. case '>':
  1556. *nl *= 3;
  1557. *nd *= 2;
  1558. return 1;
  1559. case '<':
  1560. *nd *= 2;
  1561. return 1;
  1562. default:
  1563. *b = 0;
  1564. break;
  1565. }
  1566. if( hornpipe ) { // still true then make 1/8 notes broken rithme
  1567. if( *nl == 1 && *nd == 1 ) {
  1568. *b = '>';
  1569. *nl = 3;
  1570. *nd = 2;
  1571. }
  1572. }
  1573. return 0;
  1574. }
  1575. // put p notes in the time q for the next r notes
  1576. static int abc_tuplet(int *nl, int *nd, int p, int q, int r)
  1577. {
  1578. if( !r ) return 0;
  1579. *nl *= q;
  1580. *nd *= p;
  1581. return r - 1;
  1582. }
  1583. // evaluate [Q:"string" n1/m1 n2/m2 n3/m3 n4/m4=bpm "string"]
  1584. // minimal form [Q:"string"]
  1585. // most used form [Q: 1/4=120]
  1586. static int abc_extract_tempo(const char *p, int invoice)
  1587. {
  1588. int nl, nd, ns, in, tempo;
  1589. int nl1=0, nd1, notes, state;
  1590. const char *q;
  1591. in = 0;
  1592. nl = 0;
  1593. nd = 1;
  1594. ns = 120;
  1595. notes = 0;
  1596. state = 0;
  1597. for( q=p; *q; q++ ) {
  1598. if( in ) {
  1599. if( *q=='"' )
  1600. in = 0;
  1601. }
  1602. else {
  1603. if( *q == ']' ) break;
  1604. switch( *q ) {
  1605. case '"':
  1606. in = 1;
  1607. break;
  1608. case '/':
  1609. notes++;
  1610. state = 1;
  1611. nl1 = ns;
  1612. break;
  1613. case '=':
  1614. break;
  1615. default:
  1616. if( isdigit(*q) ) {
  1617. if( state ) {
  1618. q+=abc_getnumber(q,&nd1)-1;
  1619. state = 0;
  1620. nl = nl * nd1 + nl1 * nd;
  1621. nd = nd * nd1;
  1622. }
  1623. else
  1624. q+=abc_getnumber(q,&ns)-1;
  1625. }
  1626. break;
  1627. }
  1628. }
  1629. }
  1630. if( !notes ) {
  1631. nl = 1;
  1632. nd = 4;
  1633. }
  1634. if( !nd ) tempo = 120;
  1635. else tempo = ns * nl * 4 / nd; // mod tempo is really BPM where one B is equal to a quartnote
  1636. if( invoice ) {
  1637. nl = global_tempo_factor;
  1638. nd = global_tempo_divider;
  1639. }
  1640. global_tempo_factor = 1;
  1641. global_tempo_divider = 1;
  1642. while( tempo/global_tempo_divider > 255 )
  1643. global_tempo_divider++;
  1644. tempo /= global_tempo_divider;
  1645. while( tempo * global_tempo_factor < 256 )
  1646. global_tempo_factor++;
  1647. global_tempo_factor--;
  1648. tempo *= global_tempo_factor;
  1649. if( tempo * 3 < 512 ) {
  1650. global_tempo_factor *= 3;
  1651. global_tempo_divider *= 2;
  1652. tempo = (tempo * 3) / 2;
  1653. }
  1654. if( invoice ) {
  1655. if( nl != global_tempo_factor || nd != global_tempo_divider ) {
  1656. ns = (tempo * nl * global_tempo_divider) / (nd * global_tempo_factor);
  1657. if( ns > 31 && ns < 256 ) {
  1658. tempo = ns;
  1659. global_tempo_factor = nl;
  1660. global_tempo_divider = nd;
  1661. }
  1662. else
  1663. abc_message("Failure: inconvenient tempo change in middle of voice (%s)", p);
  1664. }
  1665. }
  1666. return tempo;
  1667. }
  1668. static void abc_set_parts(char **d, char *p)
  1669. {
  1670. int i,j,k,m,n;
  1671. char *q;
  1672. #ifdef NEWMIKMOD
  1673. static MM_ALLOC *h;
  1674. if( *d ) _mmalloc_close(h);
  1675. #else
  1676. if( *d ) free(*d);
  1677. #endif
  1678. *d = 0;
  1679. if( !p ) return;
  1680. for( i=0; p[i] && p[i] != '%'; i++ ) {
  1681. if( !strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ().0123456789 ",p[i]) ) {
  1682. abc_message("invalid characters in part string scanning P:%s", p);
  1683. return;
  1684. }
  1685. }
  1686. #ifdef NEWMIKMOD
  1687. h = _mmalloc_create("Load_ABC_parts", NULL);
  1688. #endif
  1689. // decode constructs like "((AB)2.(CD)2)3.(AB)E2" to "ABABCDCDABABCDCDABABCDCDABEE"
  1690. // first compute needed storage...
  1691. j=0;
  1692. k=0;
  1693. for( i=0; p[i] && p[i] != '%'; i++ ) {
  1694. if( isupper(p[i]) ) {
  1695. j++;
  1696. }
  1697. if( isdigit(p[i]) ) {
  1698. n=abc_getnumber(p+i,&k);
  1699. if( p[i-1] == ')' )
  1700. j *= k; // never mind multiple parens, just take the worst case
  1701. else
  1702. j += k-1;
  1703. i += n-1;
  1704. }
  1705. }
  1706. q = (char *)_mm_calloc(h, j+1, sizeof(char)); // enough storage for the worst case
  1707. // now copy bytes from p to *d, taking parens and digits in account
  1708. j = 0;
  1709. for( i=0; p[i] && p[i] != '%'; i++ ) {
  1710. if( isdigit(p[i]) || isupper(p[i]) || p[i] == '(' || p[i] == ')' ) {
  1711. if( p[i] == ')' ) {
  1712. for( n=j; n > 0 && q[n-1] != '('; n-- ) ; // find open paren in q
  1713. // q[n+1] to q[j] contains the substring that must be repeated
  1714. if( n > 0 ) {
  1715. for( k = n; k<j; k++ ) q[k-1] = q[k]; // shift to the left...
  1716. j--;
  1717. }
  1718. else
  1719. abc_message("Warning: Unbalanced right parens in P: definition %s",p);
  1720. n = j - n + 1; // number of repeatable characters
  1721. i += abc_getnumber(p+i+1,&k);
  1722. while( k-- > 1 ) {
  1723. for( m=0; m<n; m++ ) {
  1724. q[j] = q[j-n];
  1725. j++;
  1726. }
  1727. }
  1728. continue;
  1729. }
  1730. if( isdigit(p[i]) ) {
  1731. n = abc_getnumber(p+i,&k);
  1732. i += n - 1;
  1733. while( k-- > 1 ) {
  1734. q[j] = q[j-1];
  1735. j++;
  1736. }
  1737. continue;
  1738. }
  1739. q[j] = p[i];
  1740. j++;
  1741. }
  1742. }
  1743. q[j] = '\0';
  1744. // remove any left over parens
  1745. for( i=0; i<j; i++ ) {
  1746. if( q[i] == '(' ) {
  1747. abc_message("Warning: Unbalanced left parens in P: definition %s",p);
  1748. for( k=i; k<j; k++ ) q[k] = q[k+1];
  1749. j--;
  1750. }
  1751. }
  1752. *d = q;
  1753. }
  1754. static void abc_appendpart(ABCHANDLE *h, ABCTRACK *tp, ULONG pt1, ULONG pt2)
  1755. {
  1756. ABCEVENT *e, *ec;
  1757. ULONG dt;
  1758. dt = tp->tail->tracktick - pt1;
  1759. for( e=tp->head; e && e->tracktick <= pt2; e=e->next ) {
  1760. if( e->tracktick >= pt1 ) {
  1761. if( e->flg != 1 || e->cmd == cmdsync || e->cmd == cmdchord ) {
  1762. if( e != tp->tail ) {
  1763. // copy this event at tail
  1764. ec = abc_copy_event(h,e);
  1765. ec->tracktick += dt;
  1766. ec->part = '*';
  1767. tp->tail->next = ec;
  1768. tp->tail = ec;
  1769. }
  1770. }
  1771. }
  1772. }
  1773. abc_add_sync(h, tp, pt2 + dt); // make sure there is progression...
  1774. }
  1775. static ULONG abc_pattracktime(ABCHANDLE *h, ULONG tracktime)
  1776. {
  1777. ABCEVENT *e;
  1778. ULONG dt,et,pt=abcticks(64 * h->speed);
  1779. if(!h || !h->track || !h->track->head ) return 0;
  1780. dt = 0;
  1781. for( e=h->track->head; e && e->tracktick <= tracktime; e=e->next ) {
  1782. if( e->flg == 1 && e->cmd == cmdpartbrk ) {
  1783. et = e->tracktick + dt;
  1784. if( et % pt ) {
  1785. et += pt;
  1786. et /= pt;
  1787. et *= pt;
  1788. dt = et - e->tracktick;
  1789. }
  1790. }
  1791. }
  1792. return (tracktime + dt);
  1793. }
  1794. static int abc_patno(ABCHANDLE *h, ULONG tracktime)
  1795. {
  1796. return modticks(abc_pattracktime(h, tracktime)) / 64 / h->speed;
  1797. }
  1798. static void abc_stripoff(ABCHANDLE *h, ABCTRACK *tp, ULONG tt)
  1799. {
  1800. ABCEVENT *e1, *e2;
  1801. e2 = NULL;
  1802. for( e1 = tp->head; e1 && e1->tracktick <= tt; e1=e1->next )
  1803. e2 = e1;
  1804. if( e2 ) {
  1805. e1 = e2->next;
  1806. tp->tail = e2;
  1807. e2->next = NULL;
  1808. }
  1809. else {
  1810. e1 = tp->tail;
  1811. tp->head = NULL;
  1812. tp->tail = NULL;
  1813. }
  1814. while( e1 ) {
  1815. e2 = e1->next;
  1816. _mm_free(h->trackhandle,e1);
  1817. e1 = e2;
  1818. }
  1819. }
  1820. static void abc_keeptiednotes(ABCHANDLE *h, ULONG fromtime, ULONG totime) {
  1821. ABCTRACK *tp;
  1822. ABCEVENT *e,*n,*f;
  1823. if( totime <= fromtime ) return;
  1824. for( tp=h->track; tp; tp=tp->next ) {
  1825. if( tp->vno ) { // if track is in use...
  1826. n = NULL;
  1827. for( e=tp->head; e && e->tracktick < fromtime; e = e->next )
  1828. if( e->flg != 1 ) n = e; // remember it when it is a note event
  1829. if( n && n->tiednote ) { // we've a candidate to tie over the break
  1830. while( e && e->tracktick < totime ) e=e->next; // skip to other part
  1831. if( e && e->tracktick == totime ) { // if this is on begin row of this part
  1832. f = NULL;
  1833. while( !f && e && e->tracktick == totime ) {
  1834. if( e->flg != 1 ) f = e;
  1835. e = e->next;
  1836. }
  1837. if( f && f->par[note] ) { // pfoeie, we've found a candidate
  1838. if( abs(n->par[note] - f->par[note]) < 3 ) { // undo the note on
  1839. f->flg = 1;
  1840. f->cmd = cmdhide;
  1841. f->lpar = 0;
  1842. }
  1843. }
  1844. }
  1845. }
  1846. }
  1847. }
  1848. }
  1849. static ULONG abc_fade_tracks(ABCHANDLE *h, char *abcparts, ULONG ptt[27])
  1850. {
  1851. ABCTRACK *tp;
  1852. ABCEVENT *e0;
  1853. char *p;
  1854. int vol;
  1855. ULONG pt1,pt2;
  1856. ULONG tt;
  1857. tt = h->track->tail->tracktick;
  1858. for( tp=h->track->next; tp; tp=tp->next ) {
  1859. if( !tp->tail ) abc_add_sync(h, tp, tt); // no empty tracks please...
  1860. if( tp->tail->tracktick > tt ) abc_stripoff(h, tp, tt); // should not happen....
  1861. if( tp->tail->tracktick < tt ) abc_add_sync(h, tp, tt);
  1862. }
  1863. for( tp=h->track; tp; tp=tp->next ) {
  1864. vol = 127;
  1865. e0 = tp->tail;
  1866. if( tp->slidevol != -2 ) {
  1867. tp->slidevol = -2;
  1868. tp->slidevoltime = e0->tracktick;
  1869. }
  1870. tp->mute = 0; // unmute track for safety, notes in a muted track already have zero volume...
  1871. while( vol > 5 ) {
  1872. for( p=abcparts; *p && vol > 5; p++ ) {
  1873. pt1 = ptt[*p-'A'];
  1874. pt2 = ptt[*p-'A'+1];
  1875. abc_appendpart(h, tp, pt1, pt2);
  1876. vol = abc_dynamic_volume(tp, tp->tail->tracktick, 127);
  1877. }
  1878. }
  1879. abc_fade_track(tp,e0);
  1880. }
  1881. return h->track->tail->tracktick;
  1882. }
  1883. static void abc_song_to_parts(ABCHANDLE *h, char **abcparts, BYTE partp[27][2])
  1884. {
  1885. ULONG starttick;
  1886. ABCEVENT *e;
  1887. int i, fading, loop, normal, partno, partsegno, partloop, partcoda, parttocoda, partfine, skip, x, y;
  1888. int vmask[27],nextp[27];
  1889. ULONG ptt[27];
  1890. char buf[256]; // must be enough, mod's cannot handle more than 240 patterns
  1891. char *pfade;
  1892. if( !h || !h->track || !h->track->capostart ) return;
  1893. strcpy(buf,"A"); // initialize our temporary array
  1894. i = 1;
  1895. loop = 1;
  1896. partno = 0;
  1897. partsegno = 0;
  1898. partloop = 0;
  1899. partcoda = -1;
  1900. parttocoda = -1;
  1901. partfine = -1;
  1902. starttick = h->track->capostart->tracktick;
  1903. ptt[0] = starttick;
  1904. vmask[0] = -1;
  1905. nextp[0] = 1;
  1906. for( e=h->track->capostart; e; e=e->next ) {
  1907. if( e->flg == 1 ) {
  1908. switch( e->cmd ) {
  1909. case cmdpartbrk:
  1910. if( e->tracktick > starttick) {
  1911. starttick = e->tracktick; // do not make empty parts
  1912. if( partno < 26 ) {
  1913. partno++;
  1914. ptt[partno] = starttick;
  1915. }
  1916. if( i < 255 ) buf[i++] = partno+'A';
  1917. vmask[partno] = -1;
  1918. nextp[partno] = partno+1;
  1919. }
  1920. break;
  1921. case cmdloop:
  1922. partloop = partno;
  1923. loop = 1; // start counting anew...
  1924. break;
  1925. case cmdvariant:
  1926. vmask[partno] = e->lpar;
  1927. break;
  1928. case cmdjump:
  1929. x = 0;
  1930. fading = 0;
  1931. normal = 0;
  1932. skip = 0;
  1933. pfade = &buf[i];
  1934. switch( e->par[jumptype] ) {
  1935. case jumpfade:
  1936. fading = 1;
  1937. case jumpnormal:
  1938. normal = 1;
  1939. x = partloop;
  1940. loop++;
  1941. break;
  1942. case jumpdsfade:
  1943. fading = 1;
  1944. case jumpdasegno:
  1945. x = partsegno;
  1946. break;
  1947. case jumpdcfade:
  1948. fading = 1;
  1949. case jumpdacapo:
  1950. x = 0;
  1951. break;
  1952. default:
  1953. x = 0;
  1954. break;
  1955. }
  1956. if( vmask[partno] != -1 ) nextp[partno] = x;
  1957. if( partno < 26 ) ptt[partno+1] = e->tracktick; // for handling ties over breaks
  1958. while( x <= partno ) {
  1959. if( skip == 1 && x == partcoda ) skip = 0;
  1960. y = !skip;
  1961. if( y ) {
  1962. if( !normal ) {
  1963. if( x == partfine ) skip = 2;
  1964. if( x == parttocoda ) skip = 1;
  1965. y = !skip;
  1966. }
  1967. if( !(vmask[x] & (1<<loop)) ) y = 0;
  1968. }
  1969. if( y ) {
  1970. if( i < 255 ) buf[i++] = x+'A';
  1971. if( nextp[x] != x + 1 ) loop++;
  1972. x = nextp[x];
  1973. }
  1974. else
  1975. x++;
  1976. }
  1977. if( fading && partno < 26 && i < 255 ) { // add single part with fading tracks
  1978. partno++;
  1979. ptt[partno] = e->tracktick;
  1980. buf[i] = '\0'; // close up pfade with zero byte
  1981. starttick = abc_fade_tracks(h, pfade, ptt);
  1982. buf[i++] = partno+'A';
  1983. partno++;
  1984. ptt[

Large files files are truncated, but you can click here to view the full file