Browse Source

cmXScore.h/c : Added dynamics, sostenuto,tick value, and ordering updating from 'reorder' file.

master
kevin 8 years ago
parent
commit
b1f5026916
2 changed files with 303 additions and 27 deletions
  1. 301
    27
      app/cmXScore.c
  2. 2
    0
      app/cmXScore.h

+ 301
- 27
app/cmXScore.c View File

@@ -1327,8 +1327,11 @@ bool     cmXScoreIsValid( cmXsH_t h )
1327 1327
 { return h.h != NULL; }
1328 1328
 
1329 1329
 //-------------------------------------------------------------------------------------------
1330
+
1331
+
1330 1332
 typedef struct
1331 1333
 {
1334
+  unsigned    idx;
1332 1335
   unsigned    voice;
1333 1336
   unsigned    locIdx;
1334 1337
   unsigned    tick;
@@ -1338,9 +1341,12 @@ typedef struct
1338 1341
   unsigned    flags;
1339 1342
   cmXsNote_t* note;
1340 1343
   int         index;
1344
+  unsigned    dynId;  // 0=ignore >0 dynamic level marking
1345
+  unsigned    sostId; // 0=ignore 1=down 2=up
1346
+  unsigned    newTick;   // 0=ignore >0 new tick value
1341 1347
 } cmXsReorder_t;
1342 1348
 
1343
-cmXsNote_t*  _cmXsReorderFindNote( cmXScore_t* p, unsigned measNumb, const cmXsReorder_t* r, int* indexRef )
1349
+cmXsNote_t*  _cmXsReorderFindNote( cmXScore_t* p, unsigned measNumb, const cmXsReorder_t* r, unsigned iii, int* indexRef )
1344 1350
 {
1345 1351
   cmXsPart_t* pp = p->partL;
1346 1352
   for(; pp!=NULL; pp=pp->link)
@@ -1349,13 +1355,18 @@ cmXsNote_t*  _cmXsReorderFindNote( cmXScore_t* p, unsigned measNumb, const cmXsR
1349 1355
     for(; mp!=NULL; mp=mp->link)
1350 1356
       if( mp->number == measNumb)
1351 1357
       {
1352
-        cmXsNote_t* np = mp->noteL;
1353
-        int index = 0;
1358
+
1359
+        cmXsNote_t* np    = mp->noteL;
1360
+        int         index = 0;
1354 1361
         for(; np!=NULL; np=np->slink,++index)
1355 1362
         {
1356 1363
           // Set 'mask' to the flags which should be ignored in the comparision
1357
-          unsigned mask    = kTieProcXsFl | kMetronomeXsFl | kBegGroupXsFl | kEndGroupXsFl; 
1358
-          unsigned npFlags = cmClrFlag(np->flags,mask);
1364
+          // unsigned mask    = kTieProcXsFl | kMetronomeXsFl | kBegGroupXsFl | kEndGroupXsFl; 
1365
+          // unsigned npFlags = cmClrFlag(np->flags,mask);
1366
+
1367
+          //if( measNumb==56 && iii == 13 )
1368
+          //  printf("voc:%i loc:%i tick:%i dur:%i rval:%f pitch:%i index:%i\n",np->voice->id,np->locIdx,np->tick,np->duration,np->rvalue,np->pitch,index);
1369
+
1359 1370
           
1360 1371
           if( np->voice->id == r->voice &&
1361 1372
             np->locIdx == r->locIdx &&
@@ -1363,16 +1374,21 @@ cmXsNote_t*  _cmXsReorderFindNote( cmXScore_t* p, unsigned measNumb, const cmXsR
1363 1374
             np->duration == r->durtn &&
1364 1375
             np->rvalue == r->rval &&
1365 1376
             np->pitch == r->midi &&
1366
-            npFlags == r->flags )
1377
+            index == r->idx // &&
1378
+            //npFlags == r->flags
1379
+              )
1367 1380
           {
1368 1381
             *indexRef = index;
1369 1382
             return np;
1370 1383
           }
1371 1384
         }
1385
+
1386
+        printf("blah");
1387
+        
1372 1388
       }
1373 1389
   }
1374 1390
 
1375
-  cmErrMsg(&p->err,kSyntaxErrorXsRC,"Reorder note not found.");
1391
+  cmErrMsg(&p->err,kSyntaxErrorXsRC,"Reorder note not found meas:%i index:%i.",measNumb,iii);
1376 1392
   return NULL;
1377 1393
 }
1378 1394
 
@@ -1417,18 +1433,16 @@ void _cmXScoreReorderFixTimes( cmXScore_t* p, unsigned measNumb, cmXsReorder_t*
1417 1433
     if( i-1 > 0 )
1418 1434
     {
1419 1435
       mm_cnt += rV[i-1].index+1 == rV[i].index;
1420
-      fl = rV[i].note->secs > rV[i-1].note->secs;
1436
+      fl = rV[i].note->secs >= rV[i-1].note->secs || rV[i].note->secs == 0;
1421 1437
     }
1422 1438
     
1423 1439
     if( i+1 < rN )
1424 1440
       mm_cnt += rV[i].index == rV[i+1].index-1;
1425 1441
 
1426 1442
     
1427
-    printf("%i %i %10.3f %s\n",i,mm_cnt,rV[i].note->secs,fl?" ":"*");
1443
+    //printf("%i %i %10.3f %s\n",i,mm_cnt,rV[i].note->secs,fl?" ":"*");
1428 1444
     
1429 1445
   }
1430
-
1431
-  
1432 1446
 }
1433 1447
 
1434 1448
 cmXsRC_t _cmXScoreReorderMeas( cmXScore_t* p, unsigned measNumb, cmXsReorder_t* rV, unsigned rN )
@@ -1441,11 +1455,11 @@ cmXsRC_t _cmXScoreReorderMeas( cmXScore_t* p, unsigned measNumb, cmXsReorder_t*
1441 1455
   // set the 'note' field on each cmXsReorder_t record
1442 1456
   for(i=0; i<rN; ++i)
1443 1457
   {
1444
-    if((rV[i].note = _cmXsReorderFindNote(p,measNumb,rV+i,&rV[i].index)) == NULL )
1458
+    if((rV[i].note = _cmXsReorderFindNote(p,measNumb,rV+i,i,&rV[i].index)) == NULL )
1445 1459
       return kSyntaxErrorXsRC;
1446 1460
   }
1447 1461
 
1448
-  _cmXScoreReorderFixTimes(p, measNumb, rV, rN );
1462
+  //_cmXScoreReorderFixTimes(p, measNumb, rV, rN );
1449 1463
   
1450 1464
   cmXsMeas_t* mp  = rV[0].note->meas;
1451 1465
   cmXsNote_t* n0p = NULL;
@@ -1461,6 +1475,9 @@ cmXsRC_t _cmXScoreReorderMeas( cmXScore_t* p, unsigned measNumb, cmXsReorder_t*
1461 1475
     else
1462 1476
       n0p->slink = rV[i].note;
1463 1477
 
1478
+    if( rV[i].newTick != 0 )
1479
+      rV[i].note->tick = rV[i].newTick;
1480
+
1464 1481
     n0p = rV[i].note;
1465 1482
     n0p->slink = NULL;
1466 1483
   }
@@ -1469,6 +1486,153 @@ cmXsRC_t _cmXScoreReorderMeas( cmXScore_t* p, unsigned measNumb, cmXsReorder_t*
1469 1486
 
1470 1487
 }
1471 1488
 
1489
+typedef struct _cmXScoreDynMark_str
1490
+{
1491
+  const cmChar_t* mark;
1492
+  unsigned        id;
1493
+} _cmXScoreDynMark_t;
1494
+
1495
+_cmXScoreDynMark_t _cmXScoreDynMarkArray[] =
1496
+{
1497
+  {"pppp",  1},
1498
+  {"pppp+", 2},
1499
+  {"ppp-",  2},
1500
+  {"ppp",   4},
1501
+  {"ppp+",  5},
1502
+  {"pp-",   5},
1503
+  {"pp",    7},
1504
+  {"pp+",   8},
1505
+  {"p-",    8},
1506
+  {"p",     9},
1507
+  {"mp",   10},
1508
+  {"mp+",  11},
1509
+  {"mf-",  11},
1510
+  {"mf",   12},
1511
+  {"f",    13},
1512
+  {"f+",   14},
1513
+  {"ff",   15},
1514
+  {"ff+",  16},
1515
+  {"fff",  17},
1516
+  {NULL,0}
1517
+  
1518
+};
1519
+
1520
+cmXsRC_t _cmXScoreReorderParseDyn(cmXScore_t* p, const cmChar_t* b, unsigned lineNumb, unsigned* dynIdRef )
1521
+{
1522
+  cmXsRC_t rc = kOkXsRC;
1523
+  const cmChar_t* s;
1524
+
1525
+  *dynIdRef = 0;
1526
+  
1527
+  if( (s = strchr(b,'!')) == NULL )
1528
+    return rc;
1529
+  
1530
+  ++s;
1531
+  
1532
+  if( *s == 0 )
1533
+    return cmErrMsg(&p->err,kSyntaxErrorXsRC,"Unexpected end-of-line on dynamics parsing on line:%i.",lineNumb);
1534
+
1535
+  if( *s == '(' )
1536
+    ++s;
1537
+
1538
+  if( *s == 0 )
1539
+    return cmErrMsg(&p->err,kSyntaxErrorXsRC,"Unexpected end-of-line on dynamics parsing on line:%i.",lineNumb);
1540
+
1541
+  unsigned i      = 0;
1542
+  unsigned j      = 0;
1543
+  unsigned n      = 6;
1544
+  bool     doneFl = false;
1545
+  cmChar_t mark[n+1];
1546
+  memset(mark,0,n+1);
1547
+  
1548
+  for(i=0; i<n && doneFl==false; ++i)
1549
+  {
1550
+    switch(s[i])
1551
+    {
1552
+      case 'm':
1553
+      case 'p':
1554
+      case 'f':
1555
+      case '+':
1556
+      case '-':
1557
+        mark[j++] = s[i];
1558
+        break;
1559
+        
1560
+      case ')':
1561
+      case 0:
1562
+      case ' ':        
1563
+      case '\n':
1564
+      default:
1565
+        doneFl = true;
1566
+        break;
1567
+        
1568
+    }
1569
+  }
1570
+
1571
+  if( !doneFl )
1572
+    return cmErrMsg(&p->err,kSyntaxErrorXsRC,"Illegal dynamic mark (%s) syntax on line:%i.",mark,lineNumb);
1573
+
1574
+  for(j=0; _cmXScoreDynMarkArray[j].mark!=NULL; ++j)
1575
+    if( strcmp(mark,_cmXScoreDynMarkArray[i].mark) == 0 )
1576
+      break;
1577
+
1578
+  if( _cmXScoreDynMarkArray[i].mark == NULL )
1579
+    return cmErrMsg(&p->err,kSyntaxErrorXsRC,"The dynamic mark '%s' is not legal on line:%i.",mark,lineNumb);
1580
+
1581
+
1582
+  *dynIdRef = _cmXScoreDynMarkArray[i].id;
1583
+      
1584
+  return rc;
1585
+}
1586
+
1587
+
1588
+cmXsRC_t  _cmXScoreReorderParseSost(cmXScore_t* p, const cmChar_t* b, unsigned line, unsigned* sostIdRef )
1589
+{
1590
+  cmXsRC_t rc = kOkXsRC;
1591
+  const cmChar_t* s;
1592
+  *sostIdRef = 0;
1593
+
1594
+  if((s = strchr(b,'~')) == NULL )
1595
+    return rc;
1596
+
1597
+  ++s;
1598
+
1599
+  switch( *s )
1600
+  {
1601
+    case 'd':
1602
+      *sostIdRef = 1;  // pedal down just after this note onset
1603
+      break;
1604
+
1605
+    case 'u':
1606
+      *sostIdRef = 2; // pedal up
1607
+      break;
1608
+            
1609
+    default:
1610
+      return cmErrMsg(&p->err,kSyntaxErrorXsRC,"Unexpected sostenuto marking '%c' on line %i.",*s,line);
1611
+  }
1612
+
1613
+  return rc;
1614
+}
1615
+
1616
+cmXsRC_t  _cmXScoreReorderParseTick(cmXScore_t* p, const cmChar_t* b, unsigned line, unsigned* tickRef )
1617
+{
1618
+  cmXsRC_t rc = kOkXsRC;
1619
+  const cmChar_t* s;
1620
+
1621
+  if((s = strchr(b,'@')) == NULL )
1622
+    return rc;
1623
+
1624
+  ++s;
1625
+
1626
+  if(!isdigit(*s))
1627
+      return cmErrMsg(&p->err,kSyntaxErrorXsRC,"Unexpected tick reorder value '%c' on line %i.",*s,line);
1628
+
1629
+  if(sscanf(s,"%i",tickRef) != 1 )
1630
+      return cmErrMsg(&p->err,kSyntaxErrorXsRC,"tick reorder parse failed on line %i.",line);
1631
+  
1632
+  return rc;
1633
+}
1634
+
1635
+
1472 1636
 cmXsRC_t cmXScoreReorder( cmXsH_t h, const cmChar_t* fn )
1473 1637
 {
1474 1638
   typedef enum { kFindMeasStId, kFindEventStId, kReadEventStId } stateId_t;
@@ -1513,14 +1677,18 @@ cmXsRC_t cmXScoreReorder( cmXsH_t h, const cmChar_t* fn )
1513 1677
           memset(&r,0,sizeof(r));
1514 1678
           
1515 1679
           // parse an event line
1516
-          if( sscanf(b,"%i %i %i %i %f",&r.voice,&r.locIdx,&r.tick,&r.durtn,&r.rval) == 5 )
1680
+          if( sscanf(b,"%i %i %i %i %i %f",&r.idx,&r.voice,&r.locIdx,&r.tick,&r.durtn,&r.rval) == 6 )
1517 1681
           {
1518 1682
             assert( strlen(b)>=52);
1519
-            if( b[35] != ' ')
1683
+            int PC = 39; // text file column where first pitch char occurs
1684
+            
1685
+            if( b[PC] == ' ')
1686
+              r.midi = 0;
1687
+            else
1520 1688
             {
1521
-              pitchStr[0] = b[35];
1522
-              pitchStr[1] = b[36];
1523
-              pitchStr[2] = b[37];              
1689
+              pitchStr[0] = b[PC+0];
1690
+              pitchStr[1] = b[PC+1];
1691
+              pitchStr[2] = b[PC+2];              
1524 1692
               pitchStr[3] = 0;
1525 1693
               
1526 1694
               if( !isdigit(pitchStr[2]) )
@@ -1535,11 +1703,20 @@ cmXsRC_t cmXScoreReorder( cmXsH_t h, const cmChar_t* fn )
1535 1703
 
1536 1704
                 r.midi = cmSciPitchToMidi(pitchStr);
1537 1705
               }
1538
-                           
1706
+
1539 1707
             }
1540 1708
 
1541 1709
             
1710
+            // parse the dynamic marking
1711
+            if((rc = _cmXScoreReorderParseDyn(p,b,ln+1,&r.dynId)) != kOkXsRC )
1712
+              goto errLabel;
1542 1713
             
1714
+            // parse the sostenuto pedal marking
1715
+            if((rc = _cmXScoreReorderParseSost(p,b,ln+1, &r.sostId)) != kOkXsRC )
1716
+              goto errLabel;
1717
+
1718
+            if((rc = _cmXScoreReorderParseTick(p, b, ln+1, &r.newTick)) != kOkXsRC )
1719
+              goto errLabel;            
1543 1720
 
1544 1721
             // store the record
1545 1722
             assert( ri < rN );
@@ -1550,8 +1727,8 @@ cmXsRC_t cmXScoreReorder( cmXsH_t h, const cmChar_t* fn )
1550 1727
 
1551 1728
           // the end of the measure was encountered -
1552 1729
           // reorder the measure based on the cmXsReorder_t in rV[ri]
1553
-          //if((rc =  _cmXScoreReorderMeas(p, measNumb, rV, ri )) != kOkXsRC )
1554
-          //  goto errLabel;
1730
+          if((rc =  _cmXScoreReorderMeas(p, measNumb, rV, ri )) != kOkXsRC )
1731
+            goto errLabel;
1555 1732
 
1556 1733
           ri = 0;
1557 1734
 
@@ -1574,13 +1751,110 @@ cmXsRC_t cmXScoreReorder( cmXsH_t h, const cmChar_t* fn )
1574 1751
 
1575 1752
   }
1576 1753
 
1577
-  //errLabel:
1754
+ errLabel:
1755
+  cmFileClose(&fH);
1756
+  cmMemFree(b);
1757
+  return rc;
1758
+}
1759
+
1760
+
1761
+cmXsRC_t cmXScoreReorder1( cmXsH_t h, const cmChar_t* fn )
1762
+{
1763
+  typedef enum { kFindMeasStId, kFindEventStId, kReadEventStId } stateId_t;
1764
+
1765
+  cmXsRC_t      rc      = kOkXsRC;
1766
+  cmXScore_t*   p       = _cmXScoreHandleToPtr(h);
1767
+  cmFileH_t     fH      = cmFileNullHandle;
1768
+  cmFileH_t     ofH     = cmFileNullHandle;
1769
+  cmChar_t*     b       = NULL;
1770
+  unsigned      bN      = 0;
1771
+  unsigned      ln      = 0;
1772
+  unsigned      measNumb = 0;
1773
+  stateId_t     stateId = kFindMeasStId;
1774
+  const cmChar_t* ofn   = "/Users/kevin/temp/orig_reorder.txt";
1775
+  unsigned t0 = 0;
1776
+  
1777
+  if( cmFileOpen(&fH,fn,kReadFileFl,p->err.rpt) != kOkFileRC )
1778
+  {
1779
+    rc = cmErrMsg(&p->err,kFileFailXsRC,"The reordering file '%s' could not be opened.",cmStringNullGuard(fn));
1780
+    return rc;
1781
+  }
1782
+
1783
+  if( cmFileOpen(&ofH,ofn,kWriteFileFl,p->err.rpt) != kOkFileRC )
1784
+  {
1785
+    rc = cmErrMsg(&p->err,kFileFailXsRC,"The reordering file '%s' could not be opened.",cmStringNullGuard(ofn));
1786
+    goto errLabel;
1787
+  }
1788
+  
1789
+
1790
+  for(; cmFileGetLineAuto(fH,&b,&bN)==kOkFileRC; ++ln)
1791
+  {
1792
+    bool fl = false;
1793
+    
1794
+    switch( stateId )
1795
+    {
1796
+      case kFindEventStId:  // scanning past labels to an event line
1797
+        {
1798
+          unsigned voice,loc;
1799
+          if( sscanf(b,"%i %i",&voice,&loc) != 2 )
1800
+            continue;
1801
+
1802
+          stateId = kReadEventStId;
1803
+          t0 = 0;
1804
+        }
1805
+        // fall through
1806
+
1807
+      case kReadEventStId:
1808
+        {
1809
+          cmXsReorder_t r;
1810
+          memset(&r,0,sizeof(r));
1811
+          
1812
+          // parse an event line
1813
+          if( sscanf(b,"%i %i %i %i %f",&r.voice,&r.locIdx,&r.tick,&r.durtn,&r.rval) == 5 )
1814
+          {
1815
+            if( r.tick < t0 )
1816
+              fl = true;
1817
+            t0 = r.tick; 
1818
+            break;
1819
+          }
1820
+          else
1821
+          {
1822
+          // the end of the measure was encountered -
1823
+          // reorder the measure based on the cmXsReorder_t in rV[ri]
1824
+            stateId = kFindMeasStId;
1825
+          }
1826
+          
1827
+          // fall through
1828
+        }
1829
+
1830
+      case kFindMeasStId:  // scanning for a bar-line
1831
+        {
1832
+          char colon;
1833
+          if( sscanf(b,"%i %c",&measNumb,&colon) == 2 && colon == ':' )
1834
+          {
1835
+            //printf("meas: %i \n",measNumb);
1836
+            stateId = kFindEventStId;
1837
+
1838
+          }
1839
+        }
1840
+        break;
1841
+    }
1842
+
1843
+    if( fl )
1844
+      b = cmTextInsertS(b,b+strlen(b)-1," <-----");
1845
+    
1846
+    cmFileWriteChar(ofH,b,strlen(b));
1847
+  }
1848
+
1849
+ errLabel:
1578 1850
   cmFileClose(&fH);
1851
+  cmFileClose(&ofH);
1579 1852
   cmMemFree(b);
1580 1853
   return rc;
1581 1854
 }
1582 1855
 
1583 1856
 
1857
+
1584 1858
 /*-------------------------------------------------------------------------------------------
1585 1859
 Dynamics File Format:
1586 1860
 <blk>*
@@ -2287,11 +2561,11 @@ cmXsRC_t cmXScoreTest(
2287 2561
   if((rc = cmXScoreInitialize( ctx, &h, xmlFn, midiFn)) != kOkXsRC )
2288 2562
     return cmErrMsg(&ctx->err,rc,"XScore alloc failed.");
2289 2563
 
2290
-  if( dynFn != NULL )
2291
-    cmXScoreInsertDynamics(h, dynFn );
2564
+  //if( dynFn != NULL )
2565
+  //  cmXScoreInsertDynamics(h, dynFn );
2292 2566
 
2293
-  //if( reorderFn != NULL )
2294
-  //  cmXScoreReorder(h,reorderFn);
2567
+  if( reorderFn != NULL )
2568
+    cmXScoreReorder(h,reorderFn);
2295 2569
 
2296 2570
   if( outFn != NULL )
2297 2571
   {
@@ -2317,7 +2591,7 @@ cmXsRC_t cmXScoreTest(
2317 2591
     
2318 2592
   }
2319 2593
   
2320
-  cmXScoreReport(h,&ctx->rpt,true);
2594
+  //cmXScoreReport(h,&ctx->rpt,true);
2321 2595
 
2322 2596
   return cmXScoreFinalize(&h);
2323 2597
 

+ 2
- 0
app/cmXScore.h View File

@@ -28,6 +28,8 @@ extern "C" {
28 28
   //
29 29
   // 1) Convert XML to UTF-8:
30 30
   //       a. Change: encoding           = 'UTF-16' to encoding='UTF-8'
31
+
32
+
31 33
   //       b. Emacs C-x <RET> f utf-8 <RET>
32 34
   //       c. Change: <?xml ... encoding = 'UTF-16' to encoding='UTF-8' ...?>
33 35
   //

Loading…
Cancel
Save