Browse Source

cmProc4.h/c : Added the 'exec' entry type to cmScModulator.

master
kevin 7 years ago
parent
commit
a607108e48
2 changed files with 265 additions and 18 deletions
  1. 250
    16
      cmProc4.c
  2. 15
    2
      cmProc4.h

+ 250
- 16
cmProc4.c View File

@@ -2687,6 +2687,7 @@ cmRC_t cmScModulatorFree(  cmScModulator** pp )
2687 2687
     return rc;
2688 2688
 
2689 2689
   cmMemFree(p->earray);
2690
+  cmMemFree(p->xlist);
2690 2691
   cmObjFree(pp);
2691 2692
   return rc;
2692 2693
 }
@@ -2700,11 +2701,12 @@ typedef struct
2700 2701
 
2701 2702
 _cmScModTypeMap_t _cmScModTypeArray[] =
2702 2703
 {
2703
-  { kDeclModTId,    0, "decl" },
2704
-  { kSetModTId,     1, "set" },
2705
-  { kLineModTId,    2, "line" },
2704
+  { kDeclModTId,    0, "decl"  },
2705
+  { kSetModTId,     1, "set"   },
2706
+  { kLineModTId,    2, "line"  },
2706 2707
   { kSetLineModTId, 3, "sline" },
2707
-  { kPostModTId,    4, "post" },
2708
+  { kPostModTId,    4, "post"  },
2709
+  { kExecModTId,    5, "exec"  },
2708 2710
   { kInvalidModTId, 0, "<invalid>"}
2709 2711
 };
2710 2712
 
@@ -2718,6 +2720,16 @@ const _cmScModTypeMap_t*  _cmScModTypeLabelToMap( const cmChar_t* label )
2718 2720
   return NULL;
2719 2721
 }
2720 2722
 
2723
+const _cmScModTypeMap_t* _cmScModTypeIdToMap( unsigned typeId )
2724
+{
2725
+  unsigned i;
2726
+  for(i=0; _cmScModTypeArray[i].typeId!=kInvalidModTId; ++i)
2727
+    if( _cmScModTypeArray[i].typeId == typeId )
2728
+      return _cmScModTypeArray + i;
2729
+
2730
+  return NULL;  
2731
+}
2732
+
2721 2733
 cmScModVar_t* _cmScModSymToVar( cmScModulator* p, unsigned varSymId )
2722 2734
 {
2723 2735
   cmScModVar_t* vp = p->vlist;  
@@ -2752,14 +2764,14 @@ cmScModVar_t* _cmScModulatorInsertVar( cmScModulator* p, unsigned varSymId, unsi
2752 2764
   return vp;
2753 2765
 }
2754 2766
 
2755
-cmScModEntry_t* _cmScModulatorInsertEntry(cmScModulator* p, unsigned idx, unsigned scLocIdx, unsigned modSymId, unsigned varSymId, unsigned typeId, unsigned paramCnt )
2767
+cmScModEntry_t* _cmScModulatorInsertEntry(cmScModulator* p, unsigned idx, unsigned scLocIdx, unsigned modSymId, unsigned varSymId, unsigned typeId, unsigned entryFlags, unsigned paramCnt )
2756 2768
 {
2757 2769
   assert( idx < p->en );
2758 2770
 
2759 2771
   p->earray[idx].scLocIdx = scLocIdx;
2760 2772
   p->earray[idx].typeId   = typeId;
2761 2773
   p->earray[idx].varPtr   = _cmScModulatorInsertVar(p,varSymId,0);
2762
-
2774
+  p->earray[idx].flags    = entryFlags;
2763 2775
 
2764 2776
   if( p->earray[idx].varPtr->outVarId == cmInvalidIdx )
2765 2777
     p->earray[idx].varPtr->outVarId = p->outVarCnt++;
@@ -2821,6 +2833,86 @@ cmScModEntry_t* _cmScModulatorInsertEntry(cmScModulator* p, unsigned idx, unsign
2821 2833
 }
2822 2834
 
2823 2835
 
2836
+void _cmScProcessEntryGroups( cmScModulator* p )
2837
+{
2838
+  unsigned i=0;
2839
+
2840
+  cmScModEntryGroup_t* g0 = NULL;
2841
+  cmScModEntryGroup_t* g1 = p->glist;
2842
+  
2843
+  while( i<p->en )
2844
+  {
2845
+    // if this is the first entry in a group
2846
+    if( cmIsFlag(p->earray[i].flags , kLocLabelEntryFl ) )
2847
+    {
2848
+      // if no group record is avaiable ...
2849
+      if( g1 == NULL )
2850
+      {
2851
+        // ... then allocate one and ...
2852
+        g1 = cmMemAllocZ(cmScModEntryGroup_t,1);
2853
+
2854
+        // ... link it to the end of the group list
2855
+        if( g0 == NULL )
2856
+          p->glist = g1;
2857
+        else
2858
+          g0->link = g1;
2859
+                
2860
+      }
2861
+
2862
+      unsigned j;
2863
+
2864
+      g1->n = 0;
2865
+      
2866
+      // get a count of the entries in this group
2867
+      while( i<p->en && p->earray[i+g1->n].scLocIdx == p->earray[i].scLocIdx )
2868
+        g1->n += 1;
2869
+      
2870
+      // allocate an array to hold the group
2871
+      g1->base = cmMemResizeZ(cmScModEntry_t*,g1->base,g1->n);
2872
+
2873
+      for(j=0; j<g1->n; ++j)
2874
+        g1->base[j] = p->earray + i + j;
2875
+
2876
+      i += g1->n;
2877
+
2878
+      // make the next group record available
2879
+      g0 = g1;
2880
+      g1 = g1->link;
2881
+
2882
+
2883
+
2884
+    }
2885
+    else
2886
+    {
2887
+      i += 1;
2888
+    }
2889
+  }
2890
+
2891
+  // set successive records as invalid
2892
+  for(; g1 != NULL; g1=g1->link)
2893
+    g1->base = NULL;
2894
+
2895
+}
2896
+
2897
+void _cmScProcessExecList( cmScModulator* p )
2898
+{
2899
+  unsigned i,j;
2900
+  unsigned n = 0;
2901
+  for(i=0; i<p->en; ++i)
2902
+    if( cmIsNotFlag(p->earray[i].flags,kLocLabelEntryFl) )
2903
+      n += 1;
2904
+
2905
+  p->xlist = cmMemResizeZ(cmScModEntry_t*,p->xlist,n);
2906
+  p->xn    = n;
2907
+
2908
+  
2909
+  for(i=0,j=0; i<p->en; ++i)
2910
+    if( cmIsNotFlag(p->earray[i].flags,kLocLabelEntryFl) )
2911
+      p->xlist[j++] = p->earray + i;
2912
+  
2913
+  assert( j == p->xn );
2914
+}
2915
+
2824 2916
 cmRC_t _cmScModulatorParse( cmScModulator* p, cmCtx_t* ctx, cmSymTblH_t stH, const cmChar_t* fn )
2825 2917
 {
2826 2918
   cmRC_t        rc  = cmOkRC;
@@ -2847,13 +2939,15 @@ cmRC_t _cmScModulatorParse( cmScModulator* p, cmCtx_t* ctx, cmSymTblH_t stH, con
2847 2939
   p->earray         = cmMemResizeZ(cmScModEntry_t,p->earray,entryCnt);
2848 2940
   p->en             = entryCnt;
2849 2941
 
2850
-  unsigned        prvScLocIdx = cmInvalidIdx;
2942
+  unsigned        prvScLocIdx   = cmInvalidIdx;
2851 2943
   const cmChar_t* prvModLabel   = NULL;
2852 2944
   const cmChar_t* prvVarLabel   = NULL;
2853 2945
   const cmChar_t* prvTypeLabel  = NULL;
2946
+  unsigned        prvEntryFlags = 0;
2947
+  
2854 2948
   for(i=0; i<entryCnt; ++i)
2855 2949
   {
2856
-    cmJsRC_t                 jsRC;
2950
+    cmJsRC_t                 jsRC        = kOkJsRC;
2857 2951
     const char*              errLabelPtr = NULL;
2858 2952
     unsigned                 scLocIdx    = cmInvalidIdx;
2859 2953
     const cmChar_t*          modLabel    = NULL;
@@ -2862,9 +2956,43 @@ cmRC_t _cmScModulatorParse( cmScModulator* p, cmCtx_t* ctx, cmSymTblH_t stH, con
2862 2956
     cmJsonNode_t*            onp         = cmJsonArrayElement(jnp,i);
2863 2957
     cmJsonNode_t*            dnp         = NULL;
2864 2958
     const _cmScModTypeMap_t* map         = NULL;
2959
+    unsigned                 locTypeId   = kIntTId;
2960
+    unsigned                 entryFlags  = cmInvalidId;
2961
+
2962
+    // if a 'loc' field was specified for this label
2963
+    if( cmJsonFindPair( onp, "loc" ) != NULL )
2964
+    {
2965
+      const cmChar_t*  locLabel = NULL;
2865 2966
 
2866
-    if((jsRC = cmJsonMemberValues( onp, &errLabelPtr, 
2867
-          "loc", kIntTId    | kOptArgJsFl, &scLocIdx,
2967
+      // get the type of the 'loc' value field
2968
+      if( cmJsonMemberType(onp, "loc", &locTypeId) == kOkJsRC )
2969
+      {
2970
+        // read the 'loc' value field
2971
+        if( locTypeId == kStringTId )
2972
+          rc         = cmJsonStringMember( onp, "loc", &locLabel );
2973
+        else
2974
+          rc       = cmJsonUIntMember( onp, "loc", &scLocIdx);
2975
+        
2976
+      }
2977
+
2978
+      // check for parsing errors
2979
+      if( rc != kOkJsRC )
2980
+      {
2981
+        rc = cmCtxRtCondition( &p->obj, cmInvalidArgRC, "Error:Reading 'loc' field on record at index %i in file:%s",i,cmStringNullGuard(fn) );
2982
+        goto errLabel;
2983
+      }
2984
+
2985
+      // if a label was given then convert it to a symbol id
2986
+      if( locLabel != NULL )
2987
+      {
2988
+        scLocIdx   = cmSymTblRegisterSymbol(stH,locLabel);
2989
+        entryFlags = kLocLabelEntryFl; 
2990
+      }
2991
+      
2992
+    }
2993
+
2994
+          
2995
+    if((jsRC = cmJsonMemberValues( onp, &errLabelPtr,
2868 2996
           "mod", kStringTId | kOptArgJsFl, &modLabel,
2869 2997
           "var", kStringTId | kOptArgJsFl, &varLabel,
2870 2998
           "type",kStringTId | kOptArgJsFl, &typeLabel,
@@ -2883,6 +3011,12 @@ cmRC_t _cmScModulatorParse( cmScModulator* p, cmCtx_t* ctx, cmSymTblH_t stH, con
2883 3011
     else
2884 3012
       prvScLocIdx = scLocIdx;
2885 3013
 
3014
+    // if the flags field was not specified
3015
+    if( entryFlags == cmInvalidId )
3016
+      entryFlags = prvEntryFlags;
3017
+    else
3018
+      prvEntryFlags = entryFlags;
3019
+
2886 3020
     // if the mod label was not given use the previous one
2887 3021
     if( modLabel == NULL )
2888 3022
       modLabel = prvModLabel;
@@ -2940,7 +3074,7 @@ cmRC_t _cmScModulatorParse( cmScModulator* p, cmCtx_t* ctx, cmSymTblH_t stH, con
2940 3074
     unsigned paramCnt = cmJsonChildCount(onp);
2941 3075
 
2942 3076
     // fill the entry record and find or create the target var
2943
-    cmScModEntry_t* ep = _cmScModulatorInsertEntry(p,i,scLocIdx,modSymId,varSymId,map->typeId,paramCnt);
3077
+    cmScModEntry_t* ep = _cmScModulatorInsertEntry(p,i,scLocIdx,modSymId,varSymId,map->typeId,entryFlags,paramCnt);
2944 3078
 
2945 3079
     typedef struct
2946 3080
     {
@@ -2994,6 +3128,10 @@ cmRC_t  _cmScModulatorReset( cmScModulator* p, cmCtx_t* ctx, unsigned scLocIdx )
2994 3128
   if((rc = _cmScModulatorParse(p,ctx,p->stH,p->fn)) != cmOkRC )
2995 3129
     goto errLabel;
2996 3130
 
3131
+  _cmScProcessEntryGroups(p);  // fill p->glist
3132
+
3133
+  _cmScProcessExecList(p);     // fill p->xlist
3134
+
2997 3135
 
2998 3136
   // clear the active flag on all variables
2999 3137
   cmScModVar_t* vp = p->vlist;
@@ -3044,6 +3182,17 @@ cmRC_t cmScModulatorFinal( cmScModulator* p )
3044 3182
     vp=np;
3045 3183
   }
3046 3184
 
3185
+  // release each group record
3186
+  cmScModEntryGroup_t* g = p->glist;
3187
+  while( g != NULL )
3188
+  {
3189
+    cmScModEntryGroup_t* g0 = g->link;
3190
+    cmMemFree(g->base);
3191
+    cmMemFree(g);
3192
+    g = g0;
3193
+  }
3194
+  p->glist = NULL;
3195
+
3047 3196
   return cmOkRC;
3048 3197
 }
3049 3198
 
@@ -3149,6 +3298,22 @@ cmRC_t  _cmScModGetParam( cmScModulator* p, const cmScModParam_t* pp, double* va
3149 3298
   return rc;
3150 3299
 }
3151 3300
 
3301
+cmRC_t  _cmScModExecEntries( cmScModulator* p, cmScModEntry_t** xparray, unsigned* idxRef, unsigned cnt, unsigned scLocIdx );
3302
+
3303
+cmRC_t  _cmScModExecGroup( cmScModulator* p, cmScModEntry_t* ep )
3304
+{
3305
+  cmScModEntryGroup_t* g = p->glist;
3306
+  for(; g!=NULL; g=g->link)
3307
+    if( g->base != NULL && g->base[0]->scLocIdx == ep->beg.symId )
3308
+    {
3309
+      unsigned idx = 0;
3310
+
3311
+      return  _cmScModExecEntries( p, g->base, &idx, g->n, ep->beg.symId );
3312
+    }
3313
+
3314
+  return cmCtxRtCondition( &p->obj, cmInvalidArgRC, "Entry group '%s' not found.",cmSymTblLabel(p->stH,ep->beg.symId));    
3315
+}
3316
+
3152 3317
 // Type specific variable activation - 
3153 3318
 cmRC_t _cmScModActivate(cmScModulator* p, cmScModEntry_t* ep )
3154 3319
 {
@@ -3191,6 +3356,10 @@ cmRC_t _cmScModActivate(cmScModulator* p, cmScModEntry_t* ep )
3191 3356
       p->postFl = vp->value;
3192 3357
       break;
3193 3358
 
3359
+    case kExecModTId:
3360
+      rc = _cmScModExecGroup(p,ep);
3361
+      break;
3362
+
3194 3363
     default:
3195 3364
       { assert(0); }
3196 3365
   }
@@ -3270,6 +3439,10 @@ bool  _cmScModExec( cmScModulator* p, cmScModVar_t* vp )
3270 3439
       sendFl = false;
3271 3440
       break;
3272 3441
 
3442
+    case kExecModTId:
3443
+      sendFl = false;
3444
+      break;
3445
+
3273 3446
     default:
3274 3447
       { assert(0); }
3275 3448
   }
@@ -3290,16 +3463,66 @@ bool  _cmScModExec( cmScModulator* p, cmScModVar_t* vp )
3290 3463
   return fl;
3291 3464
 }
3292 3465
 
3466
+// Execute the entries in xparray[] begining with entry xparray[idx] and continuing until:
3467
+// 1) cnt - idx entries have been executed
3468
+// 2) an entry is located whose scLocIdx != scLocIdx and also not -1
3469
+cmRC_t  _cmScModExecEntries( cmScModulator* p, cmScModEntry_t** xparray, unsigned* idxRef, unsigned cnt, unsigned scLocIdx )
3470
+{
3471
+  assert( idxRef != NULL );
3472
+  
3473
+  cmRC_t trc;
3474
+  cmRC_t rc = cmOkRC;
3475
+  unsigned idx = *idxRef;
3476
+  
3477
+  // trigger entries that have expired since the last call to this function
3478
+  for(; idx<cnt && (xparray[idx]->scLocIdx==-1 || xparray[idx]->scLocIdx<=scLocIdx); ++idx)
3479
+  {
3480
+    cmScModEntry_t* ep = xparray[idx];
3481
+
3482
+    // if the variable assoc'd with this entry is not on the active list ...
3483
+    if( cmIsFlag(ep->varPtr->flags,kActiveModFl) == false )
3484
+    {
3485
+      // ... then append it to the end of the active list ...
3486
+      ep->varPtr->flags |= kActiveModFl; 
3487
+
3488
+      if( p->elist == NULL )
3489
+        p->elist = ep->varPtr;
3490
+      else
3491
+      {
3492
+        p->elist->alink = ep->varPtr;
3493
+        p->elist        = ep->varPtr;
3494
+      }
3495
+
3496
+      p->elist->alink = NULL;
3497
+
3498
+      if( p->alist == NULL )
3499
+        p->alist = ep->varPtr;
3500
+    }
3501
+
3502
+    // do type specific activation
3503
+    if((trc = _cmScModActivate(p,ep)) != cmOkRC )
3504
+      rc = trc;
3505
+
3506
+    ep->varPtr->entry = ep;
3507
+
3508
+  }
3509
+
3510
+  *idxRef = idx;
3511
+  
3512
+  return rc;
3513
+}
3514
+
3293 3515
 
3294 3516
 cmRC_t cmScModulatorExec( cmScModulator* p, unsigned scLocIdx )
3295 3517
 {
3296
-  cmRC_t trc;
3297 3518
   cmRC_t rc = cmOkRC;
3519
+  /*
3520
+  cmRC_t trc;
3298 3521
 
3299 3522
   // trigger entries that have expired since the last call to this function
3300
-  for(; p->nei<p->en && (p->earray[p->nei].scLocIdx==-1 || p->earray[p->nei].scLocIdx<=scLocIdx); ++p->nei)
3523
+  for(; p->nei<p->xn && (p->xlist[p->nei]->scLocIdx==-1 || p->xlist[p->nei]->scLocIdx<=scLocIdx); ++p->nei)
3301 3524
   {
3302
-    cmScModEntry_t* ep = p->earray + p->nei;
3525
+    cmScModEntry_t* ep = p->xlist[p->nei];
3303 3526
 
3304 3527
     // if the variable assoc'd with this entry is not on the active list ...
3305 3528
     if( cmIsFlag(ep->varPtr->flags,kActiveModFl) == false )
@@ -3328,7 +3551,9 @@ cmRC_t cmScModulatorExec( cmScModulator* p, unsigned scLocIdx )
3328 3551
     ep->varPtr->entry = ep;
3329 3552
 
3330 3553
   }
3331
-    
3554
+  */
3555
+  
3556
+  rc =  _cmScModExecEntries(p, p->xlist, &p->nei, p->xn, scLocIdx );
3332 3557
   
3333 3558
   // Update the active variables
3334 3559
   cmScModVar_t* pp = NULL;
@@ -3403,7 +3628,16 @@ cmRC_t  cmScModulatorDump(  cmScModulator* p )
3403 3628
   for(i=0; i<p->en; ++i)
3404 3629
   {
3405 3630
     cmScModEntry_t* ep = p->earray + i;
3406
-    printf("%3i %4i %2i %7s ", i, ep->scLocIdx, ep->typeId, cmSymTblLabel(p->stH,ep->varPtr->varSymId));
3631
+    const _cmScModTypeMap_t* tm = _cmScModTypeIdToMap( ep->typeId );
3632
+
3633
+    printf("%3i ",i);
3634
+
3635
+    if( cmIsFlag(ep->flags,kLocLabelEntryFl) )
3636
+      printf("%10s ",cmSymTblLabel(p->stH,ep->scLocIdx));
3637
+    else
3638
+      printf("%10i ",ep->scLocIdx);
3639
+    
3640
+    printf("%5s %7s", tm==NULL ? "invld" : tm->label, cmSymTblLabel(p->stH,ep->varPtr->varSymId));
3407 3641
     _cmScModDumpParam(p," beg", &ep->beg);
3408 3642
     _cmScModDumpParam(p," end", &ep->end);
3409 3643
     _cmScModDumpParam(p," min", &ep->min);

+ 15
- 2
cmProc4.h View File

@@ -425,6 +425,7 @@ extern "C" {
425 425
     line   = ramp from its current value to <val> over <dur> seconds
426 426
     sline  = set <var> to <val> and ramp to <end> over <dur> seconds
427 427
     post   = send a 'post' msg after each transmission (can be used to change the cross-fader after each msg)
428
+    exec   = execute the entry group <val>
428 429
 
429 430
   */
430 431
   enum
@@ -434,7 +435,8 @@ extern "C" {
434 435
     kSetModTId,      // set variable to parray[0] at scLocIdx
435 436
     kLineModTId,     // linear ramp variable to parray[0] over parray[1] seconds
436 437
     kSetLineModTId,  // set variable to parray[0] and ramp to parray[1] over parray[2] seconds
437
-    kPostModTId,     // 
438
+    kPostModTId,     //
439
+    kExecModTId      // execute an entry group 
438 440
   };
439 441
 
440 442
   enum
@@ -475,12 +477,13 @@ extern "C" {
475 477
     struct cmScModVar_str*   alink;    // p->alist link
476 478
   } cmScModVar_t;
477 479
 
478
-
480
+  enum { kLocLabelEntryFl = 0x01 };
479 481
 
480 482
   // Each entry gives a time tagged location and some parameters 
481 483
   // for an algorthm which is used to set/modulate a value.
482 484
   typedef struct cmScModEntry_str
483 485
   {
486
+    unsigned       flags;         // { kLocLabelEntryFl }
484 487
     unsigned       scLocIdx;      // entry start time
485 488
     unsigned       typeId;        // variable type
486 489
     cmScModParam_t beg;           // parameter values
@@ -492,6 +495,13 @@ extern "C" {
492 495
     cmScModVar_t*  varPtr;        // target variable 
493 496
   } cmScModEntry_t;
494 497
 
498
+  typedef struct cmScModEntryGroup_str
499
+  {
500
+    cmScModEntry_t**              base;
501
+    unsigned                      n;
502
+    struct cmScModEntryGroup_str* link;
503
+  } cmScModEntryGroup_t;
504
+
495 505
   typedef void (*cmScModCb_t)( void* cbArg, unsigned varSymId, double value, bool postFl );
496 506
 
497 507
   typedef struct
@@ -512,6 +522,9 @@ extern "C" {
512 522
     unsigned        nei;          // next entry index
513 523
     unsigned        outVarCnt;    // count of unique vars that are targets of entry recds
514 524
     bool            postFl;       // send a 'post' msg after each transmission
525
+    cmScModEntry_t**     xlist;
526
+    unsigned             xn;
527
+    cmScModEntryGroup_t* glist;
515 528
   } cmScModulator;
516 529
 
517 530
 

Loading…
Cancel
Save