|
@@ -19,22 +19,23 @@ cmXsH_t cmXsNullHandle = cmSTATIC_NULL_HANDLE;
|
19
|
19
|
|
20
|
20
|
enum
|
21
|
21
|
{
|
22
|
|
- kSectionXsFl = 0x0001, // rvalue holds section number
|
23
|
|
- kBarXsFl = 0x0002,
|
24
|
|
- kRestXsFl = 0x0004,
|
25
|
|
- kGraceXsFl = 0x0008,
|
26
|
|
- kDotXsFl = 0x0010,
|
27
|
|
- kChordXsFl = 0x0020,
|
28
|
|
- kDynXsFl = 0x0040,
|
29
|
|
- kEvenXsFl = 0x0080,
|
30
|
|
- kTempoXsFl = 0x0100,
|
31
|
|
- kHeelXsFl = 0x0200,
|
32
|
|
- kTieBegXsFl = 0x0400,
|
33
|
|
- kTieEndXsFl = 0x0800,
|
34
|
|
- kPedalDnXsFl = 0x1000,
|
35
|
|
- kPedalUpXsFl = 0x2000,
|
36
|
|
- kPedalUpDnXsFl = 0x4000,
|
37
|
|
- kMetronomeXsFl = 0x8000 // duration holds BPM
|
|
22
|
+ kSectionXsFl = 0x00001, // rvalue holds section number
|
|
23
|
+ kBarXsFl = 0x00002,
|
|
24
|
+ kRestXsFl = 0x00004,
|
|
25
|
+ kGraceXsFl = 0x00008,
|
|
26
|
+ kDotXsFl = 0x00010,
|
|
27
|
+ kChordXsFl = 0x00020,
|
|
28
|
+ kDynXsFl = 0x00040,
|
|
29
|
+ kEvenXsFl = 0x00080,
|
|
30
|
+ kTempoXsFl = 0x00100,
|
|
31
|
+ kHeelXsFl = 0x00200,
|
|
32
|
+ kTieBegXsFl = 0x00400,
|
|
33
|
+ kTieEndXsFl = 0x00800,
|
|
34
|
+ kTieProcXsFl = 0x01000,
|
|
35
|
+ kPedalDnXsFl = 0x02000,
|
|
36
|
+ kPedalUpXsFl = 0x04000,
|
|
37
|
+ kPedalUpDnXsFl = 0x08000,
|
|
38
|
+ kMetronomeXsFl = 0x10000 // duration holds BPM
|
38
|
39
|
};
|
39
|
40
|
|
40
|
41
|
struct cmXsMeas_str;
|
|
@@ -42,20 +43,23 @@ struct cmXsVoice_str;
|
42
|
43
|
|
43
|
44
|
typedef struct cmXsNote_str
|
44
|
45
|
{
|
45
|
|
- unsigned flags; // See k???XsFl
|
46
|
|
- unsigned pitch; // midi pitch
|
47
|
|
- unsigned tick; //
|
48
|
|
- unsigned duration; // duration in ticks
|
49
|
|
- unsigned pticks; // play ticks (0 for non-sounding notes)
|
50
|
|
- double rvalue; // 1/rvalue = rythmic value (1/0.5 double whole 1/1 whole 1/2 half 1/4=quarter note, 1/8=eighth note, ...)
|
51
|
|
- const cmChar_t* tvalue; // text value
|
|
46
|
+ unsigned flags; // See k???XsFl
|
|
47
|
+ unsigned pitch; // midi pitch
|
|
48
|
+ cmChar_t step; // A-G
|
|
49
|
+ unsigned octave; // sci pitch octave
|
|
50
|
+ int alter; // +n=sharps,-n=flats
|
|
51
|
+ unsigned tick; //
|
|
52
|
+ unsigned duration; // duration in ticks
|
|
53
|
+ double rvalue; // 1/rvalue = rythmic value (1/0.5 double whole 1/1 whole 1/2 half 1/4=quarter note, 1/8=eighth note, ...)
|
|
54
|
+ const cmChar_t* tvalue; // text value
|
52
|
55
|
|
53
|
56
|
const struct cmXsVoice_str* voice; // voice this note belongs to
|
54
|
57
|
const struct cmXsMeas_str* meas; // measure this note belongs to
|
55
|
|
- const cmXmlNode_t* xmlNode; // note xml ptr
|
56
|
58
|
|
57
|
|
- struct cmXsNote_str* mlink; // measure note list
|
58
|
|
- struct cmXsNote_str* slink; // time sorted event list
|
|
59
|
+ const cmXmlNode_t* xmlNode; // note xml ptr
|
|
60
|
+
|
|
61
|
+ struct cmXsNote_str* mlink; // measure note list
|
|
62
|
+ struct cmXsNote_str* slink; // time sorted event list
|
59
|
63
|
|
60
|
64
|
} cmXsNote_t;
|
61
|
65
|
|
|
@@ -232,7 +236,7 @@ cmXsRC_t _cmXScoreParsePartList( cmXScore_t* p )
|
232
|
236
|
return rc;
|
233
|
237
|
}
|
234
|
238
|
|
235
|
|
-cmXsRC_t _cmXScoreParsePitch( cmXScore_t* p, const cmXmlNode_t* nnp, unsigned* midiPitchRef )
|
|
239
|
+cmXsRC_t _cmXScoreParsePitch( cmXScore_t* p, const cmXmlNode_t* nnp, cmXsNote_t* np )
|
236
|
240
|
{
|
237
|
241
|
cmXsRC_t rc = kOkXsRC;
|
238
|
242
|
unsigned octave = 0;
|
|
@@ -254,169 +258,14 @@ cmXsRC_t _cmXScoreParsePitch( cmXScore_t* p, const cmXmlNode_t* nnp, unsigned*
|
254
|
258
|
|
255
|
259
|
midi += alter;
|
256
|
260
|
|
257
|
|
- *midiPitchRef = midi;
|
|
261
|
+ np->pitch = midi;
|
|
262
|
+ np->step = *step;
|
|
263
|
+ np->octave = octave;
|
|
264
|
+ np->alter = alter;
|
258
|
265
|
|
259
|
266
|
return rc;
|
260
|
267
|
}
|
261
|
268
|
|
262
|
|
-cmXsConnect_t* _cmXScoreFindTie( const cmXScore_t* p, unsigned pitch )
|
263
|
|
-{
|
264
|
|
- cmXsConnect_t* c = p->tieL;
|
265
|
|
- for(; c!=NULL; c=c->link)
|
266
|
|
- {
|
267
|
|
- assert( c->note != NULL );
|
268
|
|
- if( c->doneFl == false && c->note->pitch == pitch )
|
269
|
|
- return c;
|
270
|
|
- }
|
271
|
|
- return NULL;
|
272
|
|
-}
|
273
|
|
-
|
274
|
|
-cmXsRC_t _cmXScoreNewTie( cmXScore_t* p, const cmXsNote_t* note )
|
275
|
|
-{
|
276
|
|
- cmXsConnect_t* c;
|
277
|
|
-
|
278
|
|
- // check that an open tie with the same pitch does not exist
|
279
|
|
- if((c = _cmXScoreFindTie(p,note->pitch)) != NULL )
|
280
|
|
- {
|
281
|
|
- cmErrWarnMsg(&p->err,kUnterminatedTieXsRC,"The tie begun from note on line %i was not terminated. (pitch=%i)",c->note->xmlNode->line,c->note->pitch);
|
282
|
|
- c->doneFl = true; // close the unterminated tie
|
283
|
|
- }
|
284
|
|
-
|
285
|
|
- // allocate a new connection record
|
286
|
|
- c = cmLhAllocZ(p->lhH,cmXsConnect_t,1);
|
287
|
|
-
|
288
|
|
- // set the first note in the connection
|
289
|
|
- c->note = note;
|
290
|
|
-
|
291
|
|
- // append the new record to the end of the tie list
|
292
|
|
- if(p->tieL == NULL )
|
293
|
|
- p->tieL = c;
|
294
|
|
- else
|
295
|
|
- {
|
296
|
|
- cmXsConnect_t* cp = p->tieL;
|
297
|
|
- while( cp->link != NULL )
|
298
|
|
- cp = cp->link;
|
299
|
|
-
|
300
|
|
- cp->link = c;
|
301
|
|
- }
|
302
|
|
-
|
303
|
|
- return kOkXsRC;
|
304
|
|
-}
|
305
|
|
-
|
306
|
|
-cmXsRC_t _cmXScoreContinueTie( cmXScore_t* p, const cmXsNote_t* note, unsigned measNumb )
|
307
|
|
-{
|
308
|
|
- cmXsConnect_t* c;
|
309
|
|
-
|
310
|
|
- // find an open tie with the same pitch
|
311
|
|
- if((c = _cmXScoreFindTie(p,note->pitch)) == NULL )
|
312
|
|
- {
|
313
|
|
- cmErrWarnMsg(&p->err,kUnterminatedTieXsRC,"The tie ending on the note on line %i does not have an associated starting note. (pitch=%i)",note->xmlNode->line,note->pitch);
|
314
|
|
- return kOkXsRC;
|
315
|
|
- }
|
316
|
|
-
|
317
|
|
- // allocate a new connection record
|
318
|
|
- cmXsConnect_t* nc = cmLhAllocZ(p->lhH,cmXsConnect_t,1);
|
319
|
|
- nc->note = note;
|
320
|
|
-
|
321
|
|
- // add the note to the end of the tie list
|
322
|
|
- if( c->nlink == NULL )
|
323
|
|
- c->nlink = nc;
|
324
|
|
- else
|
325
|
|
- {
|
326
|
|
- cmXsConnect_t* cp = c->nlink;
|
327
|
|
- while( cp->nlink != NULL )
|
328
|
|
- cp=cp->nlink;
|
329
|
|
- cp->nlink = nc;
|
330
|
|
- }
|
331
|
|
-
|
332
|
|
- // if this is the last note in the tie ...
|
333
|
|
- if( cmIsFlag(note->flags,kTieEndXsFl) && cmIsNotFlag(note->flags,kTieBegXsFl) )
|
334
|
|
- {
|
335
|
|
- c->doneFl = true; // ... mark the tie list as complete ...
|
336
|
|
- c->closeFl= true; // ... and properly closed
|
337
|
|
- printf("tie done: meas=%i line=%i pitch=%i\n",measNumb,note->xmlNode->line,note->pitch);
|
338
|
|
- }
|
339
|
|
- return kOkXsRC;
|
340
|
|
-}
|
341
|
|
-
|
342
|
|
-cmXsRC_t _cmXScoreProcessTie( cmXScore_t* p, const cmXmlNode_t* np, cmXsNote_t* note, unsigned measNumb )
|
343
|
|
-{
|
344
|
|
- cmXsRC_t rc = kOkXsRC;
|
345
|
|
-
|
346
|
|
- // is this is first note in a tied pair
|
347
|
|
- if( cmXmlNodeHasChildWithAttrAndValue(np,"tie","type","start",NULL) )
|
348
|
|
- note->flags |= kTieBegXsFl;
|
349
|
|
-
|
350
|
|
- // is this is second note in a tied pair
|
351
|
|
- if( cmXmlNodeHasChildWithAttrAndValue(np,"tie","type","stop",NULL) )
|
352
|
|
- note->flags |= kTieEndXsFl;
|
353
|
|
-
|
354
|
|
- // if this is a tie start (and not a tie continue)
|
355
|
|
- if( cmIsFlag(note->flags,kTieBegXsFl) && cmIsNotFlag(note->flags,kTieEndXsFl) )
|
356
|
|
- rc = _cmXScoreNewTie(p,note);
|
357
|
|
- else
|
358
|
|
- // if this is a tie continue or end
|
359
|
|
- if( cmIsFlag(note->flags,kTieEndXsFl) )
|
360
|
|
- rc = _cmXScoreContinueTie(p,note,measNumb); // this is a tie end or continue
|
361
|
|
-
|
362
|
|
- return rc;
|
363
|
|
-}
|
364
|
|
-
|
365
|
|
-const cmXsNote_t* _cmXScoreResolveTie( const cmXsNote_t* note )
|
366
|
|
-{
|
367
|
|
- const cmXsMeas_t* m = note->meas;
|
368
|
|
- const cmXsNote_t* n = note->slink;
|
369
|
|
-
|
370
|
|
- while( n!=NULL )
|
371
|
|
- {
|
372
|
|
- for(; n!=NULL; n=n->slink)
|
373
|
|
- if( note->pitch==n->pitch && note->voice==n->voice )
|
374
|
|
- return n;
|
375
|
|
-
|
376
|
|
- if( m->link == NULL )
|
377
|
|
- break;
|
378
|
|
-
|
379
|
|
- // got to next measure
|
380
|
|
- if((m = m->link) == NULL )
|
381
|
|
- break;
|
382
|
|
-
|
383
|
|
- n = m->noteL;
|
384
|
|
- }
|
385
|
|
-
|
386
|
|
- return NULL;
|
387
|
|
-}
|
388
|
|
-
|
389
|
|
-cmXsRC_t _cmXScoreResolveTies( cmXScore_t* p )
|
390
|
|
-{
|
391
|
|
- cmXsRC_t rc = kOkXsRC;
|
392
|
|
-
|
393
|
|
- cmXsPart_t* pp = p->partL;
|
394
|
|
- for(; pp!=NULL; pp=pp->link)
|
395
|
|
- {
|
396
|
|
- cmXsMeas_t* mp = pp->measL;
|
397
|
|
- for(; mp!=NULL; mp=mp->link)
|
398
|
|
- {
|
399
|
|
- cmXsNote_t* np = mp->noteL;
|
400
|
|
- for(; np!=NULL; np=np->slink)
|
401
|
|
- if( cmIsFlag(np->flags,kTieBegXsFl) )
|
402
|
|
- {
|
403
|
|
- const cmXsNote_t* tnp;
|
404
|
|
- if((tnp = _cmXScoreResolveTie(np)) == NULL)
|
405
|
|
- {
|
406
|
|
-
|
407
|
|
- }
|
408
|
|
- else
|
409
|
|
- {
|
410
|
|
- }
|
411
|
|
- }
|
412
|
|
- }
|
413
|
|
- }
|
414
|
|
-
|
415
|
|
- return rc;
|
416
|
|
-}
|
417
|
|
-
|
418
|
|
-
|
419
|
|
-
|
420
|
269
|
cmXsRC_t _cmXScoreParseNoteRValue( cmXScore_t* p, const cmXmlNode_t* nnp, const cmChar_t* label, double* rvalueRef )
|
421
|
270
|
{
|
422
|
271
|
typedef struct map_str
|
|
@@ -533,7 +382,7 @@ cmXsRC_t _cmXScoreParseColor( cmXScore_t* p, const cmXmlNode_t* nnp, cmXsNote_t
|
533
|
382
|
return rc;
|
534
|
383
|
}
|
535
|
384
|
|
536
|
|
-cmXsRC_t _cmXScoreParseNote(cmXScore_t* p, cmXsMeas_t* meas, const cmXmlNode_t* nnp, unsigned* tickRef )
|
|
385
|
+cmXsRC_t _cmXScoreParseNote(cmXScore_t* p, cmXsMeas_t* meas, const cmXmlNode_t* nnp, unsigned* tick0Ref, unsigned* tickRef )
|
537
|
386
|
{
|
538
|
387
|
cmXsRC_t rc = kOkXsRC;
|
539
|
388
|
cmXsNote_t* note = cmLhAllocZ(p->lhH,cmXsNote_t,1);
|
|
@@ -548,7 +397,7 @@ cmXsRC_t _cmXScoreParseNote(cmXScore_t* p, cmXsMeas_t* meas, const cmXmlNode_t*
|
548
|
397
|
|
549
|
398
|
// if this note has a pitch
|
550
|
399
|
if( cmXmlNodeHasChild(nnp,"pitch",NULL) )
|
551
|
|
- if((rc = _cmXScoreParsePitch(p,nnp,¬e->pitch)) != kOkXsRC )
|
|
400
|
+ if((rc = _cmXScoreParsePitch(p,nnp,note)) != kOkXsRC )
|
552
|
401
|
return rc;
|
553
|
402
|
|
554
|
403
|
// get the note duration
|
|
@@ -570,9 +419,13 @@ cmXsRC_t _cmXScoreParseNote(cmXScore_t* p, cmXsMeas_t* meas, const cmXmlNode_t*
|
570
|
419
|
if( cmXmlNodeHasChild(nnp,"chord",NULL) )
|
571
|
420
|
note->flags |= kChordXsFl;
|
572
|
421
|
|
573
|
|
- // process ties attached to this note
|
574
|
|
- if((rc = _cmXScoreProcessTie(p,nnp,note,meas->number)) != kOkXsRC )
|
575
|
|
- return rc;
|
|
422
|
+ // is this is first note in a tied pair
|
|
423
|
+ if( cmXmlNodeHasChildWithAttrAndValue(nnp,"tie","type","start",NULL) )
|
|
424
|
+ note->flags |= kTieBegXsFl;
|
|
425
|
+
|
|
426
|
+ // is this is second note in a tied pair
|
|
427
|
+ if( cmXmlNodeHasChildWithAttrAndValue(nnp,"tie","type","stop",NULL) )
|
|
428
|
+ note->flags |= kTieEndXsFl;
|
576
|
429
|
|
577
|
430
|
// has 'heel' mark
|
578
|
431
|
if( cmXmlNodeHasChild(nnp,"notations","technical","heel",NULL) )
|
|
@@ -586,10 +439,19 @@ cmXsRC_t _cmXScoreParseNote(cmXScore_t* p, cmXsMeas_t* meas, const cmXmlNode_t*
|
586
|
439
|
if((rc = _cmXScoreParseNoteRValue(p,nnp,"type",¬e->rvalue)) != kOkXsRC )
|
587
|
440
|
return rc;
|
588
|
441
|
|
589
|
|
- note->tick = *tickRef;
|
590
|
442
|
|
591
|
|
- if( cmIsNotFlag(note->flags,kChordXsFl) )
|
|
443
|
+ // if this is a chord note
|
|
444
|
+ if( cmIsFlag(note->flags,kChordXsFl) )
|
|
445
|
+ {
|
|
446
|
+ note->tick = *tick0Ref; // then use the onset time from the previous note and do not advance time
|
|
447
|
+ }
|
|
448
|
+ else
|
|
449
|
+ {
|
|
450
|
+ *tick0Ref = *tickRef;
|
|
451
|
+ note->tick = *tickRef;
|
|
452
|
+
|
592
|
453
|
*tickRef += note->duration;
|
|
454
|
+ }
|
593
|
455
|
|
594
|
456
|
return _cmXScorePushNote(p, meas, voiceId, note );
|
595
|
457
|
}
|
|
@@ -620,6 +482,7 @@ cmXsRC_t _cmXScoreParseDirection(cmXScore_t* p, cmXsMeas_t* meas, const cmXmlNo
|
620
|
482
|
double rvalue = 0;
|
621
|
483
|
const cmChar_t* tvalue = NULL;
|
622
|
484
|
unsigned duration = 0;
|
|
485
|
+ bool pushFl = true;
|
623
|
486
|
|
624
|
487
|
cmXmlNodeInt(dnp, &offset, "offset", NULL );
|
625
|
488
|
|
|
@@ -668,9 +531,15 @@ cmXsRC_t _cmXScoreParseDirection(cmXScore_t* p, cmXsMeas_t* meas, const cmXmlNo
|
668
|
531
|
flags = kSectionXsFl;
|
669
|
532
|
}
|
670
|
533
|
}
|
|
534
|
+ else
|
|
535
|
+ {
|
|
536
|
+ pushFl = false;
|
|
537
|
+ }
|
671
|
538
|
|
672
|
|
- return _cmXScorePushNonNote(p,meas,dnp,tick+offset,duration,rvalue,tvalue,flags);
|
673
|
|
-
|
|
539
|
+ if( pushFl )
|
|
540
|
+ rc = _cmXScorePushNonNote(p,meas,dnp,tick+offset,duration,rvalue,tvalue,flags);
|
|
541
|
+
|
|
542
|
+ return rc;
|
674
|
543
|
}
|
675
|
544
|
|
676
|
545
|
|
|
@@ -679,6 +548,7 @@ cmXsRC_t _cmXScoreParseMeasure(cmXScore_t* p, cmXsPart_t* pp, const cmXmlNode_t*
|
679
|
548
|
cmXsRC_t rc = kOkXsRC;
|
680
|
549
|
const cmXmlNode_t* np = NULL;
|
681
|
550
|
unsigned tick = 0;
|
|
551
|
+ unsigned tick0= 0;
|
682
|
552
|
|
683
|
553
|
// allocate the 'measure' record
|
684
|
554
|
cmXsMeas_t* meas = cmLhAllocZ(p->lhH,cmXsMeas_t,1);
|
|
@@ -719,7 +589,7 @@ cmXsRC_t _cmXScoreParseMeasure(cmXScore_t* p, cmXsPart_t* pp, const cmXmlNode_t*
|
719
|
589
|
// if this is a 'note' node
|
720
|
590
|
if( cmTextCmp(np->label,"note") == 0 )
|
721
|
591
|
{
|
722
|
|
- rc = _cmXScoreParseNote(p,meas,np,&tick);
|
|
592
|
+ rc = _cmXScoreParseNote(p,meas,np,&tick0,&tick);
|
723
|
593
|
}
|
724
|
594
|
else
|
725
|
595
|
// if this is a 'backup' node
|
|
@@ -728,6 +598,7 @@ cmXsRC_t _cmXScoreParseMeasure(cmXScore_t* p, cmXsPart_t* pp, const cmXmlNode_t*
|
728
|
598
|
unsigned backup;
|
729
|
599
|
cmXmlNodeUInt(np,&backup,"duration",NULL);
|
730
|
600
|
tick -= backup;
|
|
601
|
+ tick0 = tick;
|
731
|
602
|
}
|
732
|
603
|
else
|
733
|
604
|
// if this is a 'direction' node
|
|
@@ -813,6 +684,71 @@ void _cmXScoreSort( cmXScore_t* p )
|
813
|
684
|
}
|
814
|
685
|
}
|
815
|
686
|
|
|
687
|
+bool _cmXScoreFindTiedNote( cmXScore_t* p, cmXsMeas_t* mp, cmXsNote_t* np )
|
|
688
|
+{
|
|
689
|
+ cmXsNote_t* nnp = np->slink;
|
|
690
|
+ unsigned measNumb = mp->number;
|
|
691
|
+ unsigned measNumb0= measNumb;
|
|
692
|
+ cmChar_t acc = np->alter==-1?'b' : (np->alter==1?'#':' ');
|
|
693
|
+
|
|
694
|
+ for(; mp!=NULL; mp=mp->link)
|
|
695
|
+ {
|
|
696
|
+ if( nnp == NULL )
|
|
697
|
+ nnp = mp->noteL;
|
|
698
|
+
|
|
699
|
+ for(; nnp!=NULL; nnp=nnp->slink)
|
|
700
|
+ {
|
|
701
|
+ if( /*nnp->voice->id == np->voice->id &&*/ nnp->step == np->step && nnp->octave == np->octave )
|
|
702
|
+ {
|
|
703
|
+ nnp->flags |= kTieProcXsFl;
|
|
704
|
+
|
|
705
|
+ if( cmIsNotFlag(nnp->flags,kTieBegXsFl) )
|
|
706
|
+ {
|
|
707
|
+ return true;
|
|
708
|
+ }
|
|
709
|
+
|
|
710
|
+ measNumb0 = mp->number;
|
|
711
|
+ }
|
|
712
|
+ }
|
|
713
|
+
|
|
714
|
+ // if a measure was completed and no end note was found ... then the tie is unterminated
|
|
715
|
+ // (a tie must be continued in every measure which it passes through)
|
|
716
|
+ if( measNumb0 < mp->number )
|
|
717
|
+ break;
|
|
718
|
+
|
|
719
|
+ }
|
|
720
|
+
|
|
721
|
+ cmErrWarnMsg(&p->err,kUnterminatedTieXsRC,"The tied %c%c%i in measure %i was not terminated.",np->step,acc,np->octave,measNumb);
|
|
722
|
+ return false;
|
|
723
|
+}
|
|
724
|
+
|
|
725
|
+void _cmXScoreProcessTies( cmXScore_t* p )
|
|
726
|
+{
|
|
727
|
+ unsigned n = 0;
|
|
728
|
+ unsigned m = 0;
|
|
729
|
+
|
|
730
|
+ cmXsPart_t* pp = p->partL;
|
|
731
|
+ for(; pp!=NULL; pp=pp->link)
|
|
732
|
+ {
|
|
733
|
+ cmXsMeas_t* mp = pp->measL;
|
|
734
|
+ for(; mp!=NULL; mp=mp->link)
|
|
735
|
+ {
|
|
736
|
+ cmXsNote_t* np = mp->noteL;
|
|
737
|
+
|
|
738
|
+ for(; np!=NULL; np=np->slink)
|
|
739
|
+ if( cmIsFlag(np->flags,kTieBegXsFl) && cmIsNotFlag(np->flags,kTieProcXsFl))
|
|
740
|
+ {
|
|
741
|
+ if( _cmXScoreFindTiedNote(p,mp,np) )
|
|
742
|
+ m += 1;
|
|
743
|
+ n += 1;
|
|
744
|
+ }
|
|
745
|
+
|
|
746
|
+ }
|
|
747
|
+ }
|
|
748
|
+
|
|
749
|
+ printf("Found:%i Not Found:%i\n",m,n-m);
|
|
750
|
+}
|
|
751
|
+
|
816
|
752
|
cmXsRC_t cmXScoreInitialize( cmCtx_t* ctx, cmXsH_t* hp, const cmChar_t* xmlFn )
|
817
|
753
|
{
|
818
|
754
|
cmXsRC_t rc = kOkXsRC;
|
|
@@ -850,6 +786,8 @@ cmXsRC_t cmXScoreInitialize( cmCtx_t* ctx, cmXsH_t* hp, const cmChar_t* xmlFn )
|
850
|
786
|
// fill in the note->slink chain to link the notes in each measure in time order
|
851
|
787
|
_cmXScoreSort(p);
|
852
|
788
|
|
|
789
|
+ _cmXScoreProcessTies(p);
|
|
790
|
+
|
853
|
791
|
// CSV output initialize failed.
|
854
|
792
|
if( cmCsvInitialize(&p->csvH,ctx) != kOkCsvRC )
|
855
|
793
|
rc = cmErrMsg(&p->err,kCsvFailXsRC,"CSV output object create failed.");
|
|
@@ -899,17 +837,27 @@ void _cmXScoreReportNote( cmRpt_t* rpt, const cmXsNote_t* note )
|
899
|
837
|
const cmChar_t* d = cmIsFlag(note->flags,kDynXsFl) ? "d" : "-";
|
900
|
838
|
const cmChar_t* t = cmIsFlag(note->flags,kTempoXsFl) ? "t" : "-";
|
901
|
839
|
const cmChar_t* P = cmIsFlag(note->flags,kPedalDnXsFl) ? "V" : "-";
|
|
840
|
+ const cmChar_t* S = cmIsFlag(note->flags,kSectionXsFl) ? "S" : "-";
|
902
|
841
|
const cmChar_t* H = cmIsFlag(note->flags,kHeelXsFl) ? "H" : "-";
|
903
|
842
|
const cmChar_t* T0 = cmIsFlag(note->flags,kTieBegXsFl) ? "T" : "-";
|
904
|
843
|
const cmChar_t* T1 = cmIsFlag(note->flags,kTieEndXsFl) ? "_" : "-";
|
905
|
844
|
P = cmIsFlag(note->flags,kPedalUpXsFl) ? "^" : P;
|
906
|
845
|
P = cmIsFlag(note->flags,kPedalUpDnXsFl) ? "X" : P;
|
907
|
|
- const cmChar_t* N = note->pitch==0 ? " " : cmMidiToSciPitch( note->pitch, NULL, 0 );
|
908
|
|
- cmRptPrintf(rpt," %5i %5i %4.1f %3s %s%s%s%s%s%s%s%s%s%s%s%s",note->tick,note->duration,note->rvalue,N,B,R,G,D,C,e,d,t,P,H,T0,T1);
|
|
846
|
+ //const cmChar_t* N = note->pitch==0 ? " " : cmMidiToSciPitch( note->pitch, NULL, 0 );
|
|
847
|
+
|
|
848
|
+ cmChar_t N[] = {'\0','\0','\0','\0'};
|
|
849
|
+ cmChar_t acc = note->alter==-1?'b':(note->alter==1?'#':' ');
|
|
850
|
+ snprintf(N,4,"%c%c%1i",note->step,acc,note->octave);
|
|
851
|
+
|
|
852
|
+
|
|
853
|
+ cmRptPrintf(rpt," %3i %5i %5i %4.1f %3s %s%s%s%s%s%s%s%s%s%s%s%s%s",note->voice->id,note->tick,note->duration,note->rvalue,N,B,R,G,D,C,e,d,t,P,S,H,T0,T1);
|
909
|
854
|
|
910
|
855
|
if( cmIsFlag(note->flags,kSectionXsFl) )
|
911
|
856
|
cmRptPrintf(rpt," %s",cmStringNullGuard(note->tvalue));
|
912
|
857
|
|
|
858
|
+ if( cmIsFlag(note->flags,kMetronomeXsFl) )
|
|
859
|
+ cmRptPrintf(rpt," %i bpm",note->duration);
|
|
860
|
+
|
913
|
861
|
printf("\n");
|
914
|
862
|
|
915
|
863
|
}
|
|
@@ -1261,6 +1209,26 @@ void cmXScoreReport( cmXsH_t h, cmRpt_t* rpt, bool sortFl )
|
1261
|
1209
|
}
|
1262
|
1210
|
}
|
1263
|
1211
|
|
|
1212
|
+cmXsRC_t cmXScoreWriteMidi( cmXsH_t h, const cmChar_t* fn )
|
|
1213
|
+{
|
|
1214
|
+ assert(0); // function not implemented
|
|
1215
|
+ cmXScore_t* p = _cmXScoreHandleToPtr(h);
|
|
1216
|
+ cmXsPart_t* pp = p->partL;
|
|
1217
|
+
|
|
1218
|
+ for(; pp!=NULL; pp=pp->link)
|
|
1219
|
+ {
|
|
1220
|
+ const cmXsMeas_t* meas = pp->measL;
|
|
1221
|
+ for(; meas!=NULL; meas=meas->link)
|
|
1222
|
+ {
|
|
1223
|
+
|
|
1224
|
+ const cmXsNote_t* note = meas->noteL;
|
|
1225
|
+ for(; note!=NULL; note=note->slink)
|
|
1226
|
+ {
|
|
1227
|
+
|
|
1228
|
+ }
|
|
1229
|
+ }
|
|
1230
|
+ }
|
|
1231
|
+}
|
1264
|
1232
|
|
1265
|
1233
|
cmXsRC_t cmXScoreTest( cmCtx_t* ctx, const cmChar_t* fn )
|
1266
|
1234
|
{
|