Переглянути джерело

cmDspFx.c : Rewrote AvailCh.

master
kevin 9 роки тому
джерело
коміт
65706fc435
1 змінених файлів з 128 додано та 52 видалено
  1. 128
    52
      dsp/cmDspFx.c

+ 128
- 52
dsp/cmDspFx.c Переглянути файл

@@ -5797,6 +5797,11 @@ struct cmDspClass_str* cmRouterClassCons( cmDspCtx_t* ctx )
5797 5797
 //                 'false' is transmitted to notify the channel that it should shutdown.
5798 5798
 //                 The channel is not considered actually shutdown until dis[i]
5799 5799
 //                 recieves a 'false'.
5800
+//   ch            The next prospective next available channel is sent whenever it
5801
+//                 becomes available.  A next channel becomes available when
5802
+//                 a channel is marked as inactive via dis[i] or when
5803
+//                 a new channel is made active, via trigger, and another
5804
+//                 channel active channel exists.
5800 5805
 // Notes:
5801 5806
 //   The gate[] output is designed to work with the gate[] input of Xfader.  When
5802 5807
 //   availCh.gate[] goes high Xfader fades in, when availCh.gate[] goes low
@@ -5825,6 +5830,8 @@ typedef struct
5825 5830
   unsigned      baseDisInAvId;
5826 5831
   unsigned      baseGateOutAvId;
5827 5832
   bool*         stateArray;
5833
+  unsigned      nextAvailChIdx;
5834
+  unsigned      audioCycleCnt;
5828 5835
 } cmDspAvailCh_t;
5829 5836
 
5830 5837
 cmDspInst_t*  _cmDspAvailCh_Alloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned storeSymId, unsigned instSymId, unsigned id, unsigned va_cnt, va_list vl )
@@ -5864,11 +5871,13 @@ cmDspInst_t*  _cmDspAvailCh_Alloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsig
5864 5871
 
5865 5872
   p->baseDisInAvId   =  baseDisInAvId;
5866 5873
   p->baseGateOutAvId =  baseGateOutAvId;
5874
+  p->nextAvailChIdx  = cmInvalidIdx;
5875
+  p->audioCycleCnt   = 0;
5867 5876
 
5868 5877
   unsigned i;
5869 5878
   for(i=0; i<chCnt; ++i)
5870 5879
   {
5871
-    cmDspSetDefaultBool( ctx, &p->inst, baseDisInAvId+i,  false, false );
5880
+    cmDspSetDefaultBool( ctx, &p->inst, baseDisInAvId+i,   false, false );
5872 5881
     cmDspSetDefaultBool( ctx, &p->inst, baseGateOutAvId+i, false, false );
5873 5882
   }
5874 5883
   cmDspSetDefaultUInt( ctx, &p->inst, kModeAvId,  0, kExclusiveModeAvId );
@@ -5884,11 +5893,104 @@ cmDspRC_t _cmDspAvailCh_Free(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_
5884 5893
   return kOkDspRC;
5885 5894
 }
5886 5895
 
5896
+cmDspRC_t _cmDspAvailCh_DoReset( cmDspCtx_t* ctx, cmDspInst_t* inst )
5897
+{
5898
+  unsigned i;      
5899
+  cmDspAvailCh_t* p = (cmDspAvailCh_t*)inst;
5900
+    
5901
+  // ch 0 is the channel receiving parameters
5902
+  cmDspSetUInt(ctx,inst,kChIdxAvId,0); 
5903
+    
5904
+  for(i=0; i<p->chCnt; ++i)
5905
+  {
5906
+    cmDspSetBool(ctx, inst, p->baseDisInAvId   + i, i==0); // disable all channels except ch zero
5907
+    cmDspSetBool(ctx, inst, p->baseGateOutAvId + i, i==0); // enable channel 0
5908
+  }
5909
+    
5910
+  p->audioCycleCnt  = 0;
5911
+  p->nextAvailChIdx = cmInvalidIdx;
5912
+    
5913
+  // transmit reset
5914
+  cmDspSetBool(ctx,inst, kResetAvId, false );
5915
+
5916
+  return kOkDspRC;  
5917
+}
5918
+
5919
+
5887 5920
 cmDspRC_t _cmDspAvailCh_Reset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
5888 5921
 {
5889
-  return cmDspApplyAllDefaults(ctx,inst);
5922
+  cmDspRC_t rc;
5923
+  if((rc = cmDspApplyAllDefaults(ctx,inst)) == kOkDspRC )
5924
+  {
5925
+    rc = _cmDspAvailCh_DoReset(ctx,inst);
5926
+  }
5927
+  return rc;
5890 5928
 }
5891 5929
 
5930
+void _cmDspAvailCh_SetNextAvailCh( cmDspCtx_t* ctx, cmDspInst_t* inst, bool warnFl )
5931
+{
5932
+  cmDspAvailCh_t* p = (cmDspAvailCh_t*)inst;
5933
+  unsigned i;
5934
+   
5935
+  if( p->nextAvailChIdx != cmInvalidIdx )
5936
+    return;
5937
+
5938
+  for(i=0; i<p->chCnt; ++i)
5939
+  {
5940
+    // the channel's active state is held in the 'dis' variable.
5941
+    bool activeFl = cmDspBool(inst,p->baseDisInAvId+i);
5942
+    
5943
+    // if ch[i] is the first avail inactive channel
5944
+    if( !activeFl )
5945
+    {
5946
+      p->nextAvailChIdx  = i;     // set the next available channel
5947
+      break;
5948
+    }
5949
+      
5950
+  }
5951
+
5952
+  // if no available channels were found
5953
+  if( p->nextAvailChIdx == cmInvalidIdx && warnFl )
5954
+    cmDspInstErr(ctx,inst,kInvalidStateDspRC,"No available channels exist.");
5955
+  else
5956
+  {
5957
+    // Notify the external world which channel is to be used next.
5958
+    // This allows routers which are switching parameters between
5959
+    // xfade channels to switch new parameter values to go to the
5960
+    // next available channel rather than the current channel.
5961
+    // The next available channel will then be faded up with the
5962
+    // new parameters on the next trigger command.
5963
+    cmDspSetUInt(ctx,inst,kChIdxAvId,p->nextAvailChIdx); 
5964
+  }  
5965
+}
5966
+
5967
+cmDspRC_t _cmDspAvailCh_Exec( cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
5968
+{
5969
+  cmDspRC_t       rc = kOkDspRC;
5970
+  cmDspAvailCh_t* p  = (cmDspAvailCh_t*)inst;
5971
+
5972
+  p->audioCycleCnt += 1;
5973
+
5974
+  // Setting the next available channel here solves the problem of doing the
5975
+  // first 'ch' output after the program starts executing.
5976
+  // The problem is that 'ch' should be set to 0 for at least the first
5977
+  // execution cycle so that parameters may be set to the initial active channel
5978
+  // during the first cycle.  After the first cycle however parameters should be
5979
+  // sent to the next channel which will be faded up.  Setting
5980
+  // 'ch' here accomplishes this without relying on an external signal.
5981
+  // Note that we wait until the second cycle because we don't know where
5982
+  // this 'availCh' will be in the execution cycle relative to other processors.
5983
+  // If it is at the beginning then other processors that might be setting
5984
+  // initial parameters will not have had a chance to run before the
5985
+  // 'ch' change.  Waiting unitl the second cycle guarantees that all the
5986
+  // other processors had at least one chance to run.
5987
+  if( p->audioCycleCnt == 2 )
5988
+  {
5989
+    _cmDspAvailCh_SetNextAvailCh(ctx,inst,true);
5990
+  }
5991
+  
5992
+  return rc;
5993
+}
5892 5994
 
5893 5995
 cmDspRC_t _cmDspAvailCh_Recv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
5894 5996
 { 
@@ -5897,79 +5999,53 @@ cmDspRC_t _cmDspAvailCh_Recv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_
5897 5999
 
5898 6000
   bool exclModeFl  = cmDspUInt(inst, kModeAvId ) == kExclusiveModeAvId;
5899 6001
 
6002
+  // if this is a reset
5900 6003
   if( evt->dstVarId == kResetAvId )
5901 6004
   {
5902
-    unsigned i;      
5903
-
5904
-    cmDspSetUInt(ctx,inst,kChIdxAvId,0);
5905
-
5906
-    for(i=0; i<p->chCnt; ++i)
5907
-    {
5908
-      bool fl = i==0;
5909
-      cmDspSetBool(ctx, inst, p->baseDisInAvId   + i, !fl);
5910
-      cmDspSetBool(ctx, inst, p->baseGateOutAvId + i, fl);
5911
-    }
5912
-
5913
-    cmDspSetBool(ctx,inst, kResetAvId, false );
5914
-
5915
-    return rc;
6005
+    return _cmDspAvailCh_DoReset(ctx,inst);
5916 6006
   }
5917 6007
 
5918 6008
   // if this is a trigger
5919 6009
   if( evt->dstVarId == kTrigAvId )
5920 6010
   {
5921
-    unsigned i,j=-1;
5922
-    bool     fl = true;
5923
-    for(i=0; i<p->chCnt; ++i)
5924
-    {
5925
-      // the channel's active state is held in the 'dis' variable.
5926
-      bool activeFl = cmDspBool(inst,p->baseDisInAvId+i);
5927
-
5928
-      // if ch[i] is the first avail inactive channel
5929
-      if( fl && !activeFl )
5930
-      {
5931
-        // activate the available channel
5932
-        //cmDspSetUInt(ctx,inst,kChIdxAvId,j);
5933
-        //cmDspSetBool(ctx, inst, p->baseDisInAvId   + j, true);
5934
-        //cmDspSetBool(ctx, inst, p->baseGateOutAvId + j, true);
5935
-
5936
-        j  = i;
5937
-        fl = false;
5938
-      }
5939
-
5940
-      // if ch[i] is active - then request that it shutdown 
5941
-      //if( activeFl && exclModeFl)
5942
-      //  cmDspSetBool(ctx, inst, p->baseGateOutAvId + i, false);
5943
-
5944
-    }
5945
-
5946
-    if( j==-1 )
5947
-      cmDspInstErr(ctx,inst,kInvalidStateDspRC,"No available channels exist.");
6011
+    // if no available channels were previously found
6012
+    if( p->nextAvailChIdx == cmInvalidIdx )
6013
+      cmDspInstErr(ctx,inst,kInvalidStateDspRC,"There are no available channels to trigger.");
5948 6014
     else
5949 6015
     {
5950
-      // activate the available channel
5951
-      cmDspSetUInt(ctx,inst,kChIdxAvId,j);
5952
-      cmDspSetBool(ctx, inst, p->baseDisInAvId   + j, true);
5953
-      cmDspSetBool(ctx, inst, p->baseGateOutAvId + j, true);
6016
+      // indicate that the next channel is no longer available
6017
+      cmDspSetBool(ctx, inst, p->baseDisInAvId   + p->nextAvailChIdx, true);
6018
+
6019
+      // raise the gate to start the xfade.
6020
+      cmDspSetBool(ctx, inst, p->baseGateOutAvId + p->nextAvailChIdx, true); 
5954 6021
 
5955 6022
       if( exclModeFl )
5956 6023
       {
6024
+        unsigned i;
5957 6025
         for(i=0; i<p->chCnt; ++i)
5958
-          if( i!=j && cmDspBool(inst,p->baseDisInAvId+i) )
6026
+          if( i!=p->nextAvailChIdx && cmDspBool(inst,p->baseDisInAvId+i) )
5959 6027
             cmDspSetBool(ctx,inst, p->baseGateOutAvId+i, false );
5960 6028
       }
6029
+
6030
+      p->nextAvailChIdx = cmInvalidIdx;
6031
+      
6032
+      // It may be possible to know the next avail ch so try to set it here.
6033
+      _cmDspAvailCh_SetNextAvailCh(ctx, inst, false );
6034
+
5961 6035
     }
5962 6036
 
5963 6037
     
5964 6038
     return rc;
5965 6039
   }
5966 6040
 
5967
-  
5968
-
5969 6041
   // if this is an incoming disable message.
5970 6042
   if( p->baseDisInAvId <= evt->dstVarId && evt->dstVarId < p->baseDisInAvId+p->chCnt && cmDsvGetBool(evt->valuePtr) == false)
5971
-  {
6043
+  {    
5972 6044
     cmDspSetEvent(ctx,inst,evt);
6045
+
6046
+    // a channel was disabled so a new channel is available for selection
6047
+    _cmDspAvailCh_SetNextAvailCh(ctx, inst, true );
6048
+    
5973 6049
     if( !exclModeFl )
5974 6050
       cmDspSetBool(ctx, inst, p->baseGateOutAvId + (evt->dstVarId - p->baseDisInAvId), false);
5975 6051
   }
@@ -5984,7 +6060,7 @@ struct cmDspClass_str* cmAvailChClassCons( cmDspCtx_t* ctx )
5984 6060
     _cmDspAvailCh_Alloc,
5985 6061
     _cmDspAvailCh_Free,
5986 6062
     _cmDspAvailCh_Reset,
5987
-    NULL,
6063
+    _cmDspAvailCh_Exec,
5988 6064
     _cmDspAvailCh_Recv,
5989 6065
     NULL,NULL,
5990 6066
     "Enable the next availabled channel");

Завантаження…
Відмінити
Зберегти