Browse Source

cmScoreMatchGraphic.h/c : Completed initial implementation.

master
kevin 8 years ago
parent
commit
b78cf1b688
2 changed files with 83 additions and 19 deletions
  1. 82
    18
      app/cmScoreMatchGraphic.c
  2. 1
    1
      app/cmScoreMatchGraphic.h

+ 82
- 18
app/cmScoreMatchGraphic.c View File

22
 
22
 
23
 enum
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
 typedef struct cmSmgBox_str
32
 typedef struct cmSmgBox_str
79
 typedef struct
80
 typedef struct
80
 {
81
 {
81
   cmErr_t      err;
82
   cmErr_t      err;
82
-  cmSmgSc_t*   scV;
83
+  
84
+  cmSmgSc_t*   scV;   
83
   unsigned     scN;
85
   unsigned     scN;
86
+  
84
   cmSmgMidi_t* mV;
87
   cmSmgMidi_t* mV;
85
   unsigned     mN;
88
   unsigned     mN;
89
+  
86
   cmSmgLoc_t*  locV;
90
   cmSmgLoc_t*  locV;
87
   unsigned     locN;
91
   unsigned     locN;
88
   cmSmgLine_t* lines;
92
   cmSmgLine_t* lines;
135
     l0 = l1;
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
   cmMemFree(p);
145
   cmMemFree(p);
142
   return kOkSmgRC;
146
   return kOkSmgRC;
143
 }
147
 }
152
   b->text  = text;
156
   b->text  = text;
153
 
157
 
154
   if( p->locV[locIdx].bV == NULL )
158
   if( p->locV[locIdx].bV == NULL )
159
+  {
155
     p->locV[locIdx].bV = b;
160
     p->locV[locIdx].bV = b;
161
+  }
156
   else
162
   else
157
   {
163
   {
158
     cmSmgBox_t* b0 = p->locV[locIdx].bV;
164
     cmSmgBox_t* b0 = p->locV[locIdx].bV;
185
   {
191
   {
186
     cmScoreLoc_t* l = cmScoreLoc(scH,i);
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
     // for each event in location i
197
     // for each event in location i
189
     for(j=0; j<l->evtCnt; ++j)
198
     for(j=0; j<l->evtCnt; ++j)
190
     {
199
     {
195
         case kBarEvtScId:
204
         case kBarEvtScId:
196
         case kNonEvtScId:
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
             cmChar_t* text  = NULL;
209
             cmChar_t* text  = NULL;
200
           
210
           
201
             assert( k < p->scN );
211
             assert( k < p->scN );
218
     }
228
     }
219
   }
229
   }
220
 
230
 
231
+  p->scN = k;
232
+  
221
   cmScoreFinalize(&scH);
233
   cmScoreFinalize(&scH);
222
   
234
   
223
   return rc;
235
   return rc;
241
   for(i=0,j=0; i<mN; ++i)
253
   for(i=0,j=0; i<mN; ++i)
242
     if( (mV[i]!=NULL) && cmMidiIsChStatus(mV[i]->status) && cmMidiIsNoteOn(mV[i]->status) && (mV[i]->u.chMsgPtr->d1>0) )          
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
       p->mV[j].uid   = mV[i]->uid;
257
       p->mV[j].uid   = mV[i]->uid;
245
       p->mV[j].pitch = mV[i]->u.chMsgPtr->d0;
258
       p->mV[j].pitch = mV[i]->u.chMsgPtr->d0;
246
       p->mV[j].vel   = mV[i]->u.chMsgPtr->d1;
259
       p->mV[j].vel   = mV[i]->u.chMsgPtr->d1;
260
+      ++j;
247
     }
261
     }
262
+
263
+  p->mN = j;
248
   
264
   
249
   cmMidiFileClose(&mfH);
265
   cmMidiFileClose(&mfH);
250
 
266
 
275
   return rc;
291
   return rc;
276
 }
292
 }
277
 
293
 
294
+bool cmScoreMatchGraphicIsValid( cmSmgH_t h )
295
+{ return h.h != NULL; }
296
+
278
 cmSmgRC_t cmScoreMatchGraphicFree( cmSmgH_t* hp )
297
 cmSmgRC_t cmScoreMatchGraphicFree( cmSmgH_t* hp )
279
 {
298
 {
280
   cmSmgRC_t rc = kOkSmgRC;
299
   cmSmgRC_t rc = kOkSmgRC;
300
   cmSmg_t* p = _cmSmgHandleToPtr(h);
319
   cmSmg_t* p = _cmSmgHandleToPtr(h);
301
   unsigned i,j;
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
   for(i=0; i<p->mN; ++i)
330
   for(i=0; i<p->mN; ++i)
305
     if( p->mV[i].uid == midiUid )
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
       for(j=0; j<p->scN; ++j)
334
       for(j=0; j<p->scN; ++j)
309
         if( p->scV[j].csvEventId == csvScoreEventId )
335
         if( p->scV[j].csvEventId == csvScoreEventId )
310
         {
336
         {
337
+          // create a match record
311
           cmSmgMatch_t* m = cmMemAllocZ(cmSmgMatch_t,1);
338
           cmSmgMatch_t* m = cmMemAllocZ(cmSmgMatch_t,1);
312
           
339
           
313
           m->score = p->scV + j;
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
           if( p->mV[i].matchV == NULL )
346
           if( p->mV[i].matchV == NULL )
316
             p->mV[i].matchV = m;
347
             p->mV[i].matchV = m;
317
           else
348
           else
322
 
353
 
323
             m0->link = m;
354
             m0->link = m;
324
           }
355
           }
356
+
357
+          return kOkSmgRC;
325
         }
358
         }
326
 
359
 
327
       return cmErrMsg(&p->err,kScoreFailSmgRC,"The score csv event id %i not found,",csvScoreEventId);
360
       return cmErrMsg(&p->err,kScoreFailSmgRC,"The score csv event id %i not found,",csvScoreEventId);
340
   // for each midi record
373
   // for each midi record
341
   for(i=0; i<p->mN; ++i)
374
   for(i=0; i<p->mN; ++i)
342
   {
375
   {
376
+    // get the first match record for this MIDI event
343
     const cmSmgMatch_t* m = p->mV[i].matchV;
377
     const cmSmgMatch_t* m = p->mV[i].matchV;
344
 
378
 
345
     // get the score location for this midi event
379
     // get the score location for this midi event
380
   unsigned bordY = 5;
414
   unsigned bordY = 5;
381
   unsigned boxH  = 30;
415
   unsigned boxH  = 30;
382
   unsigned boxW  = 30;
416
   unsigned boxW  = 30;
383
-  unsigned top   = boxH + bordY;
417
+  unsigned top   = boxH + 2*bordY;
384
   unsigned left  = bordX;
418
   unsigned left  = bordX;
385
   
419
   
386
   for(i=0; i<p->locN; ++i)
420
   for(i=0; i<p->locN; ++i)
387
   {
421
   {
388
     cmSmgLoc_t* l = p->locV + i;
422
     cmSmgLoc_t* l = p->locV + i;
389
     cmSmgBox_t* b = l->bV;
423
     cmSmgBox_t* b = l->bV;
390
-    
424
+
425
+    // for each box attached to this location
391
     for(; b!=NULL; b=b->link)
426
     for(; b!=NULL; b=b->link)
392
     {
427
     {
428
+      // bar boxes are always drawn at the top of the column
393
       if( cmIsFlag(b->flags,kBarSmgFl) )
429
       if( cmIsFlag(b->flags,kBarSmgFl) )
394
         b->top = bordY;
430
         b->top = bordY;
395
       else
431
       else
403
       b->height = boxH;
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
   for(i=0; i<p->locN; ++i)
453
   for(i=0; i<p->locN; ++i)
417
   {
454
   {
418
     cmSmgBox_t* b = p->locV[i].bV;
455
     cmSmgBox_t* b = p->locV[i].bV;
419
-    while( b != NULL )
456
+    for(; b != NULL; b=b->link )
420
     {
457
     {
421
       if( b->left + b->width > maxWidth )
458
       if( b->left + b->width > maxWidth )
422
         maxWidth = b->left + b->width;
459
         maxWidth = b->left + b->width;
437
   unsigned  svgHeight = 0;
474
   unsigned  svgHeight = 0;
438
   unsigned  svgWidth  = 0;
475
   unsigned  svgWidth  = 0;
439
   unsigned  i;
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
   if( cmFileOpen(&fH,fn,kWriteFileFl,p->err.rpt) != kOkFileRC )
487
   if( cmFileOpen(&fH,fn,kWriteFileFl,p->err.rpt) != kOkFileRC )
442
     return cmErrMsg(&p->err,kFileFailScRC,"Graphic file create failed for '%s'.",cmStringNullGuard(fn));
488
     return cmErrMsg(&p->err,kFileFailScRC,"Graphic file create failed for '%s'.",cmStringNullGuard(fn));
443
 
489
 
444
   _cmSmgSvgSize(p,&svgWidth,&svgHeight);
490
   _cmSmgSvgSize(p,&svgWidth,&svgHeight);
445
 
491
 
492
+  svgHeight += 10; // add a right and lower border
493
+  svgWidth  += 10;
494
+
446
   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);
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
   for(i=0; i<p->locN; ++i)
497
   for(i=0; i<p->locN; ++i)
449
   {
498
   {
450
     cmSmgBox_t* b = p->locV[i].bV;
499
     cmSmgBox_t* b = p->locV[i].bV;
451
-    while( b != NULL )
500
+    for(; b != NULL; b=b->link )
452
     {
501
     {
453
       const cmChar_t* classStr = "score";
502
       const cmChar_t* classStr = "score";
454
 
503
 
504
+      if( cmIsFlag(b->flags,kLocSmgFl) )
505
+        classStr = "loc";
506
+      
455
       if( cmIsFlag(b->flags,kMidiSmgFl) )
507
       if( cmIsFlag(b->flags,kMidiSmgFl) )
456
         classStr = "midi";
508
         classStr = "midi";
457
 
509
 
467
         classStr = "bar";
519
         classStr = "bar";
468
       
520
       
469
       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 )
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
       if( b->text != NULL )
524
       if( b->text != NULL )
473
       {
525
       {
475
         unsigned ty = b->top  + 20; //g->height/2;
527
         unsigned ty = b->top  + 20; //g->height/2;
476
         
528
         
477
         if( cmFilePrintf(fH,"<text x=\"%i\" y=\"%i\" text-anchor=\"middle\" class=\"stext\">%s</text>\n",tx,ty,b->text) != kOkFileRC )
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
   cmFilePrint(fH,"</svg>\n</body>\n</html>\n");
548
   cmFilePrint(fH,"</svg>\n</body>\n</html>\n");
485
 
549
 

+ 1
- 1
app/cmScoreMatchGraphic.h View File

21
   cmSmgRC_t cmScoreMatchGraphicAlloc( cmCtx_t* ctx, cmSmgH_t* hp, const cmChar_t* scoreFn, const cmChar_t* midiFn );
21
   cmSmgRC_t cmScoreMatchGraphicAlloc( cmCtx_t* ctx, cmSmgH_t* hp, const cmChar_t* scoreFn, const cmChar_t* midiFn );
22
   cmSmgRC_t cmScoreMatchGraphicFree( cmSmgH_t* hp );
22
   cmSmgRC_t cmScoreMatchGraphicFree( cmSmgH_t* hp );
23
   bool      cmScoreMatchGraphicIsValid( cmSmgH_t h );
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
   cmSmgRC_t cmScoreMatchGraphicWrite( cmSmgH_t h, const cmChar_t* fn );
25
   cmSmgRC_t cmScoreMatchGraphicWrite( cmSmgH_t h, const cmChar_t* fn );
26
   
26
   
27
   
27
   

Loading…
Cancel
Save