Browse Source

cmXScore.c : Added cmXScoreReorder().

master
kevin 8 years ago
parent
commit
4017b8bbaa
1 changed files with 188 additions and 4 deletions
  1. 188
    4
      app/cmXScore.c

+ 188
- 4
app/cmXScore.c View File

@@ -1303,17 +1303,186 @@ cmXsRC_t cmXScoreFinalize( cmXsH_t* hp )
1303 1303
   return rc;  
1304 1304
 }
1305 1305
 
1306
-
1307 1306
 bool     cmXScoreIsValid( cmXsH_t h )
1308 1307
 { return h.h != NULL; }
1309 1308
 
1310
-/*
1309
+//-------------------------------------------------------------------------------------------
1310
+typedef struct
1311
+{
1312
+  unsigned    voice;
1313
+  unsigned    locIdx;
1314
+  unsigned    tick;
1315
+  unsigned    durtn;
1316
+  float       rval;
1317
+  unsigned    midi;
1318
+  cmXsNote_t* note;
1319
+} cmXsReorder_t;
1320
+
1321
+cmXsNote_t*  _cmXsReorderFindNote( cmXScore_t* p, unsigned measNumb, const cmXsReorder_t* r )
1322
+{
1323
+  cmXsPart_t* pp = p->partL;
1324
+  for(; pp!=NULL; pp=pp->link)
1325
+  {
1326
+    cmXsMeas_t* mp = pp->measL;
1327
+    for(; mp!=NULL; mp=mp->link)
1328
+      if( mp->number == measNumb) 
1329
+      { 
1330
+        cmXsNote_t* np = mp->noteL;
1331
+        for(; np!=NULL; np=np->slink)
1332
+          if( np->voice->id == r->voice &&
1333
+            np->locIdx == r->locIdx &&
1334
+            np->tick == r->tick &&
1335
+            np->duration == r->durtn &&
1336
+            np->rvalue == r->rval &&
1337
+            np->pitch == r->midi )
1338
+          {
1339
+            return np;
1340
+          }
1341
+      }
1342
+  }
1343
+
1344
+  cmErrMsg(&p->err,kSyntaxErrorXsRC,"Reorder note not found.");
1345
+  return NULL;
1346
+}
1347
+
1348
+cmXsRC_t _cmXScoreReorderMeas( cmXScore_t* p, unsigned measNumb, cmXsReorder_t* rV, unsigned rN )
1349
+{
1350
+  unsigned i;
1351
+  
1352
+  if( rN == 0 )
1353
+    return kOkXsRC;
1354
+
1355
+  // set the 'note' field on each cmXsReorder_t record
1356
+  for(i=0; i<rN; ++i)
1357
+    if((rV[i].note = _cmXsReorderFindNote(p,measNumb,rV+i)) == NULL )
1358
+      return kSyntaxErrorXsRC;
1359
+
1360
+  
1361
+  cmXsMeas_t* mp = rV[0].note->meas;
1362
+  cmXsNote_t* n0p = NULL;
1363
+
1364
+  assert( mp->number == measNumb );
1365
+  
1366
+  // Reassign the slink of the cmXsNote_t records in this measure
1367
+  // according to their order in rV[].
1368
+  for(i=0; i<rN; ++i)
1369
+  {
1370
+    if( n0p == NULL )
1371
+      mp->noteL = rV[i].note;
1372
+    else
1373
+      n0p->slink = rV[i].note;
1374
+
1375
+    n0p = rV[i].note;
1376
+    n0p->slink = NULL;
1377
+  }
1378
+  
1379
+  return kOkXsRC;    
1380
+  
1381
+}
1382
+
1383
+cmXsRC_t cmXScoreReorder( cmXsH_t h, const cmChar_t* fn )
1384
+{
1385
+  typedef enum { kFindMeasStId, kFindEventStId, kReadEventStId } stateId_t;
1386
+
1387
+  cmXsRC_t      rc      = kOkXsRC;
1388
+  cmXScore_t*   p       = _cmXScoreHandleToPtr(h);
1389
+  cmFileH_t     fH      = cmFileNullHandle;
1390
+  cmChar_t*     b       = NULL;
1391
+  unsigned      bN      = 0;
1392
+  unsigned      ln      = 0;
1393
+  stateId_t     stateId = kFindMeasStId;
1394
+  unsigned      rN      = 1024;
1395
+  unsigned      ri      = 0;
1396
+  unsigned     measNumb = 0;
1397
+  cmXsReorder_t rV[ rN ];
1398
+  
1399
+  if( cmFileOpen(&fH,fn,kReadFileFl,p->err.rpt) != kOkFileRC )
1400
+  {
1401
+    rc = cmErrMsg(&p->err,kFileFailXsRC,"The reordering file '%s' could not be opened.",cmStringNullGuard(fn));
1402
+    return rc;
1403
+  }
1404
+  
1405
+  for(; cmFileGetLineAuto(fH,&b,&bN)==kOkFileRC; ++ln)
1406
+  {
1407
+    switch( stateId )
1408
+    {
1409
+      case kFindEventStId:
1410
+        {
1411
+          unsigned voice,loc;
1412
+          if( sscanf(b,"%i %i",&voice,&loc) != 2 )
1413
+            continue;
1414
+          
1415
+          stateId = kReadEventStId;
1416
+        }
1417
+        // fall through
1418
+        
1419
+      case kReadEventStId:
1420
+        {
1421
+          cmXsReorder_t r;
1422
+          char     pitchStr[4];
1423
+          
1424
+          if( sscanf(b,"%i %i %i %i %f %c%c%c",&r.voice,&r.locIdx,&r.tick,&r.durtn,&r.rval,pitchStr,pitchStr+1,pitchStr+2) == 8 )
1425
+          {
1426
+            pitchStr[3] = 0;
1427
+            if( !isdigit(pitchStr[2]) )
1428
+              r.midi = 0;
1429
+            else
1430
+            {
1431
+              if( pitchStr[1] == ' ')
1432
+              {
1433
+                pitchStr[1] = pitchStr[2];
1434
+                pitchStr[2] = 0;
1435
+              }
1436
+
1437
+              r.midi = cmSciPitchToMidi(pitchStr);
1438
+            }
1439
+            
1440
+            assert( ri < rN );
1441
+            rV[ri++] = r;
1442
+            
1443
+            continue;
1444
+          }
1445
+
1446
+          if((rc =  _cmXScoreReorderMeas(p, measNumb, rV, ri )) != kOkXsRC )
1447
+            goto errLabel;
1448
+
1449
+          ri = 0;
1450
+
1451
+          stateId = kFindMeasStId;
1452
+          // fall through
1453
+        }
1454
+        
1455
+      case kFindMeasStId:
1456
+        {
1457
+          char colon;
1458
+          if( sscanf(b,"%i %c",&measNumb,&colon) == 2 && colon == ':' )
1459
+          {
1460
+            //printf("meas: %i \n",measNumb);
1461
+            stateId = kFindEventStId;
1462
+            
1463
+          }
1464
+        }
1465
+        break;
1466
+    }
1467
+        
1468
+  }
1469
+
1470
+ errLabel:
1471
+  cmFileClose(&fH);
1472
+  cmMemFree(b);
1473
+  return rc;
1474
+}
1475
+
1476
+
1477
+/*-------------------------------------------------------------------------------------------
1311 1478
 Dynamics File Format:
1312 1479
 <blk>*
1313 1480
 <blk>       -> <hdr-line> <note-line> <blank-line>
1314 1481
 <hdr-line>  -> <int> "|" 
1315 1482
 <note-line> -> <float> <sci-pitch> ":" <int>
1316 1483
 <sci-pitch> -> <A-G><#|b|<space> 
1484
+
1485
+See imag_themes/scores/dyn.txt for an example.
1317 1486
  */
1318 1487
 
1319 1488
 typedef struct cmXsDyn_str
@@ -1877,10 +2046,22 @@ void  cmXScoreReport( cmXsH_t h, cmRpt_t* rpt, bool sortFl )
1877 2046
       {
1878 2047
         
1879 2048
         const cmXsNote_t* note = meas->noteL;
2049
+        unsigned t0 = 0;
2050
+        unsigned t1 = 0;
1880 2051
         for(; note!=NULL; note=note->slink)
1881 2052
         {
1882 2053
           _cmXScoreReportNote(rpt,note);
1883
-        
2054
+
2055
+          t1 = note->slink==NULL ? note->tick : note->slink->tick;
2056
+
2057
+          if( !(t0 <= note->tick && note->tick <= t1) )
2058
+          {
2059
+            cmRptPrintf(rpt," +");            
2060
+          }
2061
+
2062
+          t0 = note->tick;
2063
+          
2064
+          
1884 2065
           if( note->slink!=NULL  || note->voice->id==0)
1885 2066
             cmRptPrintf(rpt,"\n");
1886 2067
           else
@@ -1944,8 +2125,11 @@ cmXsRC_t cmXScoreTest( cmCtx_t* ctx, const cmChar_t* xmlFn, const cmChar_t* midi
1944 2125
   if((rc = cmXScoreInitialize( ctx, &h, xmlFn, midiFn)) != kOkXsRC )
1945 2126
     return cmErrMsg(&ctx->err,rc,"XScore alloc failed.");
1946 2127
 
2128
+  //if( dynFn != NULL )
2129
+  //  cmXScoreInsertDynamics(h, dynFn );
2130
+
1947 2131
   if( dynFn != NULL )
1948
-    cmXScoreInsertDynamics(h, dynFn );
2132
+    cmXScoreReorder(h,dynFn);
1949 2133
   
1950 2134
   if( outFn != NULL )
1951 2135
     cmXScoreWriteCsv(h,outFn);

Loading…
Cancel
Save