Browse Source

cmScoreProc.c:Wrote _cmScoreGenAllMeasurements() to generate all performance

measurements from a time-line file.
master
kpl 11 years ago
parent
commit
a8ba59b2f5
1 changed files with 255 additions and 2 deletions
  1. 255
    2
      app/cmScoreProc.c

+ 255
- 2
app/cmScoreProc.c View File

@@ -8,6 +8,7 @@
8 8
 #include "cmLinkedHeap.h"
9 9
 #include "cmSymTbl.h"
10 10
 #include "cmJson.h"
11
+#include "cmFile.h"
11 12
 #include "cmMidi.h"
12 13
 #include "cmMidiFile.h"
13 14
 #include "cmAudioFile.h"
@@ -15,18 +16,33 @@
15 16
 #include "cmTimeLine.h"
16 17
 #include "cmScoreProc.h"
17 18
 
19
+#include "cmProcObj.h"
20
+#include "cmProc4.h"
21
+
18 22
 enum
19 23
 {
20 24
   kOkSpRC,
21 25
   kJsonFailSpRC,
22 26
   kScoreFailSpRC,
23
-  kTimeLineFailSpRC
27
+  kTimeLineFailSpRC,
28
+  kScoreMatchFailSpRC,
29
+  kFileFailSpRC,
24 30
 };
25 31
 
32
+typedef struct _cmScMeas_t
33
+{
34
+  cmTlMarker_t*       markPtr;  // time-line marker in which this 'set' exists
35
+  cmScoreSet_t*       setPtr;   // score set on which this measurment is based
36
+  double              value;    // the value of the measurement
37
+  double              cost;     // the quality of the perf->score match 
38
+  struct _cmScMeas_t* link;
39
+} _cmScMeas_t;
40
+
26 41
 
27 42
 typedef struct
28 43
 {
29 44
   cmErr_t         err;
45
+  cmCtx*          ctx;
30 46
   cmScH_t         scH;
31 47
   const cmChar_t* tlFn;
32 48
   cmTlH_t         tlH;
@@ -34,6 +50,12 @@ typedef struct
34 50
   unsigned*       dynArray;
35 51
   unsigned        dynCnt;
36 52
   double          srate;
53
+  cmScMeas*       meas;
54
+  cmScMatcher*    match;
55
+
56
+  cmTlMarker_t*   curMarkPtr;
57
+  _cmScMeas_t*    list_beg;
58
+  _cmScMeas_t*    list_end;
37 59
 } cmSp_t;
38 60
 
39 61
 
@@ -102,12 +124,15 @@ cmSpRC_t _cmScoreProcInit( cmCtx_t* ctx, cmSp_t* p, const cmChar_t* rsrcFn  )
102 124
     goto errLabel;
103 125
   }
104 126
 
105
-  if( cmTimeLineInitialize(ctx, &p->tlH, NULL, NULL ) != kOkTlRC )
127
+  // load the time-line file
128
+  if( cmTimeLineInitializeFromFile(ctx, &p->tlH, NULL, NULL, tlFn ) != kOkTlRC )
106 129
   {
107 130
     rc = cmErrMsg(&p->err,kTimeLineFailSpRC,"Time line load failed for time line file:%s.",cmStringNullGuard(tlFn));
108 131
     goto errLabel;
109 132
   }
110 133
 
134
+  p->ctx  = cmCtxAlloc(NULL, &ctx->rpt, cmLHeapNullHandle, cmSymTblNullHandle );
135
+
111 136
  errLabel:
112 137
   return rc;
113 138
 }
@@ -116,6 +141,8 @@ cmSpRC_t _cmScoreProcFinal( cmSp_t* p )
116 141
 {
117 142
   cmSpRC_t rc = kOkSpRC;
118 143
 
144
+  cmCtxFree(&p->ctx);
145
+
119 146
   if( cmScoreFinalize(&p->scH) != kOkScRC )
120 147
     cmErrMsg(&p->err,kScoreFailSpRC,"Score finalize failed.");
121 148
 
@@ -130,10 +157,233 @@ cmSpRC_t _cmScoreProcFinal( cmSp_t* p )
130 157
   return rc;
131 158
 }
132 159
 
160
+cmSpRC_t _cmScWriteMeasFile( cmCtx_t* ctx, cmSp_t* sp, const cmChar_t* outFn )
161
+{
162
+  cmFileH_t fH = cmFileNullHandle;
163
+  cmSpRC_t rc = kOkSpRC;
164
+  unsigned i;
165
+
166
+  if( cmFileOpen(&fH,outFn,kWriteFileFl,&ctx->rpt) != kOkFileRC )
167
+  {
168
+    rc = cmErrMsg(&sp->err,kFileFailSpRC,"Unable to create the output file '%s'.",cmStringNullGuard(outFn));
169
+    goto errLabel;
170
+  }
171
+
172
+  cmFilePrintf(fH,"{\n");
173
+
174
+  _cmScMeas_t* mp = sp->list_beg;
175
+  for(; mp!=NULL; mp=mp->link)
176
+  {
177
+    const cmChar_t* typeLabel = NULL;
178
+    switch(mp->setPtr->varId)
179
+    {
180
+      case kEvenVarScId: typeLabel="even"; break;
181
+      case kDynVarScId:  typeLabel="dyn";  break;
182
+      case kTempoVarScId:typeLabel="tempo";break;
183
+      default:
184
+        { assert(0); }
185
+    }
186
+
187
+    for(i=0; i<mp->setPtr->sectCnt; ++i)
188
+    {
189
+      cmFilePrintf(fH,"{seq:%i mark:\"%s\" typeId:%i typeLabel:\"%s\" loc:%i evt:%i sect:\"%s\" value:%f cost:%f }\n",
190
+        mp->markPtr->obj.seqId,
191
+        cmStringNullGuard(mp->markPtr->obj.name),
192
+        mp->setPtr->varId,
193
+        typeLabel,
194
+        mp->setPtr->sectArray[i]->locPtr->index,
195
+        mp->setPtr->sectArray[i]->begEvtIndex,
196
+        cmStringNullGuard(mp->setPtr->sectArray[i]->label),
197
+        mp->value,
198
+        mp->cost );
199
+    } 
200
+  }
201
+
202
+  cmFilePrintf(fH,"}\n");
203
+
204
+ errLabel:
205
+  if( cmFileClose(&fH) != kOkFileRC )
206
+    cmErrMsg(&sp->err,kFileFailSpRC,"The output file close failed on '%s'.",cmStringNullGuard(outFn));
207
+
208
+  return rc;
209
+}
210
+
211
+void _cmScMatchCb( cmScMatcher* p, void* arg, cmScMatcherResult_t* rp )
212
+{
213
+  cmSp_t*   sp = (cmSp_t*)arg;
214
+  cmScMeas* sm = sp->meas;
215
+
216
+  if( cmScMeasExec(sm, rp->mni, rp->locIdx, rp->scEvtIdx, rp->flags, rp->smpIdx, rp->pitch, rp->vel ) == cmOkRC )
217
+  {
218
+    unsigned i;
219
+    for(i=sm->vsi; i<sm->nsi; ++i)
220
+      // ignore set's which did not produce a valid value
221
+      if(sm->set[i].value != DBL_MAX )
222
+      {
223
+        _cmScMeas_t* r = cmMemAllocZ(_cmScMeas_t,1);
224
+        r->markPtr = sp->curMarkPtr;
225
+        r->setPtr  = sm->set[i].sp;
226
+        r->value   = sm->set[i].value;
227
+        r->cost    = sm->set[i].match_cost;
228
+
229
+        if( sp->list_beg == NULL )
230
+        {
231
+          sp->list_beg = r;
232
+          sp->list_end = r;
233
+        }
234
+        else
235
+        {
236
+          sp->list_end->link = r;
237
+          sp->list_end       = r;
238
+        }
239
+      }    
240
+  }
241
+}
242
+
243
+
244
+cmSpRC_t _cmScoreGenAllMeasurements(cmCtx_t* ctx, cmSp_t* sp, const cmChar_t* outFn)
245
+{
246
+  cmSpRC_t rc     = kOkSpRC;
247
+  unsigned midiN  = 7;
248
+  unsigned scWndN = 10;
249
+  unsigned seqN   = cmTimeLineSeqCount(sp->tlH);
250
+  double   srate  = cmTimeLineSampleRate(sp->tlH);
251
+  unsigned seqId;
252
+
253
+  assert( sp->srate == srate);
254
+
255
+  // allocate the performance eval. object
256
+  sp->meas = cmScMeasAlloc( sp->ctx, NULL, sp->scH, sp->srate, sp->dynArray, sp->dynCnt );
257
+  assert( sp->meas != NULL );
258
+
259
+  // allocate the score matcher
260
+  sp->match = cmScMatcherAlloc(sp->ctx,NULL,sp->srate,sp->scH,scWndN,midiN,_cmScMatchCb,sp);
261
+  assert(sp->match != NULL );
262
+
263
+  
264
+  // for each time line sequence
265
+  for(seqId=0; seqId<seqN; ++seqId)
266
+  {
267
+    cmTlObj_t* o0p = NULL;
268
+  
269
+    // for each 'marker' in this time line sequence
270
+    while(  (o0p = cmTimeLineNextTypeObj(sp->tlH, o0p, seqId, kMarkerTlId)) != NULL )
271
+    {
272
+      // get the 'marker' recd
273
+      cmTlMarker_t* markPtr = cmTimeLineMarkerObjPtr(sp->tlH,o0p);
274
+      assert( markPtr != NULL );
275
+
276
+      // if the marker does not have a valid start bar location
277
+      if( markPtr->bar == 0 )
278
+        continue;
279
+
280
+      // set the marker ptr (which is used in _cmScMatchCb())
281
+      sp->curMarkPtr = markPtr;
282
+
283
+      // get the end-of-marker time as a sample index
284
+      unsigned markEndSmpIdx = markPtr->obj.seqSmpIdx + markPtr->obj.durSmpCnt;
285
+
286
+      // get the score event associated with the marker's bar number.
287
+      const cmScoreEvt_t* evtPtr = cmScoreBarEvt(sp->scH,markPtr->bar);
288
+      assert( evtPtr != NULL );
289
+
290
+
291
+      // get the score location associated with the markers bar score event
292
+      const cmScoreLoc_t* locPtr = cmScoreEvtLoc(sp->scH,evtPtr);
293
+      assert( locPtr != NULL );
294
+
295
+      cmRptPrintf(&ctx->rpt,"Processing loc:%i seq:%i %s %s\n",locPtr->index,seqId,cmStringNullGuard(markPtr->obj.name),cmStringNullGuard(markPtr->text));
296
+
297
+      // reset the performance evaluation object
298
+      if( cmScMeasReset(sp->meas) != cmOkRC )
299
+      {
300
+        cmErrMsg(&sp->err,kScoreMatchFailSpRC,"The score performance evaluation object failed on reset.");
301
+        continue;
302
+      }
303
+      
304
+      // reset the score matcher to begin searching at the bar location
305
+      if( cmScMatcherReset(sp->match, locPtr->index ) != cmOkRC )
306
+      {
307
+        cmErrMsg(&sp->err,kScoreMatchFailSpRC,"The score matcher reset failed on location: %i.",locPtr->index);
308
+        continue;
309
+      }
310
+
311
+      cmTlObj_t* o1p = o0p;
312
+
313
+      // as long as more MIDI events are available get the next MIDI msg 
314
+      while( (rc == kOkSpRC) && (o1p = cmTimeLineNextTypeObj(sp->tlH, o1p, seqId, kMidiEvtTlId )) != NULL )
315
+      {
316
+        cmTlMidiEvt_t* mep = cmTimeLineMidiEvtObjPtr(sp->tlH,o1p);
317
+        assert(mep != NULL );
318
+
319
+        // if the msg falls after the end of the marker then we are done
320
+        if( mep->obj.seqSmpIdx != cmInvalidIdx && mep->obj.seqSmpIdx > markEndSmpIdx )
321
+          break;
322
+
323
+        
324
+        // if the time line MIDI msg a note-on
325
+        if( mep->msg->status == kNoteOnMdId )
326
+        {
327
+          cmRC_t cmRC = cmScMatcherExec(sp->match, mep->obj.seqSmpIdx, mep->msg->status, mep->msg->u.chMsgPtr->d0, mep->msg->u.chMsgPtr->d1, NULL );
328
+
329
+          switch( cmRC )
330
+          {
331
+            case cmOkRC:         // continue processing MIDI events
332
+              break;
333
+
334
+            case cmEofRC:        // end of the score was encountered
335
+              break;
336
+
337
+            case cmInvalidArgRC: // p->eli was not set correctly
338
+              rc = cmErrMsg(&sp->err,kScoreMatchFailSpRC,"The score matcher failed due to an invalid argument.");
339
+              goto errLabel;
340
+              break;
341
+
342
+            case cmSubSysFailRC: // scan resync failed
343
+              rc = cmErrMsg(&sp->err,kScoreMatchFailSpRC,"The score matcher failed on resync.");
344
+              cmScMatcherPrint(sp->match);
345
+              //goto errLabel;
346
+              break;
347
+
348
+            default:
349
+              { assert(0); }
350
+          }
351
+        }
352
+      }
353
+
354
+      rc = kOkSpRC;
355
+    }
356
+  }
357
+
358
+
359
+ errLabel:
360
+
361
+  if((rc = _cmScWriteMeasFile(ctx, sp, outFn )) != kOkSpRC )
362
+    cmErrMsg(&sp->err,kFileFailSpRC,"The measurement output did not complete without errors."); 
363
+
364
+  _cmScMeas_t* mp = sp->list_beg;
365
+  while(mp!=NULL)
366
+  {
367
+    _cmScMeas_t* np = mp->link;
368
+    cmMemFree(mp);
369
+    mp = np;
370
+  }
371
+
372
+  if( cmScMatcherFree(&sp->match) != cmOkRC )
373
+    cmErrMsg(&sp->err,kScoreMatchFailSpRC,"The score matcher release failed.");
374
+
375
+  if( cmScMeasFree(&sp->meas) != cmOkRC )
376
+    cmErrMsg(&sp->err,kScoreMatchFailSpRC,"The performance evaluation object failed.");
377
+
378
+
379
+  return rc;
380
+}
381
+
133 382
 unsigned cmScoreProc(cmCtx_t* ctx)
134 383
 {
135 384
   cmSpRC_t rc = kOkSpRC;
136 385
   const cmChar_t* rsrcFn = "/home/kevin/.kc/time_line.js";
386
+  const cmChar_t* outFn  = "/home/kevin/temp/meas0.js";
137 387
   cmSp_t sp;
138 388
 
139 389
   memset(&sp,0,sizeof(sp));
@@ -143,7 +393,10 @@ unsigned cmScoreProc(cmCtx_t* ctx)
143 393
   if((rc = _cmScoreProcInit(ctx,&sp,rsrcFn)) != kOkSpRC )
144 394
     goto errLabel;
145 395
   
396
+  _cmScoreGenAllMeasurements(ctx,&sp,outFn);
146 397
 
398
+  //cmScorePrint(sp.scH,&ctx->rpt);
399
+  //cmScorePrintLoc(sp.scH);
147 400
 
148 401
  
149 402
  errLabel:

Loading…
Cancel
Save