|
@@ -1430,6 +1430,7 @@ typedef struct
|
1430
|
1430
|
cmXfader* xfdp;
|
1431
|
1431
|
unsigned inBaseXfId;
|
1432
|
1432
|
unsigned outBaseXfId;
|
|
1433
|
+ unsigned stateBaseXfId;
|
1433
|
1434
|
unsigned gainBaseXfId;
|
1434
|
1435
|
unsigned chCnt;
|
1435
|
1436
|
bool* chGateV;
|
|
@@ -1444,8 +1445,8 @@ cmDspInst_t* _cmDspXfaderAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigne
|
1444
|
1445
|
{ "chs", kChCntXfId, 0, 0, kUIntDsvFl | kReqArgDsvFl, "Input and Output channel count"},
|
1445
|
1446
|
{ "ms", kFadeTimeMsXfId, 0, 0, kInDsvFl | kDoubleDsvFl | kOptArgDsvFl, "Fade time in milliseonds."},
|
1446
|
1447
|
{ "mgate", kMstrGateXfId, 0, 0, kInDsvFl | kBoolDsvFl | kOptArgDsvFl, "Master gate - can be used to set all gates."},
|
1447
|
|
- { "on", kOnXfId, 0, 0, kOutDsvFl | kSymDsvFl, "Send 'on' when all ch's transition from off to on."},
|
1448
|
|
- { "off", kOffXfId, 0, 0, kOutDsvFl | kSymDsvFl, "Send 'off' when all ch's transition from on to off."},
|
|
1448
|
+ { "on", kOnXfId, 0, 0, kOutDsvFl | kSymDsvFl, "Send 'on' when all ch's transition from off to on."},
|
|
1449
|
+ { "off", kOffXfId, 0, 0, kOutDsvFl | kSymDsvFl, "Send 'off' when all ch's transition from on to off."},
|
1449
|
1450
|
};
|
1450
|
1451
|
|
1451
|
1452
|
if( va_cnt < 1 )
|
|
@@ -1457,12 +1458,13 @@ cmDspInst_t* _cmDspXfaderAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigne
|
1457
|
1458
|
va_list vl1;
|
1458
|
1459
|
va_copy(vl1,vl);
|
1459
|
1460
|
|
1460
|
|
- unsigned chCnt = va_arg(vl,int);
|
1461
|
|
- unsigned fixArgCnt = sizeof(args)/sizeof(args[0]);
|
1462
|
|
- unsigned argCnt = fixArgCnt + 4*chCnt;
|
1463
|
|
- unsigned inBaseXfId = kGateBaseXfId + chCnt;
|
1464
|
|
- unsigned outBaseXfId = inBaseXfId + chCnt;
|
1465
|
|
- unsigned gainBaseXfId= outBaseXfId + chCnt;
|
|
1461
|
+ unsigned chCnt = va_arg(vl,int);
|
|
1462
|
+ unsigned fixArgCnt = sizeof(args)/sizeof(args[0]);
|
|
1463
|
+ unsigned argCnt = fixArgCnt + 5*chCnt;
|
|
1464
|
+ unsigned inBaseXfId = kGateBaseXfId + chCnt;
|
|
1465
|
+ unsigned outBaseXfId = inBaseXfId + chCnt;
|
|
1466
|
+ unsigned stateBaseXfId = outBaseXfId + chCnt;
|
|
1467
|
+ unsigned gainBaseXfId = stateBaseXfId + chCnt;
|
1466
|
1468
|
cmDspVarArg_t a[ argCnt+1 ];
|
1467
|
1469
|
|
1468
|
1470
|
|
|
@@ -1471,6 +1473,7 @@ cmDspInst_t* _cmDspXfaderAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigne
|
1471
|
1473
|
cmDspArgSetupN(ctx, a, argCnt, kGateBaseXfId, chCnt, "gate", kGateBaseXfId, 0, 0, kInDsvFl | kBoolDsvFl, "gate flags");
|
1472
|
1474
|
cmDspArgSetupN(ctx, a, argCnt, inBaseXfId, chCnt, "in", inBaseXfId, 0, 0, kInDsvFl | kAudioBufDsvFl, "audio input");
|
1473
|
1475
|
cmDspArgSetupN(ctx, a, argCnt, outBaseXfId, chCnt, "out", outBaseXfId, 0, 1, kOutDsvFl | kAudioBufDsvFl, "audio output");
|
|
1476
|
+ cmDspArgSetupN(ctx, a, argCnt, stateBaseXfId, chCnt, "state",stateBaseXfId, 0, 0, kOutDsvFl | kBoolDsvFl, "current fader state");
|
1474
|
1477
|
cmDspArgSetupN(ctx, a, argCnt, gainBaseXfId, chCnt, "gain", gainBaseXfId, 0, 0, kOutDsvFl | kDoubleDsvFl, "gain output");
|
1475
|
1478
|
cmDspArgSetupNull( a+argCnt); // set terminating arg. flag
|
1476
|
1479
|
|
|
@@ -1480,6 +1483,7 @@ cmDspInst_t* _cmDspXfaderAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigne
|
1480
|
1483
|
p->xfdp = cmXfaderAlloc(ctx->cmProcCtx,NULL,cmDspSampleRate(ctx), chCnt, fadeTimeMs);
|
1481
|
1484
|
p->inBaseXfId = inBaseXfId;
|
1482
|
1485
|
p->outBaseXfId = outBaseXfId;
|
|
1486
|
+ p->stateBaseXfId = stateBaseXfId;
|
1483
|
1487
|
p->gainBaseXfId = gainBaseXfId;
|
1484
|
1488
|
p->chCnt = chCnt;
|
1485
|
1489
|
p->chGateV = cmMemAllocZ(bool,p->chCnt);
|
|
@@ -1489,8 +1493,13 @@ cmDspInst_t* _cmDspXfaderAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigne
|
1489
|
1493
|
// set default values for the parameters that were not explicitely set in the va_arg list
|
1490
|
1494
|
cmDspSetDefaultDouble( ctx, &p->inst, kFadeTimeMsXfId, 0, 100 );
|
1491
|
1495
|
cmDspSetDefaultBool( ctx, &p->inst, kMstrGateXfId, false, false);
|
1492
|
|
- cmDspSetDefaultSymbol( ctx, &p->inst, kOnXfId, p->onSymId );
|
1493
|
|
- cmDspSetDefaultSymbol( ctx, &p->inst, kOffXfId, p->offSymId );
|
|
1496
|
+ cmDspSetDefaultSymbol( ctx, &p->inst, kOnXfId, p->onSymId );
|
|
1497
|
+ cmDspSetDefaultSymbol( ctx, &p->inst, kOffXfId, p->offSymId );
|
|
1498
|
+
|
|
1499
|
+ int i;
|
|
1500
|
+ for(i=0; i<chCnt; ++i)
|
|
1501
|
+ cmDspSetDefaultBool( ctx, &p->inst, stateBaseXfId+i, false, false );
|
|
1502
|
+
|
1494
|
1503
|
return &p->inst;
|
1495
|
1504
|
}
|
1496
|
1505
|
|
|
@@ -1541,6 +1550,12 @@ cmDspRC_t _cmDspXfaderExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t*
|
1541
|
1550
|
cmVOS_MultVVS(op,n,ip,gain);
|
1542
|
1551
|
}
|
1543
|
1552
|
|
|
1553
|
+ if( p->xfdp->chArray[i].onFl )
|
|
1554
|
+ cmDspSetBool(ctx,inst,p->stateBaseXfId+i,true);
|
|
1555
|
+
|
|
1556
|
+ if( p->xfdp->chArray[i].offFl )
|
|
1557
|
+ cmDspSetBool(ctx,inst,p->stateBaseXfId+i,false);
|
|
1558
|
+
|
1544
|
1559
|
// send the gain output
|
1545
|
1560
|
cmDspSetDouble(ctx,inst,p->gainBaseXfId+i,gain);
|
1546
|
1561
|
}
|
|
@@ -1580,8 +1595,6 @@ cmDspRC_t _cmDspXfaderRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t*
|
1580
|
1595
|
break;
|
1581
|
1596
|
}
|
1582
|
1597
|
|
1583
|
|
-
|
1584
|
|
-
|
1585
|
1598
|
// record gate changes into p->chGateV[] for later use in _cmDspXfaderExec().
|
1586
|
1599
|
if( kGateBaseXfId <= evt->dstVarId && evt->dstVarId < kGateBaseXfId + p->chCnt )
|
1587
|
1600
|
{
|
|
@@ -5284,10 +5297,10 @@ cmDspInst_t* _cmDspGateToSym_Alloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, uns
|
5284
|
5297
|
cmDspGateToSym_t* p = cmDspInstAllocV(cmDspGateToSym_t,ctx,classPtr,instSymId,id,storeSymId,va_cnt,vl,
|
5285
|
5298
|
1, "on_sym", kOnSymGsId, 0, 0, kSymDsvFl | kInDsvFl | kOptArgDsvFl,"'on' symbol id (default:'on')",
|
5286
|
5299
|
1, "off_sym",kOffSymGsId, 0, 0, kSymDsvFl | kInDsvFl | kOptArgDsvFl,"'off' symbol id (default:'off')",
|
5287
|
|
- 1, "on", kOnGsId, 0, 0, kBoolDsvFl | kInDsvFl, "On - send out 'on' symbol when a 'true' is received.",
|
5288
|
|
- 1, "off", kOffGsId, 0, 0, kBoolDsvFl | kInDsvFl, "Off - send out 'off' symbol when a 'false' is received.",
|
5289
|
|
- 1, "both", kBothGsId, 0, 0, kBoolDsvFl | kInDsvFl, "Send 'on' on 'true' and 'off' on 'false'.",
|
5290
|
|
- 1, "out", kOutGsId, 0, 0, kSymDsvFl | kOutDsvFl, "Output",
|
|
5300
|
+ 1, "on", kOnGsId, 0, 0, kBoolDsvFl | kInDsvFl, "On - send out 'on' symbol when a 'true' is received.",
|
|
5301
|
+ 1, "off", kOffGsId, 0, 0, kBoolDsvFl | kInDsvFl, "Off - send out 'off' symbol when a 'false' is received.",
|
|
5302
|
+ 1, "both", kBothGsId, 0, 0, kBoolDsvFl | kInDsvFl, "Send 'on' on 'true' and 'off' on 'false'.",
|
|
5303
|
+ 1, "out", kOutGsId, 0, 0, kSymDsvFl | kOutDsvFl, "Output",
|
5291
|
5304
|
0 );
|
5292
|
5305
|
|
5293
|
5306
|
|
|
@@ -5654,12 +5667,40 @@ struct cmDspClass_str* cmRouterClassCons( cmDspCtx_t* ctx )
|
5654
|
5667
|
}
|
5655
|
5668
|
|
5656
|
5669
|
//==========================================================================================================================================
|
|
5670
|
+// Purpose: AvailCh can be used to implement a channel switching circuit.
|
|
5671
|
+//
|
|
5672
|
+// Inputs:
|
|
5673
|
+// chs - The count of channels. Constructor only argument.
|
|
5674
|
+// trig - Any input causes the next available channel, i, to be enabled.
|
|
5675
|
+// gate[i] transmits 'true'. In 'exclusive (0) mode all active
|
|
5676
|
+// channels are then requested to shutdown by transmitting 'false' on
|
|
5677
|
+// gate[] - only the new channel will be active. In 'multi' (1) mode
|
|
5678
|
+// no signal is sent out the gate[].
|
|
5679
|
+// dis[chCnt] - Recieves a gate signal from an external object which indicates
|
|
5680
|
+// when a channel is no longer active. When a 'false' is received on dis[i]
|
|
5681
|
+// the channel i is marked as available. In 'multi' mode 'false' is
|
|
5682
|
+// then transmitted on gate[i].
|
|
5683
|
+// Outputs:
|
|
5684
|
+// gate[chCnt] - 'true' is transmitted when a channel is made active (see trig)
|
|
5685
|
+// 'false' is transmitted to notify the channel that it should shutdown.
|
|
5686
|
+// The channel is not considered actually shutdown until dis[i]
|
|
5687
|
+// recieves a 'false'.
|
|
5688
|
+// Notes:
|
|
5689
|
+// The gate[] output is designed to work with the gate[] input of Xfader. When
|
|
5690
|
+// availCh.gate[] goes high Xfader fades in, when availCh.gate[] goes low
|
|
5691
|
+// Xfader fades out. The dis[] channel is designed to connect from Xfader.state[].
|
|
5692
|
+// When Xfader.state[] goes low, when a fade-out is complete, the connected AvailCh
|
|
5693
|
+// is marked as available.
|
5657
|
5694
|
enum
|
5658
|
5695
|
{
|
5659
|
5696
|
kChCntAvId,
|
|
5697
|
+ kModeAvId,
|
5660
|
5698
|
kTrigAvId,
|
5661
|
5699
|
kChIdxAvId,
|
5662
|
|
- kBaseInDisAvId,
|
|
5700
|
+ kBaseDisInAvId,
|
|
5701
|
+
|
|
5702
|
+ kExclusiveModeAvId=0,
|
|
5703
|
+ kMultiModeAvId=1
|
5663
|
5704
|
};
|
5664
|
5705
|
|
5665
|
5706
|
cmDspClass_t _cmAvailCh_DC;
|
|
@@ -5668,10 +5709,8 @@ typedef struct
|
5668
|
5709
|
{
|
5669
|
5710
|
cmDspInst_t inst;
|
5670
|
5711
|
unsigned chCnt;
|
5671
|
|
- unsigned baseOutEnaAvId;
|
5672
|
|
- unsigned baseInDisAvId;
|
5673
|
|
- unsigned enableSymId;
|
5674
|
|
- unsigned disableSymId;
|
|
5712
|
+ unsigned baseDisInAvId;
|
|
5713
|
+ unsigned baseGateOutAvId;
|
5675
|
5714
|
bool* stateArray;
|
5676
|
5715
|
} cmDspAvailCh_t;
|
5677
|
5716
|
|
|
@@ -5694,29 +5733,33 @@ cmDspInst_t* _cmDspAvailCh_Alloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsig
|
5694
|
5733
|
return NULL;
|
5695
|
5734
|
}
|
5696
|
5735
|
|
5697
|
|
- unsigned baseInDisAvId = kBaseInDisAvId;
|
5698
|
|
- unsigned baseOutEnaAvId = baseInDisAvId + chCnt;
|
|
5736
|
+ unsigned baseDisInAvId = kBaseDisInAvId;
|
|
5737
|
+ unsigned baseGateOutAvId = baseDisInAvId + chCnt;
|
5699
|
5738
|
|
5700
|
5739
|
cmDspAvailCh_t* p = cmDspInstAllocV(cmDspAvailCh_t,ctx,classPtr,instSymId,id,storeSymId,va_cnt,vl1,
|
5701
|
|
- 1, "chs", kChCntAvId, 0, 0, kUIntDsvFl | kReqArgDsvFl, "Channel count.",
|
5702
|
|
- 1, "trig", kTrigAvId, 0, 0, kTypeDsvMask | kInDsvFl, "Trigger the unit to select the next available channel.",
|
5703
|
|
- 1, "ch", kChIdxAvId, 0, 0, kUIntDsvFl | kReqArgDsvFl | kInDsvFl, "Currently selected channel.",
|
5704
|
|
- chCnt, "dis", baseInDisAvId, 0, 0, kTypeDsvMask | kInDsvFl, "Disable inputs.",
|
5705
|
|
- chCnt, "ena", baseOutEnaAvId, 0, 0, kSymDsvFl | kOutDsvFl, "'enable' outputs",
|
|
5740
|
+ 1, "chs", kChCntAvId, 0, 0, kUIntDsvFl | kReqArgDsvFl, "Channel count.",
|
|
5741
|
+ 1, "mode", kModeAvId, 0, 0, kUIntDsvFl | kInDsvFl, "Mode: 0=exclusive (dflt) 1=multi",
|
|
5742
|
+ 1, "trig", kTrigAvId, 0, 0, kTypeDsvMask | kInDsvFl, "Trigger the unit to select the next available channel.",
|
|
5743
|
+ 1, "ch", kChIdxAvId, 0, 0, kUIntDsvFl | kOutDsvFl, "Currently selected channel.",
|
|
5744
|
+ chCnt, "dis", baseDisInAvId, 0, 0, kBoolDsvFl | kInDsvFl, "Disable channel gate",
|
|
5745
|
+ chCnt, "gate", baseGateOutAvId, 0, 0, kBoolDsvFl | kOutDsvFl, "Active channel gate",
|
5706
|
5746
|
0 );
|
5707
|
5747
|
|
5708
|
5748
|
p->chCnt = chCnt;
|
5709
|
5749
|
|
5710
|
|
- p->baseInDisAvId = baseInDisAvId;
|
5711
|
|
- p->baseOutEnaAvId = baseOutEnaAvId;
|
5712
|
|
- p->enableSymId = cmSymTblRegisterStaticSymbol(ctx->stH,"enable");
|
5713
|
|
- p->disableSymId = cmSymTblRegisterStaticSymbol(ctx->stH,"disable");
|
|
5750
|
+ p->baseDisInAvId = baseDisInAvId;
|
|
5751
|
+ p->baseGateOutAvId = baseGateOutAvId;
|
5714
|
5752
|
|
5715
|
5753
|
unsigned i;
|
5716
|
5754
|
for(i=0; i<chCnt; ++i)
|
5717
|
|
- cmDspSetDefaultSymbol( ctx, &p->inst, baseOutEnaAvId+i, p->disableSymId );
|
5718
|
|
-
|
|
5755
|
+ {
|
|
5756
|
+ cmDspSetDefaultBool( ctx, &p->inst, baseDisInAvId+i, false, false );
|
|
5757
|
+ cmDspSetDefaultBool( ctx, &p->inst, baseGateOutAvId+i, false, false );
|
|
5758
|
+ }
|
|
5759
|
+ cmDspSetDefaultUInt( ctx, &p->inst, kModeAvId, 0, kExclusiveModeAvId );
|
5719
|
5760
|
cmDspSetDefaultUInt( ctx, &p->inst, kChIdxAvId, 0, cmInvalidIdx );
|
|
5761
|
+
|
|
5762
|
+
|
5720
|
5763
|
|
5721
|
5764
|
return &p->inst;
|
5722
|
5765
|
}
|
|
@@ -5737,24 +5780,41 @@ cmDspRC_t _cmDspAvailCh_Recv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_
|
5737
|
5780
|
cmDspRC_t rc = kOkDspRC;
|
5738
|
5781
|
cmDspAvailCh_t* p = (cmDspAvailCh_t*)inst;
|
5739
|
5782
|
|
|
5783
|
+ bool exclModeFl = cmDspUInt(inst, kModeAvId ) == kExclusiveModeAvId;
|
|
5784
|
+
|
5740
|
5785
|
// if this is a trigger
|
5741
|
5786
|
if( evt->dstVarId == kTrigAvId )
|
5742
|
5787
|
{
|
5743
|
5788
|
unsigned i;
|
|
5789
|
+ bool fl = true;
|
5744
|
5790
|
for(i=0; i<p->chCnt; ++i)
|
5745
|
|
- if( cmDspSymbol(inst,p->baseOutEnaAvId+i) == p->disableSymId )
|
|
5791
|
+ {
|
|
5792
|
+ // the actual channel's active state is held in the 'dis' variable.
|
|
5793
|
+ bool activeFl = cmDspBool(inst,p->baseDisInAvId+i);
|
|
5794
|
+
|
|
5795
|
+ // if ch[i] is the first avail inactive channel
|
|
5796
|
+ if( fl && !activeFl )
|
5746
|
5797
|
{
|
5747
|
5798
|
cmDspSetUInt(ctx,inst,kChIdxAvId,i);
|
5748
|
|
- cmDspSetSymbol(ctx,inst,p->baseOutEnaAvId,p->enableSymId);
|
|
5799
|
+ cmDspSetBool(ctx, inst, p->baseDisInAvId + i, true);
|
|
5800
|
+ cmDspSetBool(ctx, inst, p->baseGateOutAvId + i, true);
|
|
5801
|
+ fl = false;
|
5749
|
5802
|
}
|
|
5803
|
+
|
|
5804
|
+ // if ch[i] is active - then request that it shutdown
|
|
5805
|
+ if( activeFl && exclModeFl)
|
|
5806
|
+ cmDspSetBool(ctx, inst, p->baseGateOutAvId + i, false);
|
|
5807
|
+
|
|
5808
|
+ }
|
5750
|
5809
|
return rc;
|
5751
|
5810
|
}
|
5752
|
5811
|
|
5753
|
5812
|
// if this is an incoming disable message.
|
5754
|
|
- if( p->baseInDisAvId <= evt->dstVarId && evt->dstVarId < p->baseInDisAvId+p->chCnt )
|
|
5813
|
+ if( p->baseDisInAvId <= evt->dstVarId && evt->dstVarId < p->baseDisInAvId+p->chCnt && cmDsvGetBool(evt->valuePtr) == false)
|
5755
|
5814
|
{
|
5756
|
|
- cmDspSetSymbol(ctx,inst,p->baseOutEnaAvId,p->disableSymId);
|
5757
|
|
- return rc;
|
|
5815
|
+ cmDspSetEvent(ctx,inst,evt);
|
|
5816
|
+ if( !exclModeFl )
|
|
5817
|
+ cmDspSetBool(ctx, inst, p->baseGateOutAvId + (evt->dstVarId - p->baseDisInAvId), false);
|
5758
|
5818
|
}
|
5759
|
5819
|
|
5760
|
5820
|
return rc;
|