Browse Source

Merge branch 'develop'

master
kevin 3 years ago
parent
commit
41ccb0f178

+ 17
- 0
.gitignore View File

@@ -1,3 +1,20 @@
1 1
 Makefile.in
2 2
 .DS_Store
3
+aclocal.m4
4
+config.h.in
5
+config.h.in~
6
+configure
7
+Makefile.in
8
+
9
+autom4te.cache
10
+build-aux
11
+
12
+m4/libtool.m4
13
+m4/lt~obsolete.m4
14
+m4/libtool.m4
15
+m4/ltoptions.m4
16
+m4/ltsugar.m4
17
+m4/ltversion.m4
18
+m4/lt~obsolete.m4
19
+m4/.DS_Store
3 20
 

+ 13
- 10
Makefile.am View File

@@ -111,10 +111,10 @@ endif
111 111
 
112 112
 lib_LTLIBRARIES=
113 113
 include_HEADERS=
114
-
114
+AM_LDFLAGS=
115 115
 
116 116
 AM_CPPFLAGS = -D _GNU_SOURCE  -I.. -I$(srcdir)/src  -I$(srcdir)/src/dsp  -I$(srcdir)/src/vop  -I$(srcdir)/src/app
117
-AM_CFLAGS   = -Wno-multichar 
117
+AM_CFLAGS   = -Wall -Wno-multichar 
118 118
 AM_CXXFLAGS = 
119 119
 
120 120
 # debug/release switches
@@ -128,6 +128,7 @@ endif
128 128
 
129 129
 # Linux specific compiler flags
130 130
 if OS_LINUX
131
+  AM_LDFLAGS += -lasound  # why add this link flag? here's why: https://stackoverflow.com/questions/35480928/alsa-unexpected-results-when-called-from-shared-library
131 132
 if OS_64
132 133
   AM_CFLAGS  += -m64
133 134
 endif	
@@ -143,13 +144,15 @@ src_libcm_la_SOURCES   = $(cmSRC) $(cmHDR)
143 144
 include_HEADERS += $(cmHDR)
144 145
 lib_LTLIBRARIES += src/libcm.la
145 146
 
146
-
147
-# distclean-local sets the source tree back to it's minimal, pre-configure, state.
147
+# See: https://www.gnu.org/savannah-checkouts/gnu/automake/manual/html_node/Clean.html#Clean
148
+# 'distclean-local' is used by automake 'distclean' to perform customized local actions
149
+# ${exec_prefix} is the install prefix given to 'configure' by the user.
150
+# ${srcdir} is the directory of this Makefile and is set by autoconf.
148 151
 distclean-local:
149 152
 	rm -rf ${exec_prefix}/src        
150
-	rm -rf ${srcdir}/autom4te.cache
151
-	rm -rf ${srcdir}/build-aux
152
-	rm -f  ${srcdir}/m4/libtool.m4   ${srcdir}/m4/lt~obsolete.m4 ${srcdir}/m4/ltsugar.m4
153
-	rm -f  ${srcdir}/m4/ltversion.m4 ${srcdir}/m4/ltoptions.m4
154
-	rm -f  ${srcdir}/aclocal.m4      ${srcdir}/config.h.in ${srcdir}/config.h.in~
155
-	rm -f  ${srcdir}/Makefile.in     ${srcdir}/configure
153
+	rm -rf ${exec_prefix}/lib        
154
+	rm -rf ${exec_prefix}/include
155
+
156
+maintainer-clean-local:
157
+	${srcdir}/config.h.in~
158
+

+ 3
- 0
README.md View File

@@ -0,0 +1,3 @@
1
+
2
+libcm is a C application development framework with an emphasis on audio signal processing.
3
+

+ 9
- 8
build/clean.sh View File

@@ -14,9 +14,9 @@ function clean_dir {
14 14
     
15 15
     rm -f  $1/bin/kc.app/Contents/MacOS/kc
16 16
     
17
-    rm -rf $1/include
18
-    rm -rf $1/lib
19
-    rm -rf $1/bin
17
+    #rm -rf $1/include
18
+    #rm -rf $1/lib
19
+    #rm -rf $1/bin
20 20
     rm -rf $1/.deps
21 21
     
22 22
 }
@@ -30,11 +30,12 @@ clean_dir osx/release
30 30
 
31 31
 rm -rf osx/debug/a.out.dSYM
32 32
 
33
-
34
-#rm -rf ../octave/results
35
-
36
-# remove all of emacs backup files (files ending width '~')
37
-# find ../ -name "*~" -exec rm {} \; 
33
+# delete everything created by 'autoreconf'.
34
+rm -rf ../build-aux
35
+rm -rf ../autom4te.cache
36
+rm -f  ../config.h.in ../config.h.in~ ../configure ../libtool.m4
37
+rm -f  ../Makefile.in ../aclocal.m4
38
+rm -f  ../m4/libtool.m4 ../m4/ltoptions.m4 ../m4/ltsugar.m4 ../m4/ltversion.m4 ../m4/lt~obsolete.m4
38 39
 
39 40
 
40 41
 

+ 2
- 1
src/app/cmMidiScoreFollow.c View File

@@ -149,6 +149,7 @@ unsigned _cmMsf_WriteMatchFileLine( cmFileH_t fH, cmScH_t scH, const cmScMatcher
149 149
   return scUid;
150 150
 }
151 151
 
152
+// This is the score follower callback function 
152 153
 void _cmMsf_ScoreFollowCb( struct cmScMatcher_str* p, void* arg, cmScMatcherResult_t* rp )
153 154
 {
154 155
   _cmMsf_ScoreFollow_t* r = (_cmMsf_ScoreFollow_t*)arg;
@@ -193,7 +194,7 @@ cmMsfRC_t cmMidiScoreFollowMain(
193 194
     goto errLabel;
194 195
   }
195 196
 
196
-  // setup the callback record
197
+  // setup the callback record with an array that has twice as many records as there are score events
197 198
   if((sfr.rAllocN  = cmScoreEvtCount( scH )*2) == 0)
198 199
   {
199 200
     rc = cmErrMsg(&err,kFailMsfRC,"The score %s appears to be empty.",cmStringNullGuard(scoreCsvFn));

+ 1
- 1
src/app/cmTakeSeqBldr.c View File

@@ -960,7 +960,7 @@ cmTsbRC_t cmTakeSeqBldrLoadTake( cmTakeSeqBldrH_t h, unsigned tlMarkUid, bool ov
960 960
   //cmMidiFileTickToSamples( mfH, cmTimeLineSampleRate(p->tlH), false );
961 961
   
962 962
   // calculate MIDI note and pedal durations (see cmMidiChMsg_t.durTicks)
963
-  cmMidiFileCalcNoteDurations( mfH );
963
+  cmMidiFileCalcNoteDurations( mfH, 0 );
964 964
   
965 965
   unsigned                 i     = 0;
966 966
   unsigned                 n     = cmMidiFileMsgCount(mfH);

+ 1
- 1
src/app/cmTimeLine.c View File

@@ -733,7 +733,7 @@ cmTlRC_t _cmTlAllocMidiFileRecd( _cmTl_t* p, const cmChar_t* nameStr, const cmCh
733 733
   //cmMidiFileTickToSamples(mfH,p->srate,false);
734 734
 
735 735
   // assign note durations to all note-on msg's
736
-  cmMidiFileCalcNoteDurations(mfH);
736
+  cmMidiFileCalcNoteDurations(mfH,0);
737 737
 
738 738
   unsigned recdByteCnt = sizeof(cmTlMidiFile_t) + strlen(fn) + 1;
739 739
 

+ 619
- 87
src/app/cmXScore.c
File diff suppressed because it is too large
View File


+ 7
- 4
src/app/cmXScore.h View File

@@ -20,7 +20,8 @@ extern "C" {
20 20
     kFileFailXsRC,
21 21
     kSvgFailXsRC,
22 22
     kOverlapWarnXsRC,
23
-    kZeroLengthEventXsRC
23
+    kZeroLengthEventXsRC,
24
+    kEventNotFoundXsRC
24 25
   };
25 26
 
26 27
   typedef cmRC_t     cmXsRC_t;
@@ -47,7 +48,7 @@ extern "C" {
47 48
   // Initialize an cmXScore object from a Sibelius generated MusicXML file.
48 49
   // 'editFn' is used to add additional information to the score.
49 50
   // See cmXScoreGenEditFile()
50
-  cmXsRC_t cmXScoreInitialize( cmCtx_t* ctx, cmXsH_t* hp, const cmChar_t* xmlFn, const cmChar_t* editFn );
51
+  cmXsRC_t cmXScoreInitialize( cmCtx_t* ctx, cmXsH_t* hp, const cmChar_t* xmlFn, const cmChar_t* editFn, bool damperRptFl );
51 52
   cmXsRC_t cmXScoreFinalize( cmXsH_t* hp );
52 53
 
53 54
   
@@ -60,7 +61,7 @@ extern "C" {
60 61
   // Generate a template 'edit file'. This file can be edited by hand to included additional
61 62
   // information in the score. See the 'editFn' argument to cmXScoreInitialize() for where
62 63
   // this file is used.
63
-  cmXsRC_t cmXScoreGenEditFile( cmCtx_t* ctx, const cmChar_t* xmlFn, const cmChar_t* outFn );
64
+  cmXsRC_t cmXScoreGenEditFile( cmCtx_t* ctx, const cmChar_t* xmlFn, const cmChar_t* outFn, bool damperRptFl );
64 65
 
65 66
   // Generate the CSV file suitable for use by cmScore.
66 67
   //
@@ -72,7 +73,9 @@ extern "C" {
72 73
   // Set reportFl to true to print a report of the score following processing.
73 74
   // Set begMeasNumb to the first measure the to be written to the output csv, MIDI and SVG files.
74 75
   // Set begBPM to 0 to use the tempo from the score otherwise set it to the tempo at begMeasNumb.
75
-  cmXsRC_t cmXScoreTest( cmCtx_t* ctx, const cmChar_t* xmlFn, const cmChar_t* reorderFn, const cmChar_t* csvOutFn, const cmChar_t* midiOutFn, const cmChar_t* svgOutFn, bool reportFl, int begMeasNumb, int begBPM, bool svgStandAloneFl, bool svgPanZoomFl );
76
+  cmXsRC_t cmXScoreTest( cmCtx_t* ctx, const cmChar_t* xmlFn, const cmChar_t* reorderFn, const cmChar_t* csvOutFn, const cmChar_t* midiOutFn, const cmChar_t* svgOutFn, bool reportFl, int begMeasNumb, int begBPM, bool svgStandAloneFl, bool svgPanZoomFl, bool damperRptFl );
77
+
78
+  cmXsRC_t cmXScoreMergeEditFiles( cmCtx_t* ctx, const cmChar_t* xmlFn, const cmChar_t* refEditFn,  unsigned refBegMeasNumb, const cmChar_t* editFn, unsigned keyMeasNumb, const cmChar_t* outFn );
76 79
   
77 80
 #ifdef __cplusplus
78 81
 }

+ 44
- 3
src/cmAudDsp.c View File

@@ -354,10 +354,15 @@ cmAdRC_t _cmAdParseSysJsonTree( cmAd_t* p )
354 354
     {
355 355
       cmAudioSysArgs_t*   asap        = &p->asCfgArray[i].cfg.ssArray[j].args;
356 356
       const cmJsonNode_t* argsNodePtr = cmJsonArrayElementC(ssArrayNodePtr,j);
357
+      
358
+      asap->inDevIdx    = cmInvalidIdx;
359
+      asap->outDevIdx   = cmInvalidIdx;
360
+      asap->inDevLabel  = NULL;
361
+      asap->outDevLabel = NULL;
357 362
 
358 363
       if((jsRC = cmJsonMemberValues( argsNodePtr, &errLabelPtr,
359
-          "inDevIdx",           kIntTId,  &asap->inDevIdx,
360
-          "outDevIdx",          kIntTId,  &asap->outDevIdx,
364
+          "inDevLabel",         kStringTId,  &asap->inDevLabel,
365
+          "outDevLabel",        kStringTId,  &asap->outDevLabel,
361 366
           "syncToInputFl",      kTrueTId, &asap->syncInputFl,
362 367
           "msgQueueByteCnt",    kIntTId,  &asap->msgQueueByteCnt,
363 368
           "devFramesPerCycle",  kIntTId,  &asap->devFramesPerCycle,
@@ -443,6 +448,35 @@ cmAdRC_t _cmAdCreateAggDevices( cmAd_t* p )
443 448
   return rc;
444 449
 }
445 450
 
451
+cmAdRC_t _cmAdResolveDeviceLabels( cmAd_t* p )
452
+{
453
+  cmAdRC_t rc = kOkAdRC;
454
+  unsigned i,j;
455
+  
456
+  // for each cmAsAudioSysCfg record in audioSysCfgArray[]
457
+  for(i=0; i<p->asCfgCnt; ++i)
458
+  {
459
+    // for each audio system sub-subsystem 
460
+    for(j=0; j<p->asCfgArray[i].cfg.ssCnt; ++j)
461
+    {
462
+      cmAudioSysArgs_t*   asap        = &p->asCfgArray[i].cfg.ssArray[j].args;
463
+      if((asap->inDevIdx = cmApDeviceLabelToIndex( asap->inDevLabel )) == cmInvalidId )
464
+      {
465
+        rc = cmErrMsg(&p->err,kInvalidAudioDevIdxAdRC,"The audio input device '%s' could not be found.", cmStringNullGuard(asap->inDevLabel));
466
+        goto errLabel;
467
+      }
468
+      
469
+      if((asap->outDevIdx = cmApDeviceLabelToIndex( asap->outDevLabel )) == cmInvalidId )
470
+      {
471
+        rc = cmErrMsg(&p->err,kInvalidAudioDevIdxAdRC,"The audio input device '%s' could not be found.", cmStringNullGuard(asap->inDevLabel));
472
+        goto errLabel;
473
+      }
474
+    }
475
+  }
476
+ errLabel:
477
+  return rc;
478
+}
479
+
446 480
 cmAdRC_t _cmAdCreateNrtDevices( cmAd_t* p )
447 481
 {
448 482
   cmAdRC_t rc = kOkAdRC;
@@ -721,10 +755,11 @@ cmAdRC_t cmAudDspAlloc( cmCtx_t* ctx, cmAdH_t* hp, cmMsgSendFuncPtr_t cbFunc, vo
721 755
   if((rc = _cmAdParseSysJsonTree(p)) != kOkAdRC )
722 756
     goto errLabel;
723 757
 
758
+ 
724 759
   // create the aggregate device
725 760
   if( _cmAdCreateAggDevices(p) != kOkAdRC )
726 761
     goto errLabel;
727
-
762
+  
728 763
   // create the non-real-time devices
729 764
   if( _cmAdCreateNrtDevices(p) != kOkAdRC )
730 765
     goto errLabel;
@@ -740,6 +775,12 @@ cmAdRC_t cmAudDspAlloc( cmCtx_t* ctx, cmAdH_t* hp, cmMsgSendFuncPtr_t cbFunc, vo
740 775
     goto errLabel;
741 776
   }
742 777
 
778
+  if( _cmAdResolveDeviceLabels(p) != kOkApRC )
779
+  {
780
+    rc = cmErrMsg(&p->err,kAudioPortFailAdRC,"Audio device labels could not be resolved..");
781
+    goto errLabel;
782
+  }
783
+
743 784
   // initialize the audio buffer
744 785
   if( cmApBufInitialize( cmApDeviceCount(), p->meterMs ) != kOkApRC )
745 786
   {

+ 2
- 1
src/cmAudDsp.h View File

@@ -27,7 +27,8 @@ extern "C" {
27 27
     kAggDevCreateFailAdRC,
28 28
     kNrtDevSysFailAdRC,
29 29
     kAfpDevSysFailAdRC,
30
-    kNetSysFailAdRC
30
+    kNetSysFailAdRC,
31
+    kInvalidAudioDevIdxAdRC
31 32
   };
32 33
 
33 34
 

+ 4
- 0
src/cmAudioNrtDev.c View File

@@ -189,6 +189,10 @@ cmApRC_t cmApNrtAllocate( cmRpt_t* rpt )
189 189
 cmApRC_t cmApNrtFree()
190 190
 {
191 191
   cmApRC_t rc = kOkApRC;
192
+  
193
+  if( _cmNrt == NULL )
194
+    return rc;
195
+  
192 196
   cmApNrtDev_t* dp = _cmNrt->devs;
193 197
   while( dp != NULL )
194 198
   {

+ 12
- 10
src/cmAudioSys.h View File

@@ -130,16 +130,18 @@ extern "C" {
130 130
   // Audio device sub-sytem configuration record 
131 131
   typedef struct cmAudioSysArgs_str
132 132
   {
133
-    cmRpt_t*       rpt;               // system console object
134
-    unsigned       inDevIdx;          // input audio device
135
-    unsigned       outDevIdx;         // output audio device
136
-    bool           syncInputFl;       // true/false sync the DSP update callbacks with audio input/output
137
-    unsigned       msgQueueByteCnt;   // Size of the internal msg queue used to buffer msgs arriving via cmAudioSysDeliverMsg().
138
-    unsigned       devFramesPerCycle; // (512) Audio device samples per channel per device update buffer.
139
-    unsigned       dspFramesPerCycle; // (64)  Audio samples per channel per DSP cycle.
140
-    unsigned       audioBufCnt;       // (3)   Audio device buffers.
141
-    double         srate;             // Audio sample rate.
142
-    int            srateMult;         // Sample rate multiplication factor (negative for divide)
133
+    cmRpt_t*        rpt;               // system console object
134
+    const cmChar_t* inDevLabel;        // input audio device text label
135
+    const cmChar_t* outDevLabel;       // output audio device text label
136
+    unsigned        inDevIdx;          // input audio device index
137
+    unsigned        outDevIdx;         // output audio device index 
138
+    bool            syncInputFl;       // true/false sync the DSP update callbacks with audio input/output
139
+    unsigned        msgQueueByteCnt;   // Size of the internal msg queue used to buffer msgs arriving via cmAudioSysDeliverMsg().
140
+    unsigned        devFramesPerCycle; // (512) Audio device samples per channel per device update buffer.
141
+    unsigned        dspFramesPerCycle; // (64)  Audio samples per channel per DSP cycle.
142
+    unsigned        audioBufCnt;       // (3)   Audio device buffers.
143
+    double          srate;             // Audio sample rate.
144
+    int             srateMult;         // Sample rate multiplication factor (negative for divide)
143 145
   } cmAudioSysArgs_t;
144 146
 
145 147
   // Audio sub-system configuration record.

+ 1
- 1
src/cmDList.c View File

@@ -150,7 +150,7 @@ void _cmDListIndexFree( cmDList_t* p, cmDListIndex_t* x )
150 150
       // x is the first index
151 151
       if( x0 == NULL )
152 152
       {
153
-        assert( x1 = p->indexes );
153
+        assert( x1 == p->indexes );
154 154
         p->indexes = x->link;
155 155
       }
156 156
       else

+ 3
- 3
src/cmMidi.h View File

@@ -88,9 +88,9 @@ extern "C" {
88 88
 #define cmMidiIsStatus( s )   (kNoteOffMdId <= (s) /*&& ((unsigned)(s)) <= kSysRtResetMdId*/ )
89 89
 #define cmMidiIsChStatus( s ) (kNoteOffMdId <= (s) && (s) <  kSysExMdId)
90 90
 
91
-#define cmMidiIsNoteOn( s )      ( kNoteOnMdId <= (s) && (s) <= (kNoteOnMdId + kMidiChCnt) )
92
-#define cmMidiIsNoteOff( s, d1 ) ( (cmMidiIsNoteOn(s) && (d1)==0) || (kNoteOffMdId <= (s) && (s) <= (kNoteOffMdId + kMidiChCnt)) )
93
-#define cmMidiIsCtl( s )         ( kCtlMdId <= (s) && (s) <= (kCtlMdId + kMidiChCnt) )
91
+#define cmMidiIsNoteOn( s )      ( kNoteOnMdId <= (s) && (s) < (kNoteOnMdId + kMidiChCnt) )
92
+#define cmMidiIsNoteOff( s, d1 ) ( (cmMidiIsNoteOn(s) && (d1)==0) || (kNoteOffMdId <= (s) && (s) < (kNoteOffMdId + kMidiChCnt)) )
93
+#define cmMidiIsCtl( s )         ( kCtlMdId <= (s) && (s) < (kCtlMdId + kMidiChCnt) )
94 94
 
95 95
 #define cmMidiIsSustainPedal(     s, d0 )    ( kCtlMdId <= (s) && (s) <= (kCtlMdId + kMidiChCnt) && (d0)== kSustainCtlMdId )
96 96
 #define cmMidiIsSustainPedalDown( s, d0, d1) ( cmMidiIsSustainPedal(s,d0) && (d1)>=64 )

+ 130
- 26
src/cmMidiFile.c View File

@@ -423,6 +423,34 @@ cmMfRC_t _cmMidiFileReadHdr( _cmMidiFile_t* mfp )
423 423
   return rc;
424 424
 }
425 425
 
426
+void _cmMidiFileDrop( _cmMidiFile_t* p )
427
+{
428
+  unsigned i;
429
+  unsigned n = 0;
430
+  for(i=0; i<p->trkN; ++i)
431
+  {
432
+    _cmMidiTrack_t*   trk = p->trkV + i;
433
+    cmMidiTrackMsg_t* m0  = NULL;
434
+    cmMidiTrackMsg_t* m   = trk->base;
435
+    
436
+    for(; m!=NULL; m=m->link)
437
+    {
438
+      if( cmIsFlag(m->flags,kDropTrkMsgFl) )
439
+      {
440
+        ++n;
441
+        if( m0 == NULL )
442
+          trk->base = m->link;
443
+        else
444
+          m0->link = m->link;
445
+      }
446
+      else
447
+      {
448
+        m0 = m;
449
+      }      
450
+    }
451
+  }
452
+}
453
+
426 454
 int _cmMidiFileSortFunc( const void *p0, const void* p1 )
427 455
 {  
428 456
   if( (*(cmMidiTrackMsg_t**)p0)->atick == (*(cmMidiTrackMsg_t**)p1)->atick )
@@ -1369,7 +1397,6 @@ cmMfRC_t cmMidiFileInsertMsg( cmMidiFileH_t h, unsigned uid, int dtick, cmMidiBy
1369 1397
   mfp->msgVDirtyFl = true;
1370 1398
 
1371 1399
   return kOkMfRC;
1372
-
1373 1400
 }
1374 1401
 
1375 1402
 cmMfRC_t  cmMidiFileInsertTrackMsg( cmMidiFileH_t h, unsigned trkIdx, const cmMidiTrackMsg_t* msg )
@@ -1532,6 +1559,38 @@ unsigned  cmMidiFileSeekUsecs( cmMidiFileH_t h, unsigned long long offsUSecs, un
1532 1559
   return mi;
1533 1560
 }
1534 1561
 
1562
+/*
1563
+1.Move closest previous tempo msg to begin.
1564
+2.The first msg in each track must be the first msg >= begin.time
1565
+3.Remove all msgs > end.time - except the 'endMsg' for each note/pedal that is active at end time.
1566
+
1567
+
1568
+ */
1569
+
1570
+unsigned _cmMidiFileIsEndMsg( cmMidiTrackMsg_t* m, cmMidiTrackMsg_t** endMsgArray, unsigned n )
1571
+{
1572
+  unsigned i = 0;
1573
+  for(; i<n; ++i)
1574
+    if( endMsgArray[i] == m )
1575
+      return i;
1576
+
1577
+  return cmInvalidIdx;
1578
+}
1579
+
1580
+bool _cmMidiFileAllEndMsgFound( cmMidiTrackMsg_t** noteMsgArray, unsigned n0, cmMidiTrackMsg_t** pedalMsgArray, unsigned n1 )
1581
+{
1582
+  unsigned i=0;
1583
+  for(; i<n0; ++i)
1584
+    if( noteMsgArray[i] != NULL )
1585
+      return false;
1586
+
1587
+  for(i=0; i<n1; ++i)
1588
+    if( pedalMsgArray[i] != NULL )
1589
+      return false;
1590
+
1591
+  return true;
1592
+}
1593
+
1535 1594
 double  cmMidiFileDurSecs( cmMidiFileH_t h )
1536 1595
 {
1537 1596
   _cmMidiFile_t* mfp = _cmMidiFileHandleToPtr(h);
@@ -1544,14 +1603,6 @@ double  cmMidiFileDurSecs( cmMidiFileH_t h )
1544 1603
   return msgV[ mfp->msgN-1 ]->amicro / 1000000.0;
1545 1604
 }
1546 1605
 
1547
-typedef struct _cmMidiVoice_str
1548
-{
1549
-  const  cmMidiTrackMsg_t*  mp;
1550
-  unsigned                  durMicros;
1551
-  bool                      sustainFl;
1552
-  struct _cmMidiVoice_str*  link;
1553
-} _cmMidiVoice_t;
1554
-
1555 1606
 
1556 1607
 void _cmMidiFileSetDur( cmMidiTrackMsg_t* m0, cmMidiTrackMsg_t* m1 )
1557 1608
 {
@@ -1574,10 +1625,11 @@ bool _cmMidiFileCalcNoteDur( cmMidiTrackMsg_t* m0, cmMidiTrackMsg_t* m1, int not
1574 1625
   return true;
1575 1626
 }
1576 1627
 
1577
-void cmMidiFileCalcNoteDurations( cmMidiFileH_t h )
1628
+void cmMidiFileCalcNoteDurations( cmMidiFileH_t h, unsigned flags )
1578 1629
 {
1579 1630
   _cmMidiFile_t* p;
1580
-
1631
+  bool warningFl = cmIsFlag(flags,kWarningsMfFl);
1632
+  
1581 1633
   if((p = _cmMidiFileHandleToPtr(h)) == NULL )
1582 1634
     return;
1583 1635
 
@@ -1586,13 +1638,14 @@ void cmMidiFileCalcNoteDurations( cmMidiFileH_t h )
1586 1638
 
1587 1639
   unsigned          mi = cmInvalidId;
1588 1640
   cmMidiTrackMsg_t* noteM[     kMidiNoteCnt * kMidiChCnt ];  // ptr to note-on or NULL if the note is not sounding
1589
-  cmMidiTrackMsg_t* sustV[                    kMidiChCnt ];
1590
-  cmMidiTrackMsg_t* sostV[                    kMidiChCnt ];
1641
+  cmMidiTrackMsg_t* sustV[                    kMidiChCnt ];  // ptr to last sustain pedal down msg or NULL if susteain pedal is not down
1642
+  cmMidiTrackMsg_t* sostV[                    kMidiChCnt ];  // ptr to last sost. pedal down msg or NULL if sost. pedal is not down
1591 1643
   int               noteGateM[ kMidiNoteCnt * kMidiChCnt ];  // true if the associated note key is depressed
1592 1644
   bool              sostGateM[ kMidiNoteCnt * kMidiChCnt ];  // true if the associated note was active when the sost. pedal went down
1593 1645
   int               sustGateV[ kMidiChCnt];                  // true if the associated sustain pedal is down
1594 1646
   int               sostGateV[ kMidiChCnt];                  // true if the associated sostenuto pedal is down
1595 1647
   unsigned          i,j;
1648
+  unsigned          n = 0;
1596 1649
   
1597 1650
   const cmMidiTrackMsg_t** msgV = _cmMidiFileMsgArray(p);
1598 1651
   
@@ -1634,12 +1687,22 @@ void cmMidiFileCalcNoteDurations( cmMidiFileH_t h )
1634 1687
       unsigned  k = ch*kMidiNoteCnt + d0;
1635 1688
 
1636 1689
       // there should be no existing sounding note instance for this pitch
1637
-      //if( noteGateM[k] == 0 && noteM[k] != NULL )
1638
-      //  cmErrWarnMsg(&p->err,kMissingNoteOffMfRC,"%i : Missing note-off instance for note on:%s",m->uid,cmMidiToSciPitch(d0,NULL,0));
1690
+      if( noteGateM[k] == 0 && noteM[k] != NULL )
1691
+      {
1692
+        if( warningFl )
1693
+          cmErrWarnMsg(&p->err,kMissingNoteOffMfRC,"%i : Missing note-off instance for note on:%s",m->uid,cmMidiToSciPitch(d0,NULL,0));
1639 1694
 
1695
+        if( cmIsFlag(flags,kDropReattacksMfFl) )
1696
+        {
1697
+          m->flags |= kDropTrkMsgFl;
1698
+          n += 1;
1699
+        }
1700
+          
1701
+      }
1702
+      // if this is a re-attack 
1640 1703
       if( noteM[k] != NULL )
1641 1704
         noteGateM[k] += 1;
1642
-      else
1705
+      else // this is a new attack
1643 1706
       {
1644 1707
         noteM[k]     = m;
1645 1708
         noteGateM[k] = 1;
@@ -1676,8 +1739,8 @@ void cmMidiFileCalcNoteDurations( cmMidiFileH_t h )
1676 1739
         if( cmMidiFileIsSustainPedalDown(m) )
1677 1740
         {
1678 1741
           // if the sustain channel is already down
1679
-          //if( sustGateV[ch] )
1680
-          //  cmErrWarnMsg(&p->err,kSustainPedalMfRC,"%i : The sustain pedal went down twice with no intervening release.",m->uid);
1742
+          if( warningFl && sustGateV[ch] )
1743
+            cmErrWarnMsg(&p->err,kSustainPedalMfRC,"%i : The sustain pedal went down twice with no intervening release.",m->uid);
1681 1744
 
1682 1745
           sustGateV[ch] += 1;
1683 1746
 
@@ -1722,8 +1785,8 @@ void cmMidiFileCalcNoteDurations( cmMidiFileH_t h )
1722 1785
             if( cmMidiFileIsSostenutoPedalDown(m) )
1723 1786
             {
1724 1787
               // if the sustain channel is already down
1725
-              //if( sostGateV[ch] )
1726
-              //  cmErrWarnMsg(&p->err,kSostenutoPedalMfRC,"%i : The sostenuto pedal went down twice with no intervening release.",m->uid);
1788
+              if( warningFl && sostGateV[ch] )
1789
+                cmErrWarnMsg(&p->err,kSostenutoPedalMfRC,"%i : The sostenuto pedal went down twice with no intervening release.",m->uid);
1727 1790
 
1728 1791
               // record the notes that are active when the sostenuto pedal went down
1729 1792
               unsigned k = ch * kMidiNoteCnt;
@@ -1770,6 +1833,46 @@ void cmMidiFileCalcNoteDurations( cmMidiFileH_t h )
1770 1833
               }
1771 1834
     
1772 1835
   } // for each midi file event
1836
+
1837
+
1838
+  if( warningFl )
1839
+  {
1840
+    unsigned sustChN   = 0; // count of channels where the sustain pedal was left on at the end of the file
1841
+    unsigned sostChN   = 0; //                             sostenuto
1842
+    unsigned sustInstN = 0; // count of sustain   on with no previous sustain off
1843
+    unsigned sostInstN = 0; //          sostenuto on   
1844
+    unsigned noteN     = 0; // count of notes left on at the end of the file
1845
+    unsigned noteInstN = 0; // count of reattacks
1846
+    
1847
+    // initialize the state tracking variables
1848
+    for(i=0; i<kMidiChCnt; ++i)
1849
+    {
1850
+      if( sustV[i]!=NULL )
1851
+        sustChN += 1;
1852
+      
1853
+      sustInstN += sustGateV[i]; 
1854
+      
1855
+        if( sostV[i] != NULL )
1856
+          sostChN += 1;
1857
+      
1858
+      sostInstN += sostGateV[i] = 0;
1859
+      
1860
+      for(j=0; j<kMidiNoteCnt; ++j)
1861
+      {
1862
+        noteN     += noteM[ i*kMidiNoteCnt + j ] != NULL;
1863
+        noteInstN += noteGateM[ i*kMidiNoteCnt + j ];
1864
+      }
1865
+    }
1866
+
1867
+    cmErrWarnMsg(&p->err,kEventTerminationMfRC,"note:%i inst:%i sustain: %i inst: %i sost: %i inst: %i",noteN,noteInstN,sustChN,sustInstN,sostChN,sostInstN);
1868
+  }
1869
+
1870
+  // drop 
1871
+  if( cmIsFlag(flags,kDropReattacksMfFl) )
1872
+    _cmMidiFileDrop(p);
1873
+  
1874
+
1875
+
1773 1876
 }
1774 1877
 
1775 1878
 void cmMidiFileSetDelay( cmMidiFileH_t h, unsigned ticks )
@@ -1833,15 +1936,16 @@ void _cmMidiFilePrintHdr( const _cmMidiFile_t* mfp, cmRpt_t* rpt )
1833 1936
 
1834 1937
   cmRptPrintf(rpt,"fmt:%i ticksPerQN:%i tracks:%i\n",mfp->fmtId,mfp->ticksPerQN,mfp->trkN);
1835 1938
 
1836
-  cmRptPrintf(rpt," UID     dtick     atick      amicro     type  ch  D0  D1\n");
1837
-  cmRptPrintf(rpt,"----- ---------- ---------- ---------- : ---- --- --- ---\n");
1939
+  cmRptPrintf(rpt," UID  trk    dtick     atick      amicro     type  ch  D0  D1\n");
1940
+  cmRptPrintf(rpt,"----- --- ---------- ---------- ---------- : ---- --- --- ---\n");
1838 1941
   
1839 1942
 }
1840 1943
 
1841 1944
 void _cmMidiFilePrintMsg( cmRpt_t* rpt, const cmMidiTrackMsg_t* tmp )
1842 1945
 {
1843
-  cmRptPrintf(rpt,"%5i %10u %10llu %10llu : ",
1946
+  cmRptPrintf(rpt,"%5i %3i %10u %10llu %10llu : ",
1844 1947
     tmp->uid,
1948
+    tmp->trkIdx,
1845 1949
     tmp->dtick,
1846 1950
     tmp->atick,
1847 1951
     tmp->amicro );
@@ -1980,7 +2084,7 @@ cmMfRC_t cmMidiFileGenPlotFile( cmCtx_t* ctx, const cmChar_t* midiFn, const cmCh
1980 2084
     goto errLabel;
1981 2085
   }
1982 2086
   
1983
-  cmMidiFileCalcNoteDurations( mfH );
2087
+  cmMidiFileCalcNoteDurations( mfH, 0 );
1984 2088
   
1985 2089
   if( cmFileOpen(&fH,outFn,kWriteFileFl,p->err.rpt) != kOkFileRC )
1986 2090
     return cmErrMsg(&p->err,kFileFailMfRC,"Unable to create the file '%s'.",cmStringNullGuard(outFn));
@@ -2013,7 +2117,7 @@ cmMfRC_t cmMidiFileGenSvgFile( cmCtx_t* ctx, const cmChar_t* midiFn, const cmCha
2013 2117
     goto errLabel;
2014 2118
   }
2015 2119
 
2016
- cmMidiFileCalcNoteDurations( mfH );
2120
+  cmMidiFileCalcNoteDurations( mfH, 0 );
2017 2121
 
2018 2122
   msgN = cmMidiFileMsgCount(mfH);
2019 2123
   msgs = cmMidiFileMsgArray(mfH);
@@ -2159,7 +2263,7 @@ void cmMidiFileTest( const char* fn, cmCtx_t* ctx )
2159 2263
     return;
2160 2264
   }
2161 2265
 
2162
-  cmMidiFileCalcNoteDurations(  h );
2266
+  cmMidiFileCalcNoteDurations(  h, 0 );
2163 2267
 
2164 2268
   if( 1 )
2165 2269
   {

+ 19
- 8
src/cmMidiFile.h View File

@@ -63,11 +63,16 @@ extern "C" {
63 63
     struct cmMidiTrackMsg_str* end; // note-off or pedal-up message
64 64
   } cmMidiChMsg_t;
65 65
 
66
+  enum
67
+  {
68
+   kDropTrkMsgFl = 0x01
69
+  };
66 70
 
67 71
   typedef struct cmMidiTrackMsg_str
68 72
   {
73
+    unsigned                   flags;   // see k???TrkMsgFl
69 74
     unsigned                   uid;     // uid's are unique among all msg's in the file
70
-    unsigned                   dtick;   // delta ticks between events on this track
75
+    unsigned                   dtick;   // delta ticks between events on this track (ticks between this event and the previous event on this track)
71 76
     unsigned long long         atick;   // global (all tracks interleaved) accumulated ticks
72 77
     unsigned long long         amicro;  // global (all tracks interleaved) accumulated microseconds adjusted for tempo changes
73 78
     cmMidiByte_t               status;  // ch msg's have the channel value removed (it is stored in u.chMsgPtr->ch)
@@ -91,9 +96,12 @@ extern "C" {
91 96
     } u;
92 97
   } cmMidiTrackMsg_t;
93 98
 
94
-#define cmMidiFileIsNoteOn(m)         (cmMidiIsNoteOn((m)->status) && (m)->u.chMsgPtr->d1>0)
99
+#define cmMidiFileIsNoteOn(m)         (cmMidiIsNoteOn((m)->status) && ((m)->u.chMsgPtr->d1>0))
95 100
 #define cmMidiFileIsNoteOff(m)        (cmMidiIsNoteOff((m)->status,(m)->u.chMsgPtr->d1))
96
-  
101
+
102
+#define cmMidiFileIsPedalUp(m)        (cmMidiIsPedalUp(    (m)->status, (m)->u.chMsgPtr->d0, (m)->u.chMsgPtr->d1) )
103
+#define cmMidiFileIsPedalDown(m)      (cmMidiIsPedalDown(  (m)->status, (m)->u.chMsgPtr->d0, (m)->u.chMsgPtr->d1) )
104
+
97 105
 #define cmMidiFileIsSustainPedalUp(m)     (cmMidiIsSustainPedalUp(    (m)->status,(m)->u.chMsgPtr->d0,(m)->u.chMsgPtr->d1))
98 106
 #define cmMidiFileIsSustainPedalDown(m)   (cmMidiIsSustainPedalDown(  (m)->status,(m)->u.chMsgPtr->d0,(m)->u.chMsgPtr->d1))
99 107
   
@@ -118,7 +126,9 @@ extern "C" {
118 126
     kUidNotFoundMfRC,    // 13
119 127
     kUidNotANoteMsgMfRC, // 14
120 128
     kInvalidTrkIndexMfRC,// 15
121
-    kSvgFailMfRC         // 16
129
+    kSvgFailMfRC,        // 16
130
+    kMsgNotFoundMfRC,     // 17
131
+    kEventTerminationMfRC // 18
122 132
   };
123 133
 
124 134
   extern cmMidiFileH_t cmMidiFileNullHandle;
@@ -172,6 +182,7 @@ extern "C" {
172 182
   // Set the velocity of a note-on/off msg identified by 'uid'.
173 183
   cmMfRC_t             cmMidiFileSetVelocity( cmMidiFileH_t h, unsigned uid, cmMidiByte_t vel );
174 184
 
185
+  
175 186
   // Insert a MIDI message relative to the reference msg identified by 'uid'.
176 187
   // If dtick is positive/negative then the new msg is inserted after/before the reference msg.  
177 188
   cmMfRC_t             cmMidiFileInsertMsg( cmMidiFileH_t h, unsigned uid, int dtick, cmMidiByte_t ch, cmMidiByte_t status, cmMidiByte_t d0, cmMidiByte_t d1 );
@@ -199,8 +210,9 @@ extern "C" {
199 210
 
200 211
   double                cmMidiFileDurSecs( cmMidiFileH_t h );
201 212
 
202
-  // Calculate Note Duration 
203
-  void                  cmMidiFileCalcNoteDurations( cmMidiFileH_t h );
213
+  // Calculate Note Duration
214
+  enum { kWarningsMfFl=0x01, kDropReattacksMfFl=0x02 };
215
+  void                  cmMidiFileCalcNoteDurations( cmMidiFileH_t h, unsigned flags );
204 216
 
205 217
   // Set the delay prior to the first non-zero msg.
206 218
   void                  cmMidiFileSetDelay( cmMidiFileH_t h, unsigned ticks );
@@ -218,8 +230,7 @@ extern "C" {
218 230
   {
219 231
     unsigned           uid;
220 232
     unsigned long long amicro;
221
-    unsigned           density;
222
-    
233
+    unsigned           density; 
223 234
   } cmMidiFileDensity_t;
224 235
 
225 236
   // Generate the note onset density measure for each note in the MIDI file.

+ 2
- 1
src/cmMsgProtocol.h View File

@@ -41,6 +41,7 @@ extern "C" {
41 41
     kDeviceDuiId,          // ui<--eng device label
42 42
     kProgramDuiId,         // ui<--eng program label
43 43
     kProgramDfltDuiId,     // ui<--eng dflt program label
44
+    kPgmDoneDuiId,         // ui<--end the program is done 
44 45
     
45 46
     // The following selId's are used by cmAudDsp to indicate various commands.
46 47
     kSetAudioCfgDuiId,     // 1) select an audio system setup
@@ -54,7 +55,7 @@ extern "C" {
54 55
     kSendMsgDuiId,         // forward msg to the audio system
55 56
     kDevReportDuiId,       // print a device report
56 57
     kPrintPgmDuiId,        // write the currently loaded pgm as a JSON file
57
-
58
+    
58 59
     kRightAlignDuiId = 0,  // label alignment id used by kLabelDuiId 
59 60
     kLeftAlignDuiId,  
60 61
     kCenterAlignDuiId

+ 45
- 0
src/cmPP_NARG.h View File

@@ -0,0 +1,45 @@
1
+#ifndef cmPP_NARG_H
2
+#define cmPP_NARG_H
3
+
4
+
5
+// Taken from here:
6
+// https://groups.google.com/forum/#!topic/comp.std.c/d-6Mj5Lko_s
7
+// and here:
8
+// https://stackoverflow.com/questions/4421681/how-to-count-the-number-of-arguments-passed-to-a-function-that-accepts-a-variabl
9
+
10
+#define PP_NARG(...) \
11
+         PP_NARG_(__VA_ARGS__,PP_RSEQ_N())
12
+
13
+#define PP_NARG_(...) \
14
+         PP_128TH_ARG(__VA_ARGS__)
15
+
16
+#define PP_128TH_ARG( \
17
+          _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
18
+         _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
19
+         _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
20
+         _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
21
+         _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
22
+         _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
23
+         _61,_62,_63,_64,_65,_66,_67,_68,_69,_70, \
24
+         _71,_72,_73,_74,_75,_76,_77,_78,_79,_80, \
25
+         _81,_82,_83,_84,_85,_86,_87,_88,_89,_90, \
26
+         _91,_92,_93,_94,_95,_96,_97,_98,_99,_100, \
27
+         _101,_102,_103,_104,_105,_106,_107,_108,_109,_110, \
28
+         _111,_112,_113,_114,_115,_116,_117,_118,_119,_120, \
29
+         _121,_122,_123,_124,_125,_126,_127,N,...) N
30
+#define PP_RSEQ_N() \
31
+         127,126,125,124,123,122,121,120, \
32
+         119,118,117,116,115,114,113,112,111,110, \
33
+         109,108,107,106,105,104,103,102,101,100, \
34
+         99,98,97,96,95,94,93,92,91,90, \
35
+         89,88,87,86,85,84,83,82,81,80, \
36
+         79,78,77,76,75,74,73,72,71,70, \
37
+         69,68,67,66,65,64,63,62,61,60, \
38
+         59,58,57,56,55,54,53,52,51,50, \
39
+         49,48,47,46,45,44,43,42,41,40, \
40
+         39,38,37,36,35,34,33,32,31,30, \
41
+         29,28,27,26,25,24,23,22,21,20, \
42
+         19,18,17,16,15,14,13,12,11,10, \
43
+         9,8,7,6,5,4,3,2,1,0
44
+
45
+#endif

+ 12
- 6
src/cmProc2.c View File

@@ -6501,7 +6501,8 @@ cmRC_t cmSpecDist2Init( cmSpecDist2_t* p, unsigned procSmpCnt, double srate, uns
6501 6501
   p->wndSmpCnt    = wndSmpCnt;
6502 6502
   p->hopSmpCnt    = (unsigned)floor(wndSmpCnt/hopFcmt);
6503 6503
   p->procSmpCnt   = procSmpCnt;
6504
-
6504
+  p->igain        = 1.0;
6505
+  
6505 6506
   p->ceiling      = 30;
6506 6507
   p->expo         = 2.0;
6507 6508
     
@@ -6511,8 +6512,9 @@ cmRC_t cmSpecDist2Init( cmSpecDist2_t* p, unsigned procSmpCnt, double srate, uns
6511 6512
 
6512 6513
   p->mix          = 0.0;
6513 6514
 
6514
-  p->pva = cmPvAnlAlloc(  p->obj.ctx, NULL, procSmpCnt, srate, wndSmpCnt, p->hopSmpCnt, flags );
6515
-  p->pvs = cmPvSynAlloc(  p->obj.ctx, NULL, procSmpCnt, srate, wndSmpCnt, p->hopSmpCnt, olaWndTypeId );
6515
+  p->igainV = cmMemResizeZ( cmSample_t, p->igainV, procSmpCnt );
6516
+  p->pva    = cmPvAnlAlloc(  p->obj.ctx, NULL, procSmpCnt, srate, wndSmpCnt, p->hopSmpCnt, flags );
6517
+  p->pvs    = cmPvSynAlloc(  p->obj.ctx, NULL, procSmpCnt, srate, wndSmpCnt, p->hopSmpCnt, olaWndTypeId );
6516 6518
 
6517 6519
 
6518 6520
   return rc;
@@ -6522,7 +6524,7 @@ cmRC_t cmSpecDist2Final(cmSpecDist2_t* p )
6522 6524
 {
6523 6525
   cmRC_t rc = cmOkRC;
6524 6526
 
6525
-  
6527
+  cmMemFree(p->igainV);
6526 6528
   cmPvAnlFree(&p->pva);
6527 6529
   cmPvSynFree(&p->pvs);
6528 6530
   return rc;
@@ -6585,8 +6587,12 @@ cmRC_t  cmSpecDist2Exec( cmSpecDist2_t* p, const cmSample_t* sp, unsigned sn )
6585 6587
 
6586 6588
   unsigned binN = p->pva->binCnt;
6587 6589
 
6590
+  cmVOS_MultVVS( p->igainV, sn, sp, p->igain );
6591
+
6592
+  //printf("%f\n",p->igainV[0]);
6593
+
6588 6594
   // cmPvAnlExec() returns true when it calc's a new spectral output frame
6589
-  if( cmPvAnlExec( p->pva, sp, sn ) )
6595
+  if( cmPvAnlExec( p->pva, p->igainV, sn ) )
6590 6596
   {
6591 6597
     cmReal_t X0m[binN];
6592 6598
     cmReal_t X1m[binN]; 
@@ -6652,7 +6658,7 @@ const cmSample_t* cmSpecDist2Out(  cmSpecDist2_t* p )
6652 6658
 
6653 6659
 void  cmSpecDist2Report( cmSpecDist2_t* p )
6654 6660
 {
6655
-  printf("ceil:%f expo:%f mix:%f thresh:%f upr:%f lwr:%f\n", p->ceiling,p->expo,p->mix,p->thresh,p->lwrSlope,p->uprSlope);
6661
+  printf("igain:%f ceil:%f expo:%f mix:%f thresh:%f upr:%f lwr:%f\n", p->igain, p->ceiling,p->expo,p->mix,p->thresh,p->lwrSlope,p->uprSlope);
6656 6662
 }
6657 6663
 
6658 6664
 

+ 10
- 9
src/cmProc2.h View File

@@ -1318,15 +1318,16 @@ extern "C" {
1318 1318
 
1319 1319
   typedef struct
1320 1320
   {
1321
-    cmObj    obj;
1322
-    double   srate;
1323
-    unsigned wndSmpCnt;
1324
-    unsigned hopFcmt;
1325
-    unsigned hopSmpCnt;
1326
-    unsigned procSmpCnt;
1327
-    
1328
-    cmPvAnl* pva;
1329
-    cmPvSyn* pvs;
1321
+    cmObj       obj;
1322
+    double      srate;
1323
+    unsigned    wndSmpCnt;
1324
+    unsigned    hopFcmt;
1325
+    unsigned    hopSmpCnt;
1326
+    unsigned    procSmpCnt;
1327
+    double      igain;
1328
+    cmSample_t* igainV;
1329
+    cmPvAnl*    pva;
1330
+    cmPvSyn*    pvs;
1330 1331
 
1331 1332
     double   ceiling;
1332 1333
     double   expo;    

+ 2
- 0
src/cmProc4.c View File

@@ -3342,6 +3342,8 @@ cmRC_t  _cmScModActivateGroup( cmScModulator* p, cmScModEntry_t* ep )
3342 3342
     {
3343 3343
       unsigned idx = 0;
3344 3344
 
3345
+      printf("Activating:%s\n",cmSymTblLabel(p->stH,ep->beg.symId));
3346
+        
3345 3347
       return  _cmScModActivateEntries( p, g->earray, &idx, g->en, ep->beg.symId );
3346 3348
     }
3347 3349
 

+ 3
- 0
src/cmXml.c View File

@@ -650,6 +650,9 @@ cmXmlRC_t _cmXmlReadNode( cmXml_t* p, cmXmlNode_t* parent )
650 650
       return rc;
651 651
     }
652 652
 
653
+    if( np==NULL && p->stack==NULL)
654
+      break;
655
+
653 656
     // if an  end-tag was just read or node was created but closed then pop the stack
654 657
     if( np==NULL || (np==p->stack && cmIsFlag(np->flags,kClosedXmlFl)) )
655 658
       p->stack = p->stack->parent;

+ 110
- 26
src/dsp/cmDspBuiltIn.c View File

@@ -1067,6 +1067,7 @@ enum
1067 1067
 {
1068 1068
   kChAoId,
1069 1069
   kGainAoId,
1070
+  kEnableAoId,
1070 1071
   kInAoId
1071 1072
 };
1072 1073
 
@@ -1075,23 +1076,30 @@ cmDspClass_t _cmAudioOutDC;
1075 1076
 typedef struct
1076 1077
 {
1077 1078
   cmDspInst_t inst;
1079
+  unsigned    onSymId;
1080
+  unsigned    offSymId;  
1078 1081
 } cmDspAudioOut_t;
1079 1082
 
1080 1083
 cmDspInst_t*  _cmDspAudioOutAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned storeSymId, unsigned instSymId, unsigned id, unsigned va_cnt, va_list vl )
1081 1084
 {
1082 1085
   cmDspVarArg_t args[] =
1083 1086
   {
1084
-    { "ch",  kChAoId,  0,      0, kInDsvFl | kUIntDsvFl   | kReqArgDsvFl, "Audio output channel index"},
1085
-    { "gain",kGainAoId,0,      0, kInDsvFl | kDoubleDsvFl | kOptArgDsvFl, "Output gain multiplier"},  
1086
-    { "in",  kInAoId,  0,      1, kInDsvFl | kAudioBufDsvFl, "Audio input" },
1087
+    { "ch",    kChAoId,    0,      0, kInDsvFl | kUIntDsvFl   | kReqArgDsvFl, "Audio output channel index"},
1088
+    { "gain",  kGainAoId,  0,      0, kInDsvFl | kDoubleDsvFl | kOptArgDsvFl, "Output gain multiplier"},
1089
+    { "enable",kEnableAoId,0,      0, kInDsvFl | kSymDsvFl    | kOptArgDsvFl, "Enable: on off"},
1090
+    { "in",    kInAoId,    0,      1, kInDsvFl | kAudioBufDsvFl, "Audio input" },
1087 1091
     { NULL, 0, 0, 0, 0 }
1088 1092
   };
1089 1093
 
1090 1094
   cmDspAudioOut_t* p = cmDspInstAlloc(cmDspAudioOut_t,ctx,classPtr,args,instSymId,id,storeSymId,va_cnt,vl);
1091 1095
 
1096
+  p->offSymId = cmSymTblRegisterStaticSymbol(ctx->stH,"off");
1097
+  p->onSymId  = cmSymTblRegisterStaticSymbol(ctx->stH,"on");
1098
+
1092 1099
 
1093 1100
   cmDspSetDefaultUInt(   ctx, &p->inst, kChAoId,   0,   0);
1094 1101
   cmDspSetDefaultDouble( ctx, &p->inst, kGainAoId, 0, 1.0);
1102
+  cmDspSetDefaultSymbol( ctx, &p->inst, kEnableAoId, p->onSymId );
1095 1103
 
1096 1104
   return &p->inst;
1097 1105
 }
@@ -1106,10 +1114,12 @@ cmDspRC_t _cmDspAudioOutReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt
1106 1114
 
1107 1115
 cmDspRC_t _cmDspAudioOutExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
1108 1116
 {
1109
-  cmDspRC_t         rc     = kOkDspRC;
1110
-  unsigned          chIdx  = cmDspUInt(inst,kChAoId);
1111
-  unsigned          oChCnt = ctx->ctx->oChCnt;
1112
-  double            gain   = cmDspDouble(inst,kGainAoId);
1117
+  cmDspRC_t        rc       = kOkDspRC;
1118
+  cmDspAudioOut_t* p        = (cmDspAudioOut_t*)inst;
1119
+  unsigned         chIdx    = cmDspUInt(inst,kChAoId);
1120
+  bool             enableFl = cmDspSymbol(inst,kEnableAoId) == p->onSymId;
1121
+  unsigned         oChCnt   = ctx->ctx->oChCnt;
1122
+  double           gain     = cmDspDouble(inst,kGainAoId);
1113 1123
 
1114 1124
   if( chIdx >= oChCnt )
1115 1125
   {
@@ -1118,7 +1128,7 @@ cmDspRC_t _cmDspAudioOutExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_
1118 1128
     return rc;
1119 1129
   }
1120 1130
 
1121
-  const cmSample_t* sp     = cmDspAudioBuf(ctx,inst,kInAoId,0);
1131
+  const cmSample_t* sp = cmDspAudioBuf(ctx,inst,kInAoId,0);
1122 1132
 
1123 1133
   if( sp == NULL )
1124 1134
   {
@@ -1132,7 +1142,7 @@ cmDspRC_t _cmDspAudioOutExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_
1132 1142
   
1133 1143
   // if this channel is disabled or set to pass-through then chArray[chIdx] will be NULL
1134 1144
   if( ctx->ctx->oChArray[chIdx] != NULL )
1135
-    cmVOS_MultVVS(ctx->ctx->oChArray[chIdx],n,sp,(cmSample_t)gain);
1145
+    cmVOS_MultVVS(ctx->ctx->oChArray[chIdx],n,sp, (cmSample_t)(enableFl ? gain : 0));
1136 1146
 
1137 1147
   return kOkDspRC;
1138 1148
 }
@@ -1154,6 +1164,11 @@ cmDspRC_t _cmDspAudioOutRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_
1154 1164
     case kGainAoId:
1155 1165
       cmDspSetEvent(ctx,inst,evt);
1156 1166
       break;
1167
+      
1168
+    case kEnableAoId:
1169
+      cmDspSetEvent(ctx,inst,evt);
1170
+      break;
1171
+
1157 1172
   }
1158 1173
   return rc;
1159 1174
 }
@@ -1687,7 +1702,8 @@ cmDspClass_t*  cmMeterClassCons( cmDspCtx_t* ctx )
1687 1702
 enum
1688 1703
 {
1689 1704
   kInLbId,
1690
-  kAlignLbId
1705
+  kAlignLbId,
1706
+  kTextLbId
1691 1707
 };
1692 1708
 
1693 1709
 cmDspClass_t _cmLabelDC;
@@ -1695,27 +1711,68 @@ cmDspClass_t _cmLabelDC;
1695 1711
 typedef struct
1696 1712
 {
1697 1713
   cmDspInst_t inst;
1714
+  cmChar_t* label;
1698 1715
 } cmDspLabel_t;
1699 1716
 
1700 1717
 cmDspInst_t*  _cmDspLabelAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned storeSymId, unsigned instSymId, unsigned id, unsigned va_cnt, va_list vl )
1701 1718
 {
1702
-  cmDspVarArg_t args[] =
1719
+  const unsigned  argCnt = 3;
1720
+  cmDspVarArg_t   args[argCnt+1];
1721
+  cmChar_t*       label  = NULL;
1722
+  unsigned        align  = kLeftAlignDuiId;
1723
+  va_list         vl1;
1724
+  
1725
+  va_copy(vl1,vl);
1726
+
1727
+  if( va_cnt < 1 )
1703 1728
   {
1704
-    { "in",   kInLbId,    0, 0,  kInDsvFl | kStrzDsvFl  | kReqArgDsvFl,  "LabelText" },
1705
-    { "align",kAlignLbId, 0, 0,  kInDsvFl | kUIntDsvFl  | kOptArgDsvFl,  "Alignment 0=right 1=left 2=center" },
1706
-    { NULL, 0, 0, 0, 0 }
1707
-  };
1729
+    va_end(vl1);
1730
+    cmDspClassErr(ctx,classPtr,kVarArgParseFailDspRC,"The 'label' constructor argument list must contain at least one argument.");
1731
+    return NULL;
1732
+  }
1708 1733
 
1709
-  cmDspLabel_t* p = cmDspInstAlloc(cmDspLabel_t,ctx,classPtr,args,instSymId,id,storeSymId,va_cnt,vl);
1734
+  // get the default label
1735
+  const char* clabel = va_arg(vl,const char*);
1736
+  if( clabel != NULL && strlen(clabel) > 0 )
1737
+  {
1738
+    label = cmLhAllocStr(ctx->lhH,clabel);
1739
+    printf("%s\n",label);
1740
+  }
1710 1741
 
1711
-  cmDspSetDefaultDouble(ctx, &p->inst, kAlignLbId,  0.0, kLeftAlignDuiId);
1742
+  // if an alignment id was provided
1743
+  if( va_cnt > 1 )
1744
+    align = va_arg(vl,double);
1745
+
1746
+  // setup the arg. config. array.
1747
+  cmDspArgSetup(ctx,args+0,"in",   cmInvalidId, kInLbId,    0,0, kInDsvFl | kTypeDsvMask, "Input to set label" );
1748
+  cmDspArgSetup(ctx,args+1,"align",cmInvalidId, kAlignLbId, 0,0, kInDsvFl | kUIntDsvFl,   "Justification: 0=right 1=center 2=left" );
1749
+  cmDspArgSetup(ctx,args+2,"text", cmInvalidId, kTextLbId,  0,0, kInDsvFl | kStrzDsvFl,   "Label text");
1750
+  cmDspArgSetupNull(args + argCnt);
1712 1751
 
1752
+  // create the instance
1753
+  cmDspLabel_t* p = cmDspInstAlloc(cmDspLabel_t,ctx,classPtr,args,instSymId,id,storeSymId,0,vl1);
1754
+
1755
+  p->label = label;
1756
+
1757
+  // set the default variable values
1758
+  cmDspSetDefaultDouble(ctx, &p->inst, kAlignLbId,  0.0, align);
1759
+  cmDspSetDefaultStrcz( ctx, &p->inst, kTextLbId,  NULL, label==NULL ? "" : label );
1760
+  
1713 1761
   // create the UI control
1714
-  cmDspUiLabelCreate(ctx,&p->inst,kInLbId,kAlignLbId);
1762
+  cmDspUiLabelCreate(ctx,&p->inst,kTextLbId,kAlignLbId);
1715 1763
 
1764
+  va_end(vl1);
1765
+  
1716 1766
   return &p->inst;
1717 1767
 }
1718 1768
 
1769
+cmDspRC_t _cmDspLabelFree(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
1770
+{
1771
+  cmDspLabel_t* p = (cmDspLabel_t*)inst;
1772
+  cmLhFree(ctx->lhH,p->label);
1773
+  return kOkDspRC;
1774
+}
1775
+
1719 1776
 cmDspRC_t _cmDspLabelReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
1720 1777
 {
1721 1778
   cmDspApplyAllDefaults(ctx,inst);
@@ -1724,6 +1781,21 @@ cmDspRC_t _cmDspLabelReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t*
1724 1781
 
1725 1782
 cmDspRC_t _cmDspLabelRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
1726 1783
 {
1784
+  const unsigned bN = 128;
1785
+  cmChar_t b[ bN+1 ];
1786
+
1787
+  // if this event is arriving on the 'in' port ...
1788
+  if( evt->dstVarId == kInLbId )
1789
+  {
1790
+    cmDspLabel_t* p = (cmDspLabel_t*)inst;
1791
+    // ... then convert it to a string
1792
+    cmDsvToString( evt->valuePtr, p->label, b, bN );
1793
+
1794
+    // and set the 'label' variable 
1795
+    return cmDspSetStrcz(ctx, inst, kTextLbId, b );
1796
+  }
1797
+
1798
+  
1727 1799
   return cmDspSetEvent(ctx,inst,evt);
1728 1800
 }
1729 1801
 
@@ -1732,7 +1804,7 @@ cmDspClass_t*  cmLabelClassCons( cmDspCtx_t* ctx )
1732 1804
   cmDspClassSetup(&_cmLabelDC,ctx,"Label",
1733 1805
     NULL,
1734 1806
     _cmDspLabelAlloc,
1735
-    NULL,
1807
+    _cmDspLabelFree,
1736 1808
     _cmDspLabelReset,
1737 1809
     NULL,
1738 1810
     _cmDspLabelRecv,
@@ -2907,6 +2979,7 @@ enum
2907 2979
   kLoopWtId,
2908 2980
   kBegWtId,
2909 2981
   kEndWtId,
2982
+  kChWtId,
2910 2983
   kCmdWtId,
2911 2984
   kOtWtId,
2912 2985
   kGainWtId,
@@ -2951,6 +3024,7 @@ typedef struct
2951 3024
   cmAudioFileH_t afH;           // current audio file handle
2952 3025
   int            nxtBegSmpIdx;  // the beg/end sample index to use with the next filename to arrive at port 'fn'
2953 3026
   int            nxtEndSmpIdx;  //
3027
+  unsigned       nxtChIdx;
2954 3028
   cmThreadH_t    thH;
2955 3029
   bool           loadFileFl;
2956 3030
   cmDspCtx_t*    ctx;
@@ -2976,6 +3050,7 @@ cmDspInst_t*  _cmDspWaveTableAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsi
2976 3050
     { "loop",   kLoopWtId,   0, 0, kInDsvFl  | kIntDsvFl  | kOptArgDsvFl, "-1=loop forever  >0=loop count (dflt:-1)"},
2977 3051
     { "beg",    kBegWtId,    0, 0, kInDsvFl  | kIntDsvFl  | kOptArgDsvFl, "File begin sample index" },
2978 3052
     { "end",    kEndWtId,    0, 0, kInDsvFl  | kIntDsvFl  | kOptArgDsvFl, "File end sample index (-1=play all)" },
3053
+    { "ch",     kChWtId,     0, 0, kInDsvFl  | kUIntDsvFl | kOptArgDsvFl, "File channel index 0=left, 1=right" },
2979 3054
     { "cmd",    kCmdWtId,    0, 0, kInDsvFl  | kSymDsvFl  | kOptArgDsvFl, "Command: on off"},
2980 3055
     { "ot",     kOtWtId,     0, 0, kInDsvFl  | kUIntDsvFl | kOptArgDsvFl, "Overtone count"},
2981 3056
     { "gain",   kGainWtId,   0, 0, kInDsvFl  | kDoubleDsvFl|kOptArgDsvFl, "Gain"},
@@ -3005,6 +3080,7 @@ cmDspInst_t*  _cmDspWaveTableAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsi
3005 3080
   cmDspSetDefaultInt(   ctx, &p->inst, kLoopWtId,  0,    -1 );
3006 3081
   cmDspSetDefaultInt(   ctx, &p->inst, kBegWtId,   0,     0 );
3007 3082
   cmDspSetDefaultInt(   ctx, &p->inst, kEndWtId,   0,    -1 );
3083
+  cmDspSetDefaultUInt(  ctx, &p->inst, kChWtId,    0,     0 );  
3008 3084
   cmDspSetDefaultSymbol(ctx, &p->inst, kCmdWtId,   p->onSymId );
3009 3085
   cmDspSetDefaultUInt(  ctx, &p->inst, kOtWtId,    0,     5 );
3010 3086
   cmDspSetDefaultDouble(ctx, &p->inst, kGainWtId,  0,     1.0 );
@@ -3038,10 +3114,9 @@ cmDspRC_t _cmDspWaveTableFree(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt
3038 3114
 // mode then the the function will automatically begin reading from the begining of the
3039 3115
 // file segment.  If the end of the file segment is encountered and the wave table is not
3040 3116
 // in loop mode then the empty portion of wt[] will be set to zero.
3041
-cmDspRC_t _cmDspWaveTableReadBlock( cmDspCtx_t* ctx, cmDspWaveTable_t* p, cmSample_t* wt, unsigned rdSmpCnt, int begSmpIdx, int endSmpIdx, int maxLoopCnt  )
3117
+cmDspRC_t _cmDspWaveTableReadBlock( cmDspCtx_t* ctx, cmDspWaveTable_t* p, cmSample_t* wt, unsigned rdSmpCnt, unsigned chIdx, int begSmpIdx, int endSmpIdx, int maxLoopCnt  )
3042 3118
 {
3043 3119
   unsigned    actFrmCnt = 0;
3044
-  unsigned    chIdx     = 0;
3045 3120
   unsigned    chCnt     = 1;
3046 3121
   unsigned    fn        = endSmpIdx - p->fi + 1; // count of samples between p->fi and endSmpIdx
3047 3122
   unsigned    n0        = rdSmpCnt;
@@ -3117,9 +3192,10 @@ cmDspRC_t _cmDspWaveTableReadAudioFile( cmDspCtx_t* ctx, cmDspWaveTable_t* p, un
3117 3192
 {
3118 3193
   unsigned    n0        = rdSmpCnt;
3119 3194
   unsigned    n1        = 0;
3120
-  int         begSmpIdx = cmDspInt(&p->inst,kBegWtId);
3121
-  int         endSmpIdx = cmDspInt(&p->inst,kEndWtId);
3122
-  int         maxLoopCnt= cmDspInt(&p->inst,kLoopWtId);
3195
+  int         begSmpIdx = cmDspInt( &p->inst,kBegWtId);
3196
+  int         endSmpIdx = cmDspInt( &p->inst,kEndWtId);
3197
+  unsigned    chIdx     = cmDspUInt(&p->inst,kChWtId);
3198
+  int         maxLoopCnt= cmDspInt( &p->inst,kLoopWtId);
3123 3199
 
3124 3200
   if( endSmpIdx < begSmpIdx )
3125 3201
     endSmpIdx = p->fn-1;
@@ -3137,7 +3213,7 @@ cmDspRC_t _cmDspWaveTableReadAudioFile( cmDspCtx_t* ctx, cmDspWaveTable_t* p, un
3137 3213
   if( p->doneFl )
3138 3214
     cmVOS_Zero(p->wt + p->wti,n0);
3139 3215
   else
3140
-    if( _cmDspWaveTableReadBlock(ctx, p, p->wt+p->wti, n0,begSmpIdx,endSmpIdx,maxLoopCnt  ) != kOkDspRC )
3216
+    if( _cmDspWaveTableReadBlock(ctx, p, p->wt+p->wti, n0, chIdx, begSmpIdx,endSmpIdx,maxLoopCnt  ) != kOkDspRC )
3141 3217
       return cmDspInstErr(ctx,&p->inst,kVarNotValidDspRC,"An error occured while reading the wave table file.");
3142 3218
 
3143 3219
   p->wtn -= n0;   // decrease the count of available samples
@@ -3149,7 +3225,7 @@ cmDspRC_t _cmDspWaveTableReadAudioFile( cmDspCtx_t* ctx, cmDspWaveTable_t* p, un
3149 3225
     if( p->doneFl )
3150 3226
       cmVOS_Zero(p->wt,n1);
3151 3227
     else
3152
-      if( _cmDspWaveTableReadBlock(ctx, p, p->wt, n1,begSmpIdx,endSmpIdx,maxLoopCnt  ) != kOkDspRC )
3228
+      if( _cmDspWaveTableReadBlock(ctx, p, p->wt, n1, chIdx, begSmpIdx,endSmpIdx,maxLoopCnt  ) != kOkDspRC )
3153 3229
         return cmDspInstErr(ctx,&p->inst,kVarNotValidDspRC,"An error occured while reading the wave table file.");
3154 3230
 
3155 3231
     p->wtn -= n1;  // decrease the count of available samples
@@ -3382,6 +3458,7 @@ cmDspRC_t _cmDspWaveTableReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEv
3382 3458
 
3383 3459
   p->nxtBegSmpIdx = cmDspInt(&p->inst,kBegWtId);
3384 3460
   p->nxtEndSmpIdx = cmDspInt(&p->inst,kEndWtId);
3461
+  p->nxtChIdx     = cmDspUInt(&p->inst,kChWtId);
3385 3462
 
3386 3463
   return _cmDspWaveTableCreateTable(ctx,p);
3387 3464
 
@@ -3490,6 +3567,7 @@ cmDspRC_t _cmDspWaveTableRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt
3490 3567
           cmDspSetEvent(ctx,inst,evt);                       // set the file name variable
3491 3568
           cmDspSetInt(ctx,inst,kBegWtId,p->nxtBegSmpIdx);    // set the beg/end smp idx var's from the stored nxtBeg/EndSmpIdx values
3492 3569
           cmDspSetInt(ctx,inst,kEndWtId,p->nxtEndSmpIdx);    // 
3570
+          cmDspSetUInt(ctx,inst,kChWtId, p->nxtChIdx);       // 
3493 3571
           cmDspSetUInt(ctx,inst,kShapeWtId,kFileWtId);       // switch to file mode 
3494 3572
           rc = _cmDspWaveTableCreateTable(ctx,p);            // reload the wavetable
3495 3573
         }
@@ -3506,6 +3584,11 @@ cmDspRC_t _cmDspWaveTableRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt
3506 3584
       p->nxtEndSmpIdx = cmDsvGetInt(evt->valuePtr);
3507 3585
       break;
3508 3586
 
3587
+    case kChWtId:
3588
+      // store for next incoming file name msg
3589
+      p->nxtChIdx = cmDsvGetUInt(evt->valuePtr);
3590
+      break;
3591
+      
3509 3592
     case kShapeWtId:
3510 3593
       if( cmDsvGetUInt(evt->valuePtr) < kShapeWtCnt )
3511 3594
       {
@@ -5546,6 +5629,7 @@ cmDspClassConsFunc_t _cmDspClassBuiltInArray[] =
5546 5629
   cm1UpClassCons,
5547 5630
   cmGateToSymClassCons,
5548 5631
   cmPortToSymClassCons,
5632
+  cmIntToSymClassCons,
5549 5633
   cmRouterClassCons,
5550 5634
   cmAvailChClassCons,
5551 5635
 

+ 4
- 1
src/dsp/cmDspClass.h View File

@@ -390,6 +390,9 @@ extern "C" {
390 390
   // Used to transmit messages to the audio system.
391 391
   cmDspRC_t  cmDspSendValueToAudioSys( cmDspCtx_t* ctx, unsigned msgTypeId, unsigned selId, unsigned valId, const cmDspValue_t* valPtr ); 
392 392
 
393
+  // Notify the system that the program is done and can be shutdown
394
+  cmDspRC_t cmDspProgramIsDone( cmDspCtx_t* ctx );
395
+  
393 396
   // The following functions are used to send message to the UI and are 
394 397
   // implemented in cmDspUi.c.  They are declared here because they are 
395 398
   // visible to the cmDspInst functions which use them but are not available
@@ -417,7 +420,7 @@ extern "C" {
417 420
   cmDspRC_t   cmDspUiFnameCreate(  cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned valVarId, unsigned patVarId, unsigned dirVarId );
418 421
   cmDspRC_t   cmDspUiMsgListCreate(cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned height, unsigned listVarId, unsigned selVarId );
419 422
 
420
- 
423
+  
421 424
   //)
422 425
   
423 426
 #ifdef __cplusplus

+ 198
- 9
src/dsp/cmDspFx.c View File

@@ -2909,6 +2909,7 @@ typedef struct cmDspScalar_str
2909 2909
   cmDspInst_t          inst;
2910 2910
   _cmDspScalarOpFunc_t func;
2911 2911
   unsigned             inPortCnt;
2912
+  bool                 allActiveFl;                  
2912 2913
 } cmDspScalarOp_t;
2913 2914
 
2914 2915
 cmDspRC_t _cmDspScalarOpFuncMult(cmDspCtx_t* ctx, cmDspInst_t* inst )
@@ -2966,6 +2967,7 @@ cmDspInst_t*  _cmDspScalarOpAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsig
2966 2967
   double             dfltVal[ inPortCnt ];
2967 2968
   unsigned           i;
2968 2969
   _cmDspScalarOpFunc_t fp = NULL;
2970
+  bool allActiveFl = false;
2969 2971
 
2970 2972
   // validate the count of input ports
2971 2973
   if( inPortCnt == 0 )
@@ -2974,12 +2976,26 @@ cmDspInst_t*  _cmDspScalarOpAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsig
2974 2976
     goto errLabel;
2975 2977
   }
2976 2978
 
2977
-  // locate the operation function
2978
-  if( strcmp(opIdStr,"*") == 0 )
2979
-    fp = _cmDspScalarOpFuncMult;
2980
-  else
2981
-    if( strcmp(opIdStr,"+") == 0 )
2982
-      fp = _cmDspScalarOpFuncAdd;
2979
+  if( opIdStr != NULL )
2980
+  {
2981
+    switch( opIdStr[0] )
2982
+    {
2983
+      case '*':
2984
+        fp = _cmDspScalarOpFuncMult;
2985
+        break;
2986
+      case '+':
2987
+        fp = _cmDspScalarOpFuncAdd;
2988
+        break;      
2989
+    }
2990
+
2991
+    // if the second character of the operator string is '$' then all input ports trigger an output
2992
+    if( strlen( opIdStr ) > 0 && opIdStr[1]=='$' )
2993
+      allActiveFl = true;
2994
+    
2995
+    
2996
+  }
2997
+  
2998
+  
2983 2999
 
2984 3000
   // validate the operation function
2985 3001
   if( fp == NULL )
@@ -3012,7 +3028,7 @@ cmDspInst_t*  _cmDspScalarOpAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsig
3012 3028
 
3013 3029
   p->inPortCnt = inPortCnt;
3014 3030
   p->func      = fp;
3015
-  
3031
+  p->allActiveFl = allActiveFl;
3016 3032
   va_end(vl1);
3017 3033
 
3018 3034
   return &p->inst;
@@ -3039,7 +3055,7 @@ cmDspRC_t _cmDspScalarOpRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_
3039 3055
 
3040 3056
   if((rc = cmDspSetEvent(ctx,inst,evt)) == kOkDspRC )
3041 3057
   {
3042
-    if( evt->dstVarId == kBaseOpdSoId )
3058
+    if( evt->dstVarId == kBaseOpdSoId || p->allActiveFl )
3043 3059
       p->func(ctx,inst);
3044 3060
   }
3045 3061
 
@@ -5587,6 +5603,7 @@ cmDspInst_t*  _cmDspPortToSym_Alloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, uns
5587 5603
     // register the symbol
5588 5604
     symIdArray[i] = cmSymTblRegisterSymbol(ctx->stH,symLabel);
5589 5605
 
5606
+    // input port - any msg in this port will generate an output from 'out' as well as the associated output port
5590 5607
     cmDspArgSetup(ctx, args+kBaseInPtsId+i, symLabel, cmInvalidId, kBaseInPtsId+i, 0, 0, kInDsvFl  | kTypeDsvMask, cmTsPrintfH(ctx->lhH,"%s Input.",symLabel) );
5591 5608
 
5592 5609
     cmDspArgSetup(ctx, args+baseOutPtsId+i, symLabel, cmInvalidId, baseOutPtsId+i, 0, 0, kOutDsvFl | kSymDsvFl,    cmTsPrintfH(ctx->lhH,"%s Output.",symLabel) );
@@ -5631,7 +5648,7 @@ cmDspRC_t _cmDspPortToSym_Recv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEv
5631 5648
     unsigned idx = evt->dstVarId - kBaseInPtsId;
5632 5649
     assert( idx < p->symIdCnt );
5633 5650
     cmDspSetSymbol(ctx,inst,p->baseOutPtsId + idx, p->symIdArray[idx]);
5634
-    return cmDspSetSymbol(ctx,inst,kOutPtsId,p->symIdArray[ evt->dstVarId - kBaseInPtsId ]);
5651
+    return cmDspSetSymbol(ctx,inst,kOutPtsId,      p->symIdArray[idx]);
5635 5652
   }
5636 5653
 
5637 5654
   return rc;
@@ -5654,6 +5671,178 @@ cmDspClass_t* cmPortToSymClassCons( cmDspCtx_t* ctx )
5654 5671
 
5655 5672
 //------------------------------------------------------------------------------------------------------------
5656 5673
 //)
5674
+//( { label:cmDspIntToSym file_desc:"Send a pre-defined symbol every time a message arrives a given input port." kw:[sunit] }
5675
+enum
5676
+{
5677
+ kInItsId,
5678
+ kOutItsId,
5679
+ kBaseInItsId
5680
+};
5681
+
5682
+cmDspClass_t _cmIntToSym_DC;
5683
+
5684
+typedef struct
5685
+{
5686
+  cmDspInst_t inst;
5687
+  int*        intArray;
5688
+  unsigned*   symIdArray;
5689
+  unsigned    symIdCnt;
5690
+  unsigned    baseIntItsId;
5691
+  unsigned    baseOutItsId;
5692
+  
5693
+} cmDspIntToSym_t;
5694
+
5695
+cmDspInst_t*  _cmDspIntToSym_Alloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned storeSymId, unsigned instSymId, unsigned id, unsigned va_cnt, va_list vl )
5696
+{
5697
+  va_list       vl1;
5698
+  va_copy(vl1,vl);
5699
+
5700
+  if( va_cnt < 2 || va_cnt % 2 !=0  )
5701
+  {
5702
+    va_end(vl1);
5703
+    cmDspClassErr(ctx,classPtr,kVarArgParseFailDspRC,"The 'IntToSym' constructor argument list must contain at least one int/symbol pair and all pairs must be complete.");
5704
+    return NULL;
5705
+  }
5706
+
5707
+  unsigned      symCnt    = va_cnt/2;
5708
+  unsigned      argCnt    = 2 + 3*symCnt;
5709
+  cmDspVarArg_t args[argCnt+1];
5710
+
5711
+  unsigned* symIdArray   = cmMemAllocZ(unsigned,symCnt);
5712
+  int*      intArray     = cmMemAllocZ(int,symCnt);
5713
+  unsigned  baseIntItsId = kBaseInItsId + symCnt;  
5714
+  unsigned  baseOutItsId = baseIntItsId + symCnt;
5715
+
5716
+  // setup the integer input and symbol output port arg recd
5717
+  cmDspArgSetup(ctx,args,  "in",  cmInvalidId, kInItsId,  0, 0, kInDsvFl  | kIntDsvFl, "Integer input" );
5718
+  cmDspArgSetup(ctx,args+1,"out", cmInvalidId, kOutItsId, 0, 0, kOutDsvFl | kSymDsvFl, "Output" );
5719
+
5720
+  unsigned i;
5721
+
5722
+  for(i=0; i<symCnt; ++i)
5723
+  {
5724
+    // get the integer value
5725
+    intArray[i] = va_arg(vl,int);
5726
+    
5727
+    // get the symbol label
5728
+    const cmChar_t* symLabel = va_arg(vl,const char*);
5729
+    assert( symLabel != NULL );
5730
+
5731
+    unsigned intLabelN = (symLabel==NULL ? 0 : strlen(symLabel)) + 5;
5732
+    cmChar_t intLabel[ intLabelN ];
5733
+    snprintf(intLabel,intLabelN,"%s%s", symLabel==NULL ? "" : symLabel, "-int" );
5734
+
5735
+    // register the symbol
5736
+    symIdArray[i] = cmSymTblRegisterSymbol(ctx->stH,symLabel);
5737
+
5738
+    // trigger port associated with this symbol (any msg on this port will trigger an output)
5739
+    cmDspArgSetup(ctx, args+kBaseInItsId+i, symLabel, cmInvalidId, kBaseInItsId+i, 0, 0, kInDsvFl  | kTypeDsvMask, cmTsPrintfH(ctx->lhH,"%s Input.",symLabel) );
5740
+
5741
+    // this port is used to set the integer value associated with this symbol
5742
+    cmDspArgSetup(ctx, args+baseIntItsId+i, intLabel, cmInvalidId, baseIntItsId+i, 0, 0, kInDsvFl  | kIntDsvFl,  cmTsPrintfH(ctx->lhH,"Set the integer value associated with %s.",symLabel) );
5743
+    
5744
+    // symbol output port - when ever this symbol is sent out it will go out this port as well as the 'out' port
5745
+    cmDspArgSetup(ctx, args+baseOutItsId+i, symLabel, cmInvalidId, baseOutItsId+i, 0, 0, kOutDsvFl | kSymDsvFl,    cmTsPrintfH(ctx->lhH,"%s Output.",symLabel) );
5746
+
5747
+    
5748
+  }
5749
+
5750
+  cmDspArgSetupNull(args + argCnt);
5751
+
5752
+  cmDspIntToSym_t* p = cmDspInstAlloc(cmDspIntToSym_t,ctx,classPtr,args,instSymId,id,storeSymId,0,vl1);
5753
+
5754
+  p->symIdCnt     = symCnt;
5755
+  p->intArray     = intArray;
5756
+  p->symIdArray   = symIdArray;
5757
+  p->baseOutItsId = baseOutItsId;
5758
+  p->baseIntItsId = baseIntItsId;
5759
+
5760
+  cmDspSetDefaultSymbol(ctx,&p->inst,kOutItsId,cmInvalidId);
5761
+
5762
+  va_end(vl1);
5763
+
5764
+  return &p->inst;
5765
+}
5766
+cmDspRC_t _cmDspIntToSym_Free(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
5767
+{
5768
+  cmDspIntToSym_t* p = (cmDspIntToSym_t*)inst;
5769
+  cmMemFree(p->symIdArray);
5770
+  return kOkDspRC;
5771
+}
5772
+
5773
+cmDspRC_t _cmDspIntToSym_Reset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
5774
+{
5775
+  return cmDspApplyAllDefaults(ctx,inst);
5776
+}
5777
+
5778
+cmDspRC_t _cmDspIntToSymSendOut( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned idx )
5779
+{
5780
+  cmDspIntToSym_t* p = (cmDspIntToSym_t*)inst;
5781
+  assert( idx < p->symIdCnt );
5782
+  cmDspSetSymbol(ctx,inst,p->baseOutItsId + idx, p->symIdArray[idx]);
5783
+  return cmDspSetSymbol(ctx, inst, kOutItsId, p->symIdArray[ idx ]);
5784
+}
5785
+
5786
+
5787
+cmDspRC_t _cmDspIntToSym_Recv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
5788
+{ 
5789
+  cmDspRC_t    rc = kOkDspRC;
5790
+  cmDspIntToSym_t* p = (cmDspIntToSym_t*)inst;
5791
+
5792
+  // if an integer arrived at 'in'
5793
+  if( evt->dstVarId == kInItsId )
5794
+  {
5795
+    cmDspSetEvent(ctx,inst,evt);
5796
+
5797
+    unsigned i;
5798
+    int      intVal = cmDspInt(inst,kInItsId);
5799
+    
5800
+    for(i=0; i<p->symIdCnt; ++i)
5801
+      if( intVal == p->intArray[i] )
5802
+      {
5803
+        rc = _cmDspIntToSymSendOut( ctx, inst, i );
5804
+        break;
5805
+      } 
5806
+  }
5807
+  else
5808
+  {  
5809
+    // if a msg of any type is recieved on an input port - send out the associated symbol
5810
+    if( kBaseInItsId <= evt->dstVarId && evt->dstVarId < kBaseInItsId + p->symIdCnt )
5811
+    {
5812
+      _cmDspIntToSymSendOut( ctx, inst, evt->dstVarId - kBaseInItsId );
5813
+    }
5814
+    else
5815
+      
5816
+      // if this is a new interger value for this symbol
5817
+      if( p->baseIntItsId <= evt->dstVarId && evt->dstVarId < p->baseIntItsId + p->symIdCnt )
5818
+      {
5819
+        cmDspSetEvent(ctx,inst,evt);
5820
+
5821
+        p->intArray[ evt->dstVarId - p->baseIntItsId ] = cmDspInt( inst, evt->dstVarId );
5822
+      }
5823
+  }
5824
+
5825
+  
5826
+  return rc;
5827
+}
5828
+
5829
+cmDspClass_t* cmIntToSymClassCons( cmDspCtx_t* ctx )
5830
+{
5831
+  cmDspClassSetup(&_cmIntToSym_DC,ctx,"IntToSym",
5832
+    NULL,
5833
+    _cmDspIntToSym_Alloc,
5834
+    _cmDspIntToSym_Free,
5835
+    _cmDspIntToSym_Reset,
5836
+    NULL,
5837
+    _cmDspIntToSym_Recv,
5838
+    NULL,NULL,
5839
+    "If a message of any kind is received on a port then send the symbol associated with the port.");
5840
+
5841
+  return &_cmIntToSym_DC;
5842
+}
5843
+
5844
+//------------------------------------------------------------------------------------------------------------
5845
+//)
5657 5846
 //( { label:cmDspRouter file_desc:"Route the input value to one of multiple output ports." kw:[sunit] }
5658 5847
  
5659 5848
 enum

+ 1
- 0
src/dsp/cmDspFx.h View File

@@ -36,6 +36,7 @@ extern "C" {
36 36
   struct cmDspClass_str* cm1UpClassCons(        cmDspCtx_t* ctx );
37 37
   struct cmDspClass_str* cmGateToSymClassCons(  cmDspCtx_t* ctx );
38 38
   struct cmDspClass_str* cmPortToSymClassCons(  cmDspCtx_t* ctx );
39
+  struct cmDspClass_str* cmIntToSymClassCons(   cmDspCtx_t* ctx );  
39 40
   struct cmDspClass_str* cmRouterClassCons(     cmDspCtx_t* ctx );
40 41
   struct cmDspClass_str* cmAvailChClassCons(    cmDspCtx_t* ctx );
41 42
   struct cmDspClass_str* cmPresetClassCons(     cmDspCtx_t* ctx );

+ 13
- 2
src/dsp/cmDspKr.c View File

@@ -302,6 +302,8 @@ enum
302 302
   kMixKr2Id,
303 303
 
304 304
   kWetKr2Id,
305
+  kIgainKr2Id,
306
+  
305 307
   kAudioInKr2Id,
306 308
   kAudioOutKr2Id
307 309
 };
@@ -320,7 +322,7 @@ cmDspInst_t*  _cmDspKr2Alloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned s
320 322
 {
321 323
   cmDspVarArg_t args[] =
322 324
   {
323
-    { "wndn",    kWndSmpCntKr2Id,   0, 0,   kInDsvFl  | kUIntDsvFl   | kReqArgDsvFl,   "Window sample count"   },
325
+    { "wndn",    kWndSmpCntKr2Id,   0, 0,   kInDsvFl  | kUIntDsvFl   | kReqArgDsvFl,   "Window sample count" },
324 326
     { "hopf",    kHopFactKr2Id,     0, 0,   kInDsvFl  | kUIntDsvFl   | kOptArgDsvFl,   "Hop factor" },
325 327
     
326 328
     { "ceil",    kCeilKr2Id,     0, 0,   kInDsvFl  | kDoubleDsvFl | kOptArgDsvFl,   "Ceiling" },
@@ -333,6 +335,8 @@ cmDspInst_t*  _cmDspKr2Alloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned s
333 335
     { "mix",     kMixKr2Id,         0, 0,   kInDsvFl  | kDoubleDsvFl | kOptArgDsvFl,   "Mix"},
334 336
     
335 337
     { "wet",     kWetKr2Id,         0, 0,   kInDsvFl  | kSampleDsvFl,                  "Wet mix level."},
338
+    { "igain",   kIgainKr2Id,       0, 0,   kInDsvFl  | kDoubleDsvFl | kOptArgDsvFl,   "Input gain."},
339
+    
336 340
     { "in",      kAudioInKr2Id,     0, 0,   kInDsvFl  | kAudioBufDsvFl, "Audio Input" },
337 341
     { "out",     kAudioOutKr2Id,    0, 1,   kOutDsvFl | kAudioBufDsvFl, "Audio Output" },
338 342
     { NULL, 0, 0, 0, 0 }
@@ -355,7 +359,10 @@ cmDspInst_t*  _cmDspKr2Alloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned s
355 359
   cmDspSetDefaultDouble( ctx,&p->inst, kMixKr2Id,      0, 0.0 );
356 360
   
357 361
   cmDspSetDefaultSample( ctx,&p->inst, kWetKr2Id,      0, 1.0);
362
+  
363
+  cmDspSetDefaultDouble( ctx,&p->inst, kIgainKr2Id,    0, 0.0 );
358 364
 
365
+  
359 366
   //_cmDspKr2CmInit(ctx,p); // initialize the cm library
360 367
 
361 368
   p->ctx = cmCtxAlloc(NULL,ctx->rpt,ctx->lhH,ctx->stH);
@@ -504,11 +511,15 @@ cmDspRC_t _cmDspKr2Recv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* ev
504 511
     case kWetKr2Id:
505 512
       break;
506 513
 
514
+    case kIgainKr2Id:
515
+      p->sdp->igain = cmDspDouble(inst,kIgainKr2Id);
516
+      break;
517
+
507 518
     default:
508 519
       { assert(0); }
509 520
   }
510 521
 
511
-  cmSpecDist2Report(p->sdp);
522
+  //cmSpecDist2Report(p->sdp);
512 523
   
513 524
   return rc;
514 525
 }

+ 75
- 18
src/dsp/cmDspPgm.c View File

@@ -21,6 +21,7 @@
21 21
 #include "cmTime.h"
22 22
 #include "cmAudioSys.h"
23 23
 #include "cmProcObj.h"
24
+#include "cmPP_NARG.h"
24 25
 #include "cmDspCtx.h"
25 26
 #include "cmDspClass.h"
26 27
 #include "cmDspSys.h"
@@ -897,7 +898,7 @@ cmDspRC_t _cmDspSysPgm_UiTest(cmDspSysH_t h, void** userPtrPtr )
897 898
   cmDspInst_t* prp = cmDspSysAllocInst(h,"Printer", NULL,   1, ">" );
898 899
   cmDspInst_t* mtp = cmDspSysAllocInst(h,"Meter", "meter",  3, 0.0,  0.0, 4.0);
899 900
   cmDspInst_t* ctp = cmDspSysAllocInst(h,"Counter", NULL,   3, 0.0, 10.0, 1.0 );
900
-                     cmDspSysAllocInst(h,"Label",  "label1", 1, "label2");
901
+  cmDspInst_t* lbl = cmDspSysAllocInst(h,"Label",  "label1", 1, "label2");
901 902
   if((rc = cmDspSysLastRC(h)) != kOkDspRC )
902 903
     return rc;
903 904
 
@@ -923,6 +924,8 @@ cmDspRC_t _cmDspSysPgm_UiTest(cmDspSysH_t h, void** userPtrPtr )
923 924
   cmDspSysInstallCb(h, chb, "out", prp, "in", NULL );
924 925
   cmDspSysInstallCb(h, chb, "sym", prp, "in", NULL );
925 926
 
927
+  cmDspSysInstallCb(h, mdp, "val", lbl, "in", NULL );
928
+
926 929
   return rc;
927 930
 
928 931
 }
@@ -2054,8 +2057,8 @@ cmDspRC_t _cmDspSysPgm_ScalarOp( cmDspSysH_t h, void** userPtrPtr )
2054 2057
 {
2055 2058
   cmDspRC_t rc;
2056 2059
 
2057
-  cmDspInst_t* add   = cmDspSysAllocInst(   h, "ScalarOp", NULL,  6, 2, "+", "in-0", 0.0, "in-1", 0.0 );
2058
-  cmDspInst_t* mul0  = cmDspSysAllocInst(   h, "ScalarOp", NULL,  6, 2, "*", "in-0", 0.0, "in-1", 0.0 );
2060
+  cmDspInst_t* add   = cmDspSysAllocInst(   h, "ScalarOp", NULL,  6, 2, "+",  "in-0", 0.0, "in-1", 0.0 );
2061
+  cmDspInst_t* mul0  = cmDspSysAllocInst(   h, "ScalarOp", NULL,  6, 2, "*$", "in-0", 0.0, "in-1", 0.0 );
2059 2062
   cmDspInst_t* mul1  = cmDspSysAllocInst(   h, "ScalarOp", NULL,  6, 2, "*", "in-0", 0.0, "in-1", 0.0 );
2060 2063
   cmDspInst_t* in    = cmDspSysAllocScalar( h, "Input",      0.0, 10.0, 0.001, 0.0);
2061 2064
   cmDspInst_t* in_m  = cmDspSysAllocScalar( h, "Input_M",    0.0, 10.0, 0.001, 0.0);
@@ -2067,6 +2070,18 @@ cmDspRC_t _cmDspSysPgm_ScalarOp( cmDspSysH_t h, void** userPtrPtr )
2067 2070
   if((rc = cmDspSysLastRC(h)) != kOkDspRC )
2068 2071
     goto errLabel;
2069 2072
 
2073
+  // Notice that changing 'in' or 'in_m' causes 'out' to be recomputed, but other
2074
+  // changes are cached prior to 'add'.  This prevents the program from going into
2075
+  // an infinite loop.
2076
+  //
2077
+  //     in   -> mult0
2078
+  //     in_m -> mult0--+
2079
+  // +-->fb   -> mult1  +----> add
2080
+  // |   fb_m -> mult1-------> add --------+------> out
2081
+  // |                                     |
2082
+  // +-------------------------------------+
2083
+  //
2084
+  
2070 2085
   cmDspSysInstallCb( h, in,    "val", mul0, "in-0", NULL );
2071 2086
   cmDspSysInstallCb( h, in_m,  "val", mul0, "in-1", NULL );
2072 2087
   cmDspSysInstallCb( h, fb,    "val", mul1, "in-0", NULL );
@@ -2870,36 +2885,77 @@ cmDspRC_t _cmDspSysPgm_PortToSym( cmDspSysH_t h, void** userPtrPtr )
2870 2885
 {
2871 2886
   cmDspRC_t rc = kOkDspRC;
2872 2887
 
2873
-  cmDspInst_t* btn0  = cmDspSysAllocButton( h, "Btn0", 0.0 );
2874
-  cmDspInst_t* btn1  = cmDspSysAllocButton( h, "Btn1", 0.0 );
2875
-  cmDspInst_t* btn2  = cmDspSysAllocButton( h, "Btn2", 0.0 );  
2888
+  inst_t* btn0  = button( "Btn0", 0.0 );
2889
+  inst_t* btn1  = button( "Btn1", 0.0 );
2890
+  inst_t* btn2  = button( "Btn2", 0.0 );  
2876 2891
 
2877
-  cmDspInst_t* pts   = cmDspSysAllocInst( h, "PortToSym", NULL, 3, "one", "two", "three");
2892
+  inst_t* pts   = inst( "PortToSym", NULL, "one", "two", "three");
2878 2893
 
2879
-  cmDspInst_t* pr0  = cmDspSysAllocInst( h, "Printer", NULL, 1, "0:" );
2880
-  cmDspInst_t* pr1  = cmDspSysAllocInst( h, "Printer", NULL, 1, "1:" );
2894
+  inst_t* pr0  = inst( "Printer", NULL,  "sym:" );
2895
+  inst_t* pr1  = inst( "Printer", NULL,  "btn:" );
2896
+  inst_t* pr2  = inst( "Printer", NULL,  "out:" );
2881 2897
 
2882 2898
   // check for allocation errors
2883 2899
   if((rc = cmDspSysLastRC(h)) != kOkDspRC )
2884 2900
     goto errLabel;
2885 2901
   
2886
-  cmDspSysInstallCb(   h, btn0, "out", pts, "one",NULL);
2887
-  cmDspSysInstallCb(   h, btn1, "out", pts, "two",NULL);
2888
-  cmDspSysInstallCb(   h, btn2, "out", pts, "three",NULL);
2902
+  event( btn0, out, pts, one );
2903
+  event( btn1, out, pts, two );
2904
+  event( btn2, out, pts, three );
2905
+
2906
+  event( btn0, out, pr1, in );
2907
+  event( btn1, out, pr1, in );
2908
+  event( btn2, out, pr1, in );
2909
+
2910
+  event( pts,  one,   pr0, in );
2911
+  event( pts,  two,   pr0, in );
2912
+  event( pts,  three, pr0, in );
2913
+  event( pts,  out,   pr2, in );
2914
+
2915
+ errLabel:
2916
+  return rc;
2917
+}
2918
+
2919
+//------------------------------------------------------------------------------
2920
+//)
2921
+//( { label:cmDspPgm_IntToSym file_desc:"IntToSym example program." kw:[spgm] }
2922
+cmDspRC_t _cmDspSysPgm_IntToSym( cmDspSysH_t h, void** userPtrPtr )
2923
+{
2924
+  cmDspRC_t rc = kOkDspRC;
2889 2925
 
2890
-  cmDspSysInstallCb(   h, btn0, "out", pr1, "in",NULL);
2891
-  cmDspSysInstallCb(   h, btn1, "out", pr1, "in",NULL);
2892
-  cmDspSysInstallCb(   h, btn2, "out", pr1, "in",NULL);
2926
+  inst_t* sel0   = scalar( "Sel0", 0.0, 10.0, 1.0, 1.0 );
2927
+  inst_t* sel1   = scalar( "Sel1", 0.0, 10.0, 1.0, 1.0 );
2928
+  inst_t* sel2   = scalar( "Sel2", 0.0, 10.0, 1.0, 1.0 );
2929
+  inst_t* val    = scalar( "Val",  0.0, 10.0, 1.0, 1.0 );
2893 2930
 
2894
-  cmDspSysInstallCb(   h, pts,  "one",   pr0, "in", NULL );
2895
-  cmDspSysInstallCb(   h, pts,  "two",   pr0, "in", NULL );
2896
-  cmDspSysInstallCb(   h, pts,  "three", pr0, "in", NULL );
2931
+  inst_t* pts   = inst( "IntToSym", NULL, 0, "one", 0, "two", 0, "three");
2932
+
2933
+  inst_t* pr0  = inst( "Printer", NULL,  "val:" );
2934
+  inst_t* pr1  = inst( "Printer", NULL,  "sym:" );
2935
+  inst_t* pr2  = inst( "Printer", NULL,  "out:" );
2936
+
2937
+  // check for allocation errors
2938
+  if((rc = cmDspSysLastRC(h)) != kOkDspRC )
2939
+    goto errLabel;
2897 2940
 
2941
+  event( sel0, val, pts, one-int );
2942
+  event( sel1, val, pts, two-int );
2943
+  event( sel2, val, pts, three-int );
2944
+  
2945
+  event( val, val, pts, in );
2946
+  event( val, val, pr0, in );
2898 2947
 
2948
+  event( pts,  one,   pr1, in );
2949
+  event( pts,  two,   pr1, in );
2950
+  event( pts,  three, pr1, in );
2951
+  
2952
+  event( pts, out, pr2, in );
2953
+  
2899 2954
  errLabel:
2900 2955
   return rc;
2901 2956
 }
2902 2957
 
2958
+
2903 2959
 //------------------------------------------------------------------------------
2904 2960
 //)
2905 2961
 //( { label:cmDspPgm_Line file_desc:"Line generator example program." kw:[spgm] }
@@ -3288,6 +3344,7 @@ _cmDspSysPgm_t _cmDspSysPgmArray[] =
3288 3344
   { "line",              _cmDspSysPgm_Line,           NULL, NULL },
3289 3345
   { "1Up",               _cmDspSysPgm_1Up,            NULL, NULL },
3290 3346
   { "PortToSym",         _cmDspSysPgm_PortToSym,      NULL, NULL },
3347
+  { "IntToSym",          _cmDspSysPgm_IntToSym,       NULL, NULL },
3291 3348
   { "preset",            _cmDspSysPgm_Preset,         NULL, NULL },
3292 3349
   { "rsrcWr",            _cmDspSysPgm_RsrcWr,         NULL, NULL },
3293 3350
   { "router",            _cmDspSysPgm_Router,         NULL, NULL },

+ 13
- 4
src/dsp/cmDspPgmKrChain2.c View File

@@ -105,6 +105,7 @@ void _cmDspSys_TlXformChain( cmDspSysH_t h, cmDspTlXform_t* c,  unsigned preGrpS
105 105
   unsigned paramRtChCnt = 2;
106 106
   cmDspInst_t* wnd_rt   = cmDspSysAllocInst(h, "Router",      NULL,  2,  paramRtChCnt, paramRtChCnt-1 );
107 107
   cmDspInst_t* hop_rt   = cmDspSysAllocInst(h, "Router",      NULL,  2,  paramRtChCnt, paramRtChCnt-1 );
108
+  cmDspInst_t* ign_rt   = cmDspSysAllocInst(h, "Router",      NULL,  2,  paramRtChCnt, paramRtChCnt-1 );
108 109
   cmDspInst_t* cel_rt   = cmDspSysAllocInst(h, "Router",      NULL,  2,  paramRtChCnt, paramRtChCnt-1 );
109 110
   cmDspInst_t* exp_rt   = cmDspSysAllocInst(h, "Router",      NULL,  2,  paramRtChCnt, paramRtChCnt-1 );
110 111
   cmDspInst_t* mix_rt   = cmDspSysAllocInst(h, "Router",      NULL,  2,  paramRtChCnt, paramRtChCnt-1 );
@@ -118,7 +119,9 @@ void _cmDspSys_TlXformChain( cmDspSysH_t h, cmDspTlXform_t* c,  unsigned preGrpS
118 119
   cmDspInst_t* kr1  = cmDspSysAllocInst(h, "Kr2",        NULL,   2, krWndSmpCnt, krHopFact );
119 120
   cmDspInst_t* xfad = cmDspSysAllocInst(h, "Xfader",     NULL,   3, xfadeChCnt,  xfadeMs, xfadeInitFl ); 
120 121
   cmDspInst_t* mix  = cmDspSysAllocInst(h, "AMix",       NULL,   3, xfadeChCnt,  mixGain, mixGain );
121
-  cmDspInst_t* cmp  = cmDspSysAllocInst(h, "Compressor", NULL,   8, cmpBypassFl, cmpThreshDb, cmpRatio_num, cmpAtkMs, cmpRlsMs, cmpMakeup, cmpWndMs, cmpWndMaxMs ); 
122
+  cmDspInst_t* cmp  = cmDspSysAllocInst(h, "Compressor", NULL,   8, cmpBypassFl, cmpThreshDb, cmpRatio_num, cmpAtkMs, cmpRlsMs, cmpMakeup, cmpWndMs, cmpWndMaxMs );
123
+
124
+  
122 125
 
123 126
   // Internal audio connections
124 127
   cmDspSysConnectAudio(h, kr0,  "out",   xfad, "in-0");
@@ -158,6 +161,7 @@ void _cmDspSys_TlXformChain( cmDspSysH_t h, cmDspTlXform_t* c,  unsigned preGrpS
158 161
   cmDspSysNewColumn(h,0);
159 162
   cmDspInst_t* wnd_ctl = cmDspSysAllocMsgListP(h,preGrpSymId,NULL, lbl("WndSmpCnt"), NULL, "wndSmpCnt", 2);
160 163
   cmDspInst_t* hop_ctl = cmDspSysAllocMsgListP(h,preGrpSymId,NULL, lbl("HopFact"),   NULL, "hopFact",   2);
164
+  cmDspInst_t* ign_ctl = cmDspSysAllocScalarP( h,preGrpSymId,NULL, lbl("In Gain"),   0.0,  10.0, 0.001, 1.0 );
161 165
   cmDspInst_t* cel_ctl = cmDspSysAllocScalarP( h,preGrpSymId,NULL, lbl("Ceiling"),   0.0, 100.0, 0.1,  30.0 );
162 166
   cmDspInst_t* exp_ctl = cmDspSysAllocScalarP( h,preGrpSymId,NULL, lbl("Expo"),    -10.0,  10.0, 0.01,  2.0 );
163 167
   cmDspInst_t* mix_ctl = cmDspSysAllocScalarP( h,preGrpSymId,NULL, lbl("Mix"),       0.0,   1.0, 0.01,  0.0 );    
@@ -166,7 +170,6 @@ void _cmDspSys_TlXformChain( cmDspSysH_t h, cmDspTlXform_t* c,  unsigned preGrpS
166 170
   cmDspInst_t* lwr_ctl = cmDspSysAllocScalarP( h,preGrpSymId,NULL, lbl("Lwr slope"), 0.3,  10.0, 0.01,  2.0 );
167 171
   cmDspInst_t* wet_ctl = cmDspSysAllocScalarP( h,preGrpSymId,NULL, lbl("Wet Dry"),   0.0,   1.0, 0.001, 1.0 );
168 172
 
169
-  
170 173
   cmDspSysInstallCb(h, wnd_ctl, "out",         wnd_rt, "f-in",    NULL );
171 174
   cmDspSysInstallCb(h, achan,   "ch",          wnd_rt, "sel",     NULL );   // ach->rt sel
172 175
   cmDspSysInstallCb(h, wnd_rt,  "f-out-0",     kr0,    "wndn",    NULL );   // wndn->kr
@@ -176,7 +179,12 @@ void _cmDspSys_TlXformChain( cmDspSysH_t h, cmDspTlXform_t* c,  unsigned preGrpS
176 179
   cmDspSysInstallCb(h, achan,   "ch",          hop_rt, "sel",     NULL );   // ach->rt sel
177 180
   cmDspSysInstallCb(h, hop_rt,  "f-out-0",     kr0,    "hopf",    NULL );   // hopf->kr
178 181
   cmDspSysInstallCb(h, hop_rt,  "f-out-1",     kr1,    "hopf",    NULL );   // hopf->kr
179
-  
182
+
183
+  cmDspSysInstallCb(h, ign_ctl,     "val",     ign_rt, "f-in",    NULL );
184
+  cmDspSysInstallCb(h, achan,       "ch",      ign_rt, "sel",     NULL );   // ach->rt sel
185
+  cmDspSysInstallCb(h, ign_rt,      "f-out-0", kr0,    "igain",   NULL );   // ign->kr
186
+  cmDspSysInstallCb(h, ign_rt,      "f-out-1", kr1,    "igain",   NULL );   // ign->kr
187
+    
180 188
   cmDspSysInstallCb(h, thr_ctl,     "val",     thr_rt, "f-in",    NULL );
181 189
   cmDspSysInstallCb(h, achan,       "ch",      thr_rt, "sel",     NULL );   // ach->rt sel
182 190
   cmDspSysInstallCb(h, thr_rt,      "f-out-0", kr0,    "thrh",    NULL );   // thr->kr
@@ -260,6 +268,7 @@ void _cmDspSys_TlXformChain( cmDspSysH_t h, cmDspTlXform_t* c,  unsigned preGrpS
260 268
 
261 269
   
262 270
   cmDspSysInstallCb(h, modp, mlbl("hop"),  hop_ctl, "sel", NULL );
271
+  cmDspSysInstallCb(h, modp, mlbl("ign"),  ign_ctl, "val", NULL );
263 272
   cmDspSysInstallCb(h, modp, mlbl("ceil"), cel_ctl, "val", NULL );
264 273
   cmDspSysInstallCb(h, modp, mlbl("expo"), exp_ctl, "val", NULL );
265 274
   cmDspSysInstallCb(h, modp, mlbl("mix"),  mix_ctl, "val", NULL );
@@ -267,7 +276,7 @@ void _cmDspSys_TlXformChain( cmDspSysH_t h, cmDspTlXform_t* c,  unsigned preGrpS
267 276
   cmDspSysInstallCb(h, modp, mlbl("upr"),  upr_ctl, "val", NULL );
268 277
   cmDspSysInstallCb(h, modp, mlbl("lwr"),  lwr_ctl, "val", NULL );
269 278
   cmDspSysInstallCb(h, modp, mlbl("wet"),  wet_ctl, "val", NULL );
270
-  cmDspSysInstallCb(h, modp, mlbl("sw"),   achan,       "trig", NULL ); // See also: amp.sfloc->achan.trig
279
+  cmDspSysInstallCb(h, modp, mlbl("sw"),   achan,  "trig", NULL ); // See also: amp.sfloc->achan.trig
271 280
 
272 281
   
273 282
   c->achan = achan; 

+ 82
- 68
src/dsp/cmDspPgmKrTimeLineLiteAf.c View File

@@ -62,32 +62,30 @@ cmDspRC_t _cmDspSysPgm_TimeLineLiteAf(cmDspSysH_t h, void** userPtrPtr )
62 62
   //int baseAudioInCh =  0; // 2;
63 63
   int baseAudioOutCh = 0;//  2;
64 64
 
65
-  //cmDspInst_t* ai0 = cmDspSysAllocInst(h,"AudioIn",     NULL,  1, baseAudioInCh + 0);
66
-  //cmDspInst_t* ai1 = cmDspSysAllocInst(h,"AudioIn",     NULL,  1, baseAudioInCh + 1);
67
-  //cmDspInst_t* mip = cmDspSysAllocInst(h,"MidiIn",      NULL,  2, "MOTU - Traveler mk3", "MIDI Port");
68
-  //cmDspInst_t* mip = cmDspSysAllocInst(h,"MidiIn",      NULL,  2, "Apple Inc. - IAC Driver", "Bus 1");
69 65
   
70 66
   cmDspInst_t* tlp  = cmDspSysAllocInst(h,"TimeLine",    "tl",  2, r.tlFn, r.tlPrefixPath );
71 67
   cmDspInst_t* scp  = cmDspSysAllocInst(h,"Score",       "sc",  1, r.scFn );
72 68
   cmDspInst_t* pts  = cmDspSysAllocInst(h,"PortToSym",   NULL,  2, "on", "off" );
73 69
 
74
-  cmDspInst_t* php =  cmDspSysAllocInst(h,"Phasor",   NULL,  0 );
75
-  cmDspInst_t* wtp =  cmDspSysAllocInst(h,"WaveTable",NULL,  2, ((int)cmDspSysSampleRate(h)), 1 );
70
+  cmDspInst_t* php =  cmDspSysAllocInst(h,"Phasor",    NULL,  0 );
71
+  cmDspInst_t* wt0 =  cmDspSysAllocInst(h,"WaveTable", NULL,  7, ((int)cmDspSysSampleRate(h)), 1, NULL, -1, 0, -1, 0 );
72
+  cmDspInst_t* wt1 =  cmDspSysAllocInst(h,"WaveTable", NULL,  7, ((int)cmDspSysSampleRate(h)), 1, NULL, -1, 0, -1, 1 );
76 73
 
77 74
   
78 75
   cmDspInst_t* mfp  = cmDspSysAllocInst(h,"MidiFilePlay",NULL,  0 );
79 76
   cmDspInst_t* nmp  = cmDspSysAllocInst(h,"NanoMap",     NULL,  0 );
80
-  //cmDspInst_t* pic  = cmDspSysAllocInst(h,"Picadae",     NULL,  0 );
81
-  cmDspInst_t* mop  = cmDspSysAllocInst(h,"MidiOut",     NULL,  2, "Fastlane","Fastlane MIDI A" );
82
-  cmDspInst_t* mo2p = cmDspSysAllocInst(h,"MidiOut",     NULL,  2, "Fastlane","Fastlane MIDI B");
83 77
   cmDspInst_t* sfp  = cmDspSysAllocInst(h,"ScFol",       NULL,  5, r.scFn, sfBufCnt, sfMaxWndCnt, sfMinVel, sfEnaMeasFl );
84 78
   cmDspInst_t* amp  = cmDspSysAllocInst(h,"ActiveMeas",  NULL,  1, 100 );
85 79
   cmDspInst_t* modp = cmDspSysAllocInst(h,"ScMod",       NULL,  2, r.modFn, "m1" );
80
+  cmDspInst_t* its  = cmDspSysAllocInst(h,"IntToSym",    NULL,  2, 0, "off");
86 81
  
87 82
   unsigned   preGrpSymId     = cmDspSysPresetRegisterGroup(h,"tl");
88 83
   unsigned   cmpPreGrpSymId  = cmDspSysPresetRegisterGroup(h,"tl_cmp"); 
89 84
 
90 85
   cmDspTlXform_t c0,c1;
86
+  memset(&c0,0,sizeof(c0));
87
+  memset(&c1,0,sizeof(c1));
88
+    
91 89
 
92 90
   cmDspSysNewPage(h,"Controls-0");
93 91
   _cmDspSys_TlXformChain(h, &c0, preGrpSymId, cmpPreGrpSymId, amp, modp, 0, 0 );
@@ -95,14 +93,14 @@ cmDspRC_t _cmDspSysPgm_TimeLineLiteAf(cmDspSysH_t h, void** userPtrPtr )
95 93
   cmDspSysNewPage(h,"Controls-1");
96 94
   _cmDspSys_TlXformChain(h, &c1, preGrpSymId, cmpPreGrpSymId, amp, modp, 1, 1 );
97 95
 
96
+  cmDspInst_t* lmix = cmDspSysAllocInst(h, "AMix",      NULL, 1, 2 );
97
+  cmDspInst_t* rmix = cmDspSysAllocInst(h, "AMix",      NULL, 1, 2 );
98 98
 
99
-  cmDspInst_t* ao0 = cmDspSysAllocInst(h,"AudioOut",    NULL,   1, baseAudioOutCh+2 ); // 4 Piano     1 Output
100
-  cmDspInst_t* ao1 = cmDspSysAllocInst(h,"AudioOut",    NULL,   1, baseAudioOutCh+3 ); // 5          2
101
-  cmDspInst_t* ao2 = cmDspSysAllocInst(h,"AudioOut",    NULL,   1, baseAudioOutCh+0 ); // 2 Transform 1 OUtput
102
-  cmDspInst_t* ao3 = cmDspSysAllocInst(h,"AudioOut",    NULL,   1, baseAudioOutCh+1 ); // 3          2
99
+  cmDspInst_t* ao0 = cmDspSysAllocInst(h,"AudioOut",    NULL,   1, baseAudioOutCh+0 ); 
100
+  cmDspInst_t* ao1 = cmDspSysAllocInst(h,"AudioOut",    NULL,   1, baseAudioOutCh+1 ); 
103 101
 
104 102
   cmDspSysNewPage(h,"Main");
105
-  cmDspInst_t* notesOffb= cmDspSysAllocInst(h,"Button", "notesOff",   2, kButtonDuiId, 1.0 );
103
+  //cmDspInst_t* notesOffb= cmDspSysAllocInst(h,"Button", "notesOff",   2, kButtonDuiId, 1.0 );
106 104
   cmDspInst_t* onb     = cmDspSysAllocInst(h,"Button", "start",   2, kButtonDuiId, 1.0 );
107 105
   cmDspInst_t* offb    = cmDspSysAllocInst(h,"Button", "stop",    2, kButtonDuiId, 1.0 );
108 106
   cmDspInst_t* mod_sel = cmDspSysAllocMsgList(h, NULL, "mod_sel", 1 );
@@ -115,11 +113,7 @@ cmDspRC_t _cmDspSysPgm_TimeLineLiteAf(cmDspSysH_t h, void** userPtrPtr )
115 113
   // Record <-> Live switches
116 114
   cmDspInst_t* tlRt  = cmDspSysAllocInst(h,"Router", NULL, 2, 2, 0);  // time line swich
117 115
   cmDspInst_t* mfpRt = cmDspSysAllocInst(h,"Router", NULL, 2, 2, 0);
118
-  //cmDspInst_t* amRt  = cmDspSysAllocInst(h,"Router", NULL, 2, 2, 0);
119 116
 
120
-  //cmDspSysNewColumn(h,0);
121
-  //cmDspInst_t* igain0 = cmDspSysAllocInst(h,"Scalar", "In Gain-0",    5, kNumberDuiId, 0.0,   100.0,0.01,   1.0 );  
122
-  //cmDspInst_t* igain1 = cmDspSysAllocInst(h,"Scalar", "In Gain-1",    5, kNumberDuiId, 0.0,   100.0,0.01,   1.0 );  
123 117
 
124 118
   //cmDspSysNewColumn(h,0);
125 119
   cmDspInst_t* ogain0 = cmDspSysAllocInst(h,"Scalar", "Dry Out Gain-0",   5, kNumberDuiId, 0.0,   10.0,0.01,   1.0 );  
@@ -127,6 +121,16 @@ cmDspRC_t _cmDspSysPgm_TimeLineLiteAf(cmDspSysH_t h, void** userPtrPtr )
127 121
   cmDspInst_t* ogain2 = cmDspSysAllocInst(h,"Scalar", "Wet Out Gain-2",   5, kNumberDuiId, 0.0,   10.0,0.01,   1.0 );  
128 122
   cmDspInst_t* ogain3 = cmDspSysAllocInst(h,"Scalar", "Wet Out Gain-3",   5, kNumberDuiId, 0.0,   10.0,0.01,   1.0 );  
129 123
 
124
+  cmDspInst_t* ogainW = cmDspSysAllocInst(h,"Scalar", "Wet Master",   5, kNumberDuiId, 0.0,   10.0,0.01,   1.0 );  
125
+  cmDspInst_t* ogainD = cmDspSysAllocInst(h,"Scalar", "Dry Master",   5, kNumberDuiId, 0.0,   10.0,0.01,   1.0 );  
126
+
127
+  cmDspInst_t* gmult0  = cmDspSysAllocInst(h,"ScalarOp", NULL, 6, 2, "*$", "in-0", 1.0, "in-1", 1.0 );
128
+  cmDspInst_t* gmult1  = cmDspSysAllocInst(h,"ScalarOp", NULL, 6, 2, "*$", "in-0", 1.0, "in-1", 1.0 );
129
+  cmDspInst_t* gmult2  = cmDspSysAllocInst(h,"ScalarOp", NULL, 6, 2, "*$", "in-0", 1.0, "in-1", 1.0 );
130
+  cmDspInst_t* gmult3  = cmDspSysAllocInst(h,"ScalarOp", NULL, 6, 2, "*$", "in-0", 1.0, "in-1", 1.0 );
131
+  
132
+ 
133
+  
130 134
   // Audio file recording
131 135
   cmDspInst_t* recdGain= cmDspSysAllocInst(h,"Scalar", "Recd Gain",  5, kNumberDuiId, 0.0,   100.0,0.01, 1.5 );  
132 136
   cmDspInst_t* recdChk = cmDspSysAllocInst(h,"Button", "Record",     2, kCheckDuiId, 0.0 );
@@ -135,10 +139,13 @@ cmDspRC_t _cmDspSysPgm_TimeLineLiteAf(cmDspSysH_t h, void** userPtrPtr )
135 139
   cmDspInst_t* mi0p    = cmDspSysAllocInst(h,"AMeter","In 0",  0);
136 140
   cmDspInst_t* mi1p    = cmDspSysAllocInst(h,"AMeter","In 1",  0);
137 141
 
138
-  cmDspInst_t* meas    = cmDspSysAllocInst(h,"Scalar", "Meas",    5, kNumberDuiId, 1.0,   59.0,1.0,   1.0 );  
142
+  cmDspInst_t* meas    = cmDspSysAllocInst(h,"Scalar", "Begin Meas", 5, kNumberDuiId, 1.0, 1000.0, 1.0, 1.0 );  
143
+  cmDspInst_t* eloc    = cmDspSysAllocInst(h,"Scalar", "End   Loc",  5, kNumberDuiId, 1.0, 1000.0, 1.0, 1.0 );
144
+  cmDspInst_t* sfp_loc = cmDspSysAllocInst(h,"Label",  NULL, 1, "sf loc:");
145
+
139 146
   cmDspSysInstallCb( h, meas, "val", scp, "meas", NULL);
140 147
   cmDspSysInstallCb( h, meas, "val", tlp, "meas", NULL);
141
-
148
+  
142 149
 
143 150
 
144 151
 
@@ -173,37 +180,34 @@ cmDspRC_t _cmDspSysPgm_TimeLineLiteAf(cmDspSysH_t h, void** userPtrPtr )
173 180
   cmDspSysInstallCb(h, recdPtS, "out", afop,    "sel",   NULL );
174 181
 
175 182
   // Audio connections
176
-
177
-  cmDspSysConnectAudio(h, php, "out", wtp, "phs" );   // phasor -> wave table
178
-  cmDspSysConnectAudio(h, wtp, "out", ao0, "in" );    // wave table -> audio out (dry output)
179
-  cmDspSysConnectAudio(h, wtp, "out", ao1, "in" );    // 
180
-  
181
-  //cmDspSysConnectAudio( h, ai0,   "out", ao0,   "in" );  //  dry signal through 
182
-  //cmDspSysConnectAudio( h, ai1,   "out", ao1,   "in" );  //
183
+  cmDspSysConnectAudio(h, php, "out", wt0, "phs" );      // phasor -> wave table
184
+  cmDspSysConnectAudio(h, php, "out", wt1, "phs" );      // 
183 185
   
184
-  //cmDspSysConnectAudio( h, ai0,   "out", mi0p,   "in" );  //
185
-  //cmDspSysConnectAudio( h, ai0,   "out", c0.kr0, "in" );  // ain -> ch0.kr0
186
-  //cmDspSysConnectAudio( h, ai0,   "out", c0.kr1, "in" );  // ain -> ch0.kr1
186
+  cmDspSysConnectAudio(h, wt0, "out", lmix, "in-0" );    // wave table -> audio out (dry output)
187
+  cmDspSysConnectAudio(h, wt1, "out", rmix, "in-0" );    // 
187 188
 
188
-  cmDspSysConnectAudio( h, wtp,   "out", mi0p,   "in" );  //
189
-  cmDspSysConnectAudio( h, wtp,   "out", c0.kr0, "in" );  // ain -> ch0.kr0
190
-  cmDspSysConnectAudio( h, wtp,   "out", c0.kr1, "in" );  // ain -> ch0.kr1
189
+  //cmDspSysConnectAudio(h, wt0, "out", lmix, "in-1" );    // wave table -> audio out (dry output)
190
+  //cmDspSysConnectAudio(h, wt1, "out", rmix, "in-1" );    // 
191
+
192
+
193
+  cmDspSysConnectAudio( h, wt0,   "out", mi0p,   "in" );  //
194
+  cmDspSysConnectAudio( h, wt0,   "out", c0.kr0, "in" );  // ain -> ch0.kr0
195
+  cmDspSysConnectAudio( h, wt0,   "out", c0.kr1, "in" );  // ain -> ch0.kr1
191 196
 
192 197
   
193
-  cmDspSysConnectAudio( h, c0.cmp,"out", ao2,    "in" );  // ch0.cmp -> aout
198
+  cmDspSysConnectAudio( h, c0.cmp,"out", lmix,    "in-1" );  // ch0.cmp -> aout
194 199
   cmDspSysConnectAudio( h, c0.cmp,"out", afop,   "in0");  // ch0.cmp -> audio_file_out
195 200
 
196
-  //cmDspSysConnectAudio( h, ai1,   "out", mi1p,   "in" );  //
197
-  //cmDspSysConnectAudio( h, ai1,   "out", c1.kr0, "in" );  // ain -> ch1.kr0
198
-  //cmDspSysConnectAudio( h, ai1,   "out", c1.kr1, "in" );  // ain -> ch1.kr1
199 201
 
200
-  cmDspSysConnectAudio( h, wtp,   "out", mi1p,   "in" );  //
201
-  cmDspSysConnectAudio( h, wtp,   "out", c1.kr0, "in" );  // ain -> ch1.kr0
202
-  cmDspSysConnectAudio( h, wtp,   "out", c1.kr1, "in" );  // ain -> ch1.kr1
202
+  cmDspSysConnectAudio( h, wt1,   "out", mi1p,   "in" );  //
203
+  cmDspSysConnectAudio( h, wt1,   "out", c1.kr0, "in" );  // ain -> ch1.kr0
204
+  cmDspSysConnectAudio( h, wt1,   "out", c1.kr1, "in" );  // ain -> ch1.kr1
203 205
 
204
-  cmDspSysConnectAudio( h, c1.cmp,"out", ao3,    "in" );  // ch1.cmp -> aout
206
+  cmDspSysConnectAudio( h, c1.cmp,"out", rmix,    "in-1" );  // ch1.cmp -> aout
205 207
   cmDspSysConnectAudio( h, c1.cmp,"out", afop,   "in1");  // ch1.cmp ->audio_file_out
206 208
   
209
+  cmDspSysConnectAudio( h, lmix, "out", ao0, "in" );
210
+  cmDspSysConnectAudio( h, rmix, "out", ao1, "in" );
207 211
 
208 212
 
209 213
   cmDspSysInstallCb( h, clrBtn, "sym",    amp, "cmd",   NULL ); // clear active meas.
@@ -252,8 +256,9 @@ cmDspRC_t _cmDspSysPgm_TimeLineLiteAf(cmDspSysH_t h, void** userPtrPtr )
252 256
   cmDspSysInstallCb( h, sfp, "vcost",prt,   "in",  NULL ); //
253 257
   cmDspSysInstallCb( h, sfp, "vtyp", prc,   "in", NULL ); //
254 258
   */
259
+  
255 260
   // wave-table to time-line cursor
256
-  //cmDspSysInstallCb(   h, wtp, "fidx",tlp,  "curs", NULL); 
261
+  cmDspSysInstallCb(   h, wt0, "fidx",tlp,  "curs", NULL); 
257 262
 
258 263
   cmDspSysInstallCb(h, prePath, "out", tlp, "path", NULL );
259 264
 
@@ -267,7 +272,8 @@ cmDspRC_t _cmDspSysPgm_TimeLineLiteAf(cmDspSysH_t h, void** userPtrPtr )
267 272
   cmDspSysInstallCb(h, mfpRt,"s-out-0",mfp,  "sel",   NULL );
268 273
 
269 274
   cmDspSysInstallCb(h, onb, "sym",     pts,     "on",     NULL );
270
-  cmDspSysInstallCb(h, pts, "on",      wtp,     "cmd",    NULL );
275
+  cmDspSysInstallCb(h, pts, "on",      wt0,     "cmd",    NULL );
276
+  cmDspSysInstallCb(h, pts, "on",      wt1,     "cmd",    NULL );
271 277
   cmDspSysInstallCb(h, pts, "on",      modp,    "cmd",    NULL );
272 278
   cmDspSysInstallCb(h, onb, "sym",     amCmd,   "rewind", NULL );
273 279
   cmDspSysInstallCb(h, onb, "out",     c0.achan,"reset",  NULL );
@@ -278,11 +284,10 @@ cmDspRC_t _cmDspSysPgm_TimeLineLiteAf(cmDspSysH_t h, void** userPtrPtr )
278 284
   // stop connections
279 285
   cmDspSysInstallCb(h, tlp,  "mfn", pts, "off",   NULL ); // Prevents WT start on new audio file from TL.
280 286
   cmDspSysInstallCb(h, offb, "sym", mfp, "sel",   NULL ); 
281
-  cmDspSysInstallCb(h, offb, "sym", pts, "off",   NULL );
282
-  cmDspSysInstallCb(h, pts,  "off", wtp, "cmd",   NULL );
287
+  cmDspSysInstallCb(h, offb, "sym", pts, "off",   NULL );  
288
+  cmDspSysInstallCb(h, pts,  "off", wt0, "cmd",   NULL );
289
+  cmDspSysInstallCb(h, pts,  "off", wt1, "cmd",   NULL );
283 290
   cmDspSysInstallCb(h, pts,  "off", modp,"cmd",   NULL );
284
-  cmDspSysInstallCb(h, offb, "sym", mop, "reset", NULL );
285
-  cmDspSysInstallCb(h, offb, "sym", mo2p,"reset", NULL );
286 291
 
287 292
 
288 293
   // time-line to MIDI file player selection
@@ -292,9 +297,13 @@ cmDspRC_t _cmDspSysPgm_TimeLineLiteAf(cmDspSysH_t h, void** userPtrPtr )
292 297
 
293 298
 
294 299
   // time-line to Audio file player selection
295
-  cmDspSysInstallCb(h, tlp, "absi", wtp, "beg",   NULL );
296
-  cmDspSysInstallCb(h, tlp, "aesi", wtp, "end",   NULL );
297
-  cmDspSysInstallCb(h, tlp, "afn",  wtp, "fn",    NULL );
300
+  cmDspSysInstallCb(h, tlp, "absi", wt0, "beg",   NULL );
301
+  cmDspSysInstallCb(h, tlp, "aesi", wt0, "end",   NULL );
302
+  cmDspSysInstallCb(h, tlp, "afn",  wt0, "fn",    NULL );
303
+
304
+  cmDspSysInstallCb(h, tlp, "absi", wt1, "beg",   NULL );
305
+  cmDspSysInstallCb(h, tlp, "aesi", wt1, "end",   NULL );
306
+  cmDspSysInstallCb(h, tlp, "afn",  wt1, "fn",    NULL );
298 307
   
299 308
   // score to score follower - to set initial search location
300 309
   cmDspSysInstallCb(h, scp, "sel",    sfp, "index", NULL );
@@ -309,41 +318,46 @@ cmDspRC_t _cmDspSysPgm_TimeLineLiteAf(cmDspSysH_t h, void** userPtrPtr )
309 318
 
310 319
   cmDspSysInstallCb(h, msrc,   "d1",     sfp,  "d1",    NULL );
311 320
   cmDspSysInstallCb(h, msrc,   "d1",     nmp,  "d1",    NULL );
312
-  cmDspSysInstallCb(h, nmp,   "d1",     mop,  "d1",    NULL );
313
-  //cmDspSysInstallCb(h, nmp,   "d1",     pic, "d1",    NULL );
314
-  //cmDspSysInstallCb(h, pic,   "d1",     mo2p, "d1",    NULL );
315 321
 
316 322
   cmDspSysInstallCb(h, msrc,  "d0",      sfp,  "d0",   NULL );
317 323
   cmDspSysInstallCb(h, msrc,  "d0",      nmp,  "d0",   NULL );
318
-  cmDspSysInstallCb(h, nmp,  "d0",      mop,  "d0",   NULL );
319
-  //cmDspSysInstallCb(h, nmp,  "d0",      pic, "d0",   NULL );
320
-  //cmDspSysInstallCb(h, pic,   "d0",     mo2p, "d0",    NULL );
321 324
 
322 325
   cmDspSysInstallCb(h, msrc,  "status",  sfp,  "status",NULL );
323 326
   cmDspSysInstallCb(h, msrc,  "status",  nmp,  "status",NULL );
324
-  cmDspSysInstallCb(h, nmp,  "status",  mop,  "status",NULL );
325
-  //cmDspSysInstallCb(h, nmp,  "status",  pic, "status",NULL );
326
-  //cmDspSysInstallCb(h, pic,   "status",  mo2p, "status",    NULL );
327 327
 
328 328
 
329 329
   // score follower to recd_play,modulator and printers
330 330
   cmDspSysInstallCb(h, sfp, "out",     modp,    "index", NULL );
331
-  cmDspSysInstallCb(h, sfp, "recent",  prp,     "in",  NULL );  // report 'recent' but only act on 'max' loc index
332
-
333
-  //cmDspSysInstallCb(h, igain0, "val", ai0, "gain", NULL );   // input gain control
334
-  //cmDspSysInstallCb(h, igain1, "val", ai1, "gain", NULL );
331
+  cmDspSysInstallCb(h, sfp, "recent",  sfp_loc,   "in",  NULL );  // report 'recent' but only act on 'max' loc index
335 332
 
333
+  cmDspSysInstallCb( h, eloc , "val", its,  "off-int", NULL);
334
+  cmDspSysInstallCb( h, sfp,   "out", its,  "in",  NULL);
335
+  cmDspSysInstallCb( h, its,   "out", offb, "in",  NULL);
336
+  cmDspSysInstallCb( h, its,   "out", prp, "in",  NULL);
337
+  
336 338
 
337
-  cmDspSysInstallCb(h, modp, "dgain0",  ogain0, "val",  NULL );
339
+  cmDspSysInstallCb(h, modp, "dgain0",  ogain0, "val",  NULL ); // mod -> ogain
338 340
   cmDspSysInstallCb(h, modp, "dgain1",  ogain1, "val",  NULL );
339 341
   cmDspSysInstallCb(h, modp, "wgain0",  ogain2, "val",  NULL );
340 342
   cmDspSysInstallCb(h, modp, "wgain1",  ogain3, "val",  NULL );
341 343
 
342
-  cmDspSysInstallCb(h, ogain0, "val", ao0, "gain", NULL );   // output gain control - dry 0
343
-  cmDspSysInstallCb(h, ogain1, "val", ao1, "gain", NULL );   //                       dry 1
344
-  cmDspSysInstallCb(h, ogain2, "val", ao2, "gain", NULL );   //                       wet 0
345
-  cmDspSysInstallCb(h, ogain3, "val", ao3, "gain", NULL );   //                       wet 1
346 344
 
345
+  cmDspSysInstallCb(h, ogain0,  "val", gmult0, "in-0", NULL ); // ogain scalars -> gmult 0
346
+  cmDspSysInstallCb(h, ogain1,  "val", gmult1, "in-0", NULL );
347
+  cmDspSysInstallCb(h, ogain2,  "val", gmult2, "in-0", NULL );
348
+  cmDspSysInstallCb(h, ogain3,  "val", gmult3, "in-0", NULL );
349
+  
350
+  cmDspSysInstallCb(h, ogainD,  "val", gmult0, "in-1", NULL ); // master scalars -> gmult 1
351
+  cmDspSysInstallCb(h, ogainD,  "val", gmult1, "in-1", NULL );
352
+  cmDspSysInstallCb(h, ogainW,  "val", gmult2, "in-1", NULL );
353
+  cmDspSysInstallCb(h, ogainW,  "val", gmult3, "in-1", NULL );
354
+  
355
+  cmDspSysInstallCb(h, gmult0, "out", lmix, "gain-0", NULL );   // gmult -> wdmix - l dry 
356
+  cmDspSysInstallCb(h, gmult1, "out", rmix, "gain-0", NULL );   //                  r dry
357
+  cmDspSysInstallCb(h, gmult2, "out", lmix, "gain-1", NULL );   //                  l wet
358
+  cmDspSysInstallCb(h, gmult3, "out", rmix, "gain-1", NULL );   //                  r wet
359
+
360
+  //cmDspSysInstallCb(h, gmult2, "out", prp, "in", NULL );
347 361
 
348 362
   return rc;
349 363
 }

+ 13
- 2
src/dsp/cmDspSys.h View File

@@ -109,8 +109,7 @@ extern "C" {
109 109
   cmDspRC_t    cmDspSysInsertHorzBorder( cmDspSysH_t h );
110 110
 
111 111
   cmDspRC_t    cmDspSysNewPage( cmDspSysH_t h, const cmChar_t* title );
112
-
113
-
112
+  
114 113
   //----------------------------------------------------------------------------------------------------
115 114
   // Connection Functions.
116 115
   //
@@ -278,6 +277,18 @@ extern "C" {
278 277
 
279 278
   //)
280 279
 
280
+  typedef cmDspInst_t inst_t;
281
+  
282
+#define inst( classLabel, instLabel, ... )       cmDspSysAllocInst( h, classLabel, instLabel, PP_NARG(__VA_ARGS__), __VA_ARGS__ )
283
+#define button( label, real_val )                cmDspSysAllocButton(  h, label, real_val )
284
+#define scalar( label, rmin, rmax, rstep, rval ) cmDspSysAllocScalar(  h, label, rmin, rmax, rstep, rval )
285
+
286
+  
287
+#define audio( src, sarg, dst, darg )      cmDspSysConnectAudio( h, src, #sarg, dst, #darg )
288
+#define event( src, sarg, dst, darg )      cmDspSysInstallCb( h, src, #sarg, dst, #darg, NULL )
289
+
290
+  
291
+  
281 292
 #ifdef __cplusplus
282 293
   }
283 294
 #endif

+ 4
- 0
src/dsp/cmDspUi.c View File

@@ -188,6 +188,9 @@ cmDspRC_t _cmDspUiUseInstSymbolAsLabel( cmDspCtx_t* ctx, cmDspInst_t* inst, unsi
188 188
 cmDspRC_t  cmDspSendValueToAudioSys( cmDspCtx_t* ctx, unsigned msgTypeId, unsigned selId, unsigned valId, const cmDspValue_t* valPtr )
189 189
 { return _cmDspUiMsg(ctx, msgTypeId, selId, 0, NULL, valId, valPtr ); }
190 190
 
191
+cmDspRC_t cmDspProgramIsDone( cmDspCtx_t* ctx )
192
+{ return _cmDspUiMsg(ctx, kUiSelAsId, kPgmDoneDuiId, 0, NULL, cmInvalidId, NULL ); }
193
+
191 194
 cmDspRC_t   cmDspUiConsolePrint( cmDspCtx_t* ctx, cmChar_t* text )
192 195
 {
193 196
   cmDspValue_t v;
@@ -514,3 +517,4 @@ cmDspRC_t  cmDspUiNewPage(          cmDspCtx_t* ctx, const cmChar_t* title )
514 517
 
515 518
   return rc;
516 519
 }
520
+

+ 73
- 0
src/dsp/cmDspValue.c View File

@@ -1527,3 +1527,76 @@ void cmDsvPrint( const cmDspValue_t* vp, const cmChar_t* label, cmRpt_t* rpt )
1527 1527
     }
1528 1528
   }
1529 1529
 }
1530
+
1531
+void cmDsvToString( const cmDspValue_t* vp, const cmChar_t* label, cmChar_t* s, unsigned sN )
1532
+{
1533
+  vp = _vcptr(vp); 
1534
+
1535
+  const char* noLbl="";
1536
+  const char* lbl  = label==NULL? noLbl : label;
1537
+
1538
+  if( cmDsvIsMtx(vp) )
1539
+  {
1540
+    unsigned i,j;
1541
+    unsigned rn = cmDsvCols(vp);
1542
+    unsigned cn = cmDsvRows(vp);
1543
+    for(i=0; i<rn; ++i)
1544
+    {
1545
+      for(j=0; j<cn && sN>2; ++j)
1546
+      {
1547
+        switch( cmDsvBasicType(vp) )
1548
+        {
1549
+          case kCharDsvFl:   snprintf(s,sN,"%s%c ",lbl,vp->u.m.u.cp[  (j*rn) + i ]); break;
1550
+          case kUCharDsvFl:  snprintf(s,sN,"%s%c ",lbl,vp->u.m.u.ucp[ (j*rn) + i ]); break;
1551
+          case kShortDsvFl:  snprintf(s,sN,"%s%i ",lbl,vp->u.m.u.sp[  (j*rn) + i ]); break;
1552
+          case kUShortDsvFl: snprintf(s,sN,"%s%i ",lbl,vp->u.m.u.usp[ (j*rn) + i ]); break;
1553
+          case kLongDsvFl:   snprintf(s,sN,"%s%li ",lbl,vp->u.m.u.lp[  (j*rn) + i ]); break;
1554
+          case kULongDsvFl:  snprintf(s,sN,"%s%li ",lbl,vp->u.m.u.ulp[ (j*rn) + i ]); break;
1555
+          case kIntDsvFl:    snprintf(s,sN,"%s%i ",lbl,vp->u.m.u.ip[  (j*rn) + i ]); break;
1556
+          case kUIntDsvFl:   snprintf(s,sN,"%s%i ",lbl,vp->u.m.u.up[  (j*rn) + i ]); break;
1557
+          case kFloatDsvFl:  snprintf(s,sN,"%s%f ",lbl,vp->u.m.u.fp[  (j*rn) + i ]); break;
1558
+          case kDoubleDsvFl: snprintf(s,sN,"%s%f ",lbl,vp->u.m.u.dp[  (j*rn) + i ]); break;
1559
+          case kSampleDsvFl: snprintf(s,sN,"%s%f ",lbl,vp->u.m.u.ap[  (j*rn) + i ]); break;
1560
+          case kRealDsvFl:   snprintf(s,sN,"%s%f ",lbl,vp->u.m.u.rp[  (j*rn) + i ]); break;
1561
+          case kStrzDsvFl:   snprintf(s,sN,"%s%s ",lbl,vp->u.m.u.zp[  (j*rn) + i ]); break;
1562
+          case kJsonDsvFl:   cmJsonLeafToString(vp->u.m.u.jp[ (j*rn) + i ],s,sN);   break;    
1563
+          default:
1564
+            { assert(0); }
1565
+        }
1566
+
1567
+        unsigned n = strlen(s);
1568
+        sN -= n;
1569
+        s  += n;
1570
+        
1571
+        
1572
+      }
1573
+      if( sN > 2 )
1574
+        snprintf(s,sN,"\n");
1575
+    }
1576
+  }
1577
+  else
1578
+  {
1579
+    switch( cmDsvBasicType(vp) )
1580
+    {
1581
+      case kBoolDsvFl:   snprintf(s,sN,"%s%s ",lbl,vp->u.b ? "true" : "false"); break;
1582
+      case kCharDsvFl:   snprintf(s,sN,"%s%c ",lbl,vp->u.c);  break;
1583
+      case kUCharDsvFl:  snprintf(s,sN,"%s%c ",lbl,vp->u.uc); break;
1584
+      case kShortDsvFl:  snprintf(s,sN,"%s%i ",lbl,vp->u.s);  break;
1585
+      case kUShortDsvFl: snprintf(s,sN,"%s%i ",lbl,vp->u.us); break;
1586
+      case kLongDsvFl:   snprintf(s,sN,"%s%li ",lbl,vp->u.l);  break;
1587
+      case kULongDsvFl:  snprintf(s,sN,"%s%li ",lbl,vp->u.ul); break;
1588
+      case kIntDsvFl:    snprintf(s,sN,"%s%i ",lbl,vp->u.i);  break;
1589
+      case kUIntDsvFl:   snprintf(s,sN,"%s%i ",lbl,vp->u.u);  break;
1590
+      case kFloatDsvFl:  snprintf(s,sN,"%s%f ",lbl,vp->u.f);  break;
1591
+      case kDoubleDsvFl: snprintf(s,sN,"%s%f ",lbl,vp->u.d);  break;
1592
+      case kSampleDsvFl: snprintf(s,sN,"%s%f ",lbl,vp->u.a);  break;
1593
+      case kRealDsvFl:   snprintf(s,sN,"%s%f ",lbl,vp->u.r);  break;
1594
+      case kPtrDsvFl:    snprintf(s,sN,"%s%p ",lbl,vp->u.vp); break;
1595
+      case kStrzDsvFl:   snprintf(s,sN,"%s%s ",lbl,vp->u.z);  break;
1596
+      case kSymDsvFl:    snprintf(s,sN,"%s%i ",lbl,vp->u.u); break;
1597
+      case kJsonDsvFl:   cmJsonLeafToString(vp->u.j,s,sN);   break;    
1598
+      default:
1599
+        { assert(0); }
1600
+    }
1601
+  }
1602
+}

+ 1
- 0
src/dsp/cmDspValue.h View File

@@ -331,6 +331,7 @@ extern "C" {
331 331
   cmDsvRC_t cmDsvDeserializeJson(     cmDspValue_t* vp, cmJsonH_t jsH );
332 332
 
333 333
   void     cmDsvPrint( const cmDspValue_t* vp, const cmChar_t* label,  cmRpt_t* rpt );
334
+  void     cmDsvToString( const cmDspValue_t* vp, const cmChar_t* label,  cmChar_t* s, unsigned sN );
334 335
 
335 336
   //)
336 337
   

Loading…
Cancel
Save