Просмотр исходного кода

cmScoreMatchGraphic.h/c : Completed initial implementation.

master
kevin 8 лет назад
Родитель
Сommit
b78cf1b688
2 измененных файлов: 83 добавлений и 19 удалений
  1. 82
    18
      app/cmScoreMatchGraphic.c
  2. 1
    1
      app/cmScoreMatchGraphic.h

+ 82
- 18
app/cmScoreMatchGraphic.c Просмотреть файл

@@ -22,10 +22,11 @@
22 22
 
23 23
 enum
24 24
 {
25
-  kBarSmgFl     = 0x0001,
26
-  kNoteSmgFl    = 0x0002,
27
-  kMidiSmgFl    = 0x0004,
28
-  kNoMatchSmgFl = 0x0008
25
+  kLocSmgFl     = 0x0001,
26
+  kBarSmgFl     = 0x0002,
27
+  kNoteSmgFl    = 0x0004,
28
+  kMidiSmgFl    = 0x0008,
29
+  kNoMatchSmgFl = 0x0010
29 30
 };
30 31
 
31 32
 typedef struct cmSmgBox_str
@@ -79,10 +80,13 @@ typedef struct
79 80
 typedef struct
80 81
 {
81 82
   cmErr_t      err;
82
-  cmSmgSc_t*   scV;
83
+  
84
+  cmSmgSc_t*   scV;   
83 85
   unsigned     scN;
86
+  
84 87
   cmSmgMidi_t* mV;
85 88
   unsigned     mN;
89
+  
86 90
   cmSmgLoc_t*  locV;
87 91
   unsigned     locN;
88 92
   cmSmgLine_t* lines;
@@ -135,9 +139,9 @@ cmSmgRC_t _cmSmgFree( cmSmg_t* p )
135 139
     l0 = l1;
136 140
   }
137 141
   
138
-  cmMemFree(&p->scV);
139
-  cmMemFree(&p->mV);
140
-  cmMemFree(&p->locV);
142
+  cmMemFree(p->scV);
143
+  cmMemFree(p->mV);
144
+  cmMemFree(p->locV);
141 145
   cmMemFree(p);
142 146
   return kOkSmgRC;
143 147
 }
@@ -152,7 +156,9 @@ cmSmgBox_t*  _cmSmgInsertBox( cmSmg_t* p, unsigned locIdx, unsigned flags, unsig
152 156
   b->text  = text;
153 157
 
154 158
   if( p->locV[locIdx].bV == NULL )
159
+  {
155 160
     p->locV[locIdx].bV = b;
161
+  }
156 162
   else
157 163
   {
158 164
     cmSmgBox_t* b0 = p->locV[locIdx].bV;
@@ -185,6 +191,9 @@ cmSmgRC_t _cmSmgInitFromScore( cmCtx_t* ctx, cmSmg_t* p, const cmChar_t* scoreFn
185 191
   {
186 192
     cmScoreLoc_t* l = cmScoreLoc(scH,i);
187 193
 
194
+    // insert the location label box
195
+    _cmSmgInsertBox(p, i, kLocSmgFl, cmInvalidId, cmTsPrintfP(NULL,"%i",i) );
196
+    
188 197
     // for each event in location i
189 198
     for(j=0; j<l->evtCnt; ++j)
190 199
     {
@@ -195,7 +204,8 @@ cmSmgRC_t _cmSmgInitFromScore( cmCtx_t* ctx, cmSmg_t* p, const cmChar_t* scoreFn
195 204
         case kBarEvtScId:
196 205
         case kNonEvtScId:
197 206
           {
198
-            unsigned  flags = e->type==kNonEvtScId ? kNoteSmgFl : kBarSmgFl;
207
+            // Note: Mark all score boxes as 'no-match' - this will be cleared in cmScoreMatchGraphicInsertMidi(). 
208
+            unsigned  flags = kNoMatchSmgFl | (e->type==kNonEvtScId ? kNoteSmgFl : kBarSmgFl);
199 209
             cmChar_t* text  = NULL;
200 210
           
201 211
             assert( k < p->scN );
@@ -218,6 +228,8 @@ cmSmgRC_t _cmSmgInitFromScore( cmCtx_t* ctx, cmSmg_t* p, const cmChar_t* scoreFn
218 228
     }
219 229
   }
220 230
 
231
+  p->scN = k;
232
+  
221 233
   cmScoreFinalize(&scH);
222 234
   
223 235
   return rc;
@@ -241,10 +253,14 @@ cmSmgRC_t _cmSmgInitFromMidi( cmCtx_t* ctx, cmSmg_t* p, const cmChar_t* midiFn )
241 253
   for(i=0,j=0; i<mN; ++i)
242 254
     if( (mV[i]!=NULL) && cmMidiIsChStatus(mV[i]->status) && cmMidiIsNoteOn(mV[i]->status) && (mV[i]->u.chMsgPtr->d1>0) )          
243 255
     {
256
+      assert(j < mN);
244 257
       p->mV[j].uid   = mV[i]->uid;
245 258
       p->mV[j].pitch = mV[i]->u.chMsgPtr->d0;
246 259
       p->mV[j].vel   = mV[i]->u.chMsgPtr->d1;
260
+      ++j;
247 261
     }
262
+
263
+  p->mN = j;
248 264
   
249 265
   cmMidiFileClose(&mfH);
250 266
 
@@ -275,6 +291,9 @@ cmSmgRC_t cmScoreMatchGraphicAlloc( cmCtx_t* ctx, cmSmgH_t* hp, const cmChar_t*
275 291
   return rc;
276 292
 }
277 293
 
294
+bool cmScoreMatchGraphicIsValid( cmSmgH_t h )
295
+{ return h.h != NULL; }
296
+
278 297
 cmSmgRC_t cmScoreMatchGraphicFree( cmSmgH_t* hp )
279 298
 {
280 299
   cmSmgRC_t rc = kOkSmgRC;
@@ -300,18 +319,30 @@ cmSmgRC_t cmScoreMatchGraphicInsertMidi( cmSmgH_t h, unsigned midiUid, unsigned
300 319
   cmSmg_t* p = _cmSmgHandleToPtr(h);
301 320
   unsigned i,j;
302 321
 
303
-  // for each MIDI event
322
+  // if this midi event did not match any score records
323
+  if( csvScoreEventId == cmInvalidId )
324
+    return kOkSmgRC;
325
+  
326
+  assert(midiUid != cmInvalidId );
327
+  assert(midiPitch<128 && midiVel<128);
328
+
329
+  // find the midi file record which matches the event
304 330
   for(i=0; i<p->mN; ++i)
305 331
     if( p->mV[i].uid == midiUid )
306 332
     {
307
-      // for each score record
333
+      // find the score record which matches the score event id
308 334
       for(j=0; j<p->scN; ++j)
309 335
         if( p->scV[j].csvEventId == csvScoreEventId )
310 336
         {
337
+          // create a match record
311 338
           cmSmgMatch_t* m = cmMemAllocZ(cmSmgMatch_t,1);
312 339
           
313 340
           m->score = p->scV + j;
314 341
 
342
+          // mark the box associated with this score record as 'matched' by clearing the kNoMatchSmgFl
343
+          p->scV[j].box->flags = cmClrFlag(p->scV[j].box->flags,kNoMatchSmgFl);
344
+
345
+          // insert the match record in the midi files match list
315 346
           if( p->mV[i].matchV == NULL )
316 347
             p->mV[i].matchV = m;
317 348
           else
@@ -322,6 +353,8 @@ cmSmgRC_t cmScoreMatchGraphicInsertMidi( cmSmgH_t h, unsigned midiUid, unsigned
322 353
 
323 354
             m0->link = m;
324 355
           }
356
+
357
+          return kOkSmgRC;
325 358
         }
326 359
 
327 360
       return cmErrMsg(&p->err,kScoreFailSmgRC,"The score csv event id %i not found,",csvScoreEventId);
@@ -340,6 +373,7 @@ void _cmSmgResolveMidi( cmSmg_t* p )
340 373
   // for each midi record
341 374
   for(i=0; i<p->mN; ++i)
342 375
   {
376
+    // get the first match record for this MIDI event
343 377
     const cmSmgMatch_t* m = p->mV[i].matchV;
344 378
 
345 379
     // get the score location for this midi event
@@ -380,16 +414,18 @@ void _cmSmgLayout( cmSmg_t* p )
380 414
   unsigned bordY = 5;
381 415
   unsigned boxH  = 30;
382 416
   unsigned boxW  = 30;
383
-  unsigned top   = boxH + bordY;
417
+  unsigned top   = boxH + 2*bordY;
384 418
   unsigned left  = bordX;
385 419
   
386 420
   for(i=0; i<p->locN; ++i)
387 421
   {
388 422
     cmSmgLoc_t* l = p->locV + i;
389 423
     cmSmgBox_t* b = l->bV;
390
-    
424
+
425
+    // for each box attached to this location
391 426
     for(; b!=NULL; b=b->link)
392 427
     {
428
+      // bar boxes are always drawn at the top of the column
393 429
       if( cmIsFlag(b->flags,kBarSmgFl) )
394 430
         b->top = bordY;
395 431
       else
@@ -403,7 +439,8 @@ void _cmSmgLayout( cmSmg_t* p )
403 439
       b->height = boxH;
404 440
     }
405 441
 
406
-    left += boxW + bordX;
442
+    left += boxW + bordX;    
443
+    top   = boxH + 2*bordY;
407 444
   }
408 445
 }
409 446
 
@@ -416,7 +453,7 @@ void _cmSmgSvgSize( cmSmg_t* p, unsigned* widthRef, unsigned* heightRef )
416 453
   for(i=0; i<p->locN; ++i)
417 454
   {
418 455
     cmSmgBox_t* b = p->locV[i].bV;
419
-    while( b != NULL )
456
+    for(; b != NULL; b=b->link )
420 457
     {
421 458
       if( b->left + b->width > maxWidth )
422 459
         maxWidth = b->left + b->width;
@@ -437,21 +474,36 @@ cmSmgRC_t cmScoreMatchGraphicWrite( cmSmgH_t h, const cmChar_t* fn )
437 474
   unsigned  svgHeight = 0;
438 475
   unsigned  svgWidth  = 0;
439 476
   unsigned  i;
477
+
478
+  
479
+  // BUG BUG BUG : this can only be called once
480
+  // create a box for each midi event
481
+  _cmSmgResolveMidi( p );
482
+
483
+  // layout the boxes
484
+  _cmSmgLayout( p );
485
+
440 486
   
441 487
   if( cmFileOpen(&fH,fn,kWriteFileFl,p->err.rpt) != kOkFileRC )
442 488
     return cmErrMsg(&p->err,kFileFailScRC,"Graphic file create failed for '%s'.",cmStringNullGuard(fn));
443 489
 
444 490
   _cmSmgSvgSize(p,&svgWidth,&svgHeight);
445 491
 
492
+  svgHeight += 10; // add a right and lower border
493
+  svgWidth  += 10;
494
+
446 495
   cmFilePrintf(fH,"<!DOCTYPE html>\n<html>\n<head><link rel=\"stylesheet\" type=\"text/css\" href=\"score0.css\"></head><body>\n<svg width=\"%i\" height=\"%i\">\n",svgWidth,svgHeight);
447 496
 
448 497
   for(i=0; i<p->locN; ++i)
449 498
   {
450 499
     cmSmgBox_t* b = p->locV[i].bV;
451
-    while( b != NULL )
500
+    for(; b != NULL; b=b->link )
452 501
     {
453 502
       const cmChar_t* classStr = "score";
454 503
 
504
+      if( cmIsFlag(b->flags,kLocSmgFl) )
505
+        classStr = "loc";
506
+      
455 507
       if( cmIsFlag(b->flags,kMidiSmgFl) )
456 508
         classStr = "midi";
457 509
 
@@ -467,7 +519,7 @@ cmSmgRC_t cmScoreMatchGraphicWrite( cmSmgH_t h, const cmChar_t* fn )
467 519
         classStr = "bar";
468 520
       
469 521
       if( cmFilePrintf(fH,"<rect x=\"%i\" y=\"%i\" width=\"%i\" height=\"%i\" class=\"%s\"/>\n",b->left,b->top,b->width,b->height,classStr) != kOkFileRC )
470
-        return cmErrMsg(&p->err,kFileFailScRC,"File write failed on graphic file output.");
522
+        return cmErrMsg(&p->err,kFileFailScRC,"File write failed on graphic file rect output.");
471 523
 
472 524
       if( b->text != NULL )
473 525
       {
@@ -475,11 +527,23 @@ cmSmgRC_t cmScoreMatchGraphicWrite( cmSmgH_t h, const cmChar_t* fn )
475 527
         unsigned ty = b->top  + 20; //g->height/2;
476 528
         
477 529
         if( cmFilePrintf(fH,"<text x=\"%i\" y=\"%i\" text-anchor=\"middle\" class=\"stext\">%s</text>\n",tx,ty,b->text) != kOkFileRC )
478
-          return cmErrMsg(&p->err,kFileFailScRC,"File write failed on graphic file output.");
530
+          return cmErrMsg(&p->err,kFileFailScRC,"File write failed on graphic file text output.");
479 531
       }
480 532
       
481 533
     }
482 534
   }
535
+
536
+  cmSmgLine_t* l = p->lines;
537
+  for(; l!=NULL; l=l->link)
538
+  {
539
+    unsigned x0 = l->b0->left + l->b0->width/2;
540
+    unsigned y0 = l->b0->top  + l->b0->height/2;
541
+    unsigned x1 = l->b1->left + l->b1->width/2;
542
+    unsigned y1 = l->b1->top  + l->b1->height/2;
543
+    
544
+    if( cmFilePrintf(fH,"<line x1=\"%i\" y1=\"%i\" x2=\"%i\" y2=\"%i\" class=\"sline\"/>\n",x0,y0,x1,y1) != kOkFileRC )
545
+      return cmErrMsg(&p->err,kFileFailScRC,"File write failed on graphic file line output.");
546
+  }
483 547
     
484 548
   cmFilePrint(fH,"</svg>\n</body>\n</html>\n");
485 549
 

+ 1
- 1
app/cmScoreMatchGraphic.h Просмотреть файл

@@ -21,7 +21,7 @@ extern "C" {
21 21
   cmSmgRC_t cmScoreMatchGraphicAlloc( cmCtx_t* ctx, cmSmgH_t* hp, const cmChar_t* scoreFn, const cmChar_t* midiFn );
22 22
   cmSmgRC_t cmScoreMatchGraphicFree( cmSmgH_t* hp );
23 23
   bool      cmScoreMatchGraphicIsValid( cmSmgH_t h );
24
-  cmSmgRC_t cmScoreMatchGraphicInsertMidi( cmSmgH_t h, unsigned midiUid, unsigned midiPitch, unsigned midiVel, unsigned csvScoreEventId ); 
24
+  cmSmgRC_t cmScoreMatchGraphicInsertMidi( cmSmgH_t h, unsigned midiUid, unsigned midiPitch, unsigned midiVel, unsigned csvScoreEventId );
25 25
   cmSmgRC_t cmScoreMatchGraphicWrite( cmSmgH_t h, const cmChar_t* fn );
26 26
   
27 27
   

Загрузка…
Отмена
Сохранить