1769 regels
76 KiB
C
1769 regels
76 KiB
C
#include "cmPrefix.h"
|
|
#include "cmGlobal.h"
|
|
#include "cmFloatTypes.h"
|
|
#include "cmRpt.h"
|
|
#include "cmErr.h"
|
|
#include "cmCtx.h"
|
|
#include "cmMem.h"
|
|
#include "cmMallocDebug.h"
|
|
#include "cmLinkedHeap.h"
|
|
#include "cmFileSys.h"
|
|
#include "cmSymTbl.h"
|
|
#include "cmJson.h"
|
|
#include "cmText.h"
|
|
#include "cmPrefs.h"
|
|
#include "cmDspValue.h"
|
|
#include "cmMsgProtocol.h"
|
|
#include "cmThread.h"
|
|
#include "cmUdpPort.h"
|
|
#include "cmUdpNet.h"
|
|
#include "cmAudioSys.h"
|
|
#include "cmProcObj.h"
|
|
#include "cmDspCtx.h"
|
|
#include "cmDspClass.h"
|
|
#include "cmDspSys.h"
|
|
#include "cmDspPgm.h"
|
|
#include "cmDspPgmPPMain.h"
|
|
|
|
#include "cmAudioFile.h"
|
|
#include "cmProcObj.h"
|
|
#include "cmProc.h"
|
|
#include "cmProc3.h"
|
|
#include "cmVectOpsTemplateMain.h"
|
|
|
|
#define COL_WIDTH (150)
|
|
|
|
|
|
|
|
|
|
cmDspInst_t** allocInstPtrArray( cmDspSysH_t h, unsigned cnt )
|
|
{ return cmLhAllocZ(cmDspSysLHeap(h),cmDspInst_t*,cnt); }
|
|
|
|
|
|
#define formLabel( h, lbl, i) cmTsPrintfH( cmDspSysLHeap(h), "%s-%i", lbl, i )
|
|
|
|
|
|
|
|
//=====================================================================================================================
|
|
cmDspInst_t* _cmDspSys_PresetMgmt( cmDspSysH_t h, const cmChar_t* preLbl, unsigned presetGroupSymId )
|
|
{
|
|
cmLHeapH_t lhH = cmDspSysLHeap(h);
|
|
cmDspInst_t* preset = cmDspSysAllocInst( h, "Preset", NULL, 1, presetGroupSymId );
|
|
cmDspInst_t* presetLbl = cmDspSysAllocInst( h, "Text", NULL, 2, "", "Preset Label" );
|
|
cmDspInst_t* storeBtn = cmDspSysAllocInst( h, "Button", cmTsPrintfH(lhH,"%s-store", preLbl), 2, kButtonDuiId, 0.0);
|
|
cmDspInst_t* recallBtn = cmDspSysAllocInst( h, "Button", cmTsPrintfH(lhH,"%s-recall",preLbl), 2, kButtonDuiId, 0.0);
|
|
cmDspInst_t* ptsStore = cmDspSysAllocInst( h, "PortToSym", NULL, 1, "store" );
|
|
cmDspInst_t* ptsRecall = cmDspSysAllocInst( h, "PortToSym", NULL, 1, "recall" );
|
|
|
|
cmDspSysInstallCb( h, presetLbl, "val", preset, "label",NULL);
|
|
cmDspSysInstallCb( h, storeBtn, "out", ptsStore, "store", NULL );
|
|
cmDspSysInstallCb( h, recallBtn, "out", ptsRecall, "recall", NULL );
|
|
cmDspSysInstallCb( h, ptsStore, "out", preset, "cmd", NULL );
|
|
cmDspSysInstallCb( h, ptsRecall, "out", preset, "cmd", NULL );
|
|
|
|
|
|
return preset;
|
|
}
|
|
//=====================================================================================================================
|
|
typedef struct
|
|
{
|
|
unsigned circuitSymId; // enable/disable symId
|
|
|
|
cmDspInst_t** aout; // aout[ ctx->outChCnt ]
|
|
const cmChar_t* aoutLbl; // "out"
|
|
|
|
} cmDspPP_Circuit_t;
|
|
|
|
//=====================================================================================================================
|
|
typedef struct
|
|
{
|
|
cmDspPP_Circuit_t c;
|
|
|
|
cmDspInst_t** sfmt;
|
|
cmDspInst_t** rmtr;
|
|
cmDspInst_t** gmtr;
|
|
|
|
} cmDspPP_TestCircuit_t;
|
|
|
|
|
|
cmDspRC_t _cmDspPP_TestCircuitAlloc(
|
|
cmDspSysH_t h,
|
|
_cmDspPP_Ctx_t* ctx,
|
|
cmDspPP_TestCircuit_t* p,
|
|
const cmChar_t* title,
|
|
const cmChar_t* preLbl,
|
|
cmDspInst_t* selChk,
|
|
cmDspInst_t** ain,
|
|
cmDspInst_t* ptIn )
|
|
{
|
|
cmDspRC_t rc;
|
|
|
|
p->c.circuitSymId = cmDspSysRegisterInstAttrSymbolStr(h,title);
|
|
unsigned presetGroupSymId = cmDspSysPresetRegisterGroup(h,title);
|
|
_cmDspSys_PresetMgmt(h,preLbl,presetGroupSymId);
|
|
cmDspSysNewColumn(h,COL_WIDTH);
|
|
|
|
p->c.aout = allocInstPtrArray(h, ctx->oChCnt);
|
|
|
|
|
|
// make processors for each input channel
|
|
cmDspInst_t** sfmt = cmDspSysAllocInstArray( h, ctx->iChCnt, "Sprintf", NULL, NULL, 1, "gate-%i:");
|
|
cmDspInst_t** rmtr = cmDspSysAllocInstArray( h, ctx->iChCnt, "Meter", "RMS", NULL, 3, 0.0, 0.0, 1.0 );
|
|
cmDspSysNewColumn(h,COL_WIDTH);
|
|
cmDspInst_t** gmtr = cmDspSysAllocInstArray( h, ctx->iChCnt, "Meter", "Gate",NULL, 3, 0.0, 0.0, 1.0 );
|
|
|
|
|
|
// make processors for each output channel
|
|
if( ctx->oChCnt )
|
|
p->c.aout[0] = cmDspSysAllocInst( h, "AMix", NULL, 1, ctx->iChCnt );
|
|
p->c.aoutLbl = "out";
|
|
|
|
|
|
// check for allocation errors
|
|
if((rc = cmDspSysLastRC(h)) != kOkDspRC )
|
|
goto errLabel;
|
|
|
|
if( ctx->oChCnt )
|
|
cmDspSysConnectAudioN11N(h, ain, "out", p->c.aout[0], "in", ctx->iChCnt );
|
|
|
|
cmDspSysInstallCb1NN1(h, ptIn, "f-out", rmtr, "in", ctx->iChCnt ); // RMS input
|
|
cmDspSysInstallCb1NN1(h, ptIn, "b-out", gmtr, "in", ctx->iChCnt ); // Gate input
|
|
cmDspSysInstallCb1NN1(h, ptIn, "b-out", sfmt, "in-0", ctx->iChCnt ); // format string
|
|
//cmDspSysInstallCbN111(h, p->sfmt, "out", ctx->print, "in", ctx->iChCnt);// print string
|
|
|
|
errLabel:
|
|
|
|
cmDspSysRemoveInstAttrSymbol(h,p->c.circuitSymId);
|
|
|
|
return rc;
|
|
}
|
|
|
|
//=====================================================================================================================
|
|
|
|
typedef struct
|
|
{
|
|
cmDspInst_t** tmop;
|
|
cmDspInst_t** amop;
|
|
cmDspInst_t** cf;
|
|
cmDspInst_t** sg;
|
|
cmDspInst_t** eq;
|
|
cmDspInst_t** env;
|
|
cmDspInst_t** rtr;
|
|
cmDspInst_t** bts;
|
|
cmDspInst_t* mix;
|
|
} cmDspSys_NShp_t;
|
|
|
|
|
|
|
|
cmDspSys_NShp_t* _cmDspSys_NShpAlloc( cmDspSysH_t h, unsigned pgSymId, const cmChar_t* preLbl, unsigned chCnt, bool seqFl )
|
|
{
|
|
cmDspRC_t rc = kOkDspRC;
|
|
|
|
unsigned secCnt = 3;
|
|
|
|
double cntMin = 1;
|
|
double cntMax = secCnt;
|
|
|
|
unsigned sgShapeId = 2;
|
|
unsigned sgOtCnt = 5;
|
|
|
|
double cfMinHz = 20.0;
|
|
double cfHz = 500;
|
|
double cfAlpha = 0.9;
|
|
bool cfFbFl = true;
|
|
bool cfBypassFl = false;
|
|
|
|
double adsrMaxMs = 20000;
|
|
double adsrMinMs = 0;
|
|
double adsrIncMs = 1;
|
|
double adsrMaxLevel = 100.0;
|
|
double adsrSusLevel = 100.0;
|
|
double adsrMinLevel = 0.0;
|
|
double adsrIncLevel = 0.001;
|
|
|
|
bool eqBypassFl = false;
|
|
unsigned eqModeSymId = cmSymTblRegisterStaticSymbol(cmDspSysSymbolTable(h),"LP");
|
|
double eqF0hz = 250;
|
|
double eqQ = 1.0;
|
|
double eqFgain = 1.0;
|
|
|
|
bool mtBypassFl = false;
|
|
double mtTimeScale= 1.0;
|
|
double mtFeedback = 0.5;
|
|
|
|
double multMin = 0.0;
|
|
double multMax = 100.0;
|
|
double multInc = 0.01;
|
|
double offsMin = 0.0;
|
|
double offsMax = 100.0;
|
|
double offsInc = 0.01;
|
|
|
|
cmDspSys_NShp_t* p = cmLhAllocZ( cmDspSysLHeap(h),cmDspSys_NShp_t,1);
|
|
|
|
cmDspInst_t** bts = NULL;
|
|
cmDspInst_t** rtr = NULL;
|
|
cmDspInst_t** cnt0 = NULL;
|
|
cmDspInst_t** cnt1 = NULL;
|
|
cmDspInst_t** cnt2 = NULL;
|
|
cmDspInst_t** seq0 = NULL;
|
|
cmDspInst_t** seq1 = NULL;
|
|
cmDspInst_t** seq2 = NULL;
|
|
|
|
|
|
cmDspSysNewColumn(h,COL_WIDTH);
|
|
cmDspInst_t** sg = p->sg = cmDspSysAllocInstArray( h, chCnt, "SigGen", NULL, NULL, 2, 1000.0, sgShapeId, 1.0, sgOtCnt );
|
|
cmDspInst_t** cf = p->cf = cmDspSysAllocInstArray( h, chCnt, "CombFilt", NULL, NULL, 5, cfBypassFl, cfMinHz, cfFbFl, cfHz, cfAlpha );
|
|
cmDspInst_t** eq = p->eq = cmDspSysAllocInstArray( h, chCnt, "BiQuadEq", NULL, NULL, 5, eqBypassFl, eqModeSymId, eqF0hz, eqQ, eqFgain );
|
|
cmDspInst_t** mt = cmDspSysAllocInstArray( h, chCnt, "MtDelay", NULL, NULL, 9, mtBypassFl, mtTimeScale, mtFeedback, 20.0, 0.8, 15.0, 0.9, 12.0, 0.9 );
|
|
|
|
// adsr time/ampl scale/offset
|
|
cmDspInst_t** tmop = p->tmop= cmDspSysAllocInstArray(h, chCnt, "ScalarOp", NULL, NULL, 6, 2, "*", "in-0", 1.0, "in-1", 1.0 );
|
|
cmDspInst_t** toop = cmDspSysAllocInstArray(h, chCnt, "ScalarOp", NULL, NULL, 6, 2, "+", "in-0", 0.0, "in-1", 0.0 );
|
|
cmDspInst_t** amop = p->amop= cmDspSysAllocInstArray(h, chCnt, "ScalarOp", NULL, NULL, 6, 2, "*", "in-0", 1.0, "in-1", 1.0 );
|
|
cmDspInst_t** aoop = cmDspSysAllocInstArray(h, chCnt, "ScalarOp", NULL, NULL, 6, 2, "+", "in-0", 0.0, "in-1", 0.0 );
|
|
cmDspInst_t** env = p->env = cmDspSysAllocInstArray( h, chCnt, "Adsr", NULL, NULL, 2, true, adsrMinLevel );
|
|
cmDspInst_t** d2l = cmDspSysAllocInstArray( h, chCnt, "DbToLin", NULL, NULL, 0 );
|
|
|
|
if( seqFl )
|
|
{
|
|
bts = p->bts = cmDspSysAllocInstArray( h, chCnt, "GateToSym",NULL, NULL, 0 );
|
|
rtr = p->rtr = cmDspSysAllocInstArray( h, chCnt, "Router", NULL, NULL, 2, secCnt, 0 );
|
|
cnt0 = cmDspSysAllocInstArray( h, chCnt, "Counter", NULL, NULL, 3, cntMin, cntMax, 1.0 );
|
|
cnt1 = cmDspSysAllocInstArray( h, chCnt, "Counter", NULL, NULL, 3, cntMin, cntMax, 1.0 );
|
|
cnt2 = cmDspSysAllocInstArray( h, chCnt, "Counter", NULL, NULL, 3, cntMin, cntMax, 1.0 );
|
|
seq0 = cmDspSysAllocInstArray( h, chCnt, "MsgList", NULL, NULL, 1, "ns_seq0");
|
|
seq1 = cmDspSysAllocInstArray( h, chCnt, "MsgList", NULL, NULL, 1, "ns_seq1");
|
|
seq2 = cmDspSysAllocInstArray( h, chCnt, "MsgList", NULL, NULL, 1, "ns_seq2");
|
|
}
|
|
|
|
// output mixer
|
|
cmDspInst_t* mix = p->mix = cmDspSysAllocInst( h, "AMix", NULL, 2, chCnt, 0.0 );
|
|
|
|
// comb filter parameters
|
|
cmDspSysNewColumn(h,COL_WIDTH);
|
|
cmDspInst_t* alpha = cmDspSysAllocScalarP( h, pgSymId, preLbl, "alpha", -1.0, 1.0, 0.001, cfAlpha );
|
|
|
|
// time/amp scale multiply and offset controls
|
|
cmDspInst_t* tmul = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Time Mult", multMin, multMax, multInc, 1.0);
|
|
cmDspInst_t* toff = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Time Offs", offsMin, offsMax, offsInc, 0.0);
|
|
cmDspInst_t* amul = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Ampl Mult", multMin, multMax, multInc, 1.0);
|
|
cmDspInst_t* aoff = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Ampl Offs", offsMin, offsMax, offsInc, 0.0);
|
|
|
|
// ADSR parameters
|
|
cmDspInst_t* dly = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Dly Ms", adsrMinMs, adsrMaxMs, adsrIncMs, 0.0);
|
|
cmDspInst_t* atk = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Atk Ms", adsrMinMs, adsrMaxMs, adsrIncMs, 5000.0);
|
|
cmDspInst_t* dcy = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Dcy Ms", adsrMinMs, adsrMaxMs, adsrIncMs, 100.0);
|
|
cmDspInst_t* hold = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Hold Ms", adsrMinMs, adsrMaxMs, adsrIncMs, 100.0);
|
|
cmDspInst_t* rls = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Rls Ms", adsrMinMs, adsrMaxMs, adsrIncMs, 9000.0);
|
|
cmDspInst_t* alvl = cmDspSysAllocScalarP( h, pgSymId, preLbl, "AdsrMax", adsrMinLevel,adsrMaxLevel,adsrIncLevel, adsrMaxLevel);
|
|
cmDspInst_t* sus = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Sustain", adsrMinLevel,adsrMaxLevel,adsrIncLevel, adsrSusLevel );
|
|
|
|
cmDspSysNewColumn(h,COL_WIDTH);
|
|
cmDspInst_t* eqbyp = cmDspSysAllocCheckP( h, pgSymId, preLbl, "Eq Byp", 0 );
|
|
cmDspInst_t* eqmode = cmDspSysAllocMsgListP(h, pgSymId, preLbl, "Mode", NULL, "biQuadEqMode", 1);
|
|
cmDspInst_t* eqq = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Q", -100.0, 100.0, 0.1, eqQ);
|
|
cmDspInst_t* eqfgn = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Filt Gain", 0.0, 1.0, 0.1, eqFgain);
|
|
|
|
cmDspInst_t* mtfb = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Mt Feedback", 0.0, 1.0, 0.01, mtFeedback);
|
|
cmDspInst_t* mtscale= cmDspSysAllocScalarP( h, pgSymId, preLbl, "Mt Time Scale", 0.01, 10.0, 0.01, mtTimeScale);
|
|
|
|
cmDspInst_t* sgsh = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Sg Shape", 0.0, 8.0, 1.0, ((double)sgShapeId));
|
|
cmDspInst_t* sgot = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Sg OT Cnt", 0.0, 10.0, 1.0, ((double)sgOtCnt));
|
|
|
|
// check for allocation errors
|
|
if((rc = cmDspSysLastRC(h)) != kOkDspRC )
|
|
goto errLabel;
|
|
|
|
cmDspSysConnectAudioN1N1( h, sg, "out", cf, "in", chCnt ); // sg -> CF
|
|
cmDspSysConnectAudioN1N1( h, cf, "out", eq, "in", chCnt ); // CF -> EQ
|
|
cmDspSysConnectAudioN1N1( h, eq, "out", mt, "in", chCnt ); // EQ -> MT
|
|
cmDspSysConnectAudioN11N( h, mt, "out", mix, "in", chCnt ); // MT -> mix
|
|
|
|
cmDspSysInstallCb11N1( h, tmul, "val", tmop, "in-1", chCnt );
|
|
cmDspSysInstallCb11N1( h, toff, "val", toop, "in-1", chCnt );
|
|
cmDspSysInstallCbN1N1( h, tmop, "out", toop, "in-0", chCnt );
|
|
cmDspSysInstallCbN1N1( h, toop, "out", env, "tscale", chCnt );
|
|
|
|
cmDspSysInstallCb11N1( h, amul, "val", amop, "in-1", chCnt );
|
|
cmDspSysInstallCb11N1( h, aoff, "val", aoop, "in-1", chCnt );
|
|
cmDspSysInstallCbN1N1( h, amop, "out", aoop, "in-0", chCnt );
|
|
cmDspSysInstallCbN1N1( h, aoop, "out", env, "ascale", chCnt );
|
|
|
|
cmDspSysInstallCbN1N1( h, env, "out", d2l, "in", chCnt ); // adsr -> dbtolin
|
|
cmDspSysInstallCbN11N( h, d2l, "out", mix, "gain", chCnt ); // db2lin -> mix (gain)
|
|
|
|
cmDspSysInstallCbN1N1( h, env, "out", d2l, "in", chCnt );
|
|
cmDspSysInstallCbN11N( h, d2l, "out", mix, "gain", chCnt );
|
|
cmDspSysInstallCb11N1( h, alpha, "val", cf, "alpha", chCnt ); // CF alpha
|
|
|
|
cmDspSysInstallCb11N1( h, sgsh, "val", sg, "shape", chCnt );
|
|
cmDspSysInstallCb11N1( h, sgot, "val", sg, "ot", chCnt );
|
|
|
|
cmDspSysInstallCb11N1( h, dly, "val", env, "dly", chCnt );
|
|
cmDspSysInstallCb11N1( h, atk, "val", env, "atk", chCnt );
|
|
cmDspSysInstallCb11N1( h, dcy, "val", env, "dcy", chCnt );
|
|
cmDspSysInstallCb11N1( h, hold, "val", env, "hold", chCnt );
|
|
cmDspSysInstallCb11N1( h, rls, "val", env, "rls", chCnt );
|
|
cmDspSysInstallCb11N1( h, alvl, "val", env, "alvl", chCnt );
|
|
cmDspSysInstallCb11N1( h, sus, "val", env, "sus", chCnt );
|
|
|
|
|
|
cmDspSysInstallCb11N1( h, eqbyp, "out", eq, "bypass", chCnt );
|
|
cmDspSysInstallCb11N1( h, eqmode, "mode", eq, "mode", chCnt );
|
|
cmDspSysInstallCb11N1( h, eqq, "val", eq, "Q", chCnt );
|
|
cmDspSysInstallCb11N1( h, eqfgn, "val", eq, "gain", chCnt );
|
|
|
|
cmDspSysInstallCb11N1( h, mtfb, "val", mt, "fb", chCnt );
|
|
cmDspSysInstallCb11N1( h, mtscale,"val", mt, "scale", chCnt );
|
|
|
|
|
|
if( seqFl )
|
|
{
|
|
cmDspSysInstallCbN1N1( h, bts, "out", rtr, "s-in", chCnt );
|
|
cmDspSysInstallCbN1N1( h, rtr, "s-out-0", cnt0, "next", chCnt );
|
|
cmDspSysInstallCbN1N1( h, rtr, "s-out-1", cnt1, "next", chCnt );
|
|
cmDspSysInstallCbN1N1( h, rtr, "s-out-2", cnt2, "next", chCnt );
|
|
|
|
cmDspSysInstallCbN1N1(h, seq0, "cnt", cnt0, "max", chCnt );
|
|
cmDspSysInstallCbN1N1(h, seq1, "cnt", cnt1, "max", chCnt );
|
|
cmDspSysInstallCbN1N1(h, seq2, "cnt", cnt2, "max", chCnt );
|
|
|
|
cmDspSysInstallCbN1N1(h, cnt0, "out", seq0, "sel", chCnt );
|
|
cmDspSysInstallCbN1N1(h, cnt1, "out", seq1, "sel", chCnt );
|
|
cmDspSysInstallCbN1N1(h, cnt2, "out", seq2, "sel", chCnt );
|
|
|
|
cmDspSysInstallCbN1N1(h, seq0, "hz", cf, "hz", chCnt );
|
|
cmDspSysInstallCbN1N1(h, seq1, "hz", cf, "hz", chCnt );
|
|
cmDspSysInstallCbN1N1(h, seq2, "hz", cf, "hz", chCnt );
|
|
|
|
cmDspSysInstallCbN1N1(h, seq0, "hz", eq, "f0", chCnt );
|
|
cmDspSysInstallCbN1N1(h, seq1, "hz", eq, "f0", chCnt );
|
|
cmDspSysInstallCbN1N1(h, seq2, "hz", eq, "f0", chCnt );
|
|
|
|
cmDspSysInstallCbN1N1(h, seq0, "hz", sg, "hz", chCnt );
|
|
cmDspSysInstallCbN1N1(h, seq1, "hz", sg, "hz", chCnt );
|
|
cmDspSysInstallCbN1N1(h, seq2, "hz", sg, "hz", chCnt );
|
|
}
|
|
|
|
|
|
errLabel:
|
|
if(cmDspSysLastRC(h) != kOkDspRC )
|
|
p = NULL;
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef struct
|
|
{
|
|
cmDspPP_Circuit_t c;
|
|
cmDspSys_NShp_t* ns0p;
|
|
cmDspSys_NShp_t* ns1p;
|
|
} cmDspPP_NSh_Circuit_t;
|
|
|
|
|
|
cmDspRC_t _cmDspPP_NoiseShaperAlloc(
|
|
cmDspSysH_t h,
|
|
cmErr_t* err,
|
|
cmDspPP_NSh_Circuit_t* p,
|
|
const cmChar_t* title,
|
|
const cmChar_t* preLbl,
|
|
cmDspInst_t* selChk,
|
|
cmDspInst_t* ptIn,
|
|
unsigned iChCnt,
|
|
unsigned oChCnt)
|
|
{
|
|
cmDspRC_t rc = kOkDspRC;
|
|
double secCnt = 3;
|
|
unsigned nsCnt = 0;
|
|
unsigned nsCnt1 = 0;
|
|
const cmChar_t* nsPitchRsrcStr = "nsMidi";
|
|
const cmChar_t* nsChIdxRsrcStr = "nsSelCh";
|
|
|
|
// get the active channel list (indexes of the input channels which will be used by the noise shaper);
|
|
if( cmDspRsrcArrayCount( h, &nsCnt1, nsChIdxRsrcStr, NULL ) != kOkDspRC )
|
|
return cmErrMsg(err,kPgmCfgFailDspRC,"The noise shaper channel index list '%s' could not be read.",cmStringNullGuard(nsChIdxRsrcStr));
|
|
|
|
// get the pitches associated with each active channel
|
|
if( cmDspRsrcArrayCount( h, &nsCnt, nsPitchRsrcStr, NULL ) != kOkDspRC )
|
|
return cmErrMsg(err,kPgmCfgFailDspRC,"The noise shaper pitch list '%s' could not be read.",cmStringNullGuard(nsPitchRsrcStr));
|
|
|
|
// the channel and pitch list must contain the same number of elements
|
|
assert( nsCnt1 == nsCnt );
|
|
|
|
p->c.circuitSymId = cmDspSysRegisterInstAttrSymbolStr(h,title);
|
|
unsigned presetGrpSymId = cmDspSysPresetRegisterGroup(h,title);
|
|
_cmDspSys_PresetMgmt(h,preLbl,presetGrpSymId);
|
|
cmDspSysNewColumn(h,COL_WIDTH);
|
|
|
|
//cmDspInst_t* printBtn = cmDspSysAllocInst( h, "Button", "_print", 2, kButtonDuiId, 0.0);
|
|
//cmDspInst_t* bcast = cmDspSysAllocInst( h, "BcastSym", NULL, 1, p->c.circuitSymId );
|
|
//cmDspSysInstallCb( h, printBtn, "sym", bcast, "msg", NULL );
|
|
|
|
p->c.aout = allocInstPtrArray(h,oChCnt);
|
|
|
|
// nom - selects active channels from among all possible input channels - coming from the EF's
|
|
cmDspInst_t* nom = cmDspSysAllocInst( h, "NofM", NULL, 2, iChCnt, nsCnt ); // EF's -> Nsh switch
|
|
|
|
// Allocate the noise shapers
|
|
p->ns0p = _cmDspSys_NShpAlloc( h, presetGrpSymId, "f", nsCnt, false );
|
|
p->ns1p = _cmDspSys_NShpAlloc( h, presetGrpSymId, "s", nsCnt, true );
|
|
|
|
cmDspSysNewColumn(h,COL_WIDTH);
|
|
cmDspInst_t* sectn = cmDspSysAllocScalar( h, "Section", 0, secCnt-1, 1.0, 0.0);
|
|
cmDspInst_t* pts = cmDspSysAllocInst( h, "PortToSym", NULL, 2, "off", "send" );
|
|
cmDspInst_t* pitarr = cmDspSysAllocInst( h, "Array", NULL, 1, nsPitchRsrcStr );
|
|
cmDspInst_t* charr = cmDspSysAllocInst( h, "Array", NULL, 1, nsChIdxRsrcStr );
|
|
cmDspInst_t** eqpc = cmDspSysAllocInstArray( h, nsCnt, "PitchCvt", NULL, NULL, 0 );
|
|
cmDspInst_t** cfpc = cmDspSysAllocInstArray( h, nsCnt, "PitchCvt", NULL, NULL, 0 );
|
|
cmDspInst_t** sgpc = cmDspSysAllocInstArray( h, nsCnt, "PitchCvt", NULL, NULL, 0 );
|
|
|
|
// check for allocation errors
|
|
if((rc = cmDspSysLastRC(h)) != kOkDspRC )
|
|
goto errLabel;
|
|
|
|
assert( oChCnt >= 2 );
|
|
|
|
// put the 'f' noise in ch:0 and the 's' noise in ch:1
|
|
p->c.aoutLbl = "out";
|
|
p->c.aout[1] = p->ns0p->mix;
|
|
p->c.aout[0] = p->ns1p->mix;
|
|
|
|
|
|
// selChk is the circuit selector check box in the main window
|
|
cmDspSysInstallCb( h, selChk, "out", pts, "off", NULL ); // First send 'off' to nom to clear its selector
|
|
cmDspSysInstallCb( h, selChk, "out", pts, "send", NULL ); // Second send 'send' to charr to select active ports on nom.
|
|
cmDspSysInstallCb( h, pts, "off", nom, "cmd", NULL ); // Clear the nom (all inputs are turned off)
|
|
cmDspSysInstallCb( h, pts, "send", charr, "cmd", NULL ); // Send the active channel indexes to the nom
|
|
cmDspSysInstallCb( h, pts, "send", pitarr, "cmd", NULL ); // Send the pitch values to the circuits (eq,cf,sg,..)
|
|
cmDspSysInstallCb( h, charr, "done", nom, "cmd", NULL ); // Tell the nom when its setup is complete
|
|
|
|
cmDspSysInstallCb1N11( h, charr, "out", nom, "seli", nsCnt ); // EF nom channel index selectors
|
|
cmDspSysInstallCb1N1N( h, ptIn, "b-out", nom, "b-in", iChCnt ); // EF -> nom (gates)
|
|
cmDspSysInstallCb1N1N( h, ptIn, "f-out", nom, "f-in", iChCnt ); // EF -> nom (rms)
|
|
|
|
|
|
cmDspSysInstallCb1NN1( h, pitarr, "out", cfpc, "midi", nsCnt ); // pitch array -> pitch converter
|
|
cmDspSysInstallCb1NN1( h, pitarr, "out", eqpc, "midi", nsCnt );
|
|
cmDspSysInstallCb1NN1( h, pitarr, "out", sgpc, "midi", nsCnt );
|
|
|
|
cmDspSysInstallCbN1N1( h, cfpc, "hz", p->ns0p->cf, "hz", nsCnt ); // pitch cvt -> CF (Hz)
|
|
cmDspSysInstallCbN1N1( h, eqpc, "hz", p->ns0p->eq, "f0", nsCnt ); // pitch cvt -> Eq (Hz)
|
|
cmDspSysInstallCbN1N1( h, sgpc, "hz", p->ns0p->sg, "hz", nsCnt ); // pitch cvt -> SG (Hz)
|
|
|
|
cmDspSysInstallCb1NN1( h, nom, "b-out", p->ns0p->env, "gate", nsCnt ); // EF -> adsr (gate)
|
|
cmDspSysInstallCb1NN1( h, nom, "b-out", p->ns1p->env, "gate", nsCnt ); //
|
|
|
|
|
|
cmDspSysInstallCb1NN1( h, nom, "f-out", p->ns0p->tmop, "in-0", nsCnt ); // EF (level) -> adsr time scale
|
|
cmDspSysInstallCb1NN1( h, nom, "f-out", p->ns0p->amop, "in-0", nsCnt ); // EF (level) -> adsr ampl scale
|
|
cmDspSysInstallCb1NN1( h, nom, "f-out", p->ns1p->tmop, "in-0", nsCnt ); // EF (level) -> adsr time scale
|
|
cmDspSysInstallCb1NN1( h, nom, "f-out", p->ns1p->amop, "in-0", nsCnt ); // EF (level) -> adsr ampl scale
|
|
|
|
cmDspSysInstallCb11N1( h, sectn, "val", p->ns1p->rtr, "sel", nsCnt ); // section scalar -> rtr sel input
|
|
cmDspSysInstallCb1NN1( h, nom, "b-out", p->ns1p->bts, "on", nsCnt ); // nom gate -> bool-to-sym -> rtr input
|
|
|
|
errLabel:
|
|
|
|
cmDspSysRemoveInstAttrSymbol(h,p->c.circuitSymId);
|
|
return rc;
|
|
}
|
|
|
|
|
|
|
|
//=====================================================================================================================
|
|
typedef struct
|
|
{
|
|
cmDspInst_t* start; // circ. sel check -> start
|
|
cmDspInst_t** tmop; // level -> time scale input
|
|
cmDspInst_t** amop; // level -> ampl scale input
|
|
cmDspInst_t** adsr; // gate -> adsr input
|
|
cmDspInst_t** mix; // audio -> input mixer
|
|
cmDspInst_t** ps; // pitch shifter
|
|
cmDspInst_t** eq;
|
|
cmDspInst_t** mt; // output prior to the mixer
|
|
cmDspInst_t* mixo; // output mixer -> aout
|
|
} cmDspFx0_Chain_t;
|
|
|
|
|
|
cmDspRC_t _cmDspFx0_ChainAlloc(
|
|
cmDspSysH_t h,
|
|
cmErr_t* err,
|
|
unsigned pgSymId,
|
|
const cmChar_t* preLbl,
|
|
const cmChar_t* rsrc,
|
|
unsigned chainChCnt,
|
|
cmDspFx0_Chain_t* p )
|
|
{
|
|
cmDspRC_t rc = kOkDspRC;
|
|
|
|
double multMin = 0.0;
|
|
double multMax = 100.0;
|
|
double multInc = 0.01;
|
|
double offsMin = 0.0;
|
|
double offsMax = 100.0;
|
|
double offsInc = 0.01;
|
|
|
|
double adsrMaxMs = 20000;
|
|
double adsrMinMs = 0;
|
|
double adsrIncMs = 1;
|
|
double adsrMaxLevel = 100.0;
|
|
double adsrSusLevel = 100.0;
|
|
double adsrMinLevel = 0.0;
|
|
double adsrIncLevel = 0.001;
|
|
|
|
unsigned sgShapeId = 2;
|
|
unsigned sgOtCnt = 5;
|
|
|
|
bool lpBypassFl = true;
|
|
|
|
bool cmpBypassFl = false;
|
|
double cmpInGain = 1.0;
|
|
double cmpThreshDb = -40.0;
|
|
double cmpRatio_num = 4.0;
|
|
double cmpAtkMs = 15.0;
|
|
double cmpRlsMs = 50.0;
|
|
double cmpMakeup = 4.0;
|
|
double cmpWndMaxMs = 1000.0;
|
|
double cmpWndMs = 200.0;
|
|
double cmpMaxGain = 100.0;
|
|
|
|
bool distBypassFl = false;
|
|
double distInGain = 4.0;
|
|
double distDsrate = 44100.0;
|
|
double distBits = 24.0;
|
|
bool distRectifyFl = false;
|
|
bool distFullRectFl = false;
|
|
double distClipDb = -10.0;
|
|
|
|
double cfMinHz = 20.0;
|
|
double cfHz = 500;
|
|
double cfAlpha = 0.9;
|
|
bool cfFbFl = true;
|
|
bool cfBypassFl = true;
|
|
|
|
bool eqBypassFl = false;
|
|
unsigned eqModeSymId = cmSymTblRegisterStaticSymbol(cmDspSysSymbolTable(h),"LP");
|
|
double eqF0hz = 250;
|
|
double eqQ = 1.0;
|
|
double eqFgain = 1.0;
|
|
|
|
bool psBypassFl = true;
|
|
double psMaxRatio = 10.0;
|
|
double psRatio = 1.0;
|
|
|
|
double dlyFb = 0.0;
|
|
double dlyMaxMs = 3000.0;
|
|
double dlyMs = 1;
|
|
|
|
bool mtBypassFl = true;
|
|
double mtTimeScale = 1.0;
|
|
double mtFeedback = 0.0;
|
|
|
|
double stOffs = 96;
|
|
|
|
double voiceMult = 1.0 / chainChCnt;
|
|
|
|
cmDspInst_t** adsr = p->adsr= cmDspSysAllocInstArray(h, chainChCnt, "Adsr", NULL, NULL, 2, true, adsrMinLevel );
|
|
cmDspInst_t** dtl = cmDspSysAllocInstArray(h, chainChCnt, "DbToLin", NULL, NULL, 0 );
|
|
cmDspInst_t** phs = cmDspSysAllocInstArray(h, chainChCnt, "Phasor", NULL, NULL, 1, cmDspSysSampleRate(h) );
|
|
cmDspInst_t** wt = cmDspSysAllocInstArray(h, chainChCnt, "WaveTable", NULL, NULL, 4, ((unsigned)cmDspSysSampleRate(h)), 2, NULL, NULL, -1 );
|
|
|
|
//cmDspInst_t** sgmul= cmDspSysAllocScalarA( h, chainChCnt, pgSymId, preLbl, "Sg Mult", 0.0, 10.0, 0.01, 1.0 );
|
|
//cmDspInst_t** mul = cmDspSysAllocInstArray(h, chainChCnt, "ScalarOp", NULL, NULL, 6, 2, "*", "in-0", 1.0, "in-1", 1.0 );
|
|
cmDspInst_t** mixa = p->mix = cmDspSysAllocInstArray(h, chainChCnt, "AMix", NULL, NULL, 1, 1);
|
|
cmDspInst_t** mixs = cmDspSysAllocInstArray(h, chainChCnt, "AMix", NULL, NULL, 2, 1, 0.0);
|
|
cmDspInst_t** mixm = cmDspSysAllocInstArray(h, chainChCnt, "AMix", NULL, NULL, 3, 2, 0.5, 0.5);
|
|
|
|
cmDspInst_t** loop = cmDspSysAllocInstArray(h, chainChCnt, "LoopRecd", NULL, NULL, 0 );
|
|
cmDspInst_t** ps = p->ps = cmDspSysAllocInstArray(h, chainChCnt, "PShift", NULL, NULL, 2, psBypassFl, psRatio );
|
|
|
|
cmDspInst_t** cmp = cmDspSysAllocInstArray(h, chainChCnt, "Compressor",NULL, NULL, 8, cmpBypassFl, cmpThreshDb, cmpRatio_num, cmpAtkMs, cmpRlsMs, cmpInGain, cmpMakeup, cmpWndMs, cmpWndMaxMs );
|
|
cmDspInst_t** dist = cmDspSysAllocInstArray(h, chainChCnt, "DistDs", NULL, NULL, 3, distBypassFl, distInGain, distDsrate, distBits );
|
|
cmDspInst_t** cf = cmDspSysAllocInstArray(h, chainChCnt, "CombFilt", NULL, NULL, 5, cfBypassFl, cfMinHz, cfFbFl, cfHz, cfAlpha );
|
|
cmDspInst_t** eq = p->eq = cmDspSysAllocInstArray(h, chainChCnt, "BiQuadEq", NULL, NULL, 5, eqBypassFl, eqModeSymId, eqF0hz, eqQ, eqFgain );
|
|
cmDspInst_t** dly = cmDspSysAllocInstArray(h, chainChCnt, "Delay", NULL, NULL, 2, dlyMaxMs, dlyFb );
|
|
cmDspInst_t** mt = p->mt = cmDspSysAllocInstArray(h, chainChCnt, "MtDelay", NULL, NULL, 5, mtBypassFl, mtTimeScale, mtFeedback, 20.0, 0.3 );
|
|
cmDspInst_t* mixo = p->mixo= cmDspSysAllocInst( h, "AMix", NULL, 1, chainChCnt );
|
|
|
|
cmDspSysNewColumn(h,COL_WIDTH);
|
|
cmDspInst_t** dlyms = cmDspSysAllocScalarA( h, chainChCnt, pgSymId, preLbl, "Dly ms", 0.0, 10000.0, 1.0, dlyMs);
|
|
|
|
cmDspInst_t* start = p->start = cmDspSysAllocInst( h, "PortToSym", NULL, 1, "send" ); // all msgs to start send the 'hz' symbol
|
|
cmDspInst_t** sgpc = cmDspSysAllocInstArray(h, chainChCnt, "PitchCvt", NULL, NULL, 0 );
|
|
cmDspInst_t** cfpc = cmDspSysAllocInstArray(h, chainChCnt, "PitchCvt", NULL, NULL, 0 );
|
|
cmDspInst_t** eqpc = cmDspSysAllocInstArray(h, chainChCnt, "PitchCvt", NULL, NULL, 0 );
|
|
cmDspInst_t* midiV = cmDspSysAllocInst( h, "Array", NULL, 1, rsrc );
|
|
|
|
cmDspSysNewColumn(h,COL_WIDTH);
|
|
|
|
cmDspInst_t** tmop = p->tmop= cmDspSysAllocInstArray(h, chainChCnt, "ScalarOp", NULL, NULL, 6, 2, "*", "in-0", 1.0, "in-1", 1.0 );
|
|
cmDspInst_t** toop = cmDspSysAllocInstArray(h, chainChCnt, "ScalarOp", NULL, NULL, 6, 2, "+", "in-0", 0.0, "in-1", 0.0 );
|
|
cmDspInst_t** amop = p->amop= cmDspSysAllocInstArray(h, chainChCnt, "ScalarOp", NULL, NULL, 6, 2, "*", "in-0", 1.0, "in-1", 1.0 );
|
|
cmDspInst_t** aoop = cmDspSysAllocInstArray(h, chainChCnt, "ScalarOp", NULL, NULL, 6, 2, "+", "in-0", 0.0, "in-1", 0.0 );
|
|
|
|
// time/amp scale multiply and offset controls
|
|
cmDspInst_t* tmul = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Time Mult", multMin, multMax, multInc, 1.0);
|
|
cmDspInst_t* toff = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Time Offs", offsMin, offsMax, offsInc, 0.0);
|
|
cmDspInst_t* amul = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Ampl Mult", multMin, multMax, multInc, 1.0);
|
|
cmDspInst_t* aoff = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Ampl Offs", offsMin, offsMax, offsInc, 0.0);
|
|
|
|
// ADSR controls
|
|
cmDspInst_t* adly = cmDspSysAllocScalarP( h, pgSymId, preLbl, "sg-Dly", adsrMinMs, adsrMaxMs, adsrIncMs, 0.0);
|
|
cmDspInst_t* atk = cmDspSysAllocScalarP( h, pgSymId, preLbl, "sg-Atk", adsrMinMs, adsrMaxMs, adsrIncMs, 20.0);
|
|
cmDspInst_t* dcy = cmDspSysAllocScalarP( h, pgSymId, preLbl, "sg-Dcy", adsrMinMs, adsrMaxMs, adsrIncMs, 100.0);
|
|
cmDspInst_t* hold = cmDspSysAllocScalarP( h, pgSymId, preLbl, "sg-Hold", adsrMinMs, adsrMaxMs, adsrIncMs, 100.0);
|
|
cmDspInst_t* rls = cmDspSysAllocScalarP( h, pgSymId, preLbl, "sg-Rls", adsrMinMs, adsrMaxMs, adsrIncMs, 1000.0);
|
|
cmDspInst_t* alvl = cmDspSysAllocScalarP( h, pgSymId, preLbl, "sg-AdsrMax", adsrMinLevel,adsrMaxLevel,adsrIncLevel, adsrMaxLevel);
|
|
cmDspInst_t* sus = cmDspSysAllocScalarP( h, pgSymId, preLbl, "sg-SusLvl", adsrMinLevel,adsrMaxLevel,adsrIncLevel, adsrSusLevel );
|
|
//cmDspInst_t* zero = cmDspSysAllocScalarP( h, pgSymId, preLbl, "zero", 0.0, 0.0, 0.0, 0.0);
|
|
|
|
// SigGen controls
|
|
cmDspInst_t* sgsh = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Sg Shape", 0.0, 11.0, 1.0, ((double)sgShapeId));
|
|
cmDspInst_t* sgot = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Sg OT Cnt", 0.0, 20.0, 1.0, ((double)sgOtCnt));
|
|
cmDspInst_t* sgpoffs = cmDspSysAllocScalarP(h, pgSymId, preLbl, "Sg ST off", -stOffs, stOffs, 0.01, 0.0 );
|
|
|
|
|
|
cmDspSysNewColumn(h,COL_WIDTH);
|
|
// Loop recorder controls
|
|
cmDspInst_t* lpByp = cmDspSysAllocCheckP( h, pgSymId, preLbl, "Lp Byps", lpBypassFl );
|
|
cmDspInst_t* lpRcd = cmDspSysAllocCheckP( h, pgSymId, preLbl, "Lp Recd", false );
|
|
cmDspInst_t* lpRat = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Lp Ratio",0.0, 10.0, 0.01, 1.0 );
|
|
|
|
// Pitch Shifter controls
|
|
cmDspInst_t* psbyp = cmDspSysAllocCheckP( h, pgSymId, preLbl, "PS Byp", psBypassFl );
|
|
cmDspInst_t* psrat = cmDspSysAllocScalarP( h, pgSymId, preLbl, "PS Ratio", 0.0, psMaxRatio, 0.01, psRatio );
|
|
|
|
|
|
cmDspSysNewColumn(h,COL_WIDTH);
|
|
// Compressor controls
|
|
cmDspInst_t* cbyp = cmDspSysAllocCheckP( h, pgSymId, preLbl, "Byp Cmp", cmpBypassFl);
|
|
cmDspInst_t* cgain = cmDspSysAllocScalarP( h, pgSymId, preLbl, "In Gain", 0.0, cmpMaxGain, 0.01,cmpInGain );
|
|
cmDspInst_t* cthr = cmDspSysAllocScalarP( h, pgSymId, preLbl, "ThreshDb", -100.0, 0.0, 0.1, cmpThreshDb);
|
|
cmDspInst_t* crat = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Ratio", 0.1, 100.0, 0.1, cmpRatio_num);
|
|
cmDspInst_t* catk = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Atk Ms", 0.0, 1000.0, 0.1, cmpAtkMs);
|
|
cmDspInst_t* crls = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Rls Ms", 0.0, 1000.0, 0.1, cmpRlsMs);
|
|
cmDspInst_t* cmkup = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Makeup", 0.0, cmpMaxGain, 0.01, cmpMakeup);
|
|
cmDspInst_t* cwnd = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Wnd Ms", 1.0, cmpWndMaxMs,1.0, cmpWndMs );
|
|
|
|
// Distortion controls
|
|
cmDspInst_t* dbyp = cmDspSysAllocCheckP( h, pgSymId, preLbl, "Dist Byp", distBypassFl);
|
|
cmDspInst_t* drct = cmDspSysAllocCheckP( h, pgSymId, preLbl, "Rectify", distRectifyFl);
|
|
cmDspInst_t* dful = cmDspSysAllocCheckP( h, pgSymId, preLbl, "Full/Half", distFullRectFl);
|
|
cmDspInst_t* dsr = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Dsrate", 0.0, 96000.0, 1.0, distDsrate);
|
|
cmDspInst_t* dbt = cmDspSysAllocScalarP( h, pgSymId, preLbl, "bits", 2.0, 32.0, 1.0, distBits);
|
|
cmDspInst_t* dclip = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Clip dB", -100.0, 0.0, 0.1, distClipDb);
|
|
cmDspInst_t* dogn = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Out Gain", 0.0, 10.0, 0.01, 1.0);
|
|
|
|
cmDspSysNewColumn(h,COL_WIDTH);
|
|
// Comb filter controls
|
|
cmDspInst_t* cfbyp = cmDspSysAllocCheckP( h, pgSymId, preLbl, "CF Byp", cfBypassFl);
|
|
cmDspInst_t* cfalpha = cmDspSysAllocScalarP( h, pgSymId, preLbl, "CF alpha", -1.0, 1.0, 0.001, cfAlpha );
|
|
cmDspInst_t* cfpoffs = cmDspSysAllocScalarP( h, pgSymId, preLbl, "CF ST off", -stOffs, stOffs, 0.01, 0.0 );
|
|
|
|
// Eq controls
|
|
cmDspInst_t* eqbyp = cmDspSysAllocCheckP( h, pgSymId, preLbl, "Eq Byp", 0 );
|
|
cmDspInst_t* eqmode = cmDspSysAllocMsgListP(h, pgSymId, preLbl, "Mode", NULL, "biQuadEqMode", 1);
|
|
cmDspInst_t* eqq = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Eq Q", -100.0, 100.0, 0.1, eqQ);
|
|
cmDspInst_t* eqfgn = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Filt Gain", 0.0, 10.0, 0.1, eqFgain);
|
|
cmDspInst_t* eqpoffs = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Eq ST off", -stOffs, stOffs, 0.01, 0.0 );
|
|
|
|
// Delay Controls
|
|
cmDspInst_t* dlybyp = cmDspSysAllocCheckP( h, pgSymId, preLbl, "Dly Byp", 0 );
|
|
//cmDspInst_t* dlyms = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Dly Time", 0.0, dlyMaxMs, 1.0, dlyMs );
|
|
cmDspInst_t* dlyfb = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Dly Fb", -1.0, 1.0, 0.001, dlyFb );
|
|
|
|
// multi-tap controls
|
|
cmDspInst_t* mtbyp = cmDspSysAllocCheckP( h, pgSymId, preLbl, "Mt Byp", mtBypassFl);
|
|
cmDspInst_t* mtfb = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Feedback", 0.0, 1.0, 0.01, mtFeedback);
|
|
cmDspInst_t* mtscale= cmDspSysAllocScalarP( h, pgSymId, preLbl, "Tm Scale", 0.01, 10.0, 0.01, mtTimeScale);
|
|
|
|
// voice scaler
|
|
cmDspInst_t* vmult = cmDspSysAllocScalarP( h, pgSymId, preLbl, "Voc Scale", 0.0, 10.0, 0.001, voiceMult);
|
|
|
|
// Compression Meters
|
|
cmDspSysNewColumn(h,COL_WIDTH);
|
|
cmDspSysAllocLabel(h,"Compression",kLeftAlignDuiId);
|
|
|
|
cmDspInst_t** cmtr = cmDspSysAllocInstArray(h, chainChCnt, "Meter", NULL, NULL, 3, 0.0, 0.0, 1.0);
|
|
|
|
|
|
// Check for allocation errors
|
|
if((rc = cmDspSysLastRC(h)) != kOkDspRC )
|
|
goto errLabel;
|
|
|
|
// NOTE:
|
|
// NOTE: ain goes to mix "in-0"
|
|
// NOTE:
|
|
|
|
// audio connections -
|
|
cmDspSysConnectAudioN1N1(h, phs, "out", wt, "phs", chainChCnt ); // phs -> wt
|
|
cmDspSysConnectAudioN1N1(h, wt, "out", mixs, "in", chainChCnt ); // wt -> mix
|
|
cmDspSysConnectAudioN1N1(h, mixs, "out", mixm, "in-0", chainChCnt ); //
|
|
cmDspSysConnectAudioN1N1(h, mixa, "out", mixm, "in-1", chainChCnt ); //
|
|
cmDspSysConnectAudioN1N1(h, mixm, "out", loop, "in", chainChCnt ); // mix -> loop
|
|
cmDspSysConnectAudioN1N1(h, loop, "out", ps, "in", chainChCnt ); // loop -> ps
|
|
cmDspSysConnectAudioN1N1(h, ps, "out", cmp, "in", chainChCnt ); // ps -> cmp
|
|
cmDspSysConnectAudioN1N1(h, cmp, "out", dist, "in", chainChCnt ); // cmp -> dist
|
|
cmDspSysConnectAudioN1N1(h, dist, "out", cf, "in", chainChCnt ); // dist -> cf
|
|
cmDspSysConnectAudioN1N1(h, cf, "out", eq, "in", chainChCnt ); // cf -> eq
|
|
cmDspSysConnectAudioN1N1(h, eq, "out", dly, "in", chainChCnt ); // cf -> dly
|
|
cmDspSysConnectAudioN1N1(h, dly, "out", mt, "in", chainChCnt ); // dly -> mt
|
|
cmDspSysConnectAudioN11N(h, mt, "out", mixo, "in", chainChCnt ); // mt -> mixo
|
|
|
|
cmDspSysInstallCb( h, start, "send", midiV, "cmd", NULL ); // force the hz value to be sent out the midV
|
|
cmDspSysInstallCb1NN1( h, midiV, "out", sgpc, "midi", chainChCnt ); // midiV -> pcvt (convert midi to pitch)
|
|
cmDspSysInstallCb1NN1( h, midiV, "out", cfpc, "midi", chainChCnt ); // midiV -> pcvt (convert midi to pitch)
|
|
cmDspSysInstallCb1NN1( h, midiV, "out", eqpc, "midi", chainChCnt ); // midiV -> pcvt (convert midi to pitch)
|
|
|
|
//cmDspSysInstallCb11N1( h, zero, "val", mix, "gain-0", chainChCnt );
|
|
//cmDspSysInstallCb11N1( h, zero, "val", mixs, "gain", chainChCnt ); // force the osc mixer to start turned off
|
|
|
|
// Adssr scale/offset controls
|
|
cmDspSysInstallCb11N1( h, tmul, "val", tmop, "in-1", chainChCnt );
|
|
cmDspSysInstallCb11N1( h, toff, "val", toop, "in-1", chainChCnt );
|
|
cmDspSysInstallCbN1N1( h, tmop, "out", toop, "in-0", chainChCnt );
|
|
cmDspSysInstallCbN1N1( h, toop, "out", adsr, "tscale", chainChCnt );
|
|
|
|
cmDspSysInstallCb11N1( h, amul, "val", amop, "in-1", chainChCnt );
|
|
cmDspSysInstallCb11N1( h, aoff, "val", aoop, "in-1", chainChCnt );
|
|
cmDspSysInstallCbN1N1( h, amop, "out", aoop, "in-0", chainChCnt );
|
|
cmDspSysInstallCbN1N1( h, aoop, "out", adsr, "ascale", chainChCnt );
|
|
|
|
// ADSR parameter controls
|
|
cmDspSysInstallCb11N1( h, adly, "val", adsr, "dly", chainChCnt );
|
|
cmDspSysInstallCb11N1( h, atk, "val", adsr, "atk", chainChCnt );
|
|
cmDspSysInstallCb11N1( h, dcy, "val", adsr, "dcy", chainChCnt );
|
|
cmDspSysInstallCb11N1( h, hold, "val", adsr, "hold", chainChCnt );
|
|
cmDspSysInstallCb11N1( h, rls, "val", adsr, "rls", chainChCnt );
|
|
cmDspSysInstallCb11N1( h, alvl, "val", adsr, "alvl", chainChCnt );
|
|
cmDspSysInstallCb11N1( h, sus, "val", adsr, "sus", chainChCnt );
|
|
cmDspSysInstallCbN1N1( h, adsr, "out", dtl, "in", chainChCnt ); // adsr -> dbToLin
|
|
cmDspSysInstallCbN1N1( h, dtl, "out", mixs, "gain", chainChCnt ); // dbToLin -> mix (gain)
|
|
|
|
// SigGen parameter controls
|
|
//cmDspSysInstallCb11N1( h, start, "send", sgmul, "send", chainChCnt ); // send cur sgmul value to mul in-0
|
|
//cmDspSysInstallCbN1N1( h, sgpc, "hz", mul, "in-1", chainChCnt ); // send hz value to mul in-1
|
|
//cmDspSysInstallCbN1N1( h, sgmul, "val", mul, "in-0", chainChCnt );
|
|
cmDspSysInstallCb11N1( h, sgpoffs, "val", sgpc, "offs", chainChCnt );
|
|
//cmDspSysInstallCbN1N1( h, mul, "out", phs, "mult", chainChCnt );
|
|
cmDspSysInstallCbN1N1( h, sgpc, "hz", phs, "mult", chainChCnt );
|
|
cmDspSysInstallCb11N1( h, sgsh, "val", wt, "shape", chainChCnt );
|
|
cmDspSysInstallCb11N1( h, sgot, "val", wt, "ot", chainChCnt );
|
|
|
|
|
|
// Pitch Shift parameter controls
|
|
cmDspSysInstallCb11N1( h, psbyp, "out", ps, "bypass", chainChCnt );
|
|
cmDspSysInstallCb11N1( h, psrat, "val", ps, "ratio", chainChCnt );
|
|
|
|
// Loop recorder parameter controls
|
|
cmDspSysInstallCb11N1(h, lpByp, "out", loop, "bypass", chainChCnt );
|
|
cmDspSysInstallCb11N1(h, lpRcd, "out", loop, "recd", chainChCnt );
|
|
cmDspSysInstallCb11N1(h, lpRat, "val", loop, "ratio", chainChCnt );
|
|
|
|
// Compressor paramter controls
|
|
cmDspSysInstallCb11N1(h, cbyp, "out", cmp, "bypass", chainChCnt );
|
|
cmDspSysInstallCb11N1(h, cgain, "val", cmp, "igain", chainChCnt );
|
|
cmDspSysInstallCb11N1(h, cthr, "val", cmp, "thr", chainChCnt );
|
|
cmDspSysInstallCb11N1(h, crat, "val", cmp, "ratio", chainChCnt );
|
|
cmDspSysInstallCb11N1(h, catk, "val", cmp, "atk", chainChCnt );
|
|
cmDspSysInstallCb11N1(h, crls, "val", cmp, "rls", chainChCnt );
|
|
cmDspSysInstallCb11N1(h, cmkup, "val", cmp, "ogain", chainChCnt );
|
|
cmDspSysInstallCb11N1(h, cwnd, "val", cmp, "wnd", chainChCnt );
|
|
cmDspSysInstallCbN1N1(h, cmp, "env", cmtr, "in", chainChCnt ); // compressor meter
|
|
|
|
// Distortion parameter controls
|
|
cmDspSysInstallCb11N1(h, dbyp, "out", dist, "bypass",chainChCnt );
|
|
cmDspSysInstallCb11N1(h, dsr, "val", dist, "srate", chainChCnt );
|
|
cmDspSysInstallCb11N1(h, dbt, "val", dist, "bits", chainChCnt );
|
|
cmDspSysInstallCb11N1(h, drct, "out", dist, "rect", chainChCnt );
|
|
cmDspSysInstallCb11N1(h, dful, "out", dist, "full", chainChCnt );
|
|
cmDspSysInstallCb11N1(h, dclip, "val", dist, "clip", chainChCnt );
|
|
cmDspSysInstallCb11N1(h, dogn, "val", dist, "ogain", chainChCnt );
|
|
|
|
// Comb filter parameter controls
|
|
cmDspSysInstallCb11N1(h, cfbyp, "out", cf, "bypass",chainChCnt );
|
|
cmDspSysInstallCb11N1(h, cfalpha, "val", cf, "alpha", chainChCnt );
|
|
cmDspSysInstallCb11N1(h, cfpoffs, "val", cfpc, "offs", chainChCnt );
|
|
cmDspSysInstallCbN1N1(h, cfpc, "hz", cf, "hz", chainChCnt );
|
|
//cmDspSysInstallCbN1N1(h, mul, "out", cf, "hz", chainChCnt );
|
|
|
|
// EQ parameter controls
|
|
cmDspSysInstallCb11N1( h, eqbyp, "out", eq, "bypass", chainChCnt );
|
|
cmDspSysInstallCb11N1( h, eqmode, "mode", eq, "mode", chainChCnt );
|
|
cmDspSysInstallCb11N1( h, eqq, "val", eq, "Q", chainChCnt );
|
|
cmDspSysInstallCb11N1( h, eqfgn, "val", eq, "gain", chainChCnt );
|
|
cmDspSysInstallCb11N1( h, eqpoffs, "val", eqpc, "offs", chainChCnt );
|
|
cmDspSysInstallCbN1N1( h, eqpc, "hz", eq, "f0", chainChCnt ); // chCfg -> Eq Hz
|
|
//cmDspSysInstallCbN1N1( h, mul, "out", eq, "f0", chainChCnt );
|
|
|
|
// Delay parameter controls
|
|
cmDspSysInstallCb11N1( h, dlybyp, "out", dly, "bypass", chainChCnt );
|
|
//cmDspSysInstallCb11N1( h, dlyms, "val", dly, "time", chainChCnt );
|
|
cmDspSysInstallCb11N1( h, dlyfb, "val", dly, "fb", chainChCnt );
|
|
cmDspSysInstallCbN1N1( h, dlyms, "val", dly, "time", chainChCnt );
|
|
|
|
// Multi-tap parameter controls
|
|
cmDspSysInstallCb11N1( h, mtbyp, "out", mt, "bypass", chainChCnt );
|
|
cmDspSysInstallCb11N1( h, mtfb, "val", mt, "fb", chainChCnt );
|
|
cmDspSysInstallCb11N1( h, mtscale, "val", mt, "scale", chainChCnt );
|
|
|
|
cmDspSysInstallCb111N( h, vmult, "val", mixo, "gain", chainChCnt );
|
|
|
|
errLabel:
|
|
|
|
return rc;
|
|
}
|
|
|
|
//=====================================================================================================================
|
|
typedef struct
|
|
{
|
|
cmDspPP_Circuit_t c;
|
|
cmDspFx0_Chain_t fx;
|
|
} cmDspPP_Fx0_t;
|
|
|
|
|
|
cmDspRC_t _cmDspPP_Fx0Alloc(
|
|
cmDspSysH_t h,
|
|
_cmDspPP_Ctx_t* ctx,
|
|
cmDspPP_Fx0_t* p,
|
|
const cmChar_t* title,
|
|
const cmChar_t* preLbl,
|
|
cmDspInst_t* selChk,
|
|
cmDspInst_t** ain,
|
|
cmDspInst_t* ptIn )
|
|
{
|
|
cmDspRC_t rc;
|
|
unsigned i;
|
|
|
|
p->c.circuitSymId = cmDspSysRegisterInstAttrSymbolStr(h,title);
|
|
unsigned presetGroupSymId = cmDspSysPresetRegisterGroup(h,title);
|
|
_cmDspSys_PresetMgmt(h,preLbl,presetGroupSymId);
|
|
cmDspSysNewColumn(h,COL_WIDTH);
|
|
|
|
unsigned fxChCnt = ctx->iChCnt;
|
|
|
|
// make processors for each input channel
|
|
if((rc = _cmDspFx0_ChainAlloc(h,ctx->err, presetGroupSymId, preLbl, "midiList", fxChCnt, &p->fx)) != kOkDspRC )
|
|
goto errLabel;
|
|
|
|
|
|
// make mixers for each output channel
|
|
p->c.aout = cmDspSysAllocInstArray( h, ctx->oChCnt, "AMix", NULL,NULL, 1, fxChCnt );
|
|
p->c.aoutLbl = "out";
|
|
|
|
|
|
// check for allocation errors
|
|
if((rc = cmDspSysLastRC(h)) != kOkDspRC )
|
|
goto errLabel;
|
|
|
|
cmDspSysConnectAudioN1N1(h, ain, "out", p->fx.mix, "in", ctx->iChCnt ); // ain -> sg/ain mixer
|
|
cmDspSysInstallCb1NN1( h, ptIn, "b-out", p->fx.adsr, "gate", ctx->iChCnt ); // gate -> adsr
|
|
cmDspSysInstallCb1NN1( h, ptIn, "f-out", p->fx.tmop, "in-0", ctx->iChCnt ); // level ->adsr (tscale)
|
|
cmDspSysInstallCb1NN1( h, ptIn, "f-out", p->fx.amop, "in-0", ctx->iChCnt ); // level ->adsr (ascale)
|
|
|
|
if(0)
|
|
{
|
|
for(i=0; i<ctx->iChCnt; ++i)
|
|
{
|
|
cmDspSysConnectAudio( h, ain[i], "out", p->fx.mix[ ctx->iChCnt + i], "in" ); // ain -> sg/ain mixer
|
|
cmDspSysInstallCb( h, ptIn, formLabel(h,"b-out",i), p->fx.adsr[ ctx->iChCnt + i], "gate", NULL ); // gate -> adsr
|
|
cmDspSysInstallCb( h, ptIn, formLabel(h,"f-out",i), p->fx.tmop[ ctx->iChCnt + i], "in-0", NULL ); // level ->adsr (tscale)
|
|
cmDspSysInstallCb( h, ptIn, formLabel(h,"f-out",i), p->fx.amop[ ctx->iChCnt + i], "in-0", NULL ); // level ->adsr (ascale)
|
|
}
|
|
}
|
|
|
|
for( i=0; i<ctx->oChCnt; ++i)
|
|
{
|
|
cmDspSysConnectAudioN11N(h, p->fx.mt, "out", p->c.aout[i], "in", fxChCnt ); // fx.mix -> mixer
|
|
}
|
|
|
|
|
|
// reset the chain - called by the master 'reset' button
|
|
cmDspSysInstallCb( h, selChk, "out", p->fx.start, "send", NULL );
|
|
|
|
errLabel:
|
|
|
|
cmDspSysRemoveInstAttrSymbol(h,p->c.circuitSymId);
|
|
|
|
return rc;
|
|
}
|
|
|
|
//=====================================================================================================================
|
|
#define cdChainCnt (5)
|
|
|
|
typedef struct
|
|
{
|
|
const cmChar_t* preLbl;
|
|
const cmChar_t* title;
|
|
const cmChar_t* midiRsrc;
|
|
const cmChar_t* chanRsrc;
|
|
unsigned chCnt;
|
|
cmDspInst_t* nom;
|
|
cmDspInst_t* ogain;
|
|
cmDspInst_t** mtr;
|
|
cmDspInst_t** envm;
|
|
unsigned* map;
|
|
} cmDspPP_Cd0_Desc_t;
|
|
|
|
|
|
typedef struct
|
|
{
|
|
cmDspPP_Circuit_t c;
|
|
cmDspFx0_Chain_t ch[ cdChainCnt ];
|
|
} cmDspPP_Cd0_t;
|
|
|
|
|
|
|
|
cmDspRC_t _cmDspPP_Cd0Alloc(
|
|
cmDspSysH_t h,
|
|
_cmDspPP_Ctx_t* ctx,
|
|
cmDspPP_Cd0_t* p,
|
|
const cmChar_t* title,
|
|
const cmChar_t* preLbl,
|
|
cmDspInst_t* selChk,
|
|
cmDspInst_t** ain,
|
|
cmDspInst_t* ptIn )
|
|
{
|
|
cmDspRC_t rc = kOkDspRC;
|
|
cmReal_t cdMaxTimeSpanMs = 50;
|
|
cmReal_t cdMinNoteCnt = 2;
|
|
cmReal_t nomXfadeMs = 25.0;
|
|
|
|
unsigned i,j;
|
|
|
|
cmDspPP_Cd0_Desc_t desc[] =
|
|
{
|
|
{ "ch","Chose", "CDmidi", "CDchan", 0, NULL, NULL, NULL, NULL, NULL },
|
|
{ "ot","Other", "CDmidi", "CDchan", 0, NULL, NULL, NULL, NULL, NULL },
|
|
{ "g0","Grp0", "CD0midi", "CD0chan", 0, NULL, NULL, NULL, NULL, NULL },
|
|
{ "g1","Grp1", "CD1midi", "CD1chan", 0, NULL, NULL, NULL, NULL, NULL },
|
|
{ "ee","Else", "NONmidi", "NONchan", 0, NULL, NULL, NULL, NULL, NULL }
|
|
};
|
|
|
|
assert( sizeof(desc)/sizeof(desc[0]) == cdChainCnt );
|
|
|
|
for(i=0; i<cdChainCnt; ++i)
|
|
{
|
|
// read channel index resource array
|
|
if( cmDspRsrcUIntArray( h, &desc[i].chCnt, &desc[i].map, desc[i].chanRsrc, NULL ) != kOkDspRC )
|
|
return cmErrMsg(ctx->err,kInvalidArgDspRC,"The chord detector channel index resource '%s' could not be read.",cmStringNullGuard(desc[i].chanRsrc));
|
|
}
|
|
|
|
|
|
p->c.circuitSymId = cmDspSysRegisterInstAttrSymbolStr(h,title);
|
|
|
|
/*
|
|
cmDspInst_t* printBtn = cmDspSysAllocInst( h, "Button", "_print", 2, kButtonDuiId, 0.0);
|
|
cmDspInst_t* bcast = cmDspSysAllocInst( h, "BcastSym", NULL, 1, p->c.circuitSymId );
|
|
cmDspSysInstallCb( h, printBtn, "sym", bcast, "msg", NULL );
|
|
*/
|
|
|
|
cmDspInst_t* cd = cmDspSysAllocInst(h, "ChordDetect", NULL, 1, "cdSel" );
|
|
cmDspInst_t* ns = cmDspSysAllocInst(h, "NoteSelect", NULL, 1, ctx->iChCnt );
|
|
|
|
// allocate the switching noms and gain controls
|
|
for(i=0; i<cdChainCnt; ++i)
|
|
{
|
|
desc[i].nom = cmDspSysAllocInst( h, "NofM", NULL, 3, desc[i].chCnt, desc[i].chCnt, nomXfadeMs );
|
|
desc[i].ogain = cmDspSysAllocScalar(h,formLabel(h,"Out Gn",i),0.0,10.0,0.01,1.0);
|
|
}
|
|
|
|
// chord detector parameters
|
|
cmDspInst_t* cdSpanMs = cmDspSysAllocScalar(h,"Span Ms", 10.0,1000.0,1.0,cdMaxTimeSpanMs);
|
|
cmDspInst_t* cdNoteCnt = cmDspSysAllocScalar(h,"Note Cnt", 1.0, 100.0,1.0,cdMinNoteCnt );
|
|
cmDspInst_t* cdCount = cmDspSysAllocScalar(h,"Ch. Count", 0, 1, 0, 0);
|
|
cmDspInst_t* nomXfade = cmDspSysAllocScalar(h,"Xfade ms", 0, 1000, 0, nomXfadeMs);
|
|
|
|
cmDspInst_t* btn = cmDspSysAllocButton(h,"print",0);
|
|
|
|
// note select gate meters
|
|
for(j=0; j<cdChainCnt; ++j)
|
|
{
|
|
cmDspSysNewColumn(h,50);
|
|
cmDspSysAllocLabel(h,desc[j].title,kLeftAlignDuiId );
|
|
desc[j].mtr = cmDspSysAllocInstArray(h, ctx->iChCnt, "Meter", NULL, NULL, 3, 0.0, 0.0, 1.0 );
|
|
}
|
|
|
|
// audio output meters
|
|
for(j=0; j<cdChainCnt; ++j)
|
|
{
|
|
cmDspSysNewColumn(h,COL_WIDTH);
|
|
cmDspSysAllocLabel(h,desc[j].title,kLeftAlignDuiId );
|
|
desc[j].envm = cmDspSysAllocInstArray(h,desc[j].chCnt,"AMeter", NULL, NULL, 3, 0.0, 0.0, 1.0 );
|
|
}
|
|
|
|
// create the fx chains
|
|
for(i=0; i<cdChainCnt; ++i )
|
|
{
|
|
cmDspSysNewPage(h,desc[i].title);
|
|
unsigned presetGroupSymId = cmDspSysPresetRegisterGroup(h,desc[i].title);
|
|
|
|
_cmDspSys_PresetMgmt(h,desc[i].preLbl,presetGroupSymId);
|
|
cmDspSysNewColumn(h,COL_WIDTH);
|
|
|
|
// create an fx chain with desc[i].chCnt channels
|
|
if((rc = _cmDspFx0_ChainAlloc(h, ctx->err, presetGroupSymId, desc[i].preLbl, desc[i].midiRsrc, desc[i].chCnt, p->ch + i)) != kOkDspRC )
|
|
goto errLabel;
|
|
|
|
}
|
|
|
|
// make mixers for each chain
|
|
p->c.aout = cmDspSysAllocInstArray( h, ctx->oChCnt, "AMix", NULL, NULL, 1, cdChainCnt );
|
|
p->c.aoutLbl = "out";
|
|
|
|
// check for allocation errors
|
|
if((rc = cmDspSysLastRC(h)) != kOkDspRC )
|
|
goto errLabel;
|
|
|
|
cmDspSysInstallCb1N1N(h, ptIn, "b-out", cd, "gate", ctx->iChCnt ); // EF -> CD gate
|
|
cmDspSysInstallCb1N1N(h, ptIn, "f-out", cd, "rms", ctx->iChCnt ); // EF -> CD rms
|
|
cmDspSysInstallCb1N1N(h, cd, "gate", ns, "gate", ctx->iChCnt ); // CD -> NS gate
|
|
cmDspSysInstallCb1N1N(h, cd, "rms", ns, "rms", ctx->iChCnt ); // CD -> NS rms
|
|
cmDspSysInstallCb(h, cd, "detect", ns, "trig", NULL ); // CD -> NS trigger
|
|
|
|
// chord detector paramter controls
|
|
cmDspSysInstallCb(h, cdSpanMs, "val", cd, "span", NULL );
|
|
cmDspSysInstallCb(h, cdNoteCnt, "val", cd, "notes", NULL );
|
|
cmDspSysInstallCb(h, cd, "count", cdCount, "val", NULL );
|
|
|
|
for(i=0; i<cdChainCnt; ++i)
|
|
{
|
|
cmDspSysInstallCb( h, nomXfade, "val", desc[i].nom, "ms", NULL );
|
|
|
|
cmDspSysInstallCb1N1NM( h, ns, formLabel(h,"gate",i), ctx->iChCnt, desc[i].nom, "sel", desc[i].chCnt, desc[i].map ); // NS -> nom's (selectors)
|
|
cmDspSysInstallCb1NN1 ( h, ns, formLabel(h,"gate",i), desc[i].mtr, "in", ctx->iChCnt ); // NS -> Meter
|
|
cmDspSysInstallCb( h, ns, "done", desc[i].nom, "cmd", NULL ); // NS -> nom's (done triggers)
|
|
|
|
cmDspSysConnectAudioN11NM( h, ain, "out", ctx->iChCnt, desc[i].nom, "a-in", desc[i].chCnt, desc[i].map ); // ain -> nom's
|
|
|
|
cmDspSysInstallCb1N1NM( h, ptIn, "b-out", ctx->iChCnt, desc[i].nom, "b-in", desc[i].chCnt, desc[i].map ); // NS -> nom (gate)
|
|
cmDspSysInstallCb1N1NM( h, ptIn, "f-out", ctx->iChCnt, desc[i].nom, "f-in", desc[i].chCnt, desc[i].map ); // NS -> nom (rms)
|
|
|
|
cmDspSysConnectAudio1NN1(h, desc[i].nom, "a-out", p->ch[i].mix, "in", desc[i].chCnt ); // nom -> chain sg/ain mixer (audio)
|
|
cmDspSysInstallCb1NN1( h, desc[i].nom, "b-out", p->ch[i].adsr, "gate", desc[i].chCnt ); // nom -> chain adsr (gate)
|
|
cmDspSysInstallCb1NN1( h, desc[i].nom, "f-out", p->ch[i].tmop, "in-0", desc[i].chCnt ); // nom -> chain adsr (tscale)
|
|
cmDspSysInstallCb1NN1( h, desc[i].nom, "f-out", p->ch[i].amop, "in-0", desc[i].chCnt ); // nom -> chain adsr (ascale)
|
|
|
|
cmDspSysInstallCb( h, btn, "sym", desc[i].nom, "cmd", NULL );
|
|
|
|
cmDspSysConnectAudioN1N1( h, p->ch[i].mt, "out", desc[i].envm, "in", desc[i].chCnt ); // chain aout -> mtr
|
|
cmDspSysConnectAudio11N1( h, p->ch[i].mixo, "out", p->c.aout, formLabel(h,"in", i), ctx->oChCnt); // chain aout -> mix out
|
|
|
|
|
|
// reset the chain - (called by the master 'reset' button)
|
|
cmDspSysInstallCb( h, selChk, "out", p->ch[i].start, "send", NULL );
|
|
|
|
}
|
|
|
|
errLabel:
|
|
|
|
cmDspSysRemoveInstAttrSymbol(h,p->c.circuitSymId);
|
|
|
|
return rc;
|
|
}
|
|
|
|
//=====================================================================================================================
|
|
|
|
#define cd1ChainCnt (10)
|
|
|
|
typedef struct
|
|
{
|
|
const cmChar_t* preLbl;
|
|
const cmChar_t* title;
|
|
unsigned chCnt;
|
|
cmDspInst_t* nom;
|
|
cmDspInst_t* ogain;
|
|
cmDspInst_t** mtr;
|
|
cmDspInst_t** envm;
|
|
const cmChar_t* midiRsrc;
|
|
unsigned* midi;
|
|
const cmChar_t* chanRsrc;
|
|
unsigned* chan;
|
|
} cmDspPP_Cd1_Desc_t;
|
|
|
|
|
|
typedef struct
|
|
{
|
|
cmDspPP_Circuit_t c;
|
|
cmDspFx0_Chain_t ch[ cd1ChainCnt ];
|
|
} cmDspPP_Cd1_t;
|
|
|
|
|
|
|
|
cmDspRC_t _cmDspPP_Cd1Alloc(
|
|
cmDspSysH_t h,
|
|
_cmDspPP_Ctx_t* ctx,
|
|
cmDspPP_Cd1_t* p,
|
|
const cmChar_t* title,
|
|
const cmChar_t* preLbl,
|
|
cmDspInst_t* selChk,
|
|
cmDspInst_t** ain,
|
|
cmDspInst_t* ptIn )
|
|
{
|
|
cmDspRC_t rc = kOkDspRC;
|
|
cmReal_t cdMaxTimeSpanMs = 50;
|
|
cmReal_t cdMinNoteCnt = 2;
|
|
cmReal_t nomXfadeMs = 25.0;
|
|
unsigned cdNetNodeId = cmInvalidId;
|
|
const cmChar_t* cdNetNodeLabel = NULL;
|
|
const cmChar_t* nonCdNetNodeLabel = NULL;
|
|
unsigned cdChCnt = 0;
|
|
cmDspInst_t* cd = NULL;
|
|
cmDspInst_t* ns = NULL;
|
|
cmDspInst_t* cdSpanMs = NULL;
|
|
cmDspInst_t* cdNoteCnt = NULL;
|
|
cmDspInst_t* cdCount = NULL;
|
|
cmDspInst_t* btn = NULL;
|
|
unsigned cd1ChainCnto2 = cd1ChainCnt/2;
|
|
unsigned pgSymId = cmInvalidId;
|
|
|
|
unsigned i,j;
|
|
|
|
cmDspPP_Cd1_Desc_t desc[] =
|
|
{
|
|
// resources for local (this) machine
|
|
{ "ch0","Ch0", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
|
|
{ "ot0","Oth0", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
|
|
{ "g00","Gr00", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
|
|
{ "g01","Gr01", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
|
|
{ "ee0","Ee00", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
|
|
|
|
// resources for remote (other) machine
|
|
{ "ch1","Ch1", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
|
|
{ "ot1","Oth1", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
|
|
{ "g10","Gr10", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
|
|
{ "g11","Gr11", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
|
|
{ "ee1","Ee01", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
|
|
|
|
};
|
|
|
|
assert( (sizeof(desc)/sizeof(desc[0])) == cd1ChainCnt );
|
|
|
|
// get the chord detector network node label of this machine
|
|
if( cmDspRsrcString(h, &cdNetNodeLabel, "cdLocalNetNode", NULL ) != kOkDspRC )
|
|
{
|
|
rc = cmErrMsg(ctx->err,kRsrcNotFoundDspRC,"The resource 'cdLocalNetNode' could not be read.");
|
|
goto errLabel;
|
|
}
|
|
|
|
// convert the chord detector network node label to an id
|
|
if( (cdNetNodeId = cmDspSysNetNodeLabelToId(h,cdNetNodeLabel)) == cmInvalidId )
|
|
{
|
|
rc = cmErrMsg(ctx->err,kInvalidArgDspRC,"The chord detector network node label '%s' is not valid.",cmStringNullGuard(cdNetNodeLabel));
|
|
goto errLabel;
|
|
}
|
|
|
|
// get the label of the network node which is not running the chord detector
|
|
if( cmDspRsrcString(h, &nonCdNetNodeLabel, "cdRemoteNetNode", NULL ) != kOkDspRC )
|
|
{
|
|
rc = cmErrMsg(ctx->err,kRsrcNotFoundDspRC,"The resource 'cdRemoteNetNode' could not be read.");
|
|
goto errLabel;
|
|
}
|
|
|
|
// validate the non-chord detector network node label
|
|
if( cmDspSysNetNodeLabelToId(h,nonCdNetNodeLabel) == cmInvalidId )
|
|
{
|
|
rc = cmErrMsg(ctx->err,kInvalidArgDspRC,"The net node label '%s' is not valid.",cmStringNullGuard(nonCdNetNodeLabel));
|
|
goto errLabel;
|
|
}
|
|
|
|
// is this the chord detector node
|
|
bool cdIsLocalFl = cdNetNodeId == cmDspSysNetNodeId(h);
|
|
unsigned ii = cdIsLocalFl ? 0 : cd1ChainCnto2;
|
|
unsigned nn = ii + cd1ChainCnto2;
|
|
|
|
// read all the resource arrays
|
|
for(i=0; i<cd1ChainCnt; ++i)
|
|
{
|
|
desc[i].midiRsrc = cmTsPrintfH( cmDspSysLHeap(h), "nsMidi-%i",i);
|
|
desc[i].chanRsrc = cmTsPrintfH( cmDspSysLHeap(h), "nsChan-%i",i);
|
|
|
|
if( cmDspRsrcUIntArray(h,&desc[i].chCnt,&desc[i].midi,desc[i].midiRsrc,NULL) != kOkDspRC )
|
|
{
|
|
rc = cmErrMsg(ctx->err,kRsrcNotFoundDspRC,"The note selector MIDI pitch resource '%s' could not be read.",cmStringNullGuard(desc[i].midiRsrc));
|
|
goto errLabel;
|
|
}
|
|
|
|
if( cmDspRsrcUIntArray(h,&desc[i].chCnt,&desc[i].chan,desc[i].chanRsrc,NULL) != kOkDspRC )
|
|
{
|
|
rc = cmErrMsg(ctx->err,kRsrcNotFoundDspRC,"The note selector channel map resource '%s' could not be read.",cmStringNullGuard(desc[i].chanRsrc));
|
|
goto errLabel;
|
|
}
|
|
|
|
}
|
|
|
|
p->c.circuitSymId = cmDspSysRegisterInstAttrSymbolStr(h,title);
|
|
|
|
if( cdIsLocalFl )
|
|
{
|
|
// get the count of chord detector input channels
|
|
if( cmDspRsrcArrayCount(h,&cdChCnt,"ChordList",NULL) != kOkDspRC )
|
|
return cmErrMsg(ctx->err,kInvalidArgDspRC,"The 'ChordList' resource could not be read.");
|
|
|
|
cd = cmDspSysAllocInst(h, "ChordDetect", "cd", 1, "ChordList" );
|
|
ns = cmDspSysAllocInst(h, "NetNoteSelect", "ns", 1, cdChCnt );
|
|
|
|
|
|
// chord detector parameters
|
|
cdSpanMs = cmDspSysAllocScalarP(h, pgSymId, preLbl, "Span Ms", 10.0,1000.0,1.0,cdMaxTimeSpanMs);
|
|
cdNoteCnt = cmDspSysAllocScalarP(h, pgSymId, preLbl, "Note Cnt", 1.0, 100.0,1.0,cdMinNoteCnt );
|
|
cdCount = cmDspSysAllocScalarP(h, pgSymId, preLbl, "Ch. Count", 0, 1,0,0);
|
|
}
|
|
|
|
cmDspInst_t* nomXfade = cmDspSysAllocScalarP(h, pgSymId, preLbl, "Xfade ms", 0, 1000, 0, nomXfadeMs);
|
|
|
|
|
|
btn = cmDspSysAllocButtonP(h,preLbl,"print",0);
|
|
|
|
// allocate the switching noms and gain controls
|
|
for(i=ii; i<nn; ++i)
|
|
{
|
|
desc[i].nom = cmDspSysAllocInst( h, "NofM", formLabel(h,"nom",i), 3, desc[i].chCnt, desc[i].chCnt, nomXfadeMs );
|
|
desc[i].ogain = cmDspSysAllocScalarP(h, pgSymId, preLbl, formLabel(h,"Out Gn",i),0.0,10.0,0.01,1.0);
|
|
}
|
|
|
|
// note-select gate meters
|
|
for(j=ii; cdIsLocalFl && j<nn; ++j)
|
|
{
|
|
cmDspSysNewColumn(h,50);
|
|
cmDspSysAllocLabel(h,desc[j].title,kLeftAlignDuiId );
|
|
desc[j].mtr = cmDspSysAllocInstArray(h, cdChCnt, "Meter", NULL, NULL, 3, 0.0, 0.0, 1.0 );
|
|
}
|
|
|
|
// audio output meters
|
|
for(j=ii; j<nn; ++j)
|
|
{
|
|
cmDspSysNewColumn(h,50);
|
|
cmDspSysAllocLabel(h,desc[j].title,kLeftAlignDuiId );
|
|
desc[j].envm = cmDspSysAllocInstArray(h,desc[j].chCnt,"AMeter", NULL, NULL, 3, 0.0, 0.0, 1.0 );
|
|
}
|
|
|
|
// create the fx chains
|
|
for(i=ii; i<nn; ++i )
|
|
{
|
|
cmDspSysNewPage(h,desc[i].title);
|
|
unsigned presetGroupSymId = cmDspSysPresetRegisterGroup(h,desc[i].title);
|
|
|
|
_cmDspSys_PresetMgmt(h,desc[i].preLbl,presetGroupSymId);
|
|
cmDspSysNewColumn(h,200);
|
|
|
|
// create an fx chain with desc[i].chCnt channels
|
|
if((rc = _cmDspFx0_ChainAlloc(h, ctx->err, presetGroupSymId, desc[i].preLbl, desc[i].midiRsrc, desc[i].chCnt, p->ch + i)) != kOkDspRC )
|
|
goto errLabel;
|
|
|
|
}
|
|
|
|
// make mixers for each chain
|
|
p->c.aout = cmDspSysAllocInstArray( h, ctx->oChCnt, "AMix", NULL, NULL, 1, cd1ChainCnto2 );
|
|
p->c.aoutLbl = "out";
|
|
|
|
// check for allocation errors
|
|
if((rc = cmDspSysLastRC(h)) != kOkDspRC )
|
|
goto errLabel;
|
|
|
|
if( cdIsLocalFl )
|
|
{
|
|
cmDspSysInstallCb1N1N(h, ptIn, "b-out", cd, "gate", ctx->iChCnt ); // EF -> CD gate
|
|
cmDspSysInstallCb1N1N(h, ptIn, "f-out", cd, "rms", ctx->iChCnt ); // EF -> CD rms
|
|
cmDspSysInstallCb1N1N(h, cd, "gate", ns, "gate", cdChCnt ); // CD -> NS gate
|
|
cmDspSysInstallCb1N1N(h, cd, "rms", ns, "rms", cdChCnt ); // CD -> NS rms
|
|
cmDspSysInstallCb(h, cd, "detect", ns, "trig", NULL ); // CD -> NS trigger
|
|
|
|
// chord detector paramter controls
|
|
cmDspSysInstallCb(h, cdSpanMs, "val", cd, "span", NULL );
|
|
cmDspSysInstallCb(h, cdNoteCnt, "val", cd, "notes", NULL );
|
|
cmDspSysInstallCb(h, cd, "count", cdCount, "val", NULL );
|
|
}
|
|
else
|
|
{
|
|
cmDspSysInstallNetCb1N1N(h, ptIn, "b-out", cdNetNodeLabel, "cd", "gate", 16, ctx->iChCnt );
|
|
cmDspSysInstallNetCb1N1N(h, ptIn, "f-out", cdNetNodeLabel, "cd", "rms", 16, ctx->iChCnt );
|
|
}
|
|
|
|
for(i=ii; i<nn; ++i)
|
|
{
|
|
|
|
if( cdIsLocalFl )
|
|
{
|
|
// local NS -> nom's (selectors)
|
|
cmDspSysInstallCb1N1N( h, ns, formLabel(h,"gate",i), desc[i].nom, "sel", desc[i].chCnt );
|
|
cmDspSysInstallCb( h, ns, "done", desc[i].nom, "cmd", NULL ); // NS -> nom's (done triggers)
|
|
|
|
// local NS -> meters
|
|
cmDspSysInstallCb1NN1M2( h, ns, formLabel(h,"gate",i), desc[i].chCnt, desc[i].chan, desc[i].mtr, "in", cdChCnt );
|
|
|
|
}
|
|
|
|
|
|
cmDspSysConnectAudioN11NM( h, ain, "out", ctx->iChCnt, desc[i].nom, "a-in", desc[i].chCnt, desc[i].chan ); // ain -> nom's
|
|
|
|
cmDspSysInstallCb1N1NM( h, ptIn, "b-out", ctx->iChCnt, desc[i].nom, "b-in", desc[i].chCnt, desc[i].chan ); // EF -> nom (gate)
|
|
cmDspSysInstallCb1N1NM( h, ptIn, "f-out", ctx->iChCnt, desc[i].nom, "f-in", desc[i].chCnt, desc[i].chan ); // EF -> nom (level)
|
|
|
|
cmDspSysConnectAudio1NN1(h, desc[i].nom, "a-out", p->ch[i].mix, "in", desc[i].chCnt ); // nom -> chain sg/ain mixer (audio)
|
|
cmDspSysInstallCb1NN1( h, desc[i].nom, "b-out", p->ch[i].adsr, "gate", desc[i].chCnt ); // nom -> chain adsr (gate)
|
|
cmDspSysInstallCb1NN1( h, desc[i].nom, "f-out", p->ch[i].tmop, "in-0", desc[i].chCnt ); // nom -> chain adsr (tscale)
|
|
cmDspSysInstallCb1NN1( h, desc[i].nom, "f-out", p->ch[i].amop, "in-0", desc[i].chCnt ); // nom -> chain adsr (ascale)
|
|
|
|
cmDspSysInstallCb( h, btn, "sym", desc[i].nom, "cmd", NULL );
|
|
cmDspSysInstallCb( h, nomXfade, "val", desc[i].nom, "ms", NULL );
|
|
|
|
cmDspSysConnectAudioN1N1( h, p->ch[i].mt, "out", desc[i].envm, "in", desc[i].chCnt ); // chain aout -> mtr
|
|
cmDspSysConnectAudio11N1( h, p->ch[i].mixo, "out", p->c.aout, formLabel(h,"in", i-ii), ctx->oChCnt); // chain aout -> mix out
|
|
cmDspSysInstallCb11N1( h, desc[i].ogain, "val", p->c.aout, formLabel(h,"gain",i-ii), ctx->oChCnt); // chain ogain -> mix gain
|
|
|
|
// reset the chain - (called by the master 'reset' button)
|
|
cmDspSysInstallCb( h, selChk, "out", p->ch[i].start, "send", NULL );
|
|
|
|
}
|
|
|
|
// local note-select to remote 'nom' connections
|
|
if( cdIsLocalFl )
|
|
{
|
|
for(i=cd1ChainCnto2; i<cd1ChainCnt; ++i)
|
|
{
|
|
// NS -> nom's (selectors and done trigger)
|
|
cmDspSysInstallNetCb1N1N( h, ns, formLabel(h,"gate",i), nonCdNetNodeLabel, cmTsPrintfS("nom-%i",i), "sel", 0, desc[i].chCnt );
|
|
cmDspSysInstallNetCb( h, ns, "done", nonCdNetNodeLabel, cmTsPrintfS("nom-%i",i), "cmd" );
|
|
|
|
// NS -> meters
|
|
unsigned map[ ctx->iChCnt ];
|
|
cmVOU_AddVVS(map,ctx->iChCnt,desc[i].chan,ctx->iChCnt );
|
|
cmDspSysInstallCb1NN1M2( h, ns, formLabel(h,"gate",i), desc[i].chCnt, map, desc[i-cd1ChainCnto2].mtr, "in", cdChCnt );
|
|
|
|
}
|
|
|
|
}
|
|
errLabel:
|
|
|
|
cmDspSysRemoveInstAttrSymbol(h,p->c.circuitSymId);
|
|
|
|
return rc;
|
|
}
|
|
|
|
//=====================================================================================================================
|
|
typedef struct
|
|
{
|
|
cmDspInst_t* phs;
|
|
cmDspInst_t* wt;
|
|
cmDspInst_t* sel;
|
|
cmDspInst_t* bts;
|
|
cmDspInst_t* gain;
|
|
} cmDspPP_Fp_t;
|
|
|
|
cmDspRC_t _cmDspPP_FilePlayer(
|
|
cmDspSysH_t h,
|
|
const cmChar_t* fn,
|
|
const cmChar_t* label,
|
|
cmDspPP_Fp_t* p
|
|
)
|
|
{
|
|
cmDspRC_t rc = kOkDspRC;
|
|
int wtPlayCnt = 1;
|
|
int wtMode = 1; // file
|
|
int wtBeg = 0;
|
|
int wtEnd = -1;
|
|
unsigned wtOffSymId = cmDspSysRegisterStaticSymbol(h,"off");
|
|
bool selFl = false;
|
|
|
|
p->sel = cmDspSysAllocCheck( h,label,selFl);
|
|
|
|
p->phs = cmDspSysAllocInst( h,"Phasor", NULL, 0 );
|
|
p->wt = cmDspSysAllocInst( h,"WaveTable",NULL, 7, ((int)cmDspSysSampleRate(h)), wtMode, fn, wtPlayCnt, wtBeg, wtEnd, wtOffSymId );
|
|
p->bts = cmDspSysAllocInst( h,"GateToSym", NULL, 0 );
|
|
p->gain = cmDspSysAllocScalar(h,NULL,0.0,10.0,0.01,1.0);
|
|
|
|
// check for allocation errors
|
|
if((rc = cmDspSysLastRC(h)) != kOkDspRC )
|
|
goto errLabel;
|
|
|
|
cmDspSysConnectAudio(h,p->phs,"out",p->wt,"phs");
|
|
|
|
cmDspSysInstallCb( h, p->sel, "out", p->bts, "both", NULL );
|
|
cmDspSysInstallCb( h, p->bts, "out", p->wt, "cmd", NULL );
|
|
cmDspSysInstallCb( h, p->sel, "out", p->phs, "phs", NULL );
|
|
|
|
errLabel:
|
|
return rc;
|
|
}
|
|
|
|
typedef struct
|
|
{
|
|
cmDspPP_Circuit_t c;
|
|
} cmDspPP_Sp0_t;
|
|
|
|
|
|
cmDspRC_t _cmDspPP_SmpPlayAlloc(
|
|
cmDspSysH_t h,
|
|
_cmDspPP_Ctx_t* ctx,
|
|
cmDspPP_Sp0_t* p,
|
|
const cmChar_t* title,
|
|
const cmChar_t* preLbl,
|
|
cmDspInst_t* selChk,
|
|
cmDspInst_t** ain,
|
|
cmDspInst_t* ptIn,
|
|
const cmChar_t** fnArray,
|
|
const cmChar_t** titleArray,
|
|
unsigned fnCnt )
|
|
{
|
|
cmDspRC_t rc;
|
|
unsigned i,j;
|
|
|
|
cmDspPP_Fp_t fp[ fnCnt ];
|
|
|
|
p->c.circuitSymId = cmDspSysRegisterInstAttrSymbolStr(h,title);
|
|
unsigned presetGroupSymId = cmDspSysPresetRegisterGroup(h,title);
|
|
_cmDspSys_PresetMgmt(h,preLbl,presetGroupSymId);
|
|
cmDspSysNewColumn(h,COL_WIDTH);
|
|
|
|
// make sample players
|
|
for(i=0; i<fnCnt; ++i)
|
|
{
|
|
if((rc = _cmDspPP_FilePlayer(h, fnArray[i], titleArray[i], fp + i )) != kOkDspRC )
|
|
break;
|
|
}
|
|
|
|
// make processors for each output channel
|
|
p->c.aout = cmDspSysAllocInstArray( h, ctx->oChCnt, "AMix", NULL, NULL, 1, fnCnt );
|
|
p->c.aoutLbl = "out";
|
|
|
|
// check for allocation errors
|
|
if((rc = cmDspSysLastRC(h)) != kOkDspRC )
|
|
goto errLabel;
|
|
|
|
for(i=0; i<ctx->oChCnt; ++i)
|
|
for(j=0; j<fnCnt; ++j)
|
|
{
|
|
cmDspSysConnectAudio(h, fp[j].wt, "out", p->c.aout[i], formLabel(h,"in",j) );
|
|
cmDspSysInstallCb( h, fp[j].gain, "val", p->c.aout[i], formLabel(h,"gain",j), NULL);
|
|
}
|
|
|
|
errLabel:
|
|
|
|
cmDspSysRemoveInstAttrSymbol(h,p->c.circuitSymId);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
//=====================================================================================================================
|
|
typedef struct
|
|
{
|
|
cmDspPP_Circuit_t c;
|
|
cmDspFx0_Chain_t fx0;
|
|
cmDspFx0_Chain_t fx1;
|
|
} cmDspPP_Gliss_t;
|
|
|
|
|
|
cmDspRC_t _cmDspPP_GlissAlloc(
|
|
cmDspSysH_t h,
|
|
_cmDspPP_Ctx_t* ctx,
|
|
cmDspPP_Gliss_t* p,
|
|
const cmChar_t* title,
|
|
const cmChar_t* preLbl,
|
|
cmDspInst_t* selChk,
|
|
cmDspInst_t** ain,
|
|
cmDspInst_t* ptIn )
|
|
{
|
|
cmDspRC_t rc;
|
|
const cmChar_t* glissChIdxRsrcStr = "glissChIdx";
|
|
const cmChar_t* glissPitchRsrcStr = "glissPitch";
|
|
const cmChar_t* glissSlineRsrcStr = "glissSline";
|
|
unsigned chCnt = 0;
|
|
unsigned i ;
|
|
|
|
p->c.circuitSymId = cmDspSysRegisterInstAttrSymbolStr(h,title);
|
|
unsigned presetGroupSymId = cmDspSysPresetRegisterGroup(h,title);
|
|
_cmDspSys_PresetMgmt(h,preLbl,presetGroupSymId);
|
|
cmDspSysNewColumn(h,COL_WIDTH);
|
|
|
|
p->c.aout = allocInstPtrArray(h, ctx->oChCnt);
|
|
|
|
// get the active channel list (indexes of the input channels which will be used by glisser);
|
|
if( cmDspRsrcArrayCount( h, &chCnt, glissChIdxRsrcStr, NULL ) != kOkDspRC )
|
|
return cmErrMsg(ctx->err,kPgmCfgFailDspRC,"The noise shaper channel index list '%s' could not be read.",cmStringNullGuard(glissChIdxRsrcStr));
|
|
|
|
cmDspInst_t* print = cmDspSysAllocInst( h, "Printer", NULL, 0 );
|
|
cmDspInst_t* nom = cmDspSysAllocInst( h, "NofM", NULL, 2, ctx->iChCnt, chCnt );
|
|
cmDspInst_t* pts = cmDspSysAllocInst( h, "PortToSym", NULL, 2, "off", "send" );
|
|
cmDspInst_t* pitarr = cmDspSysAllocInst( h, "Array", NULL, 1, glissPitchRsrcStr );
|
|
cmDspInst_t* charr = cmDspSysAllocInst( h, "Array", NULL, 1, glissChIdxRsrcStr );
|
|
cmDspInst_t** gts = cmDspSysAllocInstArray( h, chCnt, "GateToSym", NULL, NULL, 0 );
|
|
cmDspInst_t** pcvt = cmDspSysAllocInstArray( h, chCnt, "PitchCvt", NULL, NULL, 0 );
|
|
|
|
|
|
cmDspInst_t** sline = allocInstPtrArray(h, chCnt);
|
|
for(i=0; i<chCnt; ++i)
|
|
sline[i] = cmDspSysAllocInst( h, "SegLine", NULL, 1, formLabel(h,glissSlineRsrcStr,i) );
|
|
|
|
|
|
if((rc = _cmDspFx0_ChainAlloc(h,ctx->err, presetGroupSymId, formLabel(h,preLbl,0), glissPitchRsrcStr, chCnt, &p->fx0)) != kOkDspRC )
|
|
goto errLabel;
|
|
|
|
cmDspSysNewPage(h,"G-Thru");
|
|
|
|
if((rc = _cmDspFx0_ChainAlloc(h,ctx->err, presetGroupSymId, formLabel(h,preLbl,1), glissPitchRsrcStr, chCnt, &p->fx1)) != kOkDspRC )
|
|
goto errLabel;
|
|
|
|
cmDspInst_t** mix = cmDspSysAllocInstArray( h, chCnt, "AMix", NULL, NULL, 1, 2 );
|
|
|
|
p->c.aout = cmDspSysAllocInstArray( h, ctx->iChCnt, "AMix", NULL, NULL, 1, chCnt );
|
|
p->c.aoutLbl = "out";
|
|
|
|
// check for allocation errors
|
|
if((rc = cmDspSysLastRC(h)) != kOkDspRC )
|
|
goto errLabel;
|
|
|
|
// selChk is the circuit selector check box in the main window
|
|
cmDspSysInstallCb( h, selChk, "out", pts, "off", NULL ); // First send 'off' to nom to clear its selector
|
|
cmDspSysInstallCb( h, selChk, "out", pts, "send", NULL ); // Second send 'send' to charr to select active ports on nom.
|
|
cmDspSysInstallCb( h, pts, "off", nom, "cmd", NULL ); // Clear the nom (all inputs are turned off)
|
|
cmDspSysInstallCb( h, pts, "send", charr, "cmd", NULL ); // Send the active channel indexes to the nom
|
|
cmDspSysInstallCb( h, pts, "send", pitarr, "cmd", NULL ); // Send the pitch values to the circuits (eq,cf,sg,..)
|
|
cmDspSysInstallCb11N1( h, pts, "send", sline, "cmd", chCnt );
|
|
cmDspSysInstallCb( h, charr, "done", nom, "cmd", NULL ); // Tell the nom when its setup is complete
|
|
|
|
cmDspSysInstallCb1N11( h, charr, "out", nom, "seli", chCnt ); // EF nom channel index selectors
|
|
cmDspSysConnectAudioN11N(h, ain, "out", nom, "a-in", ctx->iChCnt ); // ain -> nom
|
|
cmDspSysInstallCb1N1N( h, ptIn, "b-out", nom, "b-in", ctx->iChCnt ); // EF -> nom (gates)
|
|
cmDspSysInstallCb1N1N( h, ptIn, "f-out", nom, "f-in", ctx->iChCnt ); // EF -> nom (level)
|
|
cmDspSysInstallCb1NN1( h, pitarr, "out", pcvt, "midi", chCnt ); // pitch array -> pitch converter
|
|
|
|
cmDspSysInstallCb1NN1( h, nom, "b-out", gts, "on", chCnt );
|
|
cmDspSysInstallCbN1N1( h, gts, "out", sline, "trig", chCnt );
|
|
cmDspSysInstallCbN1N1( h, sline, "out", pcvt, "offs", chCnt );
|
|
cmDspSysInstallCbN1N1( h, pcvt, "ratio", p->fx0.ps,"ratio",chCnt );
|
|
|
|
cmDspSysInstallCbN111( h, sline, "out", print, "in", chCnt );
|
|
|
|
|
|
cmDspSysConnectAudio1NN1( h, nom, "a-out", p->fx0.mix, "in", chCnt ); // ain -> sg/ain mixer
|
|
cmDspSysInstallCb1NN1( h, nom, "b-out", p->fx0.adsr, "gate", chCnt ); // gate -> adsr
|
|
cmDspSysInstallCb1NN1( h, nom, "f-out", p->fx0.tmop, "in-0", chCnt ); // level ->adsr (tscale)
|
|
cmDspSysInstallCb1NN1( h, nom, "f-out", p->fx0.amop, "in-0", chCnt ); // level ->adsr (ascale)
|
|
|
|
cmDspSysConnectAudio1NN1( h, nom, "a-out", p->fx1.mix, "in", chCnt ); // ain -> sg/ain mixer
|
|
cmDspSysInstallCb1NN1( h, nom, "b-out", p->fx1.adsr, "gate", chCnt ); // gate -> adsr
|
|
cmDspSysInstallCb1NN1( h, nom, "f-out", p->fx1.tmop, "in-0", chCnt ); // level ->adsr (tscale)
|
|
cmDspSysInstallCb1NN1( h, nom, "f-out", p->fx1.amop, "in-0", chCnt ); // level ->adsr (ascale)
|
|
|
|
cmDspSysConnectAudioN1N1( h, p->fx0.mt, "out", mix, "in-0", chCnt );
|
|
cmDspSysConnectAudioN1N1( h, p->fx1.mt, "out", mix, "in-1", chCnt );
|
|
|
|
for( i=0; i<ctx->oChCnt; ++i)
|
|
{
|
|
cmDspSysConnectAudioN11N(h, mix, "out", p->c.aout[i], "in", chCnt );
|
|
}
|
|
|
|
// reset the chain - called by the master 'reset' button
|
|
cmDspSysInstallCb( h, selChk, "out", p->fx0.start, "send", NULL );
|
|
cmDspSysInstallCb( h, selChk, "out", p->fx1.start, "send", NULL );
|
|
|
|
errLabel:
|
|
|
|
cmDspSysRemoveInstAttrSymbol(h,p->c.circuitSymId);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
//=====================================================================================================================
|
|
_cmDspPP_CircDesc_t _cmDspPP_CircDescArray[] =
|
|
{
|
|
{ "Test"," tc" },
|
|
{ "N Shaper", "ns" },
|
|
{ "Fx0", "fx0" },
|
|
{ "Smp Play", "sp" },
|
|
{ "CD", "cd" },
|
|
{ "Net CD", "ncd" },
|
|
{ "Gliss", "gss" }
|
|
};
|
|
|
|
unsigned _cmDspPP_CircuitDescCount()
|
|
{
|
|
return sizeof(_cmDspPP_CircDescArray)/sizeof(_cmDspPP_CircDescArray[0]);
|
|
}
|
|
|
|
const _cmDspPP_CircDesc_t* _cmDspPP_CircuitDesc( unsigned idx )
|
|
{
|
|
assert(idx < _cmDspPP_CircuitDescCount());
|
|
return _cmDspPP_CircDescArray + idx;
|
|
}
|
|
|
|
|
|
cmDspRC_t _cmDspPP_CircuitSwitchAlloc(
|
|
cmDspSysH_t h,
|
|
_cmDspPP_Ctx_t* ctx,
|
|
cmDspPP_CircuitSwitch_t* p,
|
|
cmDspInst_t* reset,
|
|
cmDspInst_t** sel,
|
|
cmDspInst_t** ain,
|
|
cmDspInst_t** ef )
|
|
{
|
|
cmDspRC_t rc = kOkDspRC;
|
|
double xfadeMs = 50.0;
|
|
unsigned enaSym = cmDspSysRegisterStaticSymbol(h,"_enable");
|
|
unsigned disSym = cmDspSysRegisterStaticSymbol(h,"_disable");
|
|
unsigned i;
|
|
|
|
cmDspPP_TestCircuit_t Tst; memset(&Tst,0,sizeof(Tst));
|
|
cmDspPP_NSh_Circuit_t NSh; memset(&NSh,0,sizeof(NSh));
|
|
cmDspPP_Fx0_t Fx0; memset(&Fx0,0,sizeof(Fx0));
|
|
cmDspPP_Cd0_t Cd0; memset(&Cd0,0,sizeof(Cd0));
|
|
cmDspPP_Cd1_t Cd1; memset(&Cd1,0,sizeof(Cd1));
|
|
cmDspPP_Sp0_t Sp0; memset(&Sp0,0,sizeof(Sp0));
|
|
cmDspPP_Gliss_t Gls; memset(&Gls,0,sizeof(Gls));
|
|
|
|
const cmChar_t* spFnArr[] =
|
|
{
|
|
"/home/kevin/media/audio/PP/Siren Blast 2 Peaking.wav",
|
|
"/home/kevin/media/audio/PP/Siren Blast 2.wav"
|
|
};
|
|
|
|
const cmChar_t* spLblArr[] =
|
|
{
|
|
"File 0",
|
|
"File 1"
|
|
};
|
|
|
|
unsigned spCnt = sizeof(spFnArr) / sizeof(spFnArr[0]);
|
|
unsigned splCnt = sizeof(spLblArr) / sizeof(spLblArr[0]);
|
|
assert( spCnt == splCnt );
|
|
|
|
|
|
p->circuitCnt = _cmDspPP_CircuitDescCount();
|
|
|
|
cmDspInst_t* ofd[ p->circuitCnt ];
|
|
cmDspPP_Circuit_t* carr[ p->circuitCnt ];
|
|
|
|
cmDspInst_t** mxm = cmDspSysAllocInstArray(h,ctx->oChCnt,"AMeter", NULL, NULL, 3, 0.0, 0.0, 1.0 );
|
|
|
|
for(i = 0; rc==kOkDspRC && i<p->circuitCnt; ++i)
|
|
{
|
|
|
|
const cmChar_t* title = _cmDspPP_CircDescArray[i].title;
|
|
const cmChar_t* preLbl = _cmDspPP_CircDescArray[i].preLbl;
|
|
|
|
cmDspSysNewPage(h, title );
|
|
|
|
carr[i] = NULL;
|
|
|
|
// allocate the input switches for this circuit
|
|
cmDspInst_t* bts = cmDspSysAllocInst(h,"GateToSym", NULL, 0 );
|
|
cmDspInst_t* bts_ena = cmDspSysAllocInst(h,"GateToSym", NULL, 2, enaSym, disSym );
|
|
cmDspInst_t* ipt = cmDspSysAllocInst(h,"NofM", NULL, 2, ctx->iChCnt, ctx->iChCnt );
|
|
|
|
// allocate the circuits
|
|
switch( i )
|
|
{
|
|
case 0:
|
|
if((rc = _cmDspPP_TestCircuitAlloc(h,ctx,&Tst,title,preLbl,sel[i],ain,ipt)) == kOkDspRC )
|
|
carr[i] = &Tst.c;
|
|
break;
|
|
|
|
case 1:
|
|
if((rc = _cmDspPP_NoiseShaperAlloc(h,ctx->err,&NSh,title,preLbl,sel[i],ipt,ctx->iChCnt,ctx->oChCnt)) == kOkDspRC )
|
|
carr[i] = &NSh.c;
|
|
break;
|
|
|
|
case 2:
|
|
if((rc =_cmDspPP_Fx0Alloc(h,ctx,&Fx0,title,preLbl,sel[i],ain,ipt)) == kOkDspRC )
|
|
carr[i] = &Fx0.c;
|
|
break;
|
|
|
|
case 3:
|
|
if((rc =_cmDspPP_SmpPlayAlloc(h,ctx,&Sp0,title,preLbl,sel[i],ain,ipt,spFnArr,spLblArr,spCnt)) == kOkDspRC )
|
|
carr[i] = &Sp0.c;
|
|
break;
|
|
|
|
case 4:
|
|
if((rc =_cmDspPP_Cd0Alloc(h,ctx,&Cd0,title,preLbl,sel[i],ain,ipt)) == kOkDspRC )
|
|
carr[i] = &Cd0.c;
|
|
break;
|
|
|
|
case 5:
|
|
if((rc = _cmDspPP_Cd1Alloc(h,ctx,&Cd1,title,preLbl,sel[i],ain,ipt)) == kOkDspRC )
|
|
carr[i] = &Cd1.c;
|
|
break;
|
|
|
|
case 6:
|
|
if((rc = _cmDspPP_GlissAlloc(h,ctx,&Gls,title,preLbl,sel[i],ain,ipt)) == kOkDspRC )
|
|
carr[i] = &Gls.c;
|
|
break;
|
|
|
|
default:
|
|
{ assert(0); }
|
|
}
|
|
|
|
if( rc == kOkDspRC && carr[i] != NULL )
|
|
{
|
|
printf("title:%s circuit sym id:%i\n",title,carr[i]->circuitSymId);
|
|
|
|
cmDspInst_t* pts_dis = cmDspSysAllocInst( h, "PortToSym", NULL, 1, "_disable");
|
|
cmDspInst_t* bcast = cmDspSysAllocInst( h, "BcastSym", NULL, 1, carr[i]->circuitSymId );
|
|
ofd[i] = cmDspSysAllocInst( h, "Xfader", NULL, 2, ctx->oChCnt, xfadeMs );
|
|
cmDspSysNewColumn(h,COL_WIDTH);
|
|
cmDspInst_t** fdm = cmDspSysAllocInstArray(h,ctx->oChCnt,"AMeter", NULL, NULL, 3, 0.0, 0.0, 1.0 );
|
|
|
|
// check for allocation errors
|
|
if((rc = cmDspSysLastRC(h)) != kOkDspRC )
|
|
goto errLabel;
|
|
|
|
cmDspSysConnectAudio1NN1( h, ofd[i], "out", fdm, "in", ctx->oChCnt ); // fdr -> meter
|
|
|
|
cmDspSysInstallCb( h, sel[i], "out", bts, "both", NULL ); // Convert circuit selection gate to 'on'/'off' symbols
|
|
cmDspSysInstallCb( h, bts, "out", ipt, "cmd", NULL ); // send 'on'/'off' to this circuits Gate/RMS switch
|
|
|
|
cmDspSysInstallCb( h, sel[i], "out", bts_ena, "both", NULL ); // Convert circuit selection gate to '_enable/_disable' symbols
|
|
cmDspSysInstallCb( h, bts_ena,"out", bcast, "msg", NULL ); // send '_enable/_disable' to this circuits instances.
|
|
|
|
cmDspSysInstallCb( h, reset, "out", pts_dis, "_disable",NULL ); // Convert 'reset' button output to '_disable' symbol
|
|
cmDspSysInstallCb( h, ofd[i], "off", pts_dis, "_disable",NULL ); // Convert circuit output fader 'off' event to '_disable' symbol.
|
|
cmDspSysInstallCb( h, pts_dis,"out", bcast, "msg", NULL ); // Bcast _disable symbol generated from 'reset' btn or fader 'off'
|
|
|
|
cmDspSysInstallCb( h, sel[i], "out", ofd[i], "mgate", NULL ); // Convert circuit selection gate to master fader gate 'on'/'off' msg's
|
|
|
|
cmDspSysInstallCbN11N( h, ef, "gate", ipt, "b-in", ctx->iChCnt ); // EF -> circuit (gate) pass-through
|
|
cmDspSysInstallCbN11N( h, ef, "level", ipt, "f-in", ctx->iChCnt ); // EF -> circuit (RMS) pass-through
|
|
|
|
}
|
|
|
|
}
|
|
|
|
p->omix = cmDspSysAllocInstArray(h,ctx->oChCnt,"AMix",NULL,NULL,1,p->circuitCnt);
|
|
|
|
// check for allocation errors
|
|
if(rc!=kOkDspRC || (rc = cmDspSysLastRC(h)) != kOkDspRC )
|
|
goto errLabel;
|
|
|
|
for(i=0; i<p->circuitCnt; ++i)
|
|
{
|
|
unsigned j;
|
|
for(j=0; j<ctx->oChCnt; ++j)
|
|
if( carr[i] != NULL && carr[i]->aout != NULL && carr[i]->aout[j] != NULL )
|
|
{
|
|
// circuit-> out fader
|
|
cmDspSysConnectAudio( h, carr[i]->aout[j], carr[i]->aoutLbl, ofd[i], cmDspSysPrintLabel("in",j) );
|
|
|
|
// out fader -> mixer
|
|
cmDspSysConnectAudio( h, ofd[i], cmDspSysPrintLabel("out",j), p->omix[j], cmDspSysPrintLabel2("in",i) );
|
|
}
|
|
|
|
}
|
|
|
|
cmDspSysConnectAudioN1N1( h, p->omix, "out", mxm, "in", ctx->oChCnt ); // mix -> meters
|
|
|
|
errLabel:
|
|
|
|
|
|
return rc;
|
|
}
|
|
|
|
cmDspRC_t _cmDspPP_CircuitSwitchFree( cmDspSysH_t h, cmDspPP_CircuitSwitch_t* p)
|
|
{
|
|
return kOkDspRC;
|
|
}
|