Browse Source

Merge branch 'master' of klarke.webfactional.com:webapps/git/repos/libcm

master
kevin 11 years ago
parent
commit
cc7ac752af
37 changed files with 1522 additions and 299 deletions
  1. 2
    2
      Makefile.am
  2. 26
    6
      app/cmScore.c
  3. 6
    1
      app/cmScore.h
  4. 74
    1
      cmAudDsp.c
  5. 1
    0
      cmAudDsp.h
  6. 6
    4
      cmAudioFileDev.c
  7. 1
    0
      cmAudioFileDev.h
  8. 1
    1
      cmAudioNrtDev.c
  9. 46
    5
      cmAudioPortFile.c
  10. 2
    0
      cmAudioPortFile.h
  11. 4
    2
      cmAudioSys.c
  12. 4
    3
      cmAudioSys.h
  13. 1
    0
      cmGlobal.h
  14. 8
    8
      cmLinkedHeap.h
  15. 30
    28
      cmMallocDebug.h
  16. 1
    1
      cmProc.h
  17. 34
    13
      cmProc2.c
  18. 431
    121
      cmProc4.c
  19. 57
    22
      cmProc4.h
  20. 3
    3
      cmProcObj.c
  21. 16
    0
      cmSymTbl.c
  22. 3
    0
      cmSymTbl.h
  23. 25
    26
      dsp/cmDspBuiltIn.c
  24. 9
    1
      dsp/cmDspClass.c
  25. 2
    0
      dsp/cmDspClass.h
  26. 5
    0
      dsp/cmDspCtx.h
  27. 1
    2
      dsp/cmDspFx.c
  28. 321
    18
      dsp/cmDspKr.c
  29. 1
    0
      dsp/cmDspKr.h
  30. 1
    0
      dsp/cmDspNet.c
  31. 1
    0
      dsp/cmDspNet.h
  32. 1
    0
      dsp/cmDspPgm.c
  33. 177
    31
      dsp/cmDspPgmKr.c
  34. 1
    0
      dsp/cmDspPgmKr.h
  35. 179
    0
      dsp/cmDspStore.c
  36. 30
    0
      dsp/cmDspStore.h
  37. 11
    0
      dsp/cmDspSys.c

+ 2
- 2
Makefile.am View File

@@ -39,8 +39,8 @@ cmHDR += src/libcm/cmGr.h src/libcm/cmGrDevCtx.h src/libcm/cmGrPage.h src/libcm/
39 39
 cmHDR +=  src/libcm/dsp/cmDspSys.h src/libcm/dsp/cmDspClass.h src/libcm/dsp/cmDspValue.h src/libcm/dsp/cmDspUi.h src/libcm/dsp/cmDspPreset.h src/libcm/dsp/cmDspNet.h
40 40
 cmSRC +=  src/libcm/dsp/cmDspSys.c src/libcm/dsp/cmDspClass.c src/libcm/dsp/cmDspValue.c src/libcm/dsp/cmDspUi.c src/libcm/dsp/cmDspPreset.c src/libcm/dsp/cmDspNet.c
41 41
 
42
-cmHDR += src/libcm/dsp/cmDspBuiltIn.h  src/libcm/dsp/cmDspFx.h 
43
-cmSRC += src/libcm/dsp/cmDspBuiltIn.c  src/libcm/dsp/cmDspFx.c 
42
+cmHDR += src/libcm/dsp/cmDspStore.h src/libcm/dsp/cmDspBuiltIn.h  src/libcm/dsp/cmDspFx.h 
43
+cmSRC += src/libcm/dsp/cmDspStore.c src/libcm/dsp/cmDspBuiltIn.c  src/libcm/dsp/cmDspFx.c 
44 44
 
45 45
 cmHDR += src/libcm/dsp/cmDspPgm.h src/libcm/dsp/cmDspPgmPP.h src/libcm/dsp/cmDspPgmPPMain.h
46 46
 cmSRC += src/libcm/dsp/cmDspPgm.c src/libcm/dsp/cmDspPgmPP.c src/libcm/dsp/cmDspPgmPPMain.c

+ 26
- 6
app/cmScore.c View File

@@ -9,6 +9,7 @@
9 9
 #include "cmMidi.h"
10 10
 #include "cmLex.h"
11 11
 #include "cmCsv.h"
12
+#include "cmSymTbl.h"
12 13
 #include "cmMidiFile.h"
13 14
 #include "cmAudioFile.h"
14 15
 #include "cmTimeLine.h"
@@ -78,6 +79,7 @@ typedef struct
78 79
 {
79 80
   cmErr_t           err;
80 81
   cmCsvH_t          cH;
82
+  cmSymTblH_t       stH;
81 83
   cmScCb_t          cbFunc;
82 84
   void*             cbArg;
83 85
   cmChar_t*         fn;
@@ -355,7 +357,9 @@ cmScRC_t _cmScFinalize( cmSc_t* p )
355 357
     for(i=0; i<p->setCnt; ++i)
356 358
     {
357 359
       cmMemFree(p->sets[i].eleArray);
358
-      //cmMemFree(p->sets[i].sectArray);
360
+      cmMemFree(p->sets[i].sectArray);
361
+      cmMemFree(p->sets[i].symArray);
362
+      cmMemFree(p->sets[i].costSymArray);
359 363
     }
360 364
     cmMemFree(p->sets);
361 365
   }
@@ -708,6 +712,7 @@ cmScoreSection_t* _cmScLabelToSection( cmSc_t* p, const cmChar_t* label )
708 712
 }
709 713
 
710 714
 
715
+
711 716
 // Calculate the total number of all types of sets and
712 717
 // then convert each of the cmScSet_t linked list's to 
713 718
 // a single linear cmScoreSet_t list (p->sets[]).
@@ -778,8 +783,10 @@ cmScRC_t _cmScProcSets( cmSc_t* p )
778 783
 
779 784
       // allocate the section array
780 785
       p->sets[i].varId    = _cmScVarFlagToId(sp->typeFl);
781
-      //p->sets[i].sectCnt   = en;    
782
-      //p->sets[i].sectArray = cmMemAllocZ(cmScoreSection_t*,en);
786
+      p->sets[i].sectCnt   = en;    
787
+      p->sets[i].sectArray = cmMemAllocZ(cmScoreSection_t*,en);
788
+      p->sets[i].symArray  = cmMemAllocZ(unsigned,en);
789
+      p->sets[i].costSymArray = cmMemAllocZ(unsigned,en);
783 790
 
784 791
       // fill in the section array with sections which this set will be applied to
785 792
       ep = sp->sects;
@@ -791,7 +798,18 @@ cmScRC_t _cmScProcSets( cmSc_t* p )
791 798
           rc = cmErrMsg(&p->err,kSyntaxErrScRC,"The section labelled '%s' could not be found for the set which includes row number %i.",ep->label,rowNumb);        
792 799
         else
793 800
         {
794
-          //= p->sets[i].sectArray[j];
801
+          if( cmSymTblIsValid(p->stH) )
802
+          {
803
+            p->sets[i].symArray[j]     = cmSymTblRegisterFmt(p->stH,"%c-%s", _cmScVarIdToChar(p->sets[i].varId),ep->label);
804
+            p->sets[i].costSymArray[j] = cmSymTblRegisterFmt(p->stH,"c%c-%s",_cmScVarIdToChar(p->sets[i].varId),ep->label);
805
+          }
806
+          else
807
+          {
808
+            p->sets[i].symArray[j] = cmInvalidId;
809
+            p->sets[i].symArray[j] = cmInvalidId;
810
+          }
811
+
812
+          p->sets[i].sectArray[j] = sp;
795 813
 
796 814
           sp->setArray = cmMemResizeP(cmScoreSet_t*,sp->setArray,++sp->setCnt);
797 815
           sp->setArray[sp->setCnt-1] = p->sets + i;
@@ -1107,7 +1125,7 @@ cmScRC_t _cmScInitLocArray( cmSc_t* p )
1107 1125
 }
1108 1126
 
1109 1127
 
1110
-cmScRC_t cmScoreInitialize( cmCtx_t* ctx, cmScH_t* hp, const cmChar_t* fn, double srate, const unsigned* dynRefArray, unsigned dynRefCnt, cmScCb_t cbFunc, void* cbArg )
1128
+cmScRC_t cmScoreInitialize( cmCtx_t* ctx, cmScH_t* hp, const cmChar_t* fn, double srate, const unsigned* dynRefArray, unsigned dynRefCnt, cmScCb_t cbFunc, void* cbArg, cmSymTblH_t stH )
1111 1129
 {
1112 1130
   cmScRC_t rc = kOkScRC;
1113 1131
   if((rc = cmScoreFinalize(hp)) != kOkScRC )
@@ -1117,6 +1135,8 @@ cmScRC_t cmScoreInitialize( cmCtx_t* ctx, cmScH_t* hp, const cmChar_t* fn, doubl
1117 1135
 
1118 1136
   cmErrSetup(&p->err,&ctx->rpt,"Score");
1119 1137
 
1138
+  p->stH   = stH;
1139
+
1120 1140
   if((rc = _cmScParseFile(p,ctx,fn)) != kOkScRC )
1121 1141
     goto errLabel;
1122 1142
 
@@ -1881,7 +1901,7 @@ void cmScorePrint( cmScH_t h, cmRpt_t* rpt )
1881 1901
 void cmScoreTest( cmCtx_t* ctx, const cmChar_t* fn )
1882 1902
 {
1883 1903
   cmScH_t h = cmScNullHandle;
1884
-  if( cmScoreInitialize(ctx,&h,fn,0,NULL,0,NULL,NULL) != kOkScRC )
1904
+  if( cmScoreInitialize(ctx,&h,fn,0,NULL,0,NULL,NULL, cmSymTblNullHandle ) != kOkScRC )
1885 1905
     return;
1886 1906
 
1887 1907
   cmScorePrint(h,&ctx->rpt);

+ 6
- 1
app/cmScore.h View File

@@ -94,6 +94,10 @@ extern "C" {
94 94
     unsigned               varId;      // See kXXXVarScId flags above
95 95
     cmScoreEvt_t**         eleArray;   // Events that make up this set in time order
96 96
     unsigned               eleCnt;     // 
97
+    cmScoreSection_t**     sectArray;  // Sections this set will be applied to
98
+    unsigned               sectCnt;    // 
99
+    unsigned*              symArray;   // symArray[sectCnt] - symbol name of all variables represented by this set (e.g '1a-e', '1b-e', '2-t', etc)
100
+    unsigned*              costSymArray; // costSymArray[sectCnt] - same as symbols in symArray[] with 'c' prepended to front
97 101
     bool                   doneFl;
98 102
     double                 value;
99 103
     struct cmScoreSet_str* llink;      // cmScoreLoc_t setList link
@@ -132,7 +136,8 @@ extern "C" {
132 136
   // If provided the dynRefArray[] is copied into an internal array.
133 137
   // The physical array passed here therefore does not need to remain valid.
134 138
   // Set 'srate' to zero if the score will not be used to perform measurement calculations.
135
-  cmScRC_t      cmScoreInitialize( cmCtx_t* ctx, cmScH_t* hp, const cmChar_t* fn, double srate, const unsigned* dynRefArray, unsigned dynRefCnt, cmScCb_t cbFunc, void* cbArg );
139
+  // The symbol table is only necessary if valid symbols are to be assigned to the cmScoreSet_t.symArray[].
140
+  cmScRC_t      cmScoreInitialize( cmCtx_t* ctx, cmScH_t* hp, const cmChar_t* fn, double srate, const unsigned* dynRefArray, unsigned dynRefCnt, cmScCb_t cbFunc, void* cbArg, cmSymTblH_t stH );
136 141
   cmScRC_t      cmScoreFinalize(   cmScH_t* hp );
137 142
 
138 143
   // Filename of last successfuly loaded score file.

+ 74
- 1
cmAudDsp.c View File

@@ -14,6 +14,7 @@
14 14
 #include "cmAudioPort.h"
15 15
 #include "cmAudioAggDev.h"
16 16
 #include "cmAudioNrtDev.h"
17
+#include "cmAudioPortFile.h"
17 18
 #include "cmApBuf.h"
18 19
 #include "cmMidi.h"
19 20
 #include "cmMidiPort.h"
@@ -64,6 +65,15 @@ typedef struct
64 65
 
65 66
 typedef struct
66 67
 {
68
+  const cmChar_t* label;
69
+  const cmChar_t* inAudioFn;
70
+  const cmChar_t* outAudioFn;
71
+  unsigned        oBits;
72
+  unsigned        oChCnt;
73
+} cmAdAfpDev_t;
74
+
75
+typedef struct
76
+{
67 77
   cmErr_t            err;
68 78
   cmCtx_t            ctx;
69 79
   cmMsgSendFuncPtr_t cbFunc;
@@ -84,6 +94,9 @@ typedef struct
84 94
   cmAdNrtDev_t*      nrtDevArray;
85 95
   unsigned           nrtDevCnt;
86 96
 
97
+  cmAdAfpDev_t*      afpDevArray;
98
+  unsigned           afpDevCnt;
99
+
87 100
   cmAdAsCfg_t*       asCfgArray;
88 101
   unsigned           asCfgCnt;
89 102
   
@@ -151,6 +164,7 @@ cmAdRC_t _cmAdParseSysJsonTree( cmAd_t* p )
151 164
   cmJsonNode_t*   asCfgArrNodePtr  = NULL;
152 165
   cmJsonNode_t*   aggDevArrNodePtr = NULL;
153 166
   cmJsonNode_t*   nrtDevArrNodePtr = NULL;
167
+  cmJsonNode_t*   afpDevArrNodePtr = NULL;
154 168
   cmJsonNode_t*   audDspNodePtr    = NULL;
155 169
   const cmChar_t* errLabelPtr      = NULL;
156 170
   unsigned        i;
@@ -171,6 +185,7 @@ cmAdRC_t _cmAdParseSysJsonTree( cmAd_t* p )
171 185
         "audioSysCfgArray",   kArrayTId, &asCfgArrNodePtr,
172 186
         "aggDevArray",        kArrayTId | kOptArgJsFl, &aggDevArrNodePtr,
173 187
         "nrtDevArray",        kArrayTId | kOptArgJsFl, &nrtDevArrNodePtr,
188
+        "afpDevArray",        kArrayTId | kOptArgJsFl, &afpDevArrNodePtr,
174 189
         NULL )) != kOkJsRC )
175 190
   {
176 191
     rc = _cmAdParseMemberErr(p, jsRC, errLabelPtr, "aud_dsp" );
@@ -242,6 +257,34 @@ cmAdRC_t _cmAdParseSysJsonTree( cmAd_t* p )
242 257
       }
243 258
 
244 259
     }
260
+    
261
+  }
262
+
263
+  // parse the audio file device specifications into p->afpDevArray[].
264
+  if( afpDevArrNodePtr != NULL && (p->afpDevCnt = cmJsonChildCount(afpDevArrNodePtr)) > 0)
265
+  {
266
+    // alloc the non-real-time spec. array
267
+    p->afpDevArray = cmMemResizeZ( cmAdAfpDev_t, p->afpDevArray, p->afpDevCnt );
268
+
269
+    // for each afp. device spec. recd
270
+    for(i=0; i<p->afpDevCnt; ++i)
271
+    {
272
+      const cmJsonNode_t* np   = cmJsonArrayElementC(afpDevArrNodePtr,i);
273
+
274
+      // read afpDevArray record values
275
+      if(( jsRC      = cmJsonMemberValues( np, &errLabelPtr, 
276
+            "label",      kStringTId,                &p->afpDevArray[i].label,
277
+            "iAudioFn",   kStringTId  | kOptArgJsFl, &p->afpDevArray[i].inAudioFn,
278
+            "oAudioFn",   kStringTId  | kOptArgJsFl, &p->afpDevArray[i].outAudioFn,
279
+            "oBits",      kIntTId     | kOptArgJsFl, &p->afpDevArray[i].oBits,
280
+            "oChCnt",     kIntTId     | kOptArgJsFl, &p->afpDevArray[i].oChCnt,
281
+            NULL )) != kOkJsRC )
282
+      {
283
+        rc = _cmAdParseMemberErr(p, jsRC, errLabelPtr, cmStringNullGuard(p->afpDevArray[i].label) );
284
+        goto errLabel;
285
+      }
286
+
287
+    }
245 288
 
246 289
   }
247 290
 
@@ -368,6 +411,26 @@ cmAdRC_t _cmAdCreateNrtDevices( cmAd_t* p )
368 411
   return rc;
369 412
 }
370 413
 
414
+cmAdRC_t _cmAdCreateAfpDevices( cmAd_t* p )
415
+{
416
+  cmAdRC_t rc = kOkAdRC;
417
+
418
+  if( cmApFileAllocate(p->err.rpt) != kOkApRC )
419
+    return cmErrMsg(&p->err,kAfpDevSysFailAdRC,"The audio file device system allocation failed.");
420
+
421
+  unsigned i;
422
+  // create the audio file devices
423
+  for(i=0; i<p->afpDevCnt; ++i)
424
+  {
425
+    //const cmAudioSysFilePort_t* afp = cfg->afpArray + i;
426
+    cmAdAfpDev_t* afp = p->afpDevArray + i;
427
+    if( cmApFileDeviceCreate( afp->label, afp->inAudioFn, afp->outAudioFn, afp->oBits, afp->oChCnt ) != kOkApRC )
428
+      rc = cmErrMsg(&p->err,kAfpDevSysFailAdRC,"The audio file device '%s' creation failed.",cmStringNullGuard(afp->label));
429
+  }
430
+
431
+  return rc;
432
+}
433
+
371 434
 cmAdRC_t _cmAdSendAudioSysCfgLabels( cmAd_t* p)
372 435
 {
373 436
   cmAdRC_t     rc = kOkAdRC;
@@ -480,9 +543,15 @@ cmAdRC_t _cmAudDspFree( cmAd_t* p )
480 543
     goto errLabel;
481 544
   }
482 545
 
546
+  if( cmApFileFree() != kOkApRC )
547
+  {
548
+    rc = cmErrMsg(&p->err,kAfpDevSysFailAdRC,"The audio file device system release failed.");
549
+    goto errLabel;
550
+  }
551
+
483 552
   if( cmApNrtFree() != kOkAgRC )
484 553
   {
485
-    rc = cmErrMsg(&p->err,kNrtDevSysFailAdRC,"The non-real-time device system realease failed.");
554
+    rc = cmErrMsg(&p->err,kNrtDevSysFailAdRC,"The non-real-time device system release failed.");
486 555
     goto errLabel;
487 556
   }
488 557
 
@@ -562,6 +631,10 @@ cmAdRC_t cmAudDspAlloc( cmCtx_t* ctx, cmAdH_t* hp, cmMsgSendFuncPtr_t cbFunc, vo
562 631
   if( _cmAdCreateNrtDevices(p) != kOkAdRC )
563 632
     goto errLabel;
564 633
 
634
+  // create the audio file devices
635
+  if( _cmAdCreateAfpDevices(p) != kOkAdRC )
636
+    goto errLabel;
637
+
565 638
   // initialize the audio device system
566 639
   if( cmApInitialize(&ctx->rpt) != kOkApRC )
567 640
   {

+ 1
- 0
cmAudDsp.h View File

@@ -25,6 +25,7 @@ extern "C" {
25 25
     kAggDevSysFailAdRC,
26 26
     kAggDevCreateFailAdRC,
27 27
     kNrtDevSysFailAdRC,
28
+    kAfpDevSysFailAdRC,
28 29
     kNetSysFailAdRC
29 30
   };
30 31
 

+ 6
- 4
cmAudioFileDev.c View File

@@ -220,8 +220,6 @@ cmAfdRC_t cmAudioFileDevInitialize(
220 220
       goto errLabel;
221 221
     }
222 222
 
223
-
224
-
225 223
     p->iPkt.devIdx         = devIdx;
226 224
     p->iPkt.begChIdx       = 0;
227 225
     p->iPkt.chCnt          = afInfo.chCnt;   // setting iPkt.chCnt to a non-zero value marks the input file as active
@@ -294,6 +292,7 @@ bool      cmAudioFileDevIsValid( cmAfdH_t h )
294 292
 
295 293
 cmAfdRC_t cmAudioFileDevSetup( 
296 294
   cmAfdH_t                        h, 
295
+  unsigned                        baseDevIdx,
297 296
   double                          srate, 
298 297
   unsigned                        framesPerCycle, 
299 298
   cmApCallbackPtr_t               callbackPtr, 
@@ -344,13 +343,14 @@ cmAfdRC_t cmAudioFileDevSetup(
344 343
 
345 344
     cmApSample_t* bp = (cmApSample_t*)p->oPkt.audioBytesPtr;
346 345
 
347
-    p->oPkt.devIdx         = p->devIdx;
346
+    p->oPkt.devIdx         = p->devIdx + baseDevIdx;
348 347
     p->oPkt.begChIdx       = 0;
349 348
     p->oPkt.chCnt          = p->oChCnt;
350 349
     p->oPkt.audioFramesCnt = framesPerCycle;
351 350
     p->oPkt.bitsPerSample  = p->oBits;
352 351
     p->oPkt.flags          = kFloatApFl;
353 352
     p->oPkt.audioBytesPtr  = bp = cmMemResizeZ( cmApSample_t, bp, framesPerCycle*p->oChCnt );
353
+    p->oPkt.userCbPtr      = cbDataPtr;
354 354
     p->oChArray            = cmMemResizeZ( cmApSample_t*, p->oChArray, p->oChCnt );
355 355
     
356 356
     for(i=0; i<p->oChCnt; ++i)
@@ -362,8 +362,10 @@ cmAfdRC_t cmAudioFileDevSetup(
362 362
   {
363 363
     cmApSample_t* bp = (cmApSample_t*)p->iPkt.audioBytesPtr;
364 364
 
365
+    p->iPkt.devIdx         = p->devIdx + baseDevIdx;
365 366
     p->iPkt.audioFramesCnt = framesPerCycle;
366 367
     p->iPkt.audioBytesPtr  = bp = cmMemResizeZ( cmApSample_t, bp, framesPerCycle*p->iPkt.chCnt ); ;
368
+    p->iPkt.userCbPtr      = cbDataPtr;
367 369
     for(i=0; i<p->iPkt.chCnt; ++i)
368 370
       p->iChArray[i] = bp + (i*framesPerCycle);
369 371
   }
@@ -534,7 +536,7 @@ void      cmAudioFileDevTest( cmRpt_t* rpt )
534 536
   if( cmAudioFileDevInitialize(&afdH,"file",devIdx,iFn,oFn,oBits,oChCnt,rpt) != kOkAfdRC )
535 537
     goto errLabel;
536 538
 
537
-  if( cmAudioFileDevSetup(afdH,srate,framesPerCycle,_cmAfdCallback,cbDataPtr) != kOkAfdRC )
539
+  if( cmAudioFileDevSetup(afdH,0,srate,framesPerCycle,_cmAfdCallback,cbDataPtr) != kOkAfdRC )
538 540
     goto errLabel;
539 541
 
540 542
   char c;

+ 1
- 0
cmAudioFileDev.h View File

@@ -37,6 +37,7 @@ bool      cmAudioFileDevIsValid( cmAfdH_t h );
37 37
 /// Setup the device. This function must be called prior to cmAudioFileDevStart().
38 38
 cmAfdRC_t cmAudioFileDevSetup( 
39 39
   cmAfdH_t          h, 
40
+  unsigned          baseApDevIdx,
40 41
   double            srate, 
41 42
   unsigned          framesPerCycle, 
42 43
   cmApCallbackPtr_t callbackPtr, 

+ 1
- 1
cmAudioNrtDev.c View File

@@ -25,7 +25,7 @@ typedef struct
25 25
 typedef struct cmApNrtDev_str
26 26
 {
27 27
   unsigned               flags;
28
-  unsigned               devIdx; // nrt device index
28
+  unsigned               devIdx;       // nrt device index
29 29
   unsigned               baseApDevIdx; // global audio device index for first nrt device
30 30
   cmChar_t*              label;         
31 31
   unsigned               iChCnt;

+ 46
- 5
cmAudioPortFile.c View File

@@ -11,6 +11,8 @@
11 11
 typedef struct
12 12
 {
13 13
   cmAfdH_t devH;
14
+  unsigned devIdx;  // afp dev idx
15
+  unsigned baseApDevIdx; // global audio device index for first afp device
14 16
 } cmApDev_t;
15 17
 
16 18
 typedef struct
@@ -18,19 +20,53 @@ typedef struct
18 20
   cmErr_t    err;
19 21
   cmApDev_t* devArray;
20 22
   unsigned   devCnt;
23
+  unsigned   baseApDevIdx;
21 24
 } cmApf_t;
22 25
 
23 26
 cmApf_t* _cmApf = NULL;
24 27
 
25
-cmApRC_t      cmApFileInitialize( cmRpt_t* rpt, unsigned baseApDevIdx )
28
+cmApRC_t      cmApFileAllocate( cmRpt_t* rpt )
26 29
 {
27
-  cmApRC_t rc;
28
-  if((rc = cmApFileFinalize()) != kOkApRC )
29
-    return rc;
30
+  cmApRC_t rc = kOkApRC;
31
+
32
+  if( _cmApf != NULL )
33
+    cmApFileFree();
30 34
 
31 35
   _cmApf = cmMemAllocZ(cmApf_t,1);
32 36
 
33 37
   cmErrSetup(&_cmApf->err,rpt,"Audio Port File");
38
+  _cmApf->devArray     = NULL;
39
+  _cmApf->devCnt       = 0;
40
+  _cmApf->baseApDevIdx = 0;
41
+
42
+  return rc;
43
+}
44
+
45
+cmApRC_t      cmApFileFree()
46
+{
47
+  cmApRC_t rc = kOkApRC;
48
+
49
+  if( _cmApf == NULL )
50
+    return rc;
51
+
52
+  if((rc = cmApFileFinalize()) != kOkApRC )
53
+    return rc;
54
+
55
+  cmMemFree(_cmApf);
56
+  _cmApf = NULL;
57
+  return rc;
58
+}
59
+
60
+
61
+cmApRC_t      cmApFileInitialize( cmRpt_t* rpt, unsigned baseApDevIdx )
62
+{
63
+  cmApRC_t rc = kOkApRC;
64
+
65
+  unsigned i = 0;
66
+  for(; i<_cmApf->devCnt; ++i)
67
+    _cmApf->devArray[i].baseApDevIdx = baseApDevIdx;
68
+
69
+  _cmApf->baseApDevIdx = baseApDevIdx;
34 70
 
35 71
   return rc;      
36 72
 }
@@ -85,7 +121,12 @@ unsigned      cmApFileDeviceCreate(
85 121
   {
86 122
     cmErrMsg(&_cmApf->err,kAudioPortFileFailApRC,"The audio file device initialization failed.");
87 123
     i = cmInvalidIdx;
124
+    goto errLabel;
88 125
   }
126
+
127
+  _cmApf->devArray[i].devIdx = i;
128
+
129
+ errLabel:
89 130
   
90 131
   return i;
91 132
 }
@@ -134,7 +175,7 @@ cmApRC_t      cmApFileDeviceSetup(
134 175
 {
135 176
   assert( devIdx < cmApFileDeviceCount());
136 177
 
137
-  if( cmAudioFileDevSetup( _cmApf->devArray[devIdx].devH,srate,framesPerCycle,callbackPtr,userCbPtr) != kOkAfdRC )
178
+  if( cmAudioFileDevSetup( _cmApf->devArray[devIdx].devH,_cmApf->baseApDevIdx,srate,framesPerCycle,callbackPtr,userCbPtr) != kOkAfdRC )
138 179
     return cmErrMsg(&_cmApf->err,kAudioPortFileFailApRC,"The audio file device setup failed.");
139 180
 
140 181
   return kOkApRC;

+ 2
- 0
cmAudioPortFile.h View File

@@ -5,6 +5,8 @@
5 5
 extern "C" {
6 6
 #endif
7 7
 
8
+  cmApRC_t      cmApFileAllocate( cmRpt_t* rpt );
9
+  cmApRC_t      cmApFileFree();
8 10
 
9 11
   cmApRC_t      cmApFileInitialize( cmRpt_t* rpt, unsigned baseApDevIdx );
10 12
   cmApRC_t      cmApFileFinalize();

+ 4
- 2
cmAudioSys.c View File

@@ -729,11 +729,13 @@ cmAsRC_t cmAudioSysInitialize( cmAudioSysH_t h, const cmAudioSysCfg_t* cfg )
729 729
     return rc;
730 730
 
731 731
   // create the audio file devices
732
+  /*
732 733
   for(i=0; i<cfg->afpCnt; ++i)
733 734
   {
734 735
     const cmAudioSysFilePort_t* afp = cfg->afpArray + i;
735 736
     cmApFileDeviceCreate( afp->devLabel, afp->inAudioFn, afp->outAudioFn, afp->oBits, afp->oChCnt );
736 737
   }
738
+  */
737 739
 
738 740
   p->ssArray = cmMemAllocZ( _cmAsCfg_t, cfg->ssCnt );
739 741
   p->ssCnt   = cfg->ssCnt;
@@ -1281,8 +1283,8 @@ void cmAudioSysTest( cmRpt_t* rpt, int argc, const char* argv[] )
1281 1283
 
1282 1284
   cfg.ssArray = &ss;
1283 1285
   cfg.ssCnt   = 1;
1284
-  cfg.afpArray= NULL;
1285
-  cfg.afpCnt  = 0;
1286
+  //cfg.afpArray= NULL;
1287
+  //cfg.afpCnt  = 0;
1286 1288
   cfg.meterMs = 50;
1287 1289
 
1288 1290
   if(_cmAsGetBoolOpt(argc,argv,"-h",false))

+ 4
- 3
cmAudioSys.h View File

@@ -172,6 +172,7 @@ extern "C" {
172 172
     
173 173
   } cmAudioSysCtx_t;
174 174
 
175
+  /*
175 176
   typedef struct
176 177
   {
177 178
     const cmChar_t* devLabel;
@@ -180,15 +181,15 @@ extern "C" {
180 181
     unsigned        oBits;
181 182
     unsigned        oChCnt;
182 183
   } cmAudioSysFilePort_t;
183
-
184
+  */
184 185
 
185 186
   /// Audio system configuration record used by cmAudioSysAllocate().
186 187
   typedef struct cmAudioSysCfg_str
187 188
   {
188 189
     cmAudioSysSubSys_t*   ssArray;      ///< sub-system cfg record array
189 190
     unsigned              ssCnt;        ///< count of sub-systems   
190
-    cmAudioSysFilePort_t* afpArray;     ///< audio port file cfg recd array
191
-    unsigned              afpCnt;       ///< audio port file cnt
191
+    //cmAudioSysFilePort_t* afpArray;     ///< audio port file cfg recd array
192
+    //unsigned              afpCnt;       ///< audio port file cnt
192 193
     unsigned              meterMs;      ///< Meter sample period in milliseconds
193 194
     void*                 clientCbData; ///< User arg. for clientCbFunc().
194 195
     cmTsQueueCb_t         clientCbFunc; ///< Called by  cmAudioSysReceiveMsg() to deliver internally generated msg's to the host. 

+ 1
- 0
cmGlobal.h View File

@@ -99,6 +99,7 @@ extern "C" {
99 99
 
100 100
 
101 101
 #define cmStringNullGuard(p) ((p)==NULL?"<null>":(p)) //< If 'p'==NULL return the static string "<null>" otherwise return 'p'.
102
+#define cmStringLen(s)       ((s)==NULL? 0 : strlen(s))
102 103
 
103 104
   // Default return code indicating successful function completion.
104 105
 #define cmOkRC (0)                  

+ 8
- 8
cmLinkedHeap.h View File

@@ -52,10 +52,10 @@ extern "C" {
52 52
 #define cmLhResizeN( h,t,p,n) ((t*)cmLHeapAllocate(h,p,   n,sizeof(t), kAlignMmFl,              NULL,NULL,0))
53 53
 #define cmLhResizeNZ(h,t,p,n) ((t*)cmLHeapAllocate(h,p,   n,sizeof(t), kAlignMmFl  | kZeroMmFl, NULL,NULL,0))
54 54
 
55
-#define cmLhAllocStr(   h, str )       cmLHeapAllocStr( h, NULL, str, strlen(str), kAlignMmFl, NULL,NULL,0 )
56
-#define cmLhAllocStrN(  h, str, n )    cmLHeapAllocStr( h, NULL, str, n,           kAlignMmFl, NULL,NULL,0 )
57
-#define cmLhResizeStr(  h, p, str )    cmLHeapAllocStr( h, p,    str, strlen(str), kAlignMmFl, NULL,NULL,0 )
58
-#define cmLhResizeStrN( h, p, str, n ) cmLHeapAllocStr( h, p,    str, n,           kAlignMmFl, NULL,NULL,0 )
55
+#define cmLhAllocStr(   h, str )       cmLHeapAllocStr( h, NULL, str, cmStringLen(str), kAlignMmFl, NULL,NULL,0 )
56
+#define cmLhAllocStrN(  h, str, n )    cmLHeapAllocStr( h, NULL, str, n,                kAlignMmFl, NULL,NULL,0 )
57
+#define cmLhResizeStr(  h, p, str )    cmLHeapAllocStr( h, p,    str, cmStringLen(str), kAlignMmFl, NULL,NULL,0 )
58
+#define cmLhResizeStrN( h, p, str, n ) cmLHeapAllocStr( h, p,    str, n,                kAlignMmFl, NULL,NULL,0 )
59 59
 
60 60
 #define cmLhFree( h, p )           cmLHeapFree( h, p )
61 61
 #define cmLhFreePtr(h, p )         cmLHeapFreePtr( h, p ) 
@@ -70,10 +70,10 @@ extern "C" {
70 70
 #define cmLhResizeN( h,t,p,n) ((t*)cmLHeapAllocate(h,p,   n,sizeof(t), kAlignMmFl,              __FILE__,__FUNCTION__,__LINE__))
71 71
 #define cmLhResizeNZ(h,t,p,n) ((t*)cmLHeapAllocate(h,p,   n,sizeof(t), kAlignMmFl  | kZeroMmFl, __FILE__,__FUNCTION__,__LINE__))
72 72
 
73
-#define cmLhAllocStr(  h, str )        cmLHeapAllocStr( h, NULL, str, strlen(str),    kAlignMmFl, __FILE__,__FUNCTION__,__LINE__ )
74
-#define cmLhAllocStrN( h, str, n )     cmLHeapAllocStr( h, NULL, str, n,              kAlignMmFl, __FILE__,__FUNCTION__,__LINE__ )
75
-#define cmLhResizeStr( h, p, str )     cmLHeapAllocStr( h, p,    str, strlen(str),    kAlignMmFl, __FILE__,__FUNCTION__,__LINE__ )
76
-#define cmLhResizeStrN( h, p, str, n ) cmLHeapAllocStr( h, p,    str, n,              kAlignMmFl, __FILE__,__FUNCTION__,__LINE__ )
73
+#define cmLhAllocStr(  h, str )        cmLHeapAllocStr( h, NULL, str, cmStringLen(str),  kAlignMmFl, __FILE__,__FUNCTION__,__LINE__ )
74
+#define cmLhAllocStrN( h, str, n )     cmLHeapAllocStr( h, NULL, str, n,                 kAlignMmFl, __FILE__,__FUNCTION__,__LINE__ )
75
+#define cmLhResizeStr( h, p, str )     cmLHeapAllocStr( h, p,    str, cmStringLen(str),  kAlignMmFl, __FILE__,__FUNCTION__,__LINE__ )
76
+#define cmLhResizeStrN( h, p, str, n ) cmLHeapAllocStr( h, p,    str, n,                 kAlignMmFl, __FILE__,__FUNCTION__,__LINE__ )
77 77
 
78 78
 #define cmLhFree( h, p )           cmLHeapFreeDebug(    h, p, __FILE__,__FUNCTION__,__LINE__ )
79 79
 #define cmLhFreePtr(h, p )         cmLHeapFreePtrDebug( h, p, __FILE__,__FUNCTION__,__LINE__ ) 

+ 30
- 28
cmMallocDebug.h View File

@@ -93,6 +93,8 @@ extern "C" {
93 93
   // An example and test function for the cmMallocDebug manager.
94 94
   void     cmMdTest( cmRpt_t* rpt );
95 95
 
96
+
97
+
96 98
 #if cmDEBUG_FL == 0
97 99
 
98 100
   // Memory Allocation and Release Macros:
@@ -101,20 +103,20 @@ extern "C" {
101 103
   //
102 104
 
103 105
 #define cmMemAllocate( type, p, eleCnt, fl ) ((type*)cmMdAllocate( p, eleCnt, sizeof(type), fl )) 
104
-#define cmMemMalloc(   byteCnt )                 cmMdAllocate( NULL, byteCnt,           1, kAlignMmFl) 
105
-#define cmMemMallocZ(  byteCnt )                 cmMdAllocate( NULL, byteCnt,           1, kAlignMmFl | kZeroMmFl) 
106
-#define cmMemAlloc(    type, eleCnt )    ((type*)cmMdAllocate( NULL, eleCnt, sizeof(type), kAlignMmFl))
107
-#define cmMemAllocZ(   type, eleCnt )    ((type*)cmMdAllocate( NULL, eleCnt, sizeof(type), kAlignMmFl | kZeroMmFl))
108
-#define cmMemAllocStr(  str )                    cmMdAllocStr( NULL, str,    strlen(str),  kAlignMmFl )
109
-#define cmMemAllocStrN( str, charCnt )           cmMdAllocStr( NULL, str,    charCnt,      kAlignMmFl )
110
-#define cmMemResizeStr( p, str )                 cmMdAllocStr( p,    str,    strlen(str),  kAlignMmFl )
111
-#define cmMemResizeStrN(p, str, charCnt )       cmMdAllocStr( p,    str,    charCnt,      kAlignMmFl )
112
-#define cmMemResizeN(   n, p, eleCnt )          (cmMdAllocate( p,    eleCnt, n,            kAlignMmFl))
113
-#define cmMemResizeNZ(  n, p, eleCnt )          (cmMdAllocate( p,    eleCnt, n,            kAlignMmFl | kZeroMmFl ))
114
-#define cmMemResize(   type, p, eleCnt ) ((type*)cmMdAllocate( p,    eleCnt, sizeof(type), kAlignMmFl))
115
-#define cmMemResizeZ(  type, p, eleCnt ) ((type*)cmMdAllocate( p,    eleCnt, sizeof(type), kAlignMmFl | kZeroMmFl))
116
-#define cmMemResizeP(  type, p, eleCnt ) ((type*)cmMdAllocate( p,    eleCnt, sizeof(type), kAlignMmFl | kPreserveMmFl))
117
-#define cmMemResizePZ( type, p, eleCnt ) ((type*)cmMdAllocate( p,    eleCnt, sizeof(type), kAlignMmFl | kZeroMmFl | kPreserveMmFl))
106
+#define cmMemMalloc(   byteCnt )                 cmMdAllocate( NULL, byteCnt,           1,     kAlignMmFl) 
107
+#define cmMemMallocZ(  byteCnt )                 cmMdAllocate( NULL, byteCnt,           1,     kAlignMmFl | kZeroMmFl) 
108
+#define cmMemAlloc(    type, eleCnt )    ((type*)cmMdAllocate( NULL, eleCnt, sizeof(type),     kAlignMmFl))
109
+#define cmMemAllocZ(   type, eleCnt )    ((type*)cmMdAllocate( NULL, eleCnt, sizeof(type),     kAlignMmFl | kZeroMmFl))
110
+#define cmMemAllocStr(  str )                    cmMdAllocStr( NULL, str,    cmStringLen(str), kAlignMmFl )
111
+#define cmMemAllocStrN( str, charCnt )           cmMdAllocStr( NULL, str,    charCnt,          kAlignMmFl )
112
+#define cmMemResizeStr( p, str )                 cmMdAllocStr( p,    str,    cmStringLen(str), kAlignMmFl )
113
+#define cmMemResizeStrN(p, str, charCnt )       cmMdAllocStr( p,    str,    charCnt,           kAlignMmFl )
114
+#define cmMemResizeN(   n, p, eleCnt )          (cmMdAllocate( p,    eleCnt, n,                kAlignMmFl))
115
+#define cmMemResizeNZ(  n, p, eleCnt )          (cmMdAllocate( p,    eleCnt, n,                kAlignMmFl | kZeroMmFl ))
116
+#define cmMemResize(   type, p, eleCnt ) ((type*)cmMdAllocate( p,    eleCnt, sizeof(type),     kAlignMmFl))
117
+#define cmMemResizeZ(  type, p, eleCnt ) ((type*)cmMdAllocate( p,    eleCnt, sizeof(type),     kAlignMmFl | kZeroMmFl))
118
+#define cmMemResizeP(  type, p, eleCnt ) ((type*)cmMdAllocate( p,    eleCnt, sizeof(type),     kAlignMmFl | kPreserveMmFl))
119
+#define cmMemResizePZ( type, p, eleCnt ) ((type*)cmMdAllocate( p,    eleCnt, sizeof(type),     kAlignMmFl | kZeroMmFl | kPreserveMmFl))
118 120
 #define cmMemFree(     ptr )                     cmMdFree( ptr )
119 121
 #define cmMemPtrFree(  ptrPtr )                  cmMdFreePtr(ptrPtr);
120 122
 
@@ -130,20 +132,20 @@ extern "C" {
130 132
   //
131 133
   //
132 134
 #define cmMemAllocate( type, p, eleCnt, pre, fl ) ((type*)cmMdAllocateDebug( p, eleCnt, sizeof(type), fl, __FUNCTION__, __FILE__, __LINE__ ))
133
-#define cmMemMalloc(   byteCnt )                 cmMdAllocateDebug( NULL, 1,      byteCnt,      kAlignMmFl,             __FUNCTION__, __FILE__, __LINE__ )
134
-#define cmMemMallocZ(  byteCnt )                 cmMdAllocateDebug( NULL, 1,      byteCnt,      kAlignMmFl | kZeroMmFl, __FUNCTION__, __FILE__, __LINE__ )
135
-#define cmMemAlloc(    type, eleCnt )    ((type*)cmMdAllocateDebug( NULL, eleCnt, sizeof(type), kAlignMmFl,             __FUNCTION__, __FILE__, __LINE__ ))
136
-#define cmMemAllocZ(   type, eleCnt )    ((type*)cmMdAllocateDebug( NULL, eleCnt, sizeof(type), kAlignMmFl | kZeroMmFl, __FUNCTION__, __FILE__, __LINE__ ))
137
-#define cmMemAllocStr( str )                    (cmMdAllocStrDebug( NULL, str,    strlen(str),  kAlignMmFl,             __FUNCTION__, __FILE__, __LINE__ ))
138
-#define cmMemAllocStrN(str, charCnt )           (cmMdAllocStrDebug( NULL, str,    charCnt,      kAlignMmFl,             __FUNCTION__, __FILE__, __LINE__ ))
139
-#define cmMemResizeStr(p, str )                 (cmMdAllocStrDebug( p,    str,    strlen(str),  kAlignMmFl,             __FUNCTION__, __FILE__, __LINE__ ))
140
-#define cmMemResizeStrN(p, str, charCnt )        (cmMdAllocStrDebug( p,    str,    charCnt,      kAlignMmFl,             __FUNCTION__, __FILE__, __LINE__ ))
141
-#define cmMemResizeN(  n,    p, eleCnt )        (cmMdAllocateDebug( p,    eleCnt, n,            kAlignMmFl | kZeroMmFl, __FUNCTION__, __FILE__, __LINE__ ))
142
-#define cmMemResizeNZ( n,    p, eleCnt )        (cmMdAllocateDebug( p,    eleCnt, n,                         kZeroMmFl, __FUNCTION__, __FILE__, __LINE__ ))      
143
-#define cmMemResize(   type, p, eleCnt ) ((type*)cmMdAllocateDebug( p,    eleCnt, sizeof(type), kAlignMmFl,             __FUNCTION__, __FILE__, __LINE__ )) 
144
-#define cmMemResizeZ(  type, p, eleCnt ) ((type*)cmMdAllocateDebug( p,    eleCnt, sizeof(type), kAlignMmFl | kZeroMmFl, __FUNCTION__, __FILE__, __LINE__ ))
145
-#define cmMemResizeP(  type, p, eleCnt ) ((type*)cmMdAllocateDebug( p,    eleCnt, sizeof(type), kAlignMmFl | kPreserveMmFl,             __FUNCTION__, __FILE__, __LINE__ )) 
146
-#define cmMemResizePZ( type, p, eleCnt ) ((type*)cmMdAllocateDebug( p,    eleCnt, sizeof(type), kAlignMmFl | kZeroMmFl | kPreserveMmFl, __FUNCTION__, __FILE__, __LINE__ ))
135
+#define cmMemMalloc(   byteCnt )                 cmMdAllocateDebug( NULL, 1,      byteCnt,          kAlignMmFl,             __FUNCTION__, __FILE__, __LINE__ )
136
+#define cmMemMallocZ(  byteCnt )                 cmMdAllocateDebug( NULL, 1,      byteCnt,          kAlignMmFl | kZeroMmFl, __FUNCTION__, __FILE__, __LINE__ )
137
+#define cmMemAlloc(    type, eleCnt )    ((type*)cmMdAllocateDebug( NULL, eleCnt, sizeof(type),     kAlignMmFl,             __FUNCTION__, __FILE__, __LINE__ ))
138
+#define cmMemAllocZ(   type, eleCnt )    ((type*)cmMdAllocateDebug( NULL, eleCnt, sizeof(type),     kAlignMmFl | kZeroMmFl, __FUNCTION__, __FILE__, __LINE__ ))
139
+#define cmMemAllocStr( str )                    (cmMdAllocStrDebug( NULL, str,    cmStringLen(str), kAlignMmFl,             __FUNCTION__, __FILE__, __LINE__ ))
140
+#define cmMemAllocStrN(str, charCnt )           (cmMdAllocStrDebug( NULL, str,    charCnt,          kAlignMmFl,             __FUNCTION__, __FILE__, __LINE__ ))
141
+#define cmMemResizeStr(p, str )                 (cmMdAllocStrDebug( p,    str,    cmStringLen(str), kAlignMmFl,             __FUNCTION__, __FILE__, __LINE__ ))
142
+#define cmMemResizeStrN(p, str, charCnt )       (cmMdAllocStrDebug( p,    str,    charCnt,          kAlignMmFl,             __FUNCTION__, __FILE__, __LINE__ ))
143
+#define cmMemResizeN(  n,    p, eleCnt )        (cmMdAllocateDebug( p,    eleCnt, n,                kAlignMmFl | kZeroMmFl, __FUNCTION__, __FILE__, __LINE__ ))
144
+#define cmMemResizeNZ( n,    p, eleCnt )        (cmMdAllocateDebug( p,    eleCnt, n,                kZeroMmFl,              __FUNCTION__, __FILE__, __LINE__ ))      
145
+#define cmMemResize(   type, p, eleCnt ) ((type*)cmMdAllocateDebug( p,    eleCnt, sizeof(type),     kAlignMmFl,             __FUNCTION__, __FILE__, __LINE__ )) 
146
+#define cmMemResizeZ(  type, p, eleCnt ) ((type*)cmMdAllocateDebug( p,    eleCnt, sizeof(type),     kAlignMmFl | kZeroMmFl, __FUNCTION__, __FILE__, __LINE__ ))
147
+#define cmMemResizeP(  type, p, eleCnt ) ((type*)cmMdAllocateDebug( p,    eleCnt, sizeof(type),     kAlignMmFl | kPreserveMmFl,             __FUNCTION__, __FILE__, __LINE__ )) 
148
+#define cmMemResizePZ( type, p, eleCnt ) ((type*)cmMdAllocateDebug( p,    eleCnt, sizeof(type),     kAlignMmFl | kZeroMmFl | kPreserveMmFl, __FUNCTION__, __FILE__, __LINE__ ))
147 149
 #define cmMemFree(     ptr )                     cmMdFreeDebug( ptr,                                                                  __FUNCTION__, __FILE__, __LINE__ )
148 150
 #define cmMemPtrFree(  ptrPtr )                  cmMdFreePtrDebug( (void**)ptrPtr,                                                    __FUNCTION__, __FILE__, __LINE__ )
149 151
 

+ 1
- 1
cmProc.h View File

@@ -48,7 +48,7 @@ extern "C" {
48 48
   {
49 49
     cmObj       obj;
50 50
     unsigned    bufSmpCnt;  // wndSmpCnt + hopSmpCnt
51
-    cmSample_t* bufV;
51
+    cmSample_t* bufV;       // bufV[bufSmpCnt] all other pointers use this memory
52 52
     cmSample_t* outV;       // output window outV[ outN ]
53 53
     unsigned    outN;       // outN == wndSmpCnt
54 54
     unsigned    procSmpCnt; // input sample count

+ 34
- 13
cmProc2.c View File

@@ -2300,11 +2300,10 @@ cmRC_t     cmPvAnlInit( cmPvAnl* p, unsigned procSmpCnt, double srate, unsigned
2300 2300
 cmRC_t     cmPvAnlFinal(cmPvAnl* p )
2301 2301
 { return cmOkRC; }
2302 2302
 
2303
-
2304 2303
 bool     cmPvAnlExec( cmPvAnl* p, const cmSample_t* x, unsigned xN )
2305 2304
 {
2306 2305
   bool fl = false;
2307
-  if( cmShiftBufExec(&p->sb,x,xN) )
2306
+  while( cmShiftBufExec(&p->sb,x,xN) )
2308 2307
   {
2309 2308
     cmWndFuncExec(&p->wf, p->sb.outV, p->sb.wndSmpCnt );
2310 2309
 
@@ -2421,13 +2420,12 @@ cmRC_t     cmPvSynExec( cmPvSyn* p, const cmReal_t* magV, const cmReal_t* phsV )
2421 2420
   double   twoPi     = 2.0 * M_PI;
2422 2421
   unsigned k;
2423 2422
 
2424
- 
2425 2423
   for(k=0; k<p->binCnt; ++k)
2426 2424
   {
2427 2425
     // phase dist between cur and prv frame
2428 2426
     cmReal_t dp = phsV[k] - p->phs0V[k];
2429 2427
 
2430
-    // dist must be positive (cmcum phase always increases)
2428
+    // dist must be positive (accum phase always increases)
2431 2429
     if( dp < -0.00001 )
2432 2430
       dp += twoPi;
2433 2431
 
@@ -2449,8 +2447,9 @@ cmRC_t     cmPvSynExec( cmPvSyn* p, const cmReal_t* magV, const cmReal_t* phsV )
2449 2447
     p->phs0V[k] = phsV[k];
2450 2448
     p->mag0V[k] = magV[k];
2451 2449
   }
2452
-
2453
-  cmIFftExecPolarRS( &p->ft, p->magV, p->phsV );
2450
+  
2451
+  cmIFftExecPolarRS( &p->ft, magV, phsV );
2452
+  
2454 2453
   cmOlaExecS( &p->ola, p->ft.outV, p->ft.outN ); 
2455 2454
 
2456 2455
   //printf("%i %i\n",p->binCnt,p->ft.binCnt );
@@ -2462,6 +2461,16 @@ cmRC_t     cmPvSynExec( cmPvSyn* p, const cmReal_t* magV, const cmReal_t* phsV )
2462 2461
   return cmOkRC;
2463 2462
 }
2464 2463
 
2464
+cmRC_t  cmPvSynDoIt( cmPvSyn* p, const cmSample_t* v )
2465
+{
2466
+  cmOlaExecS( &p->ola, v, p->wndSmpCnt ); 
2467
+
2468
+  //printf("%f\n",cmVOS_RMS(s,p->wndSmpCnt,p->wndSmpCnt));
2469
+
2470
+  return cmOkRC;
2471
+}
2472
+
2473
+
2465 2474
 const cmSample_t* cmPvSynExecOut(cmPvSyn* p )
2466 2475
 { return cmOlaExecOut(&p->ola); }
2467 2476
 
@@ -3653,9 +3662,14 @@ cmRC_t   cmNmfExec( cmNmf_t* p, const cmReal_t* vM, unsigned cn )
3653 3662
 cmSpecDist_t* cmSpecDistAlloc( cmCtx* ctx,cmSpecDist_t* ap, unsigned procSmpCnt, double srate, unsigned wndSmpCnt, unsigned hopFcmt, unsigned olaWndTypeId  )
3654 3663
 {
3655 3664
   cmSpecDist_t* p = cmObjAlloc( cmSpecDist_t, ctx, ap );
3665
+
3666
+
3656 3667
   if( procSmpCnt != 0 )
3668
+  {
3657 3669
     if( cmSpecDistInit( p, procSmpCnt, srate, wndSmpCnt, hopFcmt, olaWndTypeId ) != cmOkRC )
3658 3670
       cmSpecDistFree(&p);
3671
+  }
3672
+
3659 3673
   return p;
3660 3674
 
3661 3675
 }
@@ -3666,7 +3680,7 @@ cmRC_t cmSpecDistFree( cmSpecDist_t** pp )
3666 3680
     return cmOkRC;
3667 3681
 
3668 3682
   cmSpecDist_t* p = *pp;
3669
-
3683
+  
3670 3684
   cmSpecDistFinal(p);
3671 3685
   cmMemPtrFree(&p->hzV);
3672 3686
   cmObjFree(pp);
@@ -3713,8 +3727,10 @@ cmRC_t cmSpecDistInit( cmSpecDist_t* p, unsigned procSmpCnt, double srate, unsig
3713 3727
   p->aeMin  = 1000;
3714 3728
   p->aeMax  = -1000;
3715 3729
 
3730
+
3716 3731
   //p->bypOut = cmMemResizeZ(cmSample_t, p->bypOut, procSmpCnt );
3717 3732
 
3733
+
3718 3734
   return rc;
3719 3735
 }
3720 3736
 
@@ -3723,6 +3739,7 @@ cmRC_t cmSpecDistFinal(cmSpecDist_t* p )
3723 3739
   cmRC_t rc = cmOkRC;
3724 3740
   cmPvAnlFree(&p->pva);
3725 3741
   cmPvSynFree(&p->pvs);
3742
+
3726 3743
   return rc;
3727 3744
 }
3728 3745
 
@@ -3746,6 +3763,7 @@ void _cmSpecDistBasicMode0(cmSpecDist_t* p, cmReal_t* X1m, unsigned binCnt, cmRe
3746 3763
 
3747 3764
   }
3748 3765
 
3766
+
3749 3767
 }
3750 3768
 
3751 3769
 void _cmSpecDistBasicMode(cmSpecDist_t* p, cmReal_t* X1m, unsigned binCnt, cmReal_t thresh )
@@ -3856,19 +3874,18 @@ void _cmSpecDistAmpEnvMode( cmSpecDist_t* p, cmReal_t* X1m )
3856 3874
 
3857 3875
 }
3858 3876
 
3859
-
3860 3877
 cmRC_t  cmSpecDistExec( cmSpecDist_t* p, const cmSample_t* sp, unsigned sn )
3861 3878
 {
3862 3879
 
3863 3880
   assert( sn == p->procSmpCnt );
3864
-  
3881
+
3865 3882
   // cmPvAnlExec() returns true when it calc's a new spectral output frame
3866 3883
   if( cmPvAnlExec( p->pva, sp, sn ) )
3867 3884
   {
3868 3885
     cmReal_t X1m[p->pva->binCnt]; 
3869 3886
 
3870 3887
     cmVOR_AmplToDbVV(X1m, p->pva->binCnt, p->pva->magV, -1000.0 );
3871
-
3888
+   
3872 3889
     switch( p->mode )
3873 3890
     {
3874 3891
       case kBypassModeSdId:
@@ -3904,17 +3921,21 @@ cmRC_t  cmSpecDistExec( cmSpecDist_t* p, const cmSample_t* sp, unsigned sn )
3904 3921
       default:
3905 3922
         break;
3906 3923
     }
3907
-
3924
+    
3908 3925
     cmVOR_DbToAmplVV(X1m, p->pva->binCnt, X1m );
3909 3926
 
3910 3927
     cmPvSynExec(p->pvs, X1m, p->pva->phsV );
3911
-
3928
+  
3912 3929
   }
3930
+ 
3913 3931
   return cmOkRC;
3914 3932
 }
3915 3933
 
3934
+
3916 3935
 const cmSample_t* cmSpecDistOut(  cmSpecDist_t* p )
3917
-{ return cmPvSynExecOut(p->pvs); }
3936
+{ 
3937
+  return cmPvSynExecOut(p->pvs); 
3938
+}
3918 3939
 
3919 3940
 //------------------------------------------------------------------------------------------------------------
3920 3941
 

+ 431
- 121
cmProc4.c View File

@@ -1630,16 +1630,14 @@ cmRC_t cmScMatchExec( cmScMatch* p, unsigned locIdx, unsigned locN, const cmScMa
1630 1630
 }
1631 1631
 
1632 1632
 // Traverse the least cost path and:
1633
-// 1) Set p->esi to the score location index of the last MIDI note
1633
+// 1) Return, esi, the score location index of the last MIDI note
1634 1634
 // which has a positive match with the score and assign
1635 1635
 // the internal score index to cp->locIdx.
1636 1636
 //
1637 1637
 // 2) Set cmScAlignPath_t.locIdx - index into p->loc[] associated
1638 1638
 // with each path element that is a 'substitute' or an 'insert'.
1639 1639
 //
1640
-// 3) Set p->missCnt: the count of trailing non-positive matches.
1641
-// p->missCnt is eventually used in cmScAlignStep() to track the number
1642
-// of consecutive trailing missed notes.
1640
+// 3) Set *missCnPtr: the count of trailing non-positive matches.
1643 1641
 //
1644 1642
 // i_opt is index into p->loc[] of p->p_opt. 
1645 1643
 unsigned cmScMatchDoSync( cmScMatch* p, unsigned i_opt, cmScMatchMidi_t* midiBuf, unsigned midiN, unsigned* missCntPtr )
@@ -1961,6 +1959,7 @@ cmRC_t cmScMatcherInit(  cmScMatcher* p, double srate, cmScH_t scH, unsigned scW
1961 1959
   p->cbArg      = cbArg;
1962 1960
   p->mn         = midiWndN;
1963 1961
   p->midiBuf    = cmMemResizeZ(cmScMatchMidi_t,p->midiBuf,p->mn);
1962
+  p->initHopCnt = 50;
1964 1963
   p->stepCnt    = 3;
1965 1964
   p->maxMissCnt = p->stepCnt+1;
1966 1965
   p->rn         = 2 * cmScoreEvtCount(scH);
@@ -2083,7 +2082,7 @@ void cmScMatcherPrintPath( cmScMatcher* p )
2083 2082
   _cmScMatchPrintPath(p->mp, p->mp->p_opt, p->begSyncLocIdx, p->midiBuf );
2084 2083
 }
2085 2084
 
2086
-unsigned   cmScMatcherScan( cmScMatcher* p, unsigned bli, unsigned scanCnt )
2085
+unsigned   cmScMatcherScan( cmScMatcher* p, unsigned bli, unsigned hopCnt )
2087 2086
 {
2088 2087
   assert( p->mp != NULL && p->mp->mmn > 0 );
2089 2088
 
@@ -2102,7 +2101,7 @@ unsigned   cmScMatcherScan( cmScMatcher* p, unsigned bli, unsigned scanCnt )
2102 2101
     return cmInvalidIdx;
2103 2102
 
2104 2103
   // calc the edit distance from pitchV[] to a sliding score window
2105
-  for(i=0; rc==cmOkRC && (scanCnt==cmInvalidCnt || i<scanCnt); ++i)
2104
+  for(i=0; rc==cmOkRC && (hopCnt==cmInvalidCnt || i<hopCnt); ++i)
2106 2105
   {      
2107 2106
     rc = cmScMatchExec(p->mp, bli + i, p->mp->msn, p->midiBuf, p->mp->mmn, s_opt );
2108 2107
 
@@ -2227,7 +2226,7 @@ cmRC_t     cmScMatcherExec(  cmScMatcher* p, unsigned smpIdx, unsigned status, c
2227 2226
 {
2228 2227
   bool     fl  = p->mbi > 0;
2229 2228
   cmRC_t   rc  = cmOkRC;
2230
-  unsigned eli = p->eli;
2229
+  unsigned org_eli = p->eli;
2231 2230
 
2232 2231
   if( scLocIdxPtr != NULL )
2233 2232
     *scLocIdxPtr = cmInvalidIdx;
@@ -2239,7 +2238,7 @@ cmRC_t     cmScMatcherExec(  cmScMatcher* p, unsigned smpIdx, unsigned status, c
2239 2238
   // if the MIDI buffer transitioned to full then perform an initial scan sync.
2240 2239
   if( fl && p->mbi == 0 )
2241 2240
   {
2242
-    if( (p->begSyncLocIdx = cmScMatcherScan(p,p->ili,cmInvalidCnt)) == cmInvalidIdx )
2241
+    if( (p->begSyncLocIdx = cmScMatcherScan(p,p->ili,p->initHopCnt)) == cmInvalidIdx )
2243 2242
       rc = cmInvalidArgRC; // signal init. scan sync. fail
2244 2243
     else
2245 2244
     {
@@ -2253,8 +2252,21 @@ cmRC_t     cmScMatcherExec(  cmScMatcher* p, unsigned smpIdx, unsigned status, c
2253 2252
       rc = cmScMatcherStep(p);
2254 2253
   }
2255 2254
 
2256
-  if( scLocIdxPtr!=NULL && p->eli != eli )
2257
-    *scLocIdxPtr = p->mp->loc[p->eli].scLocIdx;
2255
+  // if we lost sync 
2256
+  if( p->eli == cmInvalidIdx )
2257
+  {
2258
+    // IF WE LOST SYNC THEN WE BETTER DO SOMETHING - LIKE INCREASE THE SCAN HOPS
2259
+    // ON THE NEXT EVENT.
2260
+    p->eli = org_eli;
2261
+  }
2262
+  else
2263
+  {
2264
+    if( scLocIdxPtr!=NULL && p->eli != org_eli )
2265
+    {
2266
+      //printf("LOC:%i bar:%i\n",p->eli,p->mp->loc[p->eli].barNumb);
2267
+      *scLocIdxPtr = p->mp->loc[p->eli].scLocIdx;
2268
+    }
2269
+  }
2258 2270
 
2259 2271
   return rc;
2260 2272
 }
@@ -2645,7 +2657,11 @@ cmRC_t    cmScMeasReset( cmScMeas* p )
2645 2657
 
2646 2658
   unsigned i;
2647 2659
   for(i=0; i<p->sn; ++i)
2660
+  {
2648 2661
     p->set[i].value = DBL_MAX;
2662
+    p->set[i].tempo = 0;
2663
+    p->set[i].match_cost = 0;
2664
+  }
2649 2665
   return rc;
2650 2666
 }
2651 2667
 
@@ -3028,7 +3044,10 @@ void _cmScMeasCalcVal( cmScMeas* p, cmScMeasSet_t* sp, int n_mii )
3028 3044
   // sync the score and MIDI based on the match information
3029 3045
   if( cmScMatchDoSync(p->mp, bli, mb, mn, NULL ) == cmInvalidIdx )
3030 3046
     return;
3031
-  
3047
+
3048
+  if( p->mp->opt_cost != DBL_MAX )
3049
+    sp->match_cost = p->mp->opt_cost / sp->sp->eleCnt;
3050
+
3032 3051
   switch( sp->sp->varId )
3033 3052
   {
3034 3053
     case kEvenVarScId:  
@@ -3050,7 +3069,7 @@ void _cmScMeasCalcVal( cmScMeas* p, cmScMeasSet_t* sp, int n_mii )
3050 3069
   sp->tempo = r.tempo;
3051 3070
 
3052 3071
   // print the result
3053
-  _cmScMeasPrintResult(p, sp, &r, bli, mb );
3072
+  //_cmScMeasPrintResult(p, sp, &r, bli, mb );
3054 3073
 
3055 3074
   MEAS_MATCH_CNT++;
3056 3075
 }
@@ -3378,38 +3397,53 @@ const _cmScModTypeMap_t*  _cmScModTypeLabelToMap( const cmChar_t* label )
3378 3397
   return NULL;
3379 3398
 }
3380 3399
 
3381
-cmScModVar_t* _cmScModulatorInsertValue( cmScModulator* p, unsigned varSymId )
3400
+cmScModVar_t* _cmScModSymToVar( cmScModulator* p, unsigned varSymId )
3382 3401
 {
3383 3402
   cmScModVar_t* vp = p->vlist;  
3384 3403
   for(; vp!=NULL; vp=vp->vlink)
3385 3404
     if( varSymId == vp->varSymId )
3386 3405
       return vp;
3406
+  return NULL;
3407
+}
3387 3408
 
3388
-  vp = cmMemAllocZ(cmScModVar_t,1);
3389
-  vp->varSymId = varSymId;
3390
-  vp->vlink    = p->vlist;
3391
-  p->vlist     = vp;
3409
+cmScModVar_t* _cmScModulatorInsertVar( cmScModulator* p, unsigned varSymId, unsigned flags )
3410
+{
3411
+  cmScModVar_t* vp = _cmScModSymToVar(p,varSymId);
3412
+
3413
+  if( vp == NULL )
3414
+  {
3415
+    vp = cmMemAllocZ(cmScModVar_t,1);
3416
+    vp->varSymId = varSymId;
3417
+    vp->outVarId = cmInvalidId;
3418
+    vp->vlink    = p->vlist;
3419
+    p->vlist     = vp;
3420
+  }
3421
+
3422
+  vp->flags    = flags;
3423
+  vp->value    = DBL_MAX;
3424
+  vp->min      = DBL_MAX;
3425
+  vp->max      = DBL_MAX;
3426
+  vp->rate     = DBL_MAX;
3427
+  vp->phase    = 0;
3428
+  vp->entry    = NULL;
3429
+  vp->alink    = NULL;
3430
+  
3392 3431
   return vp;
3393 3432
 }
3394 3433
 
3395
-cmRC_t _cmScModulatorInsertEntry(cmScModulator* p, unsigned idx, unsigned scLocIdx, unsigned modSymId, unsigned varSymId, unsigned typeId, const double* av, unsigned an)
3434
+cmScModEntry_t* _cmScModulatorInsertEntry(cmScModulator* p, unsigned idx, unsigned scLocIdx, unsigned modSymId, unsigned varSymId, unsigned typeId, unsigned paramCnt )
3396 3435
 {
3397 3436
   assert( idx < p->en );
3398 3437
 
3399
-  if( p->modSymId != modSymId )
3400
-    return cmOkRC;
3401
-
3402 3438
   p->earray[idx].scLocIdx = scLocIdx;
3403 3439
   p->earray[idx].typeId   = typeId;
3404
-  p->earray[idx].parray   = an==0 ? NULL : cmMemAllocZ(double,an);
3405
-  p->earray[idx].pn       = an;
3406
-  p->earray[idx].valPtr   = _cmScModulatorInsertValue(p,varSymId);
3440
+  p->earray[idx].varPtr   = _cmScModulatorInsertVar(p,varSymId,0);
3407 3441
 
3408
-  unsigned i;
3409
-  for(i=0; i<an; ++i)
3410
-    p->earray[idx].parray[i] = av[i];
3411 3442
 
3412
-  return cmOkRC;
3443
+  if( p->earray[idx].varPtr->outVarId == cmInvalidIdx )
3444
+    p->earray[idx].varPtr->outVarId = p->outVarCnt++;
3445
+
3446
+  return p->earray + idx;
3413 3447
 }
3414 3448
 
3415 3449
 
@@ -3421,12 +3455,57 @@ cmRC_t _cmScModulatorInsertEntry(cmScModulator* p, unsigned idx, unsigned scLocI
3421 3455
 }
3422 3456
  */
3423 3457
 
3424
-  cmRC_t _cmScModulatorParse( cmScModulator* p, cmCtx_t* ctx, cmSymTblH_t stH, const cmChar_t* fn )
3458
+ // Parameter values are found as values of the 'data','min' or 'max' fields.
3459
+ // A parameter value may be either a symbol identifier (mapped to a variable)
3460
+ // or a literal number.  This function determines which form the paramter
3461
+ // value takes and parses it accordingly.
3462
+  cmRC_t _cmScModulatorParseParam( cmScModulator* p, cmSymTblH_t stH, cmJsonNode_t* np, cmScModParam_t* pp )
3463
+{
3464
+  cmRC_t rc = cmOkRC;
3465
+
3466
+  switch( np->typeId )
3467
+  {
3468
+    case kIntTId:
3469
+    case kRealTId:
3470
+      if( cmJsonRealValue(np, &pp->val ) != kOkJsRC )
3471
+      {
3472
+        rc = cmCtxRtCondition( &p->obj, cmInvalidArgRC, "Error parsing in Modulator literal value." );    
3473
+        goto errLabel;
3474
+      }
3475
+      pp->pid = kLiteralModPId;
3476
+      break;
3477
+
3478
+    case kStringTId:
3479
+      {
3480
+        const cmChar_t* label = NULL;
3481
+        if( cmJsonStringValue(np, &label) != kOkJsRC )
3482
+        {
3483
+          rc = cmCtxRtCondition( &p->obj, cmInvalidArgRC, "Error parsing in Modulator symbol label." );    
3484
+          goto errLabel;
3485
+        }
3486
+
3487
+        pp->symId = cmSymTblRegisterSymbol(stH,label);
3488
+        pp->pid   = kSymbolModPId;
3489
+      }
3490
+      break;
3491
+
3492
+    default:
3493
+      rc = cmCtxRtCondition( &p->obj, cmInvalidArgRC, "Parameter value is not a number or identifier." );    
3494
+      goto errLabel;
3495
+      break;
3496
+  }
3497
+
3498
+ errLabel:
3499
+  return rc;
3500
+}
3501
+
3502
+cmRC_t _cmScModulatorParse( cmScModulator* p, cmCtx_t* ctx, cmSymTblH_t stH, const cmChar_t* fn )
3425 3503
 {
3426 3504
   cmRC_t        rc  = cmOkRC;
3427 3505
   cmJsonNode_t* jnp = NULL;
3428 3506
   cmJsonH_t     jsH = cmJsonNullHandle;
3429
-  unsigned      i;
3507
+  unsigned      i   = cmInvalidIdx;
3508
+  unsigned      j   = cmInvalidIdx;
3430 3509
 
3431 3510
   // read the JSON file
3432 3511
   if( cmJsonInitializeFromFile(&jsH, fn, ctx ) != kOkJsRC )
@@ -3442,12 +3521,13 @@ cmRC_t _cmScModulatorInsertEntry(cmScModulator* p, unsigned idx, unsigned scLocI
3442 3521
   }
3443 3522
 
3444 3523
   // allocate the entry array
3445
-  p->en     = cmJsonChildCount(jnp);
3446
-  p->earray = cmMemResizeZ(cmScModEntry_t,p->earray,p->en);
3524
+  unsigned entryCnt = cmJsonChildCount(jnp);
3525
+  p->earray         = cmMemResizeZ(cmScModEntry_t,p->earray,entryCnt);
3526
+  p->en             = entryCnt;
3447 3527
 
3448
-  for(i=0; i<p->en; ++i)
3528
+  for(i=0; i<entryCnt; ++i)
3449 3529
   {
3450
-    cmJsRC_t        jsRC;
3530
+    cmJsRC_t                jsRC;
3451 3531
     const char*              errLabelPtr = NULL;
3452 3532
     unsigned                 scLocIdx    = cmInvalidIdx;
3453 3533
     const cmChar_t*          modLabel    = NULL;
@@ -3478,49 +3558,54 @@ cmRC_t _cmScModulatorInsertEntry(cmScModulator* p, unsigned idx, unsigned scLocI
3478 3558
       goto errLabel;
3479 3559
     }
3480 3560
     
3481
-    // get a data pointer to the data node
3482
-    if((dnp = cmJsonNodeMemberValue(onp,"data")) == NULL )
3483
-    {
3484
-      rc = cmCtxRtCondition( &p->obj, cmInvalidArgRC, "Synax error in Modulator 'data' record at index %i in file:%s",i,cmStringNullGuard(fn) );
3485
-      goto errLabel;
3486
-    }
3487
-
3488 3561
     unsigned modSymId = cmSymTblRegisterSymbol(stH,modLabel);
3489 3562
     unsigned varSymId = cmSymTblRegisterSymbol(stH,varLabel);
3490 3563
 
3491
-    // the data may be an array of doubles ....
3492
-    if( cmJsonIsArray(dnp) )
3564
+    // the mod entry label must match the modulators label
3565
+    if( p->modSymId != modSymId )
3493 3566
     {
3494
-      unsigned an = cmJsonChildCount(dnp);
3495
-      double   av[an];
3496
-      unsigned j;
3567
+      --p->en;
3568
+        continue;
3569
+    } 
3497 3570
 
3498
-      // read each element in the data array
3499
-      for(j=0; j<an; ++j)
3500
-        if( cmJsonRealValue(cmJsonArrayElement(dnp,j), av+j ) != kOkJsRC )
3501
-        {
3502
-          rc = cmCtxRtCondition( &p->obj, cmInvalidArgRC, "Error parsing in Modulator 'data' record at index %i value index %i in file:%s",i,j,cmStringNullGuard(fn) );    
3503
-          goto errLabel;
3504
-        }
3505 3571
 
3506
-      _cmScModulatorInsertEntry(p,i,scLocIdx,modSymId,varSymId,map->typeId,av,an);
3507
-    }
3508
-    else  // ... or a scalar
3572
+    // get the count of the elmenets in the data array
3573
+    unsigned paramCnt = cmJsonChildCount(onp);
3574
+
3575
+    // fill the entry record and find or create the target var
3576
+    cmScModEntry_t* ep = _cmScModulatorInsertEntry(p,i,scLocIdx,modSymId,varSymId,map->typeId,paramCnt);
3577
+
3578
+    typedef struct
3509 3579
     {
3510
-      double v;
3511
-      if( cmJsonRealValue(dnp,&v) !=  kOkJsRC )
3512
-      {
3513
-        rc = cmCtxRtCondition( &p->obj, cmInvalidArgRC, "Error paring in Modulator 'data' on record index %i.",i,cmStringNullGuard(fn));
3514
-        goto errLabel;
3515
-      }
3580
+      const cmChar_t* label;
3581
+      cmScModParam_t* param;
3582
+    } map_t;
3516 3583
 
3517
-      _cmScModulatorInsertEntry(p,i,scLocIdx,modSymId,varSymId,map->typeId,&v,1);
3584
+    // parse the var and parameter records
3585
+    map_t mapArray[] = 
3586
+    {
3587
+      { "min", &ep->min  },
3588
+      { "max", &ep->max  },
3589
+      { "rate",&ep->rate },
3590
+      { "val", &ep->beg },
3591
+      { "end", &ep->end },
3592
+      { "dur", &ep->dur },
3593
+      { NULL, NULL }
3594
+    };
3518 3595
 
3519
-    }
3596
+    unsigned j=0;
3597
+    for(j=0; mapArray[j].param!=NULL; ++j)
3598
+      if((dnp = cmJsonFindValue(jsH,mapArray[j].label, onp, kInvalidTId )) != NULL )
3599
+        if((rc = _cmScModulatorParseParam(p,stH,dnp,mapArray[j].param)) != cmOkRC )
3600
+          goto errLabel;    
3520 3601
   }
3521 3602
 
3522 3603
  errLabel:
3523 3604
 
3605
+  if( rc != cmOkRC )
3606
+    cmCtxRtCondition( &p->obj, cmInvalidArgRC, "Error parsing in Modulator 'data' record at index %i value index %i in file:%s",i,j,cmStringNullGuard(fn) );    
3607
+
3608
+
3524 3609
   // release the JSON tree
3525 3610
   if( cmJsonIsValid(jsH) )
3526 3611
     cmJsonFinalize(&jsH);
@@ -3528,6 +3613,32 @@ cmRC_t _cmScModulatorInsertEntry(cmScModulator* p, unsigned idx, unsigned scLocI
3528 3613
   return rc;
3529 3614
 }
3530 3615
 
3616
+cmRC_t  _cmScModulatorReset( cmScModulator* p, cmCtx_t* ctx, unsigned scLocIdx )
3617
+{
3618
+  cmRC_t rc = cmOkRC;
3619
+
3620
+  p->alist     = NULL;
3621
+  p->elist     = NULL;
3622
+  p->nei       = 0;
3623
+  p->outVarCnt = 0;
3624
+  
3625
+  // reload the file
3626
+  if((rc = _cmScModulatorParse(p,ctx,p->stH,p->fn)) != cmOkRC )
3627
+    goto errLabel;
3628
+
3629
+
3630
+  // clear the active flag on all variables
3631
+  cmScModVar_t* vp = p->vlist;
3632
+  for(; vp!=NULL; vp=vp->vlink)
3633
+  {
3634
+    vp->flags = cmClrFlag(vp->flags,kActiveModFl);
3635
+    vp->alink = NULL;
3636
+  }
3637
+
3638
+ errLabel:
3639
+  return rc;
3640
+}
3641
+
3531 3642
 cmRC_t cmScModulatorInit(  cmScModulator* p, cmCtx_t* ctx, cmSymTblH_t stH, double srate, unsigned samplesPerCycle, const cmChar_t* fn, const cmChar_t* modLabel, cmScModCb_t cbFunc, void* cbArg )
3532 3643
 {
3533 3644
   cmRC_t rc;
@@ -3535,29 +3646,28 @@ cmRC_t cmScModulatorInit(  cmScModulator* p, cmCtx_t* ctx, cmSymTblH_t stH, doub
3535 3646
   if((rc = cmScModulatorFinal(p)) != cmOkRC )
3536 3647
     return rc;
3537 3648
 
3649
+  p->fn              = cmMemAllocStr(fn);
3650
+  p->stH             = stH;
3538 3651
   p->modSymId        = cmSymTblRegisterSymbol(stH,modLabel);
3539 3652
   p->cbFunc          = cbFunc;
3540 3653
   p->cbArg           = cbArg;
3541 3654
   p->samplesPerCycle = samplesPerCycle;
3542 3655
   p->srate           = srate;
3656
+  
3543 3657
 
3544
-  if((rc = _cmScModulatorParse(p,ctx,stH,fn)) != cmOkRC )
3545
-    goto errLabel;
3546
-
3547
- errLabel:
3548 3658
   if( rc != cmOkRC )
3549 3659
     cmScModulatorFinal(p);
3550 3660
   else
3551
-    cmScModulatorReset(p,0);
3661
+    _cmScModulatorReset(p,ctx,0);
3552 3662
 
3553 3663
   return rc;
3554 3664
 }
3555 3665
 
3556 3666
 cmRC_t cmScModulatorFinal( cmScModulator* p )
3557 3667
 {
3558
-  unsigned i;
3668
+  cmMemFree(p->fn);
3559 3669
 
3560
-  // release each value record
3670
+  // release each var record
3561 3671
   cmScModVar_t* vp = p->vlist;
3562 3672
   while( vp!=NULL )
3563 3673
   {
@@ -3566,61 +3676,126 @@ cmRC_t cmScModulatorFinal( cmScModulator* p )
3566 3676
     vp=np;
3567 3677
   }
3568 3678
 
3569
-  // release each entry record
3570
-  for(i=0; i<p->en; ++i)
3571
-    cmMemFree(p->earray[i].parray);
3572
-
3573 3679
   return cmOkRC;
3574 3680
 }
3575 3681
 
3576
-unsigned        cmScModulatorVarCount( cmScModulator* p )
3682
+unsigned        cmScModulatorOutVarCount( cmScModulator* p )
3683
+{ return p->outVarCnt; }
3684
+
3685
+cmScModVar_t* cmScModulatorOutVar( cmScModulator* p, unsigned idx )
3577 3686
 {
3578
-  unsigned n = 0;
3579
-  const cmScModVar_t* vp = p->vlist;
3580
-  for(; vp!=NULL; vp=vp->vlink)
3581
-    ++n;
3687
+  unsigned i;
3688
+  for(i=0; i<p->en; ++i)
3689
+    if( p->earray[i].varPtr->outVarId == idx )
3690
+      return p->earray[i].varPtr;
3582 3691
 
3583
-  return n;
3692
+  return NULL;  
3584 3693
 }
3585 3694
 
3586
-cmScModVar_t* cmScModulatorVar( cmScModulator* p, unsigned idx )
3695
+cmRC_t         cmScModulatorSetValue( cmScModulator* p, unsigned varSymId, double value, double min, double max )
3587 3696
 {
3588
-  unsigned n = 0;
3589
-  cmScModVar_t* vp = p->vlist;
3590
-  for(; vp!=NULL; vp=vp->vlink,++n)
3591
-    if( n == idx )
3592
-      return vp;
3697
+  cmScModVar_t* vp;
3698
+  // if the var does not exist ....
3699
+  if((vp = _cmScModSymToVar(p, varSymId )) == NULL )
3700
+  {
3701
+    // ... then create it
3702
+    vp =  _cmScModulatorInsertVar(p,varSymId,kCalcModFl);
3703
+    assert(vp!=NULL);    
3704
+  }
3593 3705
 
3594
-  assert(0);
3595
-  return NULL;
3706
+  assert( min <= max);
3707
+
3708
+  vp->min   = min;
3709
+  vp->max   = max;  
3710
+  vp->value = value;
3711
+
3712
+  return cmOkRC;
3596 3713
 }
3597 3714
 
3598
-cmRC_t cmScModulatorReset( cmScModulator* p, unsigned scLocIdx )
3599
-{
3600
-  p->alist = NULL;
3601
-  p->nei   = 0;
3602 3715
 
3716
+cmRC_t cmScModulatorReset( cmScModulator* p, cmCtx_t* ctx, unsigned scLocIdx )
3717
+{
3718
+  _cmScModulatorReset(p,ctx,scLocIdx);
3603 3719
   return cmScModulatorExec(p,scLocIdx);
3604 3720
 }
3605 3721
 
3606
-void  _cmScModUnlink( cmScModulator* p, cmScModVar_t* vp, cmScModVar_t* pp )
3722
+void  _cmScModUnlinkActive( cmScModulator* p, cmScModVar_t* vp, cmScModVar_t* pp )
3607 3723
 {
3608
-  if( pp == NULL )
3724
+  // if vp is the first link on the chain
3725
+  if( vp == p->alist )
3609 3726
     p->alist = vp->alink;
3610
-  else
3611
-    pp->alink = vp->alink;  
3612 3727
 
3613
-  vp->flags = 0;
3728
+  // if vp is the last link on the chain
3729
+  if( vp == p->elist )
3730
+    p->elist = pp;
3731
+
3732
+  if( pp != NULL )
3733
+    pp->alink = vp->alink;
3734
+
3735
+  vp->flags = cmClrFlag(vp->flags,kActiveModFl);
3614 3736
   vp->alink = NULL;  
3615 3737
   vp->entry = NULL;
3616 3738
 }
3617 3739
 
3618
-// Type specific variable activation
3740
+// If the requested parameter has a value then return it in *valPtr.
3741
+// If it does not then do nothing. This function applies scaling to RHS values.
3742
+cmRC_t  _cmScModGetParam( cmScModulator* p, const cmScModParam_t* pp, double* valPtr )
3743
+{
3744
+  cmRC_t rc = cmOkRC;
3745
+
3746
+  switch( pp->pid )
3747
+  {
3748
+    case kInvalidModPId:
3749
+      break;
3750
+
3751
+    case kLiteralModPId:
3752
+      *valPtr = pp->val;
3753
+      break;
3754
+
3755
+    case kSymbolModPId:
3756
+      {
3757
+        cmScModVar_t* vp;
3758
+
3759
+        // get a pointer to the parameter variable
3760
+        if((vp = _cmScModSymToVar(p, pp->symId )) == NULL )
3761
+        {
3762
+          rc  = cmCtxRtCondition( &p->obj, cmInvalidArgRC, "Variable '%s' not found.",cmSymTblLabel(p->stH,pp->symId));    
3763
+          goto errLabel;
3764
+        } 
3765
+
3766
+        // if this is not a 'calculated' paramter then scale it here.
3767
+        if( cmIsFlag(vp->flags,kCalcModFl ) && vp->min!=DBL_MAX && vp->max!=DBL_MAX )
3768
+          *valPtr = (vp->value - vp->min)/(vp->max-vp->min);
3769
+        else
3770
+          *valPtr = vp->value;
3771
+      }
3772
+      break;
3773
+
3774
+    default:
3775
+      { assert(0); }
3776
+  }
3777
+
3778
+ errLabel:
3779
+  return rc;
3780
+}
3781
+
3782
+// Type specific variable activation - 
3619 3783
 cmRC_t _cmScModActivate(cmScModulator* p, cmScModEntry_t* ep )
3620 3784
 {
3621 3785
   cmRC_t rc = cmOkRC;
3622 3786
 
3623
-  cmScModVar_t* vp = ep->valPtr;
3787
+  cmScModVar_t* vp = ep->varPtr;
3788
+
3789
+  // optionally update the min/max/rate values in the target var
3790
+  if((rc = _cmScModGetParam(p,&ep->min,&vp->min)) != cmOkRC )
3791
+    goto errLabel;
3792
+
3793
+  if((rc = _cmScModGetParam(p,&ep->max,&vp->max)) != cmOkRC )
3794
+    goto errLabel;
3795
+
3796
+ if((rc = _cmScModGetParam(p,&ep->rate,&vp->rate)) != cmOkRC )
3797
+    goto errLabel;
3798
+
3624 3799
 
3625 3800
   switch( ep->typeId )
3626 3801
   {
@@ -3633,49 +3808,94 @@ cmRC_t _cmScModActivate(cmScModulator* p, cmScModEntry_t* ep )
3633 3808
       break;
3634 3809
 
3635 3810
     case kSetLineModTId:
3636
-      vp->value     = ep->parray[0];
3637
-      vp->v0        = ep->parray[0];
3638
-      vp->phase     = 0;
3639
-      ep->parray[0] = ep->parray[1];
3640
-      ep->parray[1] = ep->parray[2];
3811
+      _cmScModGetParam(p,&ep->beg,&vp->value); // starting value
3812
+      vp->v0     = vp->value;                  // set initial value
3813
+      vp->phase  = 0;                          // reset phase
3641 3814
       break;
3642 3815
 
3643 3816
     default:
3644 3817
       { assert(0); }
3645 3818
   }
3646 3819
 
3820
+ errLabel:
3821
+  return rc;
3822
+}
3823
+
3824
+// Callback the application with a new variable value.
3825
+cmRC_t  _cmScModExecSendValue( cmScModulator* p, cmScModVar_t* vp )
3826
+{
3827
+  cmRC_t rc     = cmOkRC;
3828
+  bool   sendFl = true;
3829
+  double v      = vp->value;
3830
+
3831
+  // scale the output value - this is equiv to scaling the LHS
3832
+  if( cmIsFlag(vp->flags,kCalcModFl) && vp->min!=DBL_MAX && vp->max!=DBL_MAX )
3833
+    v = vp->min + v * (vp->max - vp->min);
3834
+
3835
+  // if an output rate throttle is in effect ....
3836
+  if( vp->rate!=DBL_MAX && vp->phase!=0 )
3837
+    sendFl = remainder(vp->phase*p->samplesPerCycle, p->srate*vp->rate/1000 ) < p->samplesPerCycle;
3838
+
3839
+  if(sendFl)
3840
+    p->cbFunc(p->cbArg,vp->varSymId,v);
3841
+
3647 3842
   return rc;
3648 3843
 }
3649 3844
 
3650 3845
 // Return true if vp should be deactivated otherwise return false.
3651 3846
 bool  _cmScModExec( cmScModulator* p, cmScModVar_t* vp )
3652 3847
 {
3653
-  bool fl = false;
3848
+  cmRC_t rc = cmOkRC;
3849
+  bool   fl = false;
3850
+
3654 3851
   switch( vp->entry->typeId )
3655 3852
   {
3656 3853
     case kSetModTId:
3657
-      p->cbFunc(p->cbArg,vp->varSymId,vp->entry->parray[0]);
3658
-      fl = true;
3854
+      {
3855
+        if((rc = _cmScModGetParam(p,&vp->entry->beg,&vp->value)) != cmOkRC )
3856
+          goto errLabel;
3857
+        
3858
+        vp->phase = 0; // force the value to be sent
3859
+        fl = true;
3860
+      }
3659 3861
       break;
3660 3862
 
3661 3863
     case kSetLineModTId:
3662 3864
     case kLineModTId:
3663 3865
       {
3664
-        double v1 = vp->entry->parray[0];
3665
-        double v  = vp->value + (v1-vp->v0) * (vp->phase * p->samplesPerCycle) / (p->srate * vp->entry->parray[1]);        
3866
+        double v1, td;
3867
+
3868
+        // get the target value
3869
+        if((rc = _cmScModGetParam(p,&vp->entry->end,&v1)) != cmOkRC) 
3870
+          goto errLabel;
3871
+
3872
+        // get the time duration
3873
+        if((rc = _cmScModGetParam(p,&vp->entry->dur,&td)) != cmOkRC) 
3874
+          goto errLabel;
3875
+
3876
+        double v  = vp->v0 + (v1-vp->v0) * (vp->phase * p->samplesPerCycle) / (p->srate * td);        
3666 3877
 
3667 3878
         if((fl =  (vp->value <= v1 && v >= v1) || (vp->value >= v1 && v <= v1 )) == true )
3668 3879
           v  = v1;
3669 3880
        
3670
-        vp->phase += 1;
3671 3881
         vp->value  = v;
3672
-        p->cbFunc(p->cbArg,vp->varSymId,v);
3673 3882
       }
3674 3883
       break;
3675 3884
 
3676 3885
     default:
3677 3886
       { assert(0); }
3678 3887
   }
3888
+
3889
+  // notify the application that a new variable value has been generated
3890
+  rc = _cmScModExecSendValue(p,vp);
3891
+
3892
+  // increment the phase - after send because send notices when phase is zero
3893
+  vp->phase += 1;
3894
+
3895
+ errLabel:
3896
+  if( rc != cmOkRC )
3897
+    fl = true;
3898
+
3679 3899
   return fl;
3680 3900
 }
3681 3901
 
@@ -3686,25 +3906,35 @@ cmRC_t cmScModulatorExec( cmScModulator* p, unsigned scLocIdx )
3686 3906
   cmRC_t rc = cmOkRC;
3687 3907
 
3688 3908
   // trigger entries that have expired since the last call to this function
3689
-  for(; p->nei<p->en && p->earray[p->nei].scLocIdx<=scLocIdx; ++p->nei)
3909
+  for(; p->nei<p->en && (p->earray[p->nei].scLocIdx==-1 || p->earray[p->nei].scLocIdx<=scLocIdx); ++p->nei)
3690 3910
   {
3691 3911
     cmScModEntry_t* ep = p->earray + p->nei;
3692 3912
 
3693 3913
     // if the variable assoc'd with this entry is not on the active list ...
3694
-    if( cmIsFlag(ep->valPtr->flags,kActiveModFl) == false )
3914
+    if( cmIsFlag(ep->varPtr->flags,kActiveModFl) == false )
3695 3915
     {
3696
-      // ... then push it onto the front of the active list ...
3697
-      ep->valPtr->flags = kActiveModFl; 
3698
-      ep->valPtr->alink = p->alist;
3699
-      p->alist          = ep->valPtr;
3700
-    }
3916
+      // ... then append it to the end of the active list ...
3917
+      ep->varPtr->flags |= kActiveModFl; 
3918
+
3919
+      if( p->elist == NULL )
3920
+        p->elist = ep->varPtr;
3921
+      else
3922
+      {
3923
+        p->elist->alink = ep->varPtr;
3924
+        p->elist        = ep->varPtr;
3925
+      }
3701 3926
 
3927
+      p->elist->alink = NULL;
3928
+
3929
+      if( p->alist == NULL )
3930
+        p->alist = ep->varPtr;
3931
+    }
3702 3932
 
3703 3933
     // do type specific activation
3704 3934
     if((trc = _cmScModActivate(p,ep)) != cmOkRC )
3705 3935
       rc = trc;
3706 3936
 
3707
-    ep->valPtr->entry = ep;
3937
+    ep->varPtr->entry = ep;
3708 3938
 
3709 3939
   }
3710 3940
     
@@ -3714,10 +3944,90 @@ cmRC_t cmScModulatorExec( cmScModulator* p, unsigned scLocIdx )
3714 3944
   for(; vp!=NULL; vp=vp->alink)
3715 3945
   {
3716 3946
     if( _cmScModExec(p,vp) )
3717
-      _cmScModUnlink(p,vp,pp);
3947
+      _cmScModUnlinkActive(p,vp,pp);
3718 3948
     else
3719 3949
       pp = vp;
3720 3950
   }
3721 3951
 
3722 3952
   return rc;
3723 3953
 }
3954
+
3955
+
3956
+void _cmScModDumpParam( cmScModulator* p, const cmChar_t* label, cmScModParam_t* pp )
3957
+{
3958
+  printf("%s: ",label);
3959
+
3960
+  switch( pp->pid )
3961
+  {
3962
+    case kInvalidModPId:
3963
+      printf("<invalid>");
3964
+      break;
3965
+
3966
+    case kLiteralModPId:
3967
+      if( pp->val == DBL_MAX )
3968
+        printf("<max> ");
3969
+      else
3970
+        printf("%f ",pp->val);
3971
+      break;
3972
+
3973
+    case kSymbolModPId:
3974
+      printf("%s ",cmSymTblLabel(p->stH,pp->symId));
3975
+      break;
3976
+
3977
+    default:
3978
+      { assert(0); }
3979
+  }
3980
+}
3981
+
3982
+void _cmScModDumpVal( cmChar_t* label, double val )
3983
+{
3984
+  printf("%s:",label);
3985
+
3986
+  if( val == DBL_MAX )
3987
+    printf("<max> " );
3988
+  else
3989
+    printf("%f ",val);
3990
+}
3991
+
3992
+void _cmScModDumpVar( cmScModulator* p, const cmScModVar_t* vp )
3993
+{
3994
+    printf("%7s %3i fl:0x%x entry:%p alink:%p ",cmSymTblLabel(p->stH,vp->varSymId),vp->outVarId,vp->flags,vp->entry,vp->alink);
3995
+    _cmScModDumpVal("val",vp->value);
3996
+    _cmScModDumpVal("min",vp->min);
3997
+    _cmScModDumpVal("max",vp->max);
3998
+    _cmScModDumpVal("rate",vp->rate);
3999
+    _cmScModDumpVal("v0",vp->v0);
4000
+}
4001
+
4002
+cmRC_t  cmScModulatorDump(  cmScModulator* p )
4003
+{
4004
+  cmRC_t rc = cmOkRC;
4005
+
4006
+  printf("MOD:\n");
4007
+  printf("nei:%i alist:%p outVarCnt:%i\n",p->nei,p->alist,p->outVarCnt);
4008
+
4009
+  printf("ENTRIES:\n");
4010
+  unsigned i;
4011
+  for(i=0; i<p->en; ++i)
4012
+  {
4013
+    cmScModEntry_t* ep = p->earray + i;
4014
+    printf("%3i %4i %2i %7s ", i, ep->scLocIdx, ep->typeId, cmSymTblLabel(p->stH,ep->varPtr->varSymId));
4015
+    _cmScModDumpParam(p," beg", &ep->beg);
4016
+    _cmScModDumpParam(p," end", &ep->end);
4017
+    _cmScModDumpParam(p," min", &ep->min);
4018
+    _cmScModDumpParam(p," max", &ep->max);
4019
+    _cmScModDumpParam(p," rate",&ep->rate);
4020
+    printf("\n");
4021
+  }
4022
+
4023
+  printf("VARIABLES\n");
4024
+  cmScModVar_t* vp = p->vlist;
4025
+  for(; vp!=NULL; vp=vp->vlink)
4026
+  {
4027
+    _cmScModDumpVar(p,vp);
4028
+    printf("\n");
4029
+  }
4030
+  
4031
+  return rc;
4032
+
4033
+}

+ 57
- 22
cmProc4.h View File

@@ -5,8 +5,6 @@
5 5
 extern "C" {
6 6
 #endif
7 7
 
8
-
9
-
10 8
 typedef struct
11 9
 {
12 10
   unsigned     smpIdx;  // time tag sample index for val
@@ -340,16 +338,17 @@ typedef void (*cmScMatcherCb_t)( struct cmScMatcher_str* p, void* arg, cmScMatch
340 338
    unsigned             ri;       // next avail res[] recd.
341 339
 
342 340
    double               s_opt;          // 
343
-   unsigned             missCnt;        // count of consecutive trailing non-matches
341
+   unsigned             missCnt;        // current count of consecutive trailing non-matches
344 342
    unsigned             ili;            // index into loc[] to start scan following reset
345 343
    unsigned             eli;            // index into loc[] of the last positive match. 
346
-   unsigned             mni;            // track the count of MIDI events since the last call to cmScMatcherReset()
347
-   unsigned             mbi;            // index of oldest MIDI event in midiBuf[]; 0 when the buffer is full.
344
+   unsigned             mni;            // current count of MIDI events since the last call to cmScMatcherReset()
345
+   unsigned             mbi;            // index of oldest MIDI event in midiBuf[]; stays at 0 when the buffer is full.
348 346
    unsigned             begSyncLocIdx;  // start of score window, in mp->loc[], of best match in previous scan
347
+   unsigned             initHopCnt;     // max window hops during the initial (when the MIDI buffer fills for first time) sync scan 
349 348
    unsigned             stepCnt;        // count of forward/backward score loc's to examine for a match during cmScMatcherStep().
350 349
    unsigned             maxMissCnt;     // max. number of consecutive non-matches during step prior to executing a scan.
351
-   unsigned             scanCnt;        // count of time scan was executed inside cmScMatcherStep()
352
-
350
+   unsigned             scanCnt;        // current count of times a resync-scan was executed during cmScMatcherStep()
351
+ 
353 352
    bool                 printFl;
354 353
 } cmScMatcher;
355 354
 
@@ -363,13 +362,13 @@ cmRC_t       cmScMatcherFinal( cmScMatcher* p );
363 362
 // 'scLocIdx' is a score index as used by cmScoreLoc(scH) not into p->mp->loc[].
364 363
 cmRC_t       cmScMatcherReset( cmScMatcher* p, unsigned scLocIdx );
365 364
 
366
-// Slide a score window scanCnt times, beginning at 'bli' (an
365
+// Slide a score window hopCnt times, beginning at 'bli' (an
367 366
 // index int p->mp->loc[]) looking for the best match to p->midiBuf[].  
368 367
 // The score window contain scWndN (p->mp->mcn-1) score locations.
369 368
 // Returns the index into p->mp->loc[] of the start of the best
370 369
 // match score window. The score associated
371 370
 // with this match is stored in s_opt.
372
-unsigned   cmScMatcherScan( cmScMatcher* p, unsigned bli, unsigned scanCnt );
371
+unsigned   cmScMatcherScan( cmScMatcher* p, unsigned bli, unsigned hopCnt );
373 372
 
374 373
 // Step forward/back by p->stepCnt from p->eli.
375 374
 // p->eli must therefore be valid prior to calling this function.
@@ -385,7 +384,7 @@ cmRC_t     cmScMatcherStep(  cmScMatcher* p );
385 384
 // If the MIDI note passed by the call results in a successful match then
386 385
 // p->eli will be updated to the location in p->mp->loc[] of the latest 
387 386
 // match, the MIDI note in p->midiBuf[] associated with this match
388
-// will be assigned valid locIdx and scLocIdx values, and *scLocIdxPtr
387
+// will be assigned a valid locIdx and scLocIdx values, and *scLocIdxPtr
389 388
 // will be set with the matched scLocIdx of the match.
390 389
 // If this call does not result in a successful match *scLocIdxPtr is set
391 390
 // to cmInvalidIdx.
@@ -413,7 +412,9 @@ typedef struct
413 412
   unsigned      eli;   //
414 413
 
415 414
   double        value; // DBL_MAX if the value has not yet been set
416
-  double        tempo; // DBL_MAX until set
415
+  double        tempo; //
416
+  double        match_cost; // cost of the match to the performance divided by sp->eleCnt
417
+
417 418
 
418 419
 } cmScMeasSet_t;
419 420
 
@@ -488,30 +489,57 @@ enum
488 489
 
489 490
 enum
490 491
 {
491
-  kActiveModFl = 0x01
492
+  kActiveModFl = 0x01,  // this variable is on the 'active' list
493
+  kCalcModFl   = 0x02   // when this variable is used as a parameter it's value must be calculated rather than used directly.
492 494
 };
493 495
 
494 496
 struct cmScModEntry_str;
495 497
 
498
+typedef enum
499
+{
500
+  kInvalidModPId,
501
+  kLiteralModPId,  // this is a literal value
502
+  kSymbolModPId    // 
503
+} cmScModPId_t;
504
+
505
+typedef struct cmScModParam_str
506
+{
507
+  cmScModPId_t pid;     // parameter type: literal or symbol
508
+  unsigned     symId;   // symbol of external and internal variables
509
+  double       val;     // value of literals
510
+} cmScModParam_t;
511
+
496 512
 typedef struct cmScModVar_str
497 513
 {
498 514
   unsigned                 flags;    // see kXXXModFl flags above.
499 515
   unsigned                 varSymId; // variable name 
500
-  double                   value;    // current value 
516
+  unsigned                 outVarId; // output var id
517
+  double                   value;    // current value of this variable
501 518
   double                   v0;       // reserved internal variable
502
-  unsigned                 phase;    // cycle phase since activation
519
+  unsigned                 phase;    // cycle phase since activation  
520
+  double                   min;
521
+  double                   max;
522
+  double                   rate;     // output rate in milliseconds
503 523
   struct cmScModEntry_str* entry;    // last entry assoc'd with this value
504 524
   struct cmScModVar_str*   vlink;    // p->vlist link
505 525
   struct cmScModVar_str*   alink;    // p->alist link
506 526
 } cmScModVar_t;
507 527
 
528
+
529
+
530
+// Each entry gives a time tagged location and some parameters 
531
+// for an algorthm which is used to set/modulate a value.
508 532
 typedef struct cmScModEntry_str
509 533
 {
510
-  unsigned        scLocIdx;     // entry start time
511
-  unsigned        typeId;       // variable type
512
-  double*         parray;       // parray[pn] - parameter array
513
-  unsigned        pn;           // parameter count
514
-  cmScModVar_t*   valPtr;       // target variable 
534
+  unsigned       scLocIdx;      // entry start time
535
+  unsigned       typeId;        // variable type
536
+  cmScModParam_t beg;           // parameter values
537
+  cmScModParam_t end;           //
538
+  cmScModParam_t dur;           //
539
+  cmScModParam_t min;           // min value for this variable
540
+  cmScModParam_t max;           // max value for this variable
541
+  cmScModParam_t rate;          // update rate in milliseconds (DBL_MAX to disable)
542
+  cmScModVar_t*  varPtr;        // target variable 
515 543
 } cmScModEntry_t;
516 544
 
517 545
 typedef void (*cmScModCb_t)( void* cbArg, unsigned varSymId, double value );
@@ -519,7 +547,9 @@ typedef void (*cmScModCb_t)( void* cbArg, unsigned varSymId, double value );
519 547
 typedef struct
520 548
 {
521 549
   cmObj           obj;
550
+  cmChar_t*       fn;           // modulator score file
522 551
   unsigned        modSymId;     // modulator name
552
+  cmSymTblH_t     stH;          // symbol table used by this modulator
523 553
   cmScModCb_t     cbFunc;       // active value callback function
524 554
   void*           cbArg;        // first arg to cbFunc()
525 555
   unsigned        samplesPerCycle; // interval in samples between calls to cmScModulatorExec()
@@ -528,7 +558,9 @@ typedef struct
528 558
   unsigned        en;           // count 
529 559
   cmScModVar_t*   vlist;        // variable list
530 560
   cmScModVar_t*   alist;        // active variable list
561
+  cmScModVar_t*   elist;        // last element on the active list
531 562
   unsigned        nei;          // next entry index
563
+  unsigned        outVarCnt;    // count of unique vars that are targets of entry recds
532 564
 } cmScModulator;
533 565
 
534 566
 
@@ -538,13 +570,16 @@ cmRC_t         cmScModulatorInit(  cmScModulator* p, cmCtx_t* ctx, cmSymTblH_t s
538 570
 cmRC_t         cmScModulatorFinal( cmScModulator* p );
539 571
 
540 572
 // Return count of variables.
541
-unsigned        cmScModulatorVarCount( cmScModulator* p );
573
+unsigned       cmScModulatorOutVarCount( cmScModulator* p );
542 574
 
543 575
 // Return a pointer to the variable at vlist[idx].
544
-cmScModVar_t* cmScModulatorVar( cmScModulator* p, unsigned idx ); 
576
+cmScModVar_t*  cmScModulatorOutVar( cmScModulator* p, unsigned idx ); 
577
+
578
+cmRC_t         cmScModulatorSetValue( cmScModulator* p, unsigned varSymId, double value, double min, double max );
545 579
 
546
-cmRC_t         cmScModulatorReset( cmScModulator* p, unsigned scLocIdx );
580
+cmRC_t         cmScModulatorReset( cmScModulator* p, cmCtx_t* ctx, unsigned scLocIdx );
547 581
 cmRC_t         cmScModulatorExec(  cmScModulator* p, unsigned scLocIdx );
582
+cmRC_t         cmScModulatorDump(  cmScModulator* p );
548 583
 
549 584
 #ifdef __cplusplus
550 585
 }

+ 3
- 3
cmProcObj.c View File

@@ -182,7 +182,7 @@ cmRC_t      cmMtxFileClose( cmMtxFile* p )
182 182
   return cmOkRC;
183 183
 }
184 184
 
185
-cmRC_t      cmMtxFileFloatExec(  cmMtxFile* p, const float*      inPtr, unsigned inCnt, unsigned inStride )
185
+cmRC_t      cmMtxFileFloatExec(  cmMtxFile* p, const float* inPtr, unsigned inCnt, unsigned inStride )
186 186
 {
187 187
   const float* ep = inPtr + (inCnt * inStride);
188 188
   for(; inPtr < ep; inPtr+=inStride )
@@ -191,7 +191,7 @@ cmRC_t      cmMtxFileFloatExec(  cmMtxFile* p, const float*      inPtr, unsigned
191 191
   return cmOkRC;
192 192
 }
193 193
 
194
-cmRC_t      cmMtxFileDoubleExec( cmMtxFile* p, const double*     inPtr, unsigned inCnt, unsigned inStride )
194
+cmRC_t      cmMtxFileDoubleExec( cmMtxFile* p, const double* inPtr, unsigned inCnt, unsigned inStride )
195 195
 {
196 196
   const double* ep = inPtr + (inCnt * inStride);
197 197
   for(; inPtr < ep; inPtr+=inStride )
@@ -201,7 +201,7 @@ cmRC_t      cmMtxFileDoubleExec( cmMtxFile* p, const double*     inPtr, unsigned
201 201
   return cmOkRC;
202 202
 }
203 203
 
204
-cmRC_t      cmMtxFileComplexExec( cmMtxFile* p, const cmComplexR_t*     inPtr, unsigned inCnt, unsigned inStride )
204
+cmRC_t      cmMtxFileComplexExec( cmMtxFile* p, const cmComplexR_t* inPtr, unsigned inCnt, unsigned inStride )
205 205
 {
206 206
   const cmComplexR_t* sp = inPtr;
207 207
   const cmComplexR_t* ep = inPtr + (inCnt * inStride);

+ 16
- 0
cmSymTbl.c View File

@@ -261,6 +261,22 @@ unsigned    cmSymTblRegisterSymbol(       cmSymTblH_t h, const char* label )
261 261
 unsigned    cmSymTblRegisterStaticSymbol( cmSymTblH_t h, const char* label )
262 262
 { return cmSymTblRegister( h, label, true ); }
263 263
 
264
+unsigned    cmSymTblRegisterVFmt( cmSymTblH_t h, const cmChar_t* fmt, va_list vl )
265
+{
266
+  unsigned n = vsnprintf(NULL,0,fmt,vl);
267
+  cmChar_t b[n+1];
268
+  vsnprintf(b,n,fmt,vl);
269
+  return cmSymTblRegister(h,fmt,vl);
270
+
271
+}
272
+
273
+unsigned    cmSymTblRegisterFmt( cmSymTblH_t h, const cmChar_t* fmt, ... )
274
+{
275
+  va_list vl;
276
+  va_start(vl,fmt);
277
+  cmSymTblRegisterVFmt(h,fmt,vl);
278
+  va_end(vl);
279
+}
264 280
 
265 281
 
266 282
 bool        cmSymTblRemove( cmSymTblH_t h, unsigned symId )

+ 3
- 0
cmSymTbl.h View File

@@ -37,6 +37,9 @@ extern "C" {
37 37
   unsigned    cmSymTblRegisterSymbol( cmSymTblH_t h, const char* label );
38 38
   unsigned    cmSymTblRegisterStaticSymbol( cmSymTblH_t h, const char* label );
39 39
 
40
+  unsigned    cmSymTblRegisterVFmt( cmSymTblH_t h, const cmChar_t* fmt, va_list vl );
41
+  unsigned    cmSymTblRegisterFmt( cmSymTblH_t h, const cmChar_t* fmt, ... );
42
+
40 43
   bool        cmSymTblRemove(    cmSymTblH_t h, unsigned symId );
41 44
 
42 45
   // Given a symbol id return the associated label.

+ 25
- 26
dsp/cmDspBuiltIn.c View File

@@ -1298,47 +1298,44 @@ cmDspRC_t _cmDspAudioFileOutReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDs
1298 1298
   return rc;
1299 1299
 } 
1300 1300
 
1301
-
1302 1301
 cmDspRC_t _cmDspAudioFileOutExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
1303 1302
 {
1304 1303
   cmDspRC_t            rc    = kOkDspRC;
1305 1304
   cmDspAudioFileOut_t* p     = (cmDspAudioFileOut_t*)inst;;
1306
-  unsigned             fpc   = cmDspSamplesPerCycle(ctx);
1307
-  unsigned             chCnt = cmDspUInt(inst,kChCntAofId);
1305
+  unsigned             chCnt = cmMin(2,cmDspUInt(inst,kChCntAofId));
1306
+  unsigned             smpCnt = 0;
1308 1307
   cmSample_t*          chArray[chCnt];
1309
-  unsigned             i;
1310
-
1311
-  // Assume that both channls have the same number of samples.
1312
-  // (cmAudioWriteFile() has the same constraint )
1313
-  int                  sn = cmDspAudioBufSmpCount(ctx,inst,kIn0AofId,0);
1314
-  
1315
-  // This code can handle the case where the input channels contain
1316
-  // more than or less than cmDspSamplesPerCycle().
1308
+  unsigned             i,j;
1317 1309
 
1318
-  while(sn>0)
1310
+  for(i=0,j=0; i<chCnt; ++i)
1319 1311
   {
1320
-    // we can process at most 'fpc' samples on one iteration
1321
-    unsigned n = cmMin(sn,fpc);
1322
-    sn -= n;
1312
+    unsigned          chVarId = i == 0 ? kIn0AofId : kIn1AofId;     // get audio buf var id for this ch
1313
+    unsigned          iSmpCnt = cmDspVarRows(inst,chVarId);
1323 1314
 
1324
-    // apply output gain
1325
-    for(i=0; i<chCnt; ++i)
1315
+    if( iSmpCnt == 0 )
1316
+    {
1317
+      chArray[j] = NULL;
1318
+    }
1319
+    else
1326 1320
     {
1327
-      chArray[i]            = p->smpBuf + i*fpc;
1328
-      const cmSample_t* sp  = i==0 ? cmDspAudioBuf(ctx,inst,kIn0AofId,0) : cmDspAudioBuf(ctx,inst,kIn1AofId,0);
1329
-      cmSample_t       gain = i==0 ? cmDspDouble(inst,kGain0AofId) : cmDspDouble(inst,kGain1AofId);
1321
+      cmSample_t gain = cmDspSample(inst,i==0?kGain0AofId:kGain1AofId); // get ch gain
1322
+    
1323
+      chArray[j] = cmDspAudioBuf(ctx,inst,chVarId,i);                   // get incoming audio buf ptr
1330 1324
 
1331
-      cmVOS_MultVVS(chArray[i], n, sp, (cmSample_t)gain);
1325
+      if( gain != 1.0 )
1326
+        cmVOS_MultVVS(chArray[j], iSmpCnt, chArray[j], gain);           // apply gain
1332 1327
 
1328
+      ++j;                                                              // incr chArray[] index
1329
+      assert( smpCnt==0 || iSmpCnt==smpCnt);                          
1330
+      smpCnt = iSmpCnt;                                                 // set outgoing sample count
1333 1331
     }
1334 1332
 
1335
-    // write the samples
1336
-    if( cmAudioFileWriteSample(p->afH, n, chCnt, chArray ) != kOkAfRC )
1337
-      rc = cmDspClassErr(ctx,inst->classPtr,kFileWriteFailDspRC,"An audio output file write failed.");
1338
-
1339
-    
1340 1333
   }
1341 1334
 
1335
+  // write the samples
1336
+  if( cmAudioFileWriteSample(p->afH, smpCnt, j, chArray ) != kOkAfRC )
1337
+    rc = cmDspClassErr(ctx,inst->classPtr,kFileWriteFailDspRC,"An audio output file write failed.");
1338
+
1342 1339
   return rc;
1343 1340
 }
1344 1341
 
@@ -5020,6 +5017,8 @@ cmDspClassConsFunc_t _cmDspClassBuiltInArray[] =
5020 5017
   cmMidiFilePlayClassCons,
5021 5018
   cmScFolClassCons,
5022 5019
   cmScModClassCons,
5020
+  cmGSwitchClassCons,
5021
+
5023 5022
   NULL,
5024 5023
 };
5025 5024
 

+ 9
- 1
dsp/cmDspClass.c View File

@@ -411,7 +411,7 @@ void   cmDspArgSetup(
411 411
   {
412 412
     lp = label;
413 413
     label[labelCharCnt]        = 0;
414
-    snprintf(label,labelCharCnt,"%s-%i",labelPrefix,labelId);
414
+    snprintf(label,labelCharCnt,"%s-%i",labelPrefix,labelId);    
415 415
   }
416 416
 
417 417
   // use the symbol table to hold the label string
@@ -898,6 +898,14 @@ cmDspRC_t   cmDspValueSet( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned varId, c
898 898
       cmDsvSetDouble(dvp, cmDsvGetDouble(svp)); 
899 899
       break;
900 900
 
901
+    case kSampleDsvFl:
902
+      cmDsvSetSample(dvp, cmDsvGetSample(svp));
903
+      break;
904
+
905
+    case kRealDsvFl:
906
+      cmDsvSetReal(dvp, cmDsvGetReal(svp));
907
+      break;
908
+
901 909
     case kSymDsvFl:
902 910
       cmDsvSetSymbol(dvp, cmDsvGetSymbol(svp));
903 911
       break;

+ 2
- 0
dsp/cmDspClass.h View File

@@ -18,6 +18,7 @@ extern "C" {
18 18
     kThreadFailDspRC,    // 6
19 19
     kNetFailDspRC,       // 7
20 20
     kCsvFailDspRC,       // 8
21
+    kDspStoreFailDspRC,
21 22
 
22 23
     kProcFailDspRC,
23 24
 
@@ -150,6 +151,7 @@ extern "C" {
150 151
     const cmChar_t* doc;      // document string
151 152
   } cmDspVar_t;
152 153
 
154
+
153 155
   typedef struct
154 156
   {
155 157
     const char*      label;

+ 5
- 0
dsp/cmDspCtx.h View File

@@ -6,8 +6,11 @@ extern "C" {
6 6
 #endif
7 7
 
8 8
   typedef cmHandle_t cmDspSysH_t;
9
+  typedef cmHandle_t cmDspStoreH_t;
10
+  
9 11
 
10 12
   struct cmAudioSysCtx_str;
13
+  struct cmDspGlobalVar_str;
11 14
 
12 15
   // DSP system context passed to many DSP instance functions
13 16
   typedef struct
@@ -20,9 +23,11 @@ extern "C" {
20 23
     cmLHeapH_t                lhH;
21 24
     cmJsonH_t                 jsH;
22 25
     cmSymTblH_t               stH;
26
+    cmDspStoreH_t             dsH;
23 27
     cmJsonH_t                 rsrcJsH;
24 28
     unsigned                  cycleCnt;  // count of DSP execution cycles (multiply by cmDspSamplesPerCycle() to get time since start of DSP system in samples)
25 29
 
30
+
26 31
     unsigned _disableSymId;
27 32
     unsigned _enableSymId;
28 33
 

+ 1
- 2
dsp/cmDspFx.c View File

@@ -1587,7 +1587,6 @@ cmDspRC_t _cmDspXfaderRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t*
1587 1587
     case kMstrGateXfId:
1588 1588
       {
1589 1589
         bool fl = cmDspBool(inst,kMstrGateXfId);
1590
-        printf("mstr:%i\n",fl);
1591 1590
         unsigned i;
1592 1591
         for(i=0; i<p->chCnt; ++i)
1593 1592
           p->chGateV[i] = fl;
@@ -4510,7 +4509,7 @@ struct cmDspClass_str* cmDistDsClassCons( cmDspCtx_t* ctx )
4510 4509
     _cmDspDistDsExec,
4511 4510
     _cmDspDistDsRecv,
4512 4511
     NULL,NULL,
4513
-    "Comb Filter");
4512
+    "Distortion and Downsampler");
4514 4513
 
4515 4514
   return &_cmDistDsDC;
4516 4515
 }

+ 321
- 18
dsp/cmDspKr.c View File

@@ -21,6 +21,7 @@
21 21
 #include "cmAudioSys.h"
22 22
 #include "cmDspCtx.h"
23 23
 #include "cmDspClass.h"
24
+#include "cmDspStore.h"
24 25
 #include "cmDspUi.h"
25 26
 #include "cmDspSys.h"
26 27
 #include "cmMath.h"
@@ -51,6 +52,8 @@ enum
51 52
   kUprSlopeKrId,
52 53
   kOffsetKrId,
53 54
   kInvertKrId,
55
+  kBypassKrId,
56
+  kWetKrId,
54 57
   kAudioInKrId,
55 58
   kAudioOutKrId
56 59
 };
@@ -79,6 +82,8 @@ cmDspClass_t _cmKrDC;
79 82
     { "uprs",    kUprSlopeKrId,    0, 0,   kInDsvFl  | kDoubleDsvFl | kOptArgDsvFl,   "Upper Slope"},
80 83
     { "offs",    kOffsetKrId,      0, 0,   kInDsvFl  | kDoubleDsvFl | kOptArgDsvFl,   "Offset"},
81 84
     { "invt",    kInvertKrId,      0, 0,   kInDsvFl  | kUIntDsvFl   | kOptArgDsvFl,   "Invert"},
85
+    { "bypass",  kBypassKrId,      0, 0,   kInDsvFl  | kBoolDsvFl   | kOptArgDsvFl,   "Bypass enable flag." },
86
+    { "wet",     kWetKrId,         0, 0,   kInDsvFl  | kSampleDsvFl,                  "Wet mix level."},
82 87
     { "in",      kAudioInKrId,     0, 0,   kInDsvFl  | kAudioBufDsvFl, "Audio Input" },
83 88
     { "out",     kAudioOutKrId,    0, 1,   kOutDsvFl | kAudioBufDsvFl, "Audio Output" },
84 89
     { NULL, 0, 0, 0, 0 }
@@ -96,6 +101,9 @@ cmDspClass_t _cmKrDC;
96 101
   cmDspSetDefaultDouble( ctx,&p->inst, kUprSlopeKrId, 0, 0.0 );
97 102
   cmDspSetDefaultDouble( ctx,&p->inst, kOffsetKrId,   0, 30.0);
98 103
   cmDspSetDefaultUInt(   ctx,&p->inst, kInvertKrId,   0, 0 );
104
+  cmDspSetDefaultUInt(   ctx,&p->inst, kBypassKrId,   0, 0 );
105
+  cmDspSetDefaultSample( ctx,&p->inst, kWetKrId,      0, 1.0);
106
+
99 107
   //_cmDspKrCmInit(ctx,p); // initialize the cm library
100 108
 
101 109
   p->ctx = cmCtxAlloc(NULL,ctx->rpt,ctx->lhH,ctx->stH);
@@ -122,9 +130,10 @@ cmDspRC_t _cmDspKrSetup(cmDspCtx_t* ctx, cmDspKr_t* p )
122 130
   cmDspRC_t rc           = kOkDspRC;
123 131
   unsigned  wndSmpCnt    = cmDspUInt(&p->inst,kWndSmpCntKrId);
124 132
   unsigned  hopFact      = cmDspUInt(&p->inst,kHopFactKrId);
125
-  unsigned  olaWndTypeId = kHannWndId;
133
+  unsigned  olaWndTypeId =kHannWndId;
126 134
 
127 135
   cmSpecDistFree(&p->sdp);
136
+
128 137
   p->sdp = cmSpecDistAlloc(p->ctx, NULL, cmDspSamplesPerCycle(ctx), cmDspSampleRate(ctx), wndSmpCnt, hopFact, olaWndTypeId);
129 138
 
130 139
   assert(p->sdp != NULL );
@@ -165,11 +174,18 @@ cmDspRC_t _cmDspKrExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt
165 174
   unsigned          oSmpCnt = cmDspVarRows(inst,kAudioOutKrId);
166 175
   const cmSample_t* sp;
167 176
 
177
+  cmSample_t wet = cmDspSample(inst,kWetKrId);
178
+
168 179
   cmSpecDistExec(p->sdp,ip,iSmpCnt);
169 180
   
170 181
   if((sp = cmSpecDistOut(p->sdp)) != NULL )
171
-    cmVOS_Copy(op,oSmpCnt,sp);
172
-  
182
+  {
183
+    cmVOS_MultVVS(op,oSmpCnt,sp,wet);
184
+  }
185
+
186
+  if( wet<1.0 )
187
+    cmVOS_MultSumVVS(op,oSmpCnt,ip,1.0-wet);
188
+
173 189
   return rc;
174 190
 }
175 191
 
@@ -178,6 +194,7 @@ cmDspRC_t _cmDspKrRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt
178 194
   cmDspKr_t* p = (cmDspKr_t*)inst;
179 195
   cmDspRC_t rc = kOkDspRC;
180 196
 
197
+
181 198
   cmDspSetEvent(ctx,inst,evt);
182 199
 
183 200
   switch( evt->dstVarId )
@@ -185,6 +202,22 @@ cmDspRC_t _cmDspKrRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt
185 202
     case kWndSmpCntKrId:
186 203
     case kHopFactKrId:
187 204
       _cmDspKrSetup(ctx,p);
205
+
206
+      // THIS IS A HACK
207
+      // WHEN WND OR HOP CHANGE THE RESULTING CHANGES
208
+      // SHOULD BE ISOLATED IN cmSpecDist() AND THE
209
+      // CURRENT STATE OF THE PARAMETERS SHOULD NOT BE
210
+      // LOST - IF THE CHANGES WERE ISOLATED WITHIN PVANL 
211
+      // AND PVSYN IT MIGHT BE POSSIBLE TO DO WITH 
212
+      // MINIMAL AUDIO INTERUPTION.
213
+
214
+      p->sdp->mode = cmDspUInt(inst,kModeKrId);
215
+      p->sdp->thresh   = cmDspDouble(inst,kThreshKrId);   
216
+      p->sdp->uprSlope = cmDspDouble(inst,kUprSlopeKrId); 
217
+      p->sdp->lwrSlope = cmDspDouble(inst,kLwrSlopeKrId); 
218
+      p->sdp->offset   = cmDspDouble(inst,kOffsetKrId);   
219
+      p->sdp->invertFl = cmDspUInt(inst,kInvertKrId)!=0;  
220
+
188 221
       printf("wsn:%i hsn:%i\n",p->sdp->wndSmpCnt,p->sdp->hopSmpCnt);
189 222
       break;
190 223
 
@@ -195,16 +228,17 @@ cmDspRC_t _cmDspKrRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt
195 228
       
196 229
     case kThreshKrId:     
197 230
       p->sdp->thresh   = cmDspDouble(inst,kThreshKrId);   
231
+      //printf("thr:p:%p sdp:%p %f\n",p,p->sdp,p->sdp->thresh);
198 232
       break;
199 233
 
200 234
     case kUprSlopeKrId:   
201 235
       p->sdp->uprSlope = cmDspDouble(inst,kUprSlopeKrId); 
202
-      printf("upr slope:%f\n",p->sdp->uprSlope);
236
+      //printf("upr slope:%f\n",p->sdp->uprSlope);
203 237
       break;
204 238
 
205 239
     case kLwrSlopeKrId:   
206 240
       p->sdp->lwrSlope = cmDspDouble(inst,kLwrSlopeKrId); 
207
-      printf("upr slope:%f\n",p->sdp->lwrSlope);
241
+      //printf("upr slope:%f\n",p->sdp->lwrSlope);
208 242
       break;
209 243
 
210 244
     case kOffsetKrId:     
@@ -215,6 +249,9 @@ cmDspRC_t _cmDspKrRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt
215 249
       p->sdp->invertFl = cmDspUInt(inst,kInvertKrId)!=0;  
216 250
       break;
217 251
 
252
+    case kWetKrId:
253
+      break;
254
+
218 255
     default:
219 256
       { assert(0); }
220 257
   }
@@ -517,7 +554,7 @@ cmDspRC_t _cmDspScoreReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t*
517 554
   }
518 555
 
519 556
   if((tlFn =  cmDspStrcz(inst, kFnScId )) !=  NULL )
520
-    if( cmScoreInitialize(ctx->cmCtx, &p->scH, tlFn, cmDspSampleRate(ctx), dynRefArray, dynRefCnt, _cmDspScoreCb, p ) != kOkTlRC )
557
+    if( cmScoreInitialize(ctx->cmCtx, &p->scH, tlFn, cmDspSampleRate(ctx), dynRefArray, dynRefCnt, _cmDspScoreCb, p, cmSymTblNullHandle ) != kOkTlRC )
521 558
       rc = cmErrMsg(&inst->classPtr->err, kInstResetFailDspRC, "Score file open failed.");
522 559
 
523 560
  errLabel:
@@ -822,7 +859,9 @@ enum
822 859
   kOutSfId,
823 860
   kDynSfId,
824 861
   kEvenSfId,
825
-  kTempoSfId
862
+  kTempoSfId,
863
+  kCostSfId,
864
+  kSymSfId
826 865
 };
827 866
 
828 867
 cmDspClass_t _cmScFolDC;
@@ -864,6 +903,8 @@ cmDspInst_t*  _cmDspScFolAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned
864 903
     { "dyn",   kDynSfId,      0, 0, kOutDsvFl| kDoubleDsvFl,                  "Dynamic value."},
865 904
     { "even",  kEvenSfId,     0, 0, kOutDsvFl| kDoubleDsvFl,                  "Evenness value."},
866 905
     { "tempo", kTempoSfId,    0, 0, kOutDsvFl| kDoubleDsvFl,                  "Tempo value."},
906
+    { "cost",  kCostSfId,     0, 0, kOutDsvFl| kDoubleDsvFl,                  "Match cost value."},
907
+    { "sym",   kSymSfId,      0, 0, kOutDsvFl| kSymDsvFl,                     "Symbol associated with a global variable which has changed value."},
867 908
     { NULL,    0,             0, 0, 0, NULL }
868 909
   };
869 910
 
@@ -886,6 +927,7 @@ cmDspInst_t*  _cmDspScFolAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned
886 927
   cmDspSetDefaultDouble( ctx, &p->inst,  kDynSfId,        0,     0);
887 928
   cmDspSetDefaultDouble( ctx, &p->inst,  kEvenSfId,       0,     0);
888 929
   cmDspSetDefaultDouble( ctx, &p->inst,  kTempoSfId,      0,     0);
930
+  cmDspSetDefaultDouble( ctx, &p->inst,  kCostSfId,       0,     0);
889 931
   
890 932
   cmDspSetDefaultSymbol(ctx,&p->inst,  kCmdSfId, p->quietSymId );
891 933
 
@@ -916,6 +958,7 @@ void _cmScFolMatcherCb( cmScMatcher* p, void* arg, cmScMatcherResult_t* rp )
916 958
     unsigned i;
917 959
     for(i=ap->sfp->smp->vsi; i<ap->sfp->smp->nsi; ++i)
918 960
     {
961
+
919 962
       switch( ap->sfp->smp->set[i].sp->varId )
920 963
       {
921 964
         case kEvenVarScId:
@@ -933,6 +976,26 @@ void _cmScFolMatcherCb( cmScMatcher* p, void* arg, cmScMatcherResult_t* rp )
933 976
         default:
934 977
           { assert(0); }
935 978
       }           
979
+
980
+      cmDspSetDouble(ap->ctx,inst,kCostSfId,ap->sfp->smp->set[i].match_cost);
981
+
982
+
983
+      // Set the values in the global variable storage
984
+      cmDspValue_t vv,cv;
985
+      unsigned     j;
986
+      cmDsvSetDouble(&vv,ap->sfp->smp->set[i].value);
987
+      cmDsvSetDouble(&cv,ap->sfp->smp->set[i].match_cost);
988
+
989
+      for(j=0; j<ap->sfp->smp->set[i].sp->sectCnt; ++j)
990
+      {
991
+        cmDspStoreSetValueViaSym(ap->ctx->dsH, ap->sfp->smp->set[i].sp->symArray[j], &vv );
992
+        cmDspStoreSetValueViaSym(ap->ctx->dsH, ap->sfp->smp->set[i].sp->costSymArray[j], &cv );
993
+
994
+        cmDspSetSymbol(ap->ctx,inst,kSymSfId,ap->sfp->smp->set[i].sp->symArray[j]);
995
+        cmDspSetSymbol(ap->ctx,inst,kSymSfId,ap->sfp->smp->set[i].sp->costSymArray[j]);
996
+      }
997
+
998
+
936 999
     }
937 1000
 
938 1001
     /*
@@ -957,7 +1020,7 @@ cmDspRC_t _cmDspScFolOpenScore( cmDspCtx_t* ctx, cmDspInst_t* inst )
957 1020
   if((fn = cmDspStrcz(inst,kFnSfId)) == NULL || strlen(fn)==0 )
958 1021
     return cmErrMsg(&inst->classPtr->err, kInvalidArgDspRC, "No score file name supplied.");
959 1022
 
960
-  if( cmScoreInitialize(ctx->cmCtx, &p->scH, fn, cmDspSampleRate(ctx), NULL, 0, NULL, NULL ) != kOkScRC )
1023
+  if( cmScoreInitialize(ctx->cmCtx, &p->scH, fn, cmDspSampleRate(ctx), NULL, 0, NULL, NULL, ctx->stH ) != kOkScRC )
961 1024
     return cmErrMsg(&inst->classPtr->err, kSubSysFailDspRC, "Unable to open the score '%s'.",fn);
962 1025
 
963 1026
   if( cmScoreIsValid(p->scH) )
@@ -1070,7 +1133,9 @@ struct cmDspClass_str* cmScFolClassCons( cmDspCtx_t* ctx )
1070 1133
 
1071 1134
 enum
1072 1135
 {
1073
-  kScLocIdxMdId
1136
+  kScLocIdxMdId,
1137
+  kResetIdxMdId,
1138
+  kCmdMdId
1074 1139
 };
1075 1140
 
1076 1141
 cmDspClass_t _cmModulatorDC;
@@ -1080,6 +1145,10 @@ typedef struct
1080 1145
   cmDspInst_t    inst;
1081 1146
   cmScModulator* mp;
1082 1147
   cmDspCtx_t*    tmp_ctx;       // used to temporarily hold the current cmDspCtx during callback
1148
+  cmChar_t*      fn;
1149
+  cmChar_t*      modLabel;
1150
+  unsigned       onSymId;
1151
+  unsigned       offSymId;
1083 1152
 } cmDspScMod_t;
1084 1153
 
1085 1154
 void _cmDspScModCb( void* arg, unsigned varSymId, double value )
@@ -1101,7 +1170,9 @@ cmDspInst_t*  _cmDspScModAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned
1101 1170
 
1102 1171
   cmDspVarArg_t args[] =
1103 1172
   {
1104
-    { "index",   kScLocIdxMdId,0,0, kInDsvFl  | kUIntDsvFl,                "Score follower index input."},
1173
+    { "index",   kScLocIdxMdId, 0,0, kInDsvFl  | kUIntDsvFl,  "Score follower index input."},
1174
+    { "reset",   kResetIdxMdId, 0,0, kInDsvFl  | kUIntDsvFl | kOptArgDsvFl, "Reset the modulator and go to the score index."},
1175
+    { "cmd",     kCmdMdId,      0,0, kInDsvFl  | kSymDsvFl  | kOptArgDsvFl, "on | off."},
1105 1176
     { NULL, 0, 0, 0, 0 }
1106 1177
   };
1107 1178
 
@@ -1116,6 +1187,8 @@ cmDspInst_t*  _cmDspScModAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned
1116 1187
   const cmChar_t* fn       = va_arg(vl1,const cmChar_t*);
1117 1188
   const cmChar_t* modLabel = va_arg(vl1,const cmChar_t*);
1118 1189
 
1190
+  va_end(vl1);
1191
+
1119 1192
   // validate the file
1120 1193
   if( fn==NULL || cmFsIsFile(fn)==false )
1121 1194
   {
@@ -1131,8 +1204,8 @@ cmDspInst_t*  _cmDspScModAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned
1131 1204
     cmDspClassErr(ctx,classPtr,kInvalidArgDspRC,"The internal modulator object initialization failed.");
1132 1205
     return NULL;
1133 1206
   }
1134
-  unsigned      fixArgCnt = 1;
1135
-  unsigned      argCnt    = fixArgCnt + cmScModulatorVarCount(mp);
1207
+  unsigned      fixArgCnt = sizeof(args)/sizeof(args[0]) - 1;
1208
+  unsigned      argCnt    = fixArgCnt + cmScModulatorOutVarCount(mp);
1136 1209
   cmDspVarArg_t a[ argCnt+1 ];
1137 1210
   unsigned      i;
1138 1211
 
@@ -1141,7 +1214,7 @@ cmDspInst_t*  _cmDspScModAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned
1141 1214
   for(i=fixArgCnt; i<argCnt; ++i)
1142 1215
   {
1143 1216
     unsigned            varIdx    = i - fixArgCnt;
1144
-    const cmScModVar_t* vp        = cmScModulatorVar(mp,varIdx);
1217
+    const cmScModVar_t* vp        = cmScModulatorOutVar(mp,varIdx);
1145 1218
     const cmChar_t*     label     = cmSymTblLabel( ctx->stH, vp->varSymId );
1146 1219
     const cmChar_t*     docStr    = cmTsPrintfS("Variable output for %s",label);
1147 1220
 
@@ -1149,13 +1222,21 @@ cmDspInst_t*  _cmDspScModAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned
1149 1222
   }
1150 1223
   cmDspArgSetupNull(a+argCnt); // set terminating arg. flags
1151 1224
 
1152
-  cmDspScMod_t* p = cmDspInstAlloc(cmDspScMod_t,ctx,classPtr,a,instSymId,id,storeSymId,0,vl);
1225
+  cmDspScMod_t* p = cmDspInstAlloc(cmDspScMod_t,ctx,classPtr,a,instSymId,id,storeSymId,va_cnt,vl);
1226
+
1227
+
1228
+  p->fn       = cmMemAllocStr(fn);
1229
+  p->modLabel = cmMemAllocStr(modLabel);
1230
+  p->mp       = mp;
1231
+  p->onSymId  = cmSymTblId(ctx->stH,"on");
1232
+  p->offSymId = cmSymTblId(ctx->stH,"off");
1153 1233
 
1154
-  p->mp = mp;
1155 1234
   mp->cbArg = p;  // set the modulator callback arg
1156 1235
 
1157
-  cmDspSetDefaultUInt(ctx,&p->inst,kScLocIdxMdId,0,0);
1236
+  
1158 1237
 
1238
+  cmDspSetDefaultUInt(ctx,&p->inst,kScLocIdxMdId,0,0);
1239
+  cmDspSetDefaultSymbol(ctx,&p->inst,kCmdMdId,p->offSymId);
1159 1240
   return &p->inst;
1160 1241
 }
1161 1242
 
@@ -1164,9 +1245,12 @@ cmDspRC_t _cmDspScModFree(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t*
1164 1245
   cmDspRC_t        rc = kOkDspRC;
1165 1246
   cmDspScMod_t* p = (cmDspScMod_t*)inst;
1166 1247
 
1248
+
1167 1249
   if( cmScModulatorFree(&p->mp) != kOkTlRC )
1168 1250
     return cmErrMsg(&inst->classPtr->err, kInstFinalFailDspRC, "Modulator release failed.");
1169 1251
 
1252
+  cmMemFree(p->fn);
1253
+  cmMemFree(p->modLabel);
1170 1254
   return rc;
1171 1255
 }
1172 1256
 
@@ -1182,8 +1266,25 @@ cmDspRC_t _cmDspScModReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t*
1182 1266
 
1183 1267
 cmDspRC_t _cmDspScModRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
1184 1268
 {
1269
+  cmDspScMod_t* p  = (cmDspScMod_t*)inst;
1185 1270
 
1186 1271
   cmDspSetEvent(ctx,inst,evt);
1272
+  
1273
+  switch( evt->dstVarId )
1274
+  {
1275
+    case kResetIdxMdId:
1276
+      cmDspSetUInt(ctx,inst,kScLocIdxMdId,cmDspUInt(inst,kResetIdxMdId));
1277
+      break;
1278
+
1279
+    case kCmdMdId:
1280
+      {
1281
+        unsigned symId = cmDspSymbol(inst,kCmdMdId);
1282
+        if( symId == p->onSymId )
1283
+          cmScModulatorReset(p->mp, ctx->cmCtx, cmDspUInt(inst,kScLocIdxMdId));
1284
+      }
1285
+      break;
1286
+
1287
+  }
1187 1288
 
1188 1289
   return kOkDspRC;
1189 1290
 }
@@ -1193,8 +1294,12 @@ cmDspRC_t _cmDspScModExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t*
1193 1294
   cmDspRC_t         rc = kOkDspRC;
1194 1295
   cmDspScMod_t* p  = (cmDspScMod_t*)inst;
1195 1296
   
1196
-  p->tmp_ctx = ctx;
1197
-  cmScModulatorExec(p->mp,cmDspUInt(inst,kScLocIdxMdId));
1297
+  if( cmDspSymbol(inst,kCmdMdId) != p->offSymId )
1298
+  {
1299
+    p->tmp_ctx = ctx;
1300
+    cmScModulatorExec(p->mp,cmDspUInt(inst,kScLocIdxMdId));
1301
+  }
1302
+
1198 1303
   return rc;
1199 1304
 }
1200 1305
 
@@ -1212,3 +1317,201 @@ struct cmDspClass_str* cmScModClassCons( cmDspCtx_t* ctx )
1212 1317
 
1213 1318
   return &_cmModulatorDC;
1214 1319
 }
1320
+
1321
+//==========================================================================================================================================
1322
+
1323
+enum
1324
+{
1325
+  kInChCntGsId,
1326
+  kOutGroupCntGsId,
1327
+  kGroupSelIdxGsId,
1328
+  kBaseInFloatGsId
1329
+};
1330
+
1331
+cmDspClass_t _cmGSwitchDC;
1332
+
1333
+typedef struct
1334
+{
1335
+  cmDspInst_t    inst;
1336
+
1337
+  unsigned iChCnt;
1338
+  unsigned oGroupCnt;
1339
+
1340
+  unsigned baseInFloatGsId;
1341
+  unsigned baseInSymGsId;
1342
+  unsigned baseInBoolGsId;
1343
+
1344
+  unsigned baseOutFloatGsId;
1345
+  unsigned baseOutSymGsId;
1346
+  unsigned baseOutBoolGsId;
1347
+
1348
+} cmDspGSwitch_t;
1349
+
1350
+
1351
+cmDspInst_t*  _cmDspGSwitchAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned storeSymId, unsigned instSymId, unsigned id, unsigned va_cnt, va_list vl )
1352
+{
1353
+  va_list vl1;
1354
+  va_copy(vl1,vl);
1355
+
1356
+  cmDspVarArg_t args[] =
1357
+  {
1358
+    { "ichs",   kInChCntGsId,     0,0,            kUIntDsvFl | kReqArgDsvFl, "Input channel count."},
1359
+    { "ochs",   kOutGroupCntGsId, 0,0,            kUIntDsvFl | kReqArgDsvFl, "Output group count."},
1360
+    { "sel",    kGroupSelIdxGsId, 0,0, kInDsvFl | kUIntDsvFl,                "Group select index."},
1361
+    { NULL, 0, 0, 0, 0 }
1362
+  };
1363
+
1364
+  // validate the argument count
1365
+  if( va_cnt != 2 )
1366
+  {
1367
+    cmDspClassErr(ctx,classPtr,kInvalidArgDspRC,"The GSwitch requires at least two arguments.");
1368
+    return NULL;
1369
+  }    
1370
+
1371
+  // read the input ch and output group count
1372
+  unsigned iChCnt     = va_arg(vl1,unsigned);
1373
+  unsigned oGroupCnt  = va_arg(vl1,unsigned);
1374
+
1375
+  va_end(vl1);
1376
+  
1377
+  // validate the channel counts
1378
+  if( iChCnt == 0 || oGroupCnt==0 )
1379
+  {
1380
+    cmDspClassErr(ctx,classPtr,kInvalidArgDspRC,"The GSwitch input channel count and group count must be greater than zero.");
1381
+    return NULL;
1382
+  }
1383
+
1384
+  unsigned typeCnt          = 3; // i.e. float,sym,bool
1385
+  unsigned baseInFloatGsId  = kBaseInFloatGsId;
1386
+  unsigned baseInSymGsId    = baseInFloatGsId  + iChCnt;
1387
+  unsigned baseInBoolGsId   = baseInSymGsId    + iChCnt;
1388
+  unsigned baseOutFloatGsId = baseInBoolGsId   + iChCnt;
1389
+  unsigned baseOutSymGsId   = baseOutFloatGsId + (iChCnt * oGroupCnt);
1390
+  unsigned baseOutBoolGsId  = baseOutSymGsId   + (iChCnt * oGroupCnt);
1391
+
1392
+  unsigned      fixArgCnt        = 3;
1393
+  unsigned      varArgCnt        = (iChCnt * typeCnt) + (iChCnt * typeCnt * oGroupCnt);
1394
+  unsigned      argCnt           = fixArgCnt + varArgCnt;
1395
+  cmDspVarArg_t a[ argCnt+1 ];
1396
+  unsigned      i;
1397
+
1398
+  cmDspArgCopy( a, argCnt, 0, args, fixArgCnt );
1399
+  cmDspArgSetupN( ctx, a, argCnt, baseInFloatGsId, iChCnt, "f-in", baseInFloatGsId, 0, 0, kInDsvFl | kDoubleDsvFl, "Float input");
1400
+  cmDspArgSetupN( ctx, a, argCnt, baseInSymGsId,   iChCnt, "s-in", baseInSymGsId,   0, 0, kInDsvFl | kSymDsvFl,    "Symbol input");
1401
+  cmDspArgSetupN( ctx, a, argCnt, baseInBoolGsId,  iChCnt, "b-in", baseInBoolGsId,  0, 0, kInDsvFl | kBoolDsvFl,   "Bool input");
1402
+
1403
+  unsigned labelCharCnt = 63;
1404
+  cmChar_t label[labelCharCnt+1];
1405
+  label[labelCharCnt] = 0;
1406
+
1407
+  unsigned gsid = baseOutFloatGsId;
1408
+  for(i=0; i<oGroupCnt; ++i, gsid+=iChCnt)
1409
+  {
1410
+    snprintf(label,labelCharCnt,"f-out-%i",i);
1411
+    cmDspArgSetupN( ctx, a, argCnt, gsid, iChCnt, label, gsid, 0, 0, kInDsvFl | kDoubleDsvFl, "Float output");
1412
+  }
1413
+
1414
+  gsid = baseOutSymGsId;
1415
+  for(i=0; i<oGroupCnt; ++i, gsid+=iChCnt)
1416
+  {
1417
+    snprintf(label,labelCharCnt,"s-out-%i",i);
1418
+    cmDspArgSetupN( ctx, a, argCnt, gsid, iChCnt, label, gsid, 0, 0, kInDsvFl | kSymDsvFl, "Symbol output");
1419
+  }
1420
+
1421
+  gsid = baseOutBoolGsId;
1422
+  for(i=0; i<oGroupCnt; ++i, gsid+=iChCnt)
1423
+  {
1424
+    snprintf(label,labelCharCnt,"b-out-%i",i);
1425
+    cmDspArgSetupN( ctx,a, argCnt, gsid, iChCnt, label, gsid, 0, 0, kInDsvFl | kBoolDsvFl, "Bool output");
1426
+  }
1427
+
1428
+  cmDspArgSetupNull(a+argCnt); // set terminating arg. flags  
1429
+
1430
+  cmDspGSwitch_t* p = cmDspInstAlloc(cmDspGSwitch_t,ctx,classPtr,a,instSymId,id,storeSymId,va_cnt,vl);
1431
+
1432
+  p->iChCnt           = iChCnt;
1433
+  p->oGroupCnt        = oGroupCnt;
1434
+  p->baseInFloatGsId  = baseInFloatGsId;
1435
+  p->baseInSymGsId    = baseInSymGsId;
1436
+  p->baseInBoolGsId   = baseInBoolGsId;
1437
+  p->baseOutFloatGsId = baseOutFloatGsId;
1438
+  p->baseOutSymGsId   = baseOutSymGsId;
1439
+  p->baseOutBoolGsId  = baseOutBoolGsId;
1440
+
1441
+  cmDspSetDefaultUInt(ctx,&p->inst,kGroupSelIdxGsId,0,0);
1442
+
1443
+  return &p->inst;
1444
+}
1445
+
1446
+cmDspRC_t _cmDspGSwitchReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
1447
+{
1448
+  cmDspRC_t       rc          = kOkDspRC;
1449
+
1450
+  cmDspApplyAllDefaults(ctx,inst);
1451
+
1452
+  return rc;
1453
+}
1454
+
1455
+cmDspRC_t _cmDspGSwitchRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
1456
+{
1457
+  cmDspRC_t       rc = kOkDspRC;
1458
+  cmDspGSwitch_t* p  = (cmDspGSwitch_t*)inst;
1459
+
1460
+  // if this is the group selector
1461
+  if( evt->dstVarId == kGroupSelIdxGsId )
1462
+  {
1463
+    unsigned idx;
1464
+    if( (idx = cmDsvGetUInt(evt->valuePtr)) > p->oGroupCnt )
1465
+      cmDspInstErr(ctx,inst,kInvalidArgDspRC,"The GSwitch group select index %i is out of range %i.",idx,p->oGroupCnt);
1466
+    else
1467
+      cmDspSetEvent(ctx,inst,evt);
1468
+    return rc;
1469
+  }
1470
+
1471
+  // get the group selector
1472
+  unsigned groupIdx = cmDspUInt(inst,kGroupSelIdxGsId);
1473
+  assert( groupIdx < p->oGroupCnt);
1474
+
1475
+
1476
+  // if this is a float input
1477
+  if( p->baseInFloatGsId <= evt->dstVarId && evt->dstVarId < p->baseInFloatGsId + p->iChCnt )
1478
+  {
1479
+    unsigned outVarId = p->baseOutFloatGsId + (groupIdx * p->iChCnt) + (evt->dstVarId - p->baseInFloatGsId);
1480
+    cmDspValueSet(ctx, inst, outVarId, evt->valuePtr, 0 );
1481
+    return rc;
1482
+  }
1483
+
1484
+  // if this is a symbol input
1485
+  if( p->baseInSymGsId <= evt->dstVarId && evt->dstVarId < p->baseInSymGsId + p->iChCnt )
1486
+  {
1487
+    unsigned outVarId = p->baseOutSymGsId + (groupIdx * p->iChCnt) + (evt->dstVarId - p->baseInSymGsId);
1488
+    cmDspValueSet(ctx, inst, outVarId, evt->valuePtr, 0 );    
1489
+    return rc;
1490
+  }
1491
+
1492
+  // if this is a bool input
1493
+  if( p->baseInBoolGsId <= evt->dstVarId && evt->dstVarId < p->baseInBoolGsId + p->iChCnt )
1494
+  {
1495
+    unsigned outVarId = p->baseOutBoolGsId + (groupIdx * p->iChCnt) + (evt->dstVarId - p->baseInBoolGsId);
1496
+    cmDspValueSet(ctx, inst, outVarId, evt->valuePtr, 0 );        
1497
+    return rc;
1498
+  }
1499
+
1500
+  return rc;
1501
+}
1502
+
1503
+
1504
+struct cmDspClass_str* cmGSwitchClassCons( cmDspCtx_t* ctx )
1505
+{
1506
+  cmDspClassSetup(&_cmGSwitchDC,ctx,"GSwitch",
1507
+    NULL,
1508
+    _cmDspGSwitchAlloc,
1509
+    NULL,
1510
+    _cmDspGSwitchReset,
1511
+    NULL,
1512
+    _cmDspGSwitchRecv,
1513
+    NULL,NULL,
1514
+    "Ganged switch.");
1515
+
1516
+  return &_cmGSwitchDC;
1517
+}

+ 1
- 0
dsp/cmDspKr.h View File

@@ -11,6 +11,7 @@ extern "C" {
11 11
   struct cmDspClass_str* cmMidiFilePlayClassCons( cmDspCtx_t* ctx );
12 12
   struct cmDspClass_str* cmScFolClassCons( cmDspCtx_t* ctx );
13 13
   struct cmDspClass_str* cmScModClassCons( cmDspCtx_t* ctx );
14
+  struct cmDspClass_str* cmGSwitchClassCons( cmDspCtx_t* ctx );
14 15
 
15 16
 #ifdef __cplusplus
16 17
 }

+ 1
- 0
dsp/cmDspNet.c View File

@@ -20,6 +20,7 @@
20 20
 #include "cmProcObj.h"
21 21
 #include "cmDspCtx.h"
22 22
 #include "cmDspClass.h"
23
+#include "cmDspStore.h"
23 24
 #include "cmDspSys.h"
24 25
 #include "cmDspPreset.h"
25 26
 #include "cmDspNet.h"

+ 1
- 0
dsp/cmDspNet.h View File

@@ -62,6 +62,7 @@ extern "C" {
62 62
     cmDspCtx_t          ctx;
63 63
     cmLHeapH_t          lhH;      // DSP system lHeap used for system memory (DSP instance memory uses ctx->lhH so that it can be removed independent of the DSP system memory)
64 64
     cmSymTblH_t         stH;      // DSP system symbol table (holds class based symbols) (DSP instances use ctx->stH)
65
+    cmDspStoreH_t       dsH;      // DSP system global variable storate table
65 66
     cmJsonH_t           jsH;      // DSP json for use by the system 
66 67
     const cmChar_t*     rsrcFn;   // name of the JSON file containing resource specific resource      
67 68
     _cmDspClass_t*      classList;

+ 1
- 0
dsp/cmDspPgm.c View File

@@ -2366,6 +2366,7 @@ cmDspRC_t _cmDspSysPgm_AvailCh( cmDspSysH_t h, void** userPtrPtr )
2366 2366
 _cmDspSysPgm_t _cmDspSysPgmArray[] = 
2367 2367
 {
2368 2368
   { "time_line",     _cmDspSysPgm_TimeLine,     NULL, NULL },
2369
+  { "switcher",      _cmDspSysPgm_Switcher,     NULL, NULL },
2369 2370
   { "main",          _cmDspSysPgm_Main,         NULL, NULL },
2370 2371
   { "array",         _cmDspSysPgm_Array,        NULL, NULL },
2371 2372
   { "line",          _cmDspSysPgm_Line,         NULL, NULL },

+ 177
- 31
dsp/cmDspPgmKr.c View File

@@ -64,11 +64,14 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr )
64 64
   cmCtx_t*        cmCtx      = cmDspSysPgmCtx(h);
65 65
   cmErr_t         err;
66 66
   krRsrc_t        r;
67
-  unsigned        wtLoopCnt  = 1;                           // 1=play once (-1=loop forever)
67
+  unsigned        wtLoopCnt  = 1;                            // 1=play once (-1=loop forever)
68 68
   unsigned        wtInitMode = 0;                            // initial wt mode is 'silence'
69 69
   unsigned        wtSmpCnt   = floor(cmDspSysSampleRate(h)); // wt length == srate
70 70
   int             krWndSmpCnt = 2048;
71 71
   int             krHopFact   = 4;
72
+  unsigned        xfadOutChCnt = 2;
73
+  double          xfadMs      = 200;
74
+  bool            xfadAllOnFl  = true;
72 75
 
73 76
   memset(&r,0,sizeof(r));
74 77
   cmErrSetup(&err,&cmCtx->rpt,"Kr Timeline");
@@ -83,11 +86,15 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr )
83 86
   cmDspInst_t* pts  = cmDspSysAllocInst(h,"PortToSym",   NULL,  2, "on", "off" );
84 87
   cmDspInst_t* mfp  = cmDspSysAllocInst(h,"MidiFilePlay",NULL,  0 );
85 88
   cmDspInst_t* sfp  = cmDspSysAllocInst(h,"ScFol",       NULL,  1, r.scFn );
89
+  cmDspInst_t* modp = cmDspSysAllocInst(h,"ScMod",       NULL,  2, r.modFn, "m1" );
86 90
   cmDspInst_t* kr0p = cmDspSysAllocInst(h,"Kr",          NULL,   2, krWndSmpCnt, krHopFact );
87 91
   cmDspInst_t* kr1p = cmDspSysAllocInst(h,"Kr",          NULL,   2, krWndSmpCnt, krHopFact );
92
+  cmDspInst_t* xfad = cmDspSysAllocInst(h,"Xfader",      NULL,   3, xfadOutChCnt, xfadMs, xfadAllOnFl );
93
+ 
88 94
 
89 95
   cmDspInst_t* ao0p = cmDspSysAllocInst(h,"AudioOut",    NULL,  1, 0 );
90 96
   cmDspInst_t* ao1p = cmDspSysAllocInst(h,"AudioOut",    NULL,  1, 1 );
97
+  //cmDspInst_t* af0p = cmDspSysAllocInst(h,"AudioFileOut",NULL,  2, "/home/kevin/temp/debug0.wav",1);
91 98
 
92 99
   cmDspSysNewPage(h,"Controls");
93 100
   cmDspInst_t* onb  = cmDspSysAllocInst(h,"Button", "start",  2, kButtonDuiId, 1.0 );
@@ -109,6 +116,7 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr )
109 116
   cmDspInst_t* ls0p = cmDspSysAllocInst(h,"Scalar", "lwr slope", 5, kNumberDuiId, 0.3,  10.0, 0.01,  2.0 );
110 117
   cmDspInst_t* of0p = cmDspSysAllocInst(h,"Scalar", "offset",    5, kNumberDuiId, 0.0, 100.0, 0.01, 30.0 );
111 118
   cmDspInst_t* iv0p = cmDspSysAllocInst(h,"Scalar", "invert",    5, kNumberDuiId, 0.0,   1.0, 1.0,   0.0 );  
119
+  cmDspInst_t* wet0  = cmDspSysAllocInst(h,"Scalar", "wet",      5, kNumberDuiId, 0.0,    1.0,0.001,  1.0 );  
112 120
   cmDspSysNewColumn(h,0);
113 121
 
114 122
   //cmDspInst_t* al1p = cmDspSysAllocInst(h,"MsgList","audFiles", 2, "audFiles",NULL);
@@ -122,20 +130,37 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr )
122 130
   cmDspInst_t* ls1p = cmDspSysAllocInst(h,"Scalar", "lwr slope1", 5, kNumberDuiId, 0.3,  10.0, 0.01,  2.0 );
123 131
   cmDspInst_t* of1p = cmDspSysAllocInst(h,"Scalar", "offset1",    5, kNumberDuiId, 0.0, 100.0, 0.01, 30.0 );
124 132
   cmDspInst_t* iv1p = cmDspSysAllocInst(h,"Scalar", "invert1",    5, kNumberDuiId, 0.0,   1.0, 1.0,   0.0 );  
133
+  cmDspInst_t* wet1  = cmDspSysAllocInst(h,"Scalar", "wet1",      5, kNumberDuiId, 0.0,    1.0,0.001,  1.0 );  
134
+
135
+  cmDspSysNewColumn(h,0);
136
+  cmDspInst_t* ogain = cmDspSysAllocInst(h,"Scalar", "Out Gain",   5, kNumberDuiId, 0.0,   10.0,0.01,   3.0 );  
137
+  //cmDspInst_t* reload = cmDspSysAllocInst(h,"Button", "Reload",     2, kButtonDuiId, 0.0 );
125 138
 
126 139
 
127 140
   if((rc = cmDspSysLastRC(h)) != kOkDspRC )
128 141
     return rc;
129 142
 
130 143
   // phasor->wt->aout
131
-  cmDspSysConnectAudio(h, php, "out", wtp,  "phs" );   // phs -> wt
132
-  //cmDspSysConnectAudio(h, wtp, "out", kr0p,  "in"  );  // wt->kr
133
-  //cmDspSysConnectAudio(h, wtp, "out", kr1p,  "in"  );
134
-  //cmDspSysConnectAudio(h, kr0p, "out", ao0p, "in");  // kr->aout- 0
135
-  //cmDspSysConnectAudio(h, kr1p, "out", ao1p, "in"); 
136
-  cmDspSysConnectAudio(h, wtp, "out", ao0p, "in"  );   // wt  -> aout0
137
-  cmDspSysConnectAudio(h, wtp, "out", ao1p, "in" );    // wt  -> aout1
144
+  cmDspSysConnectAudio(h, php,  "out", wtp,  "phs" );   // phs -> wt
145
+
146
+  if(1)
147
+  {
148
+    cmDspSysConnectAudio(h, wtp,  "out", kr0p,  "in"  );  // wt->kr
149
+    cmDspSysConnectAudio(h, wtp,  "out", kr1p,  "in"  );
150
+    cmDspSysConnectAudio(h, kr0p, "out", xfad, "in-0");     // kr->aout
151
+    cmDspSysConnectAudio(h, kr1p, "out", xfad, "in-1");
152
+    cmDspSysConnectAudio(h, xfad, "out-0", ao0p, "in");     // kr->aout
153
+    cmDspSysConnectAudio(h, xfad, "out-1", ao1p, "in");
138 154
  
155
+  }
156
+  else
157
+  {
158
+    cmDspSysConnectAudio(h, wtp, "out", ao0p, "in"  );   // wt  -> aout0
159
+    cmDspSysConnectAudio(h, wtp, "out", ao1p, "in" );    // wt  -> aout1
160
+    //cmDspSysConnectAudio(h, wtp, "out", af0p, "in0" );   // wt  -> audio file
161
+  }
162
+
163
+  // wave-table to time-line cursor
139 164
   cmDspSysInstallCb(   h, wtp, "fidx",tlp,  "curs", NULL); 
140 165
 
141 166
   // start connections
@@ -144,6 +169,7 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr )
144 169
   cmDspSysInstallCb(h, onb, "sym", mfp, "sel",   NULL );
145 170
   cmDspSysInstallCb(h, onb, "sym", pts, "on",    NULL );
146 171
   cmDspSysInstallCb(h, pts, "on",  wtp, "cmd",   NULL );
172
+  cmDspSysInstallCb(h, pts, "on",  modp,"cmd",   NULL );
147 173
 
148 174
   // stop connections
149 175
   cmDspSysInstallCb(h, wtp,  "done",offb,"in",  NULL ); // 'done' from WT simulates pressing Stop btn.
@@ -151,6 +177,7 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr )
151 177
   cmDspSysInstallCb(h, offb, "sym", mfp, "sel", NULL ); 
152 178
   cmDspSysInstallCb(h, offb, "sym", pts, "off", NULL );
153 179
   cmDspSysInstallCb(h, pts,  "off", wtp, "cmd", NULL );
180
+  cmDspSysInstallCb(h, pts,  "off", modp,"cmd", NULL );
154 181
 
155 182
   // time-line to wave-table selection 
156 183
   cmDspSysInstallCb(h, tlp, "absi", wtp, "beg", NULL );  
@@ -161,25 +188,32 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr )
161 188
   cmDspSysInstallCb(h, tlp, "mbsi", mfp, "bsi",   NULL );
162 189
   cmDspSysInstallCb(h, tlp, "mesi", mfp, "esi",   NULL );
163 190
   cmDspSysInstallCb(h, tlp, "mfn",  mfp, "fn",    NULL );
164
-
165 191
   // score to score follower - to set initial search location
166 192
   cmDspSysInstallCb(h, scp, "sel",    sfp, "index",  NULL );
193
+  //cmDspSysInstallCb(h, scp, "sel",    prv, "in", NULL );
194
+  cmDspSysInstallCb(h, scp, "sel",    modp,"reset", NULL );
167 195
   
196
+  //cmDspSysInstallCb(h, reload,"out",  modp, "reload", NULL );
168 197
 
169
-  // MIDI file player to score-follower and score - the order of connections is the same
170
-  // as the msg transmision order from MFP
171
-  //cmDspSysInstallCb(h, mfp, "smpidx", scp, "smpidx", NULL );
172
-  cmDspSysInstallCb(h, mfp, "smpidx", sfp, "smpidx", NULL );
173
-  //cmDspSysInstallCb(h, mfp, "d1",     scp, "d1",     NULL );
174
-  cmDspSysInstallCb(h, mfp, "d1",     sfp, "d1",     NULL );
175
-  //cmDspSysInstallCb(h, mfp, "d0",     scp, "d0",     NULL );
176
-  cmDspSysInstallCb(h, mfp, "d0",     sfp, "d0",     NULL );
177
-  //cmDspSysInstallCb(h, mfp, "status", scp, "status", NULL );
178
-  cmDspSysInstallCb(h, mfp, "status", sfp, "status", NULL );
179 198
 
199
+  // MIDI file play er to score follower
200
+  if(1)
201
+  {
202
+    cmDspSysInstallCb(h, mfp, "smpidx", sfp, "smpidx", NULL );
203
+    cmDspSysInstallCb(h, mfp, "d1",     sfp, "d1",     NULL );
204
+    cmDspSysInstallCb(h, mfp, "d0",     sfp, "d0",     NULL );
205
+    cmDspSysInstallCb(h, mfp, "status", sfp, "status", NULL );
206
+  }
180 207
 
181
-  // score follower to score
182
-  //cmDspSysInstallCb(h, sfp, "out",  modp, "index", NULL );
208
+  // score follower to modulator and printers
209
+  cmDspSysInstallCb(h, sfp, "out",  modp, "index", NULL );
210
+  cmDspSysInstallCb(h, sfp, "out",  prp, "in",  NULL );
211
+  cmDspSysInstallCb(h, sfp, "even", pre, "in", NULL );
212
+  cmDspSysInstallCb(h, sfp, "dyn",  prd, "in", NULL );
213
+  cmDspSysInstallCb(h, sfp, "tempo",prt, "in", NULL );
214
+
215
+  cmDspSysInstallCb(h, prtb, "sym", sfp, "cmd", NULL );
216
+  cmDspSysInstallCb(h, qtb,  "sym", sfp, "cmd", NULL );
183 217
 
184 218
 
185 219
   cmDspSysInstallCb(h, ws0p, "out", kr0p, "wndn", NULL );   // wndSmpCnt->kr
@@ -190,6 +224,7 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr )
190 224
   cmDspSysInstallCb(h, us0p, "val", kr0p, "uprs", NULL );   // uprSlope->kr
191 225
   cmDspSysInstallCb(h, of0p, "val", kr0p, "offs", NULL );   // offset->kr
192 226
   cmDspSysInstallCb(h, iv0p, "val", kr0p, "invt", NULL );   // invert->kr
227
+  cmDspSysInstallCb(h, wet0, "val", kr0p, "wet", NULL );    //  wet->kr
193 228
 
194 229
   cmDspSysInstallCb(h, ws1p, "out", kr1p, "wndn", NULL );   // wndSmpCnt->kr
195 230
   cmDspSysInstallCb(h, hf1p, "out", kr1p, "hopf", NULL );   // hopFact->kr
@@ -199,23 +234,134 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr )
199 234
   cmDspSysInstallCb(h, us1p, "val", kr1p, "uprs", NULL );   // uprSlope->kr
200 235
   cmDspSysInstallCb(h, of1p, "val", kr1p, "offs", NULL );   // offset->kr
201 236
   cmDspSysInstallCb(h, iv1p, "val", kr1p, "invt", NULL );   // invert->kr
237
+  cmDspSysInstallCb(h, wet1, "val", kr1p, "wet", NULL );    //  wet->kr
238
+
239
+  cmDspSysInstallCb(h, ogain, "val", ao0p, "gain", NULL );   // output gain control
240
+  cmDspSysInstallCb(h, ogain, "val", ao1p, "gain", NULL );
202 241
 
203 242
   // Printer connections
204 243
   cmDspSysInstallCb(h, tlp, "afn",  prp, "in",  NULL );
205 244
   cmDspSysInstallCb(h, tlp, "mfn",  prp, "in",  NULL );
206 245
   cmDspSysInstallCb(h, tlp, "sel",  prp, "in",  NULL );
207
-  cmDspSysInstallCb(h, sfp, "out",  prp, "in",     NULL );
208
-
209
-  cmDspSysInstallCb(h, sfp, "even", pre, "in", NULL );
210
-  cmDspSysInstallCb(h, sfp, "dyn",  prd, "in", NULL );
211
-  cmDspSysInstallCb(h, sfp, "tempo",prt, "in", NULL );
212
-  //cmDspSysInstallCb(h, modp,"v0",   prv, "in", NULL );
213
-  //cmDspSysInstallCb(h, modp,"v1",   prv, "in", NULL );
214
-  //cmDspSysInstallCb(h, modp,"v2",   prv, "in", NULL );
215 246
 
247
+  cmDspSysInstallCb(h, modp, "mod0", md0p, "val", NULL );
248
+  cmDspSysInstallCb(h, modp, "win0", kr0p, "wndn",NULL );
249
+  cmDspSysInstallCb(h, modp, "thr0", th0p, "val", NULL );
250
+  cmDspSysInstallCb(h, modp, "upr0", us0p, "val", NULL );
251
+  cmDspSysInstallCb(h, modp, "lwr0", ls0p, "val", NULL );
252
+  cmDspSysInstallCb(h, modp, "off0", of0p, "val", NULL );
253
+  cmDspSysInstallCb(h, modp, "inv0", iv0p, "val", NULL );
254
+  cmDspSysInstallCb(h, modp, "wet0", wet0, "val", NULL );
255
+  cmDspSysInstallCb(h, modp, "xf0", xfad, "gate-0", NULL );
256
+
257
+  cmDspSysInstallCb(h, modp, "mod1", md1p, "val", NULL );
258
+  cmDspSysInstallCb(h, modp, "win1", kr1p, "wndn",NULL );
259
+  cmDspSysInstallCb(h, modp, "thr1", th1p, "val", NULL );
260
+  cmDspSysInstallCb(h, modp, "upr1", us1p, "val", NULL );
261
+  cmDspSysInstallCb(h, modp, "lwr1", ls1p, "val", NULL );
262
+  cmDspSysInstallCb(h, modp, "off1", of1p, "val", NULL );
263
+  cmDspSysInstallCb(h, modp, "inv1", iv1p, "val", NULL );
264
+  cmDspSysInstallCb(h, modp, "wet1", wet1, "val", NULL );
265
+  cmDspSysInstallCb(h, modp, "xf1", xfad, "gate-1", NULL );
216 266
 
217
-  cmDspSysInstallCb(h, prtb, "sym", sfp, "cmd", NULL );
218
-  cmDspSysInstallCb(h, qtb,  "sym", sfp, "cmd", NULL );
219 267
   
220 268
   return rc;
221 269
 }
270
+
271
+cmDspRC_t _cmDspSysPgm_Switcher(cmDspSysH_t h, void** userPtrPtr )
272
+{
273
+  cmDspRC_t rc = kOkDspRC;
274
+
275
+  const char*     fn0          = "media/audio/20110723-Kriesberg/Audio Files/Piano 3_01.wav";
276
+  const cmChar_t* fn           = cmFsMakeFn(cmFsUserDir(),fn0,NULL,NULL );
277
+
278
+  bool   bypassFl   = false;
279
+  double inGain     = 1.0;
280
+  double dsrate     = 96000.0;
281
+  double bits       = 24.0;
282
+  bool   rectifyFl  = false;
283
+  bool   fullRectFl = false;
284
+  double clipDb     = -10.0;
285
+
286
+  double cfMinHz    = 20.0;
287
+  double cfHz       = 1000.0;
288
+  double cfAlpha    = 0.9;
289
+  bool   cfFbFl     = true;
290
+  bool   cfBypassFl = false;
291
+
292
+  unsigned outChCnt = 2;
293
+  double   xfadeMs  = 250;
294
+
295
+
296
+  cmDspInst_t* gsw = cmDspSysAllocInst(h,"GSwitch", NULL, 2, 12,2 );
297
+
298
+  cmDspInst_t* ofp =  cmDspSysAllocInst(h,"Scalar", "Offset",  5, kNumberDuiId, 0.0,  cmDspSysSampleRate(h)*600.0, 1.0,  6900000.0);
299
+  cmDspInst_t* fnp =  cmDspSysAllocInst(h,"Fname",    NULL,  3, false,"Audio Files (*.wav,*.aiff,*.aif)\tAudio Files (*.{wav,aiff,aif})",fn);
300
+  cmDspInst_t* php =  cmDspSysAllocInst(h,"Phasor",   NULL,  0 );
301
+  cmDspInst_t* wtp =  cmDspSysAllocInst(h,"WaveTable",NULL,  2, ((int)cmDspSysSampleRate(h)), 1 );
302
+
303
+  cmDspInst_t* dst =  cmDspSysAllocInst(h,"DistDs",   NULL, 3, bypassFl, inGain, dsrate, bits  ); 
304
+  cmDspInst_t* cf  = cmDspSysAllocInst( h,"CombFilt", NULL, 5, cfBypassFl, cfMinHz, cfFbFl, cfMinHz, cfAlpha );
305
+  
306
+  cmDspInst_t* xfad  = cmDspSysAllocInst(h,"Xfader", NULL,    2, outChCnt, xfadeMs );
307
+
308
+
309
+  cmDspInst_t* ao0p = cmDspSysAllocInst(h,"AudioOut",NULL,   1, 0 );
310
+  cmDspInst_t* ao1p = cmDspSysAllocInst(h,"AudioOut",NULL,   1, 1 );
311
+
312
+
313
+  cmDspInst_t* ign   = cmDspSysAllocScalar( h, "In Gain",      0.0, 10.0, 0.01, 1.0);
314
+  cmDspInst_t* rct   = cmDspSysAllocCheck(  h, "Rectify",   rectifyFl);
315
+  cmDspInst_t* ful   = cmDspSysAllocCheck(  h, "Full/Half", fullRectFl);
316
+  cmDspInst_t* dsr   = cmDspSysAllocScalar( h, "Srate",        0.0, 96000, 1.0, dsrate);
317
+  cmDspInst_t* dbt   = cmDspSysAllocScalar( h, "bits",         2.0,  32.0, 1.0, bits);
318
+  cmDspInst_t* clip  = cmDspSysAllocScalar( h, "Clip dB",   -100.0,   0.0, 0.1, clipDb);
319
+  cmDspInst_t* ogn   = cmDspSysAllocScalar( h, "Out Gain",    0.0, 10.0, 0.01, 1.0);
320
+
321
+  cmDspInst_t* cfhz    = cmDspSysAllocScalar( h, "CF Hz",     25, 10000, 1, cfHz );
322
+  cmDspInst_t* cfalpha = cmDspSysAllocScalar( h, "CF Alpha",   0.0, 2.0, 0.001, cfAlpha);
323
+  cmDspInst_t* cfgain  = cmDspSysAllocScalar( h, "CF Gain",    0.0, 20.0, 0.001, 1.0);
324
+  cmDspInst_t* cffb    = cmDspSysAllocInst(   h,"Button", "CF Fb",  2, kCheckDuiId, 0.0 );
325
+
326
+  cmDspInst_t* dfdb    = cmDspSysAllocInst(   h,"Button", "Dist Fade",  2, kCheckDuiId, 0.0 );
327
+  cmDspInst_t* cfdb    = cmDspSysAllocInst(   h,"Button", "CF Fade",  2, kCheckDuiId, 0.0 );
328
+
329
+
330
+  if((rc = cmDspSysLastRC(h)) != kOkDspRC )
331
+    return rc;
332
+  
333
+  cmDspSysConnectAudio(h, php, "out", wtp,  "phs" );  // phasor -> wave table
334
+
335
+  cmDspSysConnectAudio(h, wtp, "out",  dst,  "in" );   // wt   -> dist
336
+  cmDspSysConnectAudio(h, dst, "out",  xfad, "in-0");  // dist -> xfad
337
+  cmDspSysConnectAudio(h, xfad,"out-0",ao0p, "in" );   // xfad -> aout
338
+
339
+  cmDspSysConnectAudio(h, wtp, "out",  cf,   "in" );   // wt   -> xfad
340
+  cmDspSysConnectAudio(h, cf,  "out",  xfad, "in-1");  // xfad -> cf
341
+  cmDspSysConnectAudio(h, xfad,"out-1",ao1p, "in" );   // cf   -> aout 
342
+
343
+  cmDspSysInstallCb(h, ofp, "val", wtp, "beg", NULL ); // offset -> wavetable
344
+  cmDspSysInstallCb(h, fnp, "out", wtp, "fn", NULL);   // filename -> wavetable  
345
+
346
+
347
+  // Distortion control connections
348
+  cmDspSysInstallCb(h, ign,  "val", dst, "igain", NULL );
349
+  cmDspSysInstallCb(h, dsr,  "val", dst, "srate", NULL );
350
+  cmDspSysInstallCb(h, dbt,  "val", dst, "bits", NULL );
351
+  cmDspSysInstallCb(h, rct,  "out", dst, "rect", NULL );
352
+  cmDspSysInstallCb(h, ful,  "out", dst, "full", NULL );
353
+  cmDspSysInstallCb(h, clip, "val", dst, "clip", NULL );
354
+
355
+  cmDspSysInstallCb(h, ogn,  "val", dst, "ogain", NULL );
356
+
357
+  cmDspSysInstallCb(h, cfhz,    "val", cf, "hz",    NULL );  
358
+  cmDspSysInstallCb(h, cfalpha, "val", cf, "alpha", NULL );
359
+  cmDspSysInstallCb(h, cffb,    "out", cf, "fb",    NULL );
360
+  cmDspSysInstallCb(h, cfgain,  "val", ao1p, "gain", NULL );
361
+
362
+  cmDspSysInstallCb(h, dfdb, "out", xfad, "gate-0", NULL);
363
+  cmDspSysInstallCb(h, cfdb, "out", xfad, "gate-1", NULL);
364
+
365
+  return cmDspSysLastRC(h);
366
+}
367
+

+ 1
- 0
dsp/cmDspPgmKr.h View File

@@ -6,6 +6,7 @@ extern "C" {
6 6
 #endif
7 7
 
8 8
   cmDspRC_t _cmDspSysPgm_TimeLine( cmDspSysH_t h, void** userPtrPtr );
9
+  cmDspRC_t _cmDspSysPgm_Switcher( cmDspSysH_t h, void** userPtrPtr );
9 10
 
10 11
 #ifdef __cplusplus
11 12
   }

+ 179
- 0
dsp/cmDspStore.c View File

@@ -0,0 +1,179 @@
1
+#include "cmPrefix.h"
2
+#include "cmGlobal.h"
3
+#include "cmFloatTypes.h"
4
+#include "cmRpt.h"
5
+#include "cmErr.h"
6
+#include "cmCtx.h"
7
+#include "cmMem.h"
8
+#include "cmMallocDebug.h"
9
+#include "cmLinkedHeap.h"
10
+#include "cmSymTbl.h"
11
+#include "cmJson.h"
12
+#include "cmDspValue.h"
13
+#include "cmDspCtx.h"
14
+#include "cmDspClass.h"
15
+#include "cmDspStore.h"
16
+
17
+typedef struct
18
+{
19
+  unsigned     symId;
20
+  cmDspValue_t value;
21
+} cmDspStoreVar_t;
22
+
23
+typedef struct 
24
+{
25
+  cmErr_t          err;
26
+  cmDspStoreVar_t* array;
27
+  unsigned         allocCnt;
28
+  unsigned         growCnt;
29
+  unsigned         curCnt;
30
+} cmDspStore_t;
31
+
32
+
33
+cmDspStoreH_t cmDspStoreNullHandle = cmSTATIC_NULL_HANDLE;
34
+
35
+cmDspStore_t* _cmDspStoreHandleToPtr( cmDspStoreH_t h )
36
+{
37
+  cmDspStore_t* p = (cmDspStore_t*)h.h;
38
+  assert( p != NULL );
39
+  return p;
40
+}
41
+
42
+cmDspRC_t _cmDspStoreFree( cmDspStore_t* p )
43
+{
44
+  cmMemFree(p->array);
45
+  cmMemFree(p);
46
+  return kOkDspRC;
47
+}
48
+
49
+
50
+cmDspRC_t cmDspStoreAlloc( cmCtx_t* ctx, cmDspStoreH_t* hp, unsigned initStoreCnt, unsigned growStoreCnt )
51
+{
52
+  cmDspRC_t rc;
53
+  if((rc = cmDspStoreFree(hp)) != kOkDspRC )
54
+    return rc;
55
+
56
+  cmDspStore_t* p = cmMemAllocZ(cmDspStore_t,1);
57
+
58
+  cmErrSetup(&p->err,&ctx->rpt,"cmDspStore");
59
+
60
+  p->array    = cmMemAllocZ(cmDspStoreVar_t,initStoreCnt);
61
+  p->allocCnt = initStoreCnt;
62
+  p->curCnt   = 0;
63
+  p->growCnt  = growStoreCnt;
64
+
65
+  hp->h = p;
66
+
67
+  return rc;
68
+}
69
+  
70
+cmDspRC_t cmDspStoreFree( cmDspStoreH_t *hp )
71
+{
72
+  cmDspRC_t rc = kOkDspRC;
73
+  if(hp==NULL || cmDspStoreIsValid(*hp)==false )
74
+    return rc;
75
+
76
+  cmDspStore_t* p = _cmDspStoreHandleToPtr(*hp);
77
+
78
+  if((rc = _cmDspStoreFree(p)) != kOkDspRC )
79
+    return rc;
80
+
81
+  hp->h = NULL;
82
+
83
+  return rc;
84
+}
85
+
86
+bool      cmDspStoreIsValid( cmDspStoreH_t h )
87
+{ return h.h; }
88
+
89
+
90
+cmDspStoreVar_t*  _cmDspStoreSymToPtr( cmDspStore_t* p, unsigned symId )
91
+{
92
+  cmDspStoreVar_t* vp = p->array;
93
+  cmDspStoreVar_t* ep = p->array + p->curCnt;
94
+  for(; vp<ep; ++vp)
95
+    if( vp->symId == symId )
96
+      return vp;
97
+  return NULL;
98
+}
99
+
100
+cmDspStoreVar_t*  _cmDspStoreIdToPtr( cmDspStore_t* p, unsigned id )
101
+{
102
+  if( id < p->curCnt )
103
+    return p->array + id;
104
+ 
105
+  return NULL;
106
+}
107
+
108
+cmDspStoreVar_t* _cmDspStoreAppend( cmDspStore_t* p )
109
+{
110
+  cmDspStoreVar_t* vp = NULL;
111
+
112
+  if( p->curCnt >= p->allocCnt )
113
+  {
114
+    p->allocCnt += p->growCnt;
115
+    p->array = cmMemResizePZ(cmDspStoreVar_t,p->array,p->allocCnt);
116
+  }
117
+
118
+  vp = p->array + p->curCnt;
119
+
120
+  p->curCnt += 1;
121
+
122
+  return vp;
123
+}
124
+  
125
+unsigned  cmDspStoreSymToId( cmDspStoreH_t h, unsigned symId )
126
+{
127
+  cmDspStore_t* p = _cmDspStoreHandleToPtr(h);
128
+  const cmDspStoreVar_t* vp;
129
+  if((vp = _cmDspStoreSymToPtr(p,symId)) == NULL )
130
+    return cmInvalidId;
131
+  return vp - p->array;
132
+}
133
+
134
+unsigned  cmDspStoreIdToSym( cmDspStoreH_t h, unsigned id )
135
+{
136
+  cmDspStore_t* p = _cmDspStoreHandleToPtr(h);
137
+  const cmDspStoreVar_t* vp;
138
+  if((vp = _cmDspStoreIdToPtr(p,id)) == NULL )
139
+    return cmInvalidId;
140
+  return vp->symId;
141
+}
142
+
143
+const cmDspValue_t*  cmDspStoreIdToValue( cmDspStoreH_t h, unsigned id )
144
+{
145
+  cmDspStore_t* p = _cmDspStoreHandleToPtr(h);
146
+  const cmDspStoreVar_t* vp;
147
+  if((vp = _cmDspStoreIdToPtr(p,id)) == NULL )
148
+    return NULL;
149
+  return &vp->value;
150
+}
151
+
152
+cmDspRC_t cmDspStoreSetValueViaId(  cmDspStoreH_t h, unsigned id, const cmDspValue_t* val )
153
+{
154
+  cmDspRC_t rc = kOkDspRC;
155
+  cmDspStore_t*     p = _cmDspStoreHandleToPtr(h);
156
+  cmDspStoreVar_t* vp = NULL;
157
+
158
+  if((vp = _cmDspStoreIdToPtr(p,id)) == NULL )
159
+    return cmErrMsg(&p->err,kVarNotFoundDspRC,"There is not global variable at with id:%i\n",id);
160
+
161
+  cmDsvCopy(&vp->value,val);    
162
+  return rc;
163
+}
164
+
165
+unsigned cmDspStoreSetValueViaSym( cmDspStoreH_t h, unsigned symId, const cmDspValue_t* val )
166
+{
167
+  cmDspStore_t*     p = _cmDspStoreHandleToPtr(h);
168
+  cmDspStoreVar_t* vp = NULL;
169
+
170
+  if((vp = _cmDspStoreSymToPtr(p,symId)) == NULL )
171
+    vp = _cmDspStoreAppend(p);
172
+
173
+  assert(vp != NULL );
174
+
175
+  cmDsvCopy(&vp->value,val);    
176
+  vp->symId = symId;
177
+
178
+  return vp - p->array;
179
+}

+ 30
- 0
dsp/cmDspStore.h View File

@@ -0,0 +1,30 @@
1
+#ifndef cmDspStore_h
2
+#define cmDspStore_h
3
+
4
+#ifdef __cplusplus
5
+extern "C" {
6
+#endif
7
+
8
+  extern cmDspStoreH_t cmDspStoreNullHandle;
9
+
10
+  cmDspRC_t cmDspStoreAlloc( cmCtx_t* ctx, cmDspStoreH_t* hp, unsigned initStoreCnt, unsigned growStoreCnt );
11
+  
12
+  cmDspRC_t cmDspStoreFree( cmDspStoreH_t *hp );
13
+
14
+  bool      cmDspStoreIsValid( cmDspStoreH_t h );
15
+  
16
+  unsigned  cmDspStoreSymToId( cmDspStoreH_t h, unsigned symId );
17
+  unsigned  cmDspStoreIdToSym( cmDspStoreH_t h, unsigned id );
18
+  const cmDspValue_t*  cmDspStoreIdToValue( cmDspStoreH_t h, unsigned id );
19
+
20
+  cmDspRC_t cmDspStoreSetValueViaId(  cmDspStoreH_t h, unsigned id,    const cmDspValue_t* val );
21
+
22
+  // Sets the variable to the value (and creates it if it does not exist).
23
+  // Returns the 'id' of the variable.
24
+  unsigned cmDspStoreSetValueViaSym( cmDspStoreH_t h, unsigned symId, const cmDspValue_t* val );
25
+
26
+#ifdef __cplusplus
27
+  }
28
+#endif
29
+
30
+#endif

+ 11
- 0
dsp/cmDspSys.c View File

@@ -21,6 +21,7 @@
21 21
 #include "cmProcObj.h"
22 22
 #include "cmDspCtx.h"
23 23
 #include "cmDspClass.h"
24
+#include "cmDspStore.h"
24 25
 #include "cmDspSys.h"
25 26
 #include "cmDspBuiltIn.h"
26 27
 #include "cmDspPgm.h"
@@ -140,6 +141,8 @@ cmDspRC_t _cmDspSysFinalize( cmDsp_t* p )
140 141
     if( cmCtxFree(&p->ctx.cmProcCtx) != cmOkRC )
141 142
       rc = cmErrMsg(&p->err,kProcFailDspRC,"The proc context finalizatoin failed.");
142 143
 
144
+  cmDspStoreFree(&p->dsH);
145
+
143 146
   if( cmSymTblIsValid(p->stH) ) 
144 147
     cmSymTblDestroy(&p->stH);
145 148
 
@@ -195,6 +198,13 @@ cmDspRC_t cmDspSysInitialize( cmCtx_t* ctx, cmDspSysH_t* hp, cmUdpNetH_t netH )
195 198
     goto errLabel;
196 199
   }
197 200
 
201
+  // allocate the DSP system variable storage object
202
+  if( cmDspStoreAlloc(ctx,&p->dsH,10,10) != kOkDspRC )
203
+  {
204
+    rc = cmErrMsg(&p->err,kDspStoreFailDspRC,"DSP store allocation failed.");
205
+    goto errLabel;
206
+  }
207
+
198 208
   // initialize the proc context
199 209
   if( (p->ctx.cmProcCtx = cmCtxAlloc(NULL,&ctx->rpt,p->lhH,p->stH)) == NULL )
200 210
   {
@@ -214,6 +224,7 @@ cmDspRC_t cmDspSysInitialize( cmCtx_t* ctx, cmDspSysH_t* hp, cmUdpNetH_t netH )
214 224
   p->ctx.lhH     = p->lhH;
215 225
   p->ctx.jsH     = p->jsH;
216 226
   p->ctx.stH     = p->stH;
227
+  p->ctx.dsH     = p->dsH;
217 228
   p->ctx.rsrcJsH = cmJsonNullHandle;
218 229
   p->ctx.rpt     = &ctx->rpt;
219 230
   p->ctx.cmCtx   = &p->cmCtx;

Loading…
Cancel
Save