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

This commit is contained in:
kevin 2017-04-15 11:20:22 -04:00
commit 98cef5668f
7 changed files with 679 additions and 6 deletions

View File

@ -764,7 +764,12 @@ cmScRC_t _cmScParseNoteOn( cmSc_t* p, unsigned rowIdx, cmScoreEvt_t* s, unsigned
return cmErrMsg(&p->err,kSyntaxErrScRC,"Unable to convert the scientific pitch '%s' to a MIDI value. "); return cmErrMsg(&p->err,kSyntaxErrScRC,"Unable to convert the scientific pitch '%s' to a MIDI value. ");
if((midiVel = cmCsvCellUInt( p->cH,rowIdx,kD1ColScIdx)) >= kInvalidMidiVelocity ) if((midiVel = cmCsvCellUInt( p->cH,rowIdx,kD1ColScIdx)) >= kInvalidMidiVelocity )
return cmErrMsg(&p->err,kSyntaxErrScRC,"An invalid MIDI velocity (%i) was encountered.",midiVel); {
//return cmErrMsg(&p->err,kSyntaxErrScRC,"An invalid MIDI velocity (%i) was encountered.",midiVel);
midiVel = 64;
cmErrWarnMsg(&p->err,kSyntaxErrScRC,"An invalilid MIDI velocity (%i) was encountered.",midiVel);
}
// get the sec's field - or DBL_MAX if it is not set // get the sec's field - or DBL_MAX if it is not set
if((secs = cmCsvCellDouble(p->cH, rowIdx, kSecsColScIdx )) == DBL_MAX) // Returns DBL_MAX on error. if((secs = cmCsvCellDouble(p->cH, rowIdx, kSecsColScIdx )) == DBL_MAX) // Returns DBL_MAX on error.

199
cmProc2.c
View File

@ -2498,10 +2498,10 @@ cmRC_t cmPvSynDoIt( cmPvSyn* p, const cmSample_t* v )
return cmOkRC; return cmOkRC;
} }
const cmSample_t* cmPvSynExecOut(cmPvSyn* p ) const cmSample_t* cmPvSynExecOut(cmPvSyn* p )
{ return cmOlaExecOut(&p->ola); } { return cmOlaExecOut(&p->ola); }
//------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
cmMidiSynth* cmMidiSynthAlloc( cmCtx* ctx, cmMidiSynth* ap, const cmMidiSynthPgm* pgmArray, unsigned pgmCnt, unsigned voiceCnt, unsigned procSmpCnt, unsigned outChCnt, cmReal_t srate ) cmMidiSynth* cmMidiSynthAlloc( cmCtx* ctx, cmMidiSynth* ap, const cmMidiSynthPgm* pgmArray, unsigned pgmCnt, unsigned voiceCnt, unsigned procSmpCnt, unsigned outChCnt, cmReal_t srate )
{ {
@ -6459,6 +6459,203 @@ const cmSample_t* cmSpecDistOut( cmSpecDist_t* p )
return cmPvSynExecOut(p->pvs); return cmPvSynExecOut(p->pvs);
} }
//------------------------------------------------------------------------------------------------------------
cmSpecDist2_t* cmSpecDist2Alloc( cmCtx* ctx,cmSpecDist2_t* ap, unsigned procSmpCnt, double srate, unsigned wndSmpCnt, unsigned hopFcmt, unsigned olaWndTypeId )
{
cmSpecDist2_t* p = cmObjAlloc( cmSpecDist2_t, ctx, ap );
if( procSmpCnt != 0 )
{
if( cmSpecDist2Init( p, procSmpCnt, srate, wndSmpCnt, hopFcmt, olaWndTypeId ) != cmOkRC )
cmSpecDist2Free(&p);
}
return p;
}
cmRC_t cmSpecDist2Free( cmSpecDist2_t** pp )
{
if( pp == NULL || *pp == NULL )
return cmOkRC;
cmSpecDist2_t* p = *pp;
cmSpecDist2Final(p);
cmObjFree(pp);
return cmOkRC;
}
cmRC_t cmSpecDist2Init( cmSpecDist2_t* p, unsigned procSmpCnt, double srate, unsigned wndSmpCnt, unsigned hopFcmt, unsigned olaWndTypeId )
{
cmRC_t rc;
if((rc = cmSpecDist2Final(p)) != cmOkRC )
return rc;
unsigned flags = 0;
p->srate = srate;
p->wndSmpCnt = wndSmpCnt;
p->hopSmpCnt = (unsigned)floor(wndSmpCnt/hopFcmt);
p->procSmpCnt = procSmpCnt;
p->ceiling = 30;
p->expo = 2.0;
p->thresh = 60;
p->uprSlope = 0.0;
p->lwrSlope = 2.0;
p->mix = 0.0;
p->pva = cmPvAnlAlloc( p->obj.ctx, NULL, procSmpCnt, srate, wndSmpCnt, p->hopSmpCnt, flags );
p->pvs = cmPvSynAlloc( p->obj.ctx, NULL, procSmpCnt, srate, wndSmpCnt, p->hopSmpCnt, olaWndTypeId );
return rc;
}
cmRC_t cmSpecDist2Final(cmSpecDist2_t* p )
{
cmRC_t rc = cmOkRC;
cmPvAnlFree(&p->pva);
cmPvSynFree(&p->pvs);
return rc;
}
void _cmSpecDist2Bump( cmSpecDist2_t* p, cmReal_t* x, unsigned binCnt, double thresh, double expo)
{
unsigned i = 0;
double minDb = -100.0;
thresh = -fabs(thresh);
for(i=0; i<binCnt; ++i)
{
double y;
if( x[i] < minDb )
x[i] = minDb;
if( x[i] > thresh )
y = 1;
else
{
y = (minDb - x[i])/(minDb - thresh);
y += y - pow(y,expo);
}
x[i] = minDb + (-minDb) * y;
}
}
void _cmSpecDist2BasicMode(cmSpecDist2_t* p, cmReal_t* X1m, unsigned binCnt, cmReal_t thresh, double upr, double lwr )
{
unsigned i=0;
if( lwr < 0.3 )
lwr = 0.3;
for(i=0; i<binCnt; ++i)
{
cmReal_t a = fabs(X1m[i]);
cmReal_t d = a - thresh;
X1m[i] = -thresh;
if( d > 0 )
X1m[i] -= (lwr*d);
else
X1m[i] -= (upr*d);
}
}
cmRC_t cmSpecDist2Exec( cmSpecDist2_t* p, const cmSample_t* sp, unsigned sn )
{
assert( sn == p->procSmpCnt );
unsigned binN = p->pva->binCnt;
// cmPvAnlExec() returns true when it calc's a new spectral output frame
if( cmPvAnlExec( p->pva, sp, sn ) )
{
cmReal_t X0m[binN];
cmReal_t X1m[binN];
// take the mean of the the input magntitude spectrum
cmReal_t u0 = cmVOR_Mean(p->pva->magV,binN);
// convert magnitude to db (range=-1000.0 to 0.0)
cmVOR_AmplToDbVV(X0m, binN, p->pva->magV, -1000.0 );
cmVOR_Copy(X1m,binN,X0m);
// bump transform X0m
_cmSpecDist2Bump(p,X0m, binN, p->ceiling, p->expo);
// xfade bump output with raw input: X1m = (X0m*mix) + (X1m*(1.0-mix))
cmVOR_MultVS(X0m,binN,p->mix);
cmVOR_MultVS(X1m,binN,1.0 - p->mix );
cmVOR_AddVV(X1m,binN,X0m);
// basic transform
_cmSpecDist2BasicMode(p,X1m,binN,p->thresh,p->uprSlope,p->lwrSlope);
// convert db back to magnitude
cmVOR_DbToAmplVV(X1m, binN, X1m );
// convert the mean input magnitude to db
cmReal_t idb = 20*log10(u0);
// get the mean output magnitude spectra
cmReal_t u1 = cmVOR_Mean(X1m,binN);
if( idb > -150.0 )
{
// set the output gain such that the mean output magnitude
// will match the mean input magnitude
p->ogain = u0/u1;
}
else
{
cmReal_t a0 = 0.9;
p->ogain *= a0;
}
// apply the output gain
cmVOR_MultVS(X1m,binN,cmMin(4.0,p->ogain));
// convert back to time domain
cmPvSynExec(p->pvs, X1m, p->pva->phsV );
p->fi += 1;
}
return cmOkRC;
}
const cmSample_t* cmSpecDist2Out( cmSpecDist2_t* p )
{
return cmPvSynExecOut(p->pvs);
}
void cmSpecDist2Report( cmSpecDist2_t* p )
{
printf("ceil:%f expo:%f mix:%f thresh:%f upr:%f lwr:%f\n", p->ceiling,p->expo,p->mix,p->thresh,p->lwrSlope,p->uprSlope);
}
//------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
cmRC_t _cmBinMtxFileWriteHdr( cmBinMtxFile_t* p ) cmRC_t _cmBinMtxFileWriteHdr( cmBinMtxFile_t* p )

View File

@ -1314,6 +1314,44 @@ extern "C" {
//------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
//) //)
//( { label:cmSpecDist file_desc:"Spectral distortion 2 algorithm based on non-linear transform." kw:[proc]}
typedef struct
{
cmObj obj;
double srate;
unsigned wndSmpCnt;
unsigned hopFcmt;
unsigned hopSmpCnt;
unsigned procSmpCnt;
cmPvAnl* pva;
cmPvSyn* pvs;
double ceiling;
double expo;
double mix;
double thresh;
double uprSlope;
double lwrSlope;
cmReal_t ogain;
unsigned fi; // total count of frames processed by cmSpecDistExec()
} cmSpecDist2_t;
cmSpecDist2_t* cmSpecDist2Alloc( cmCtx* ctx,cmSpecDist2_t* ap, unsigned procSmpCnt, double srate, unsigned wndSmpCnt, unsigned hopFcmt, unsigned olaWndTypeId );
cmRC_t cmSpecDist2Free( cmSpecDist2_t** pp );
cmRC_t cmSpecDist2Init( cmSpecDist2_t* p, unsigned procSmpCnt, double srate, unsigned wndSmpCnt, unsigned hopFcmt, unsigned olaWndTypeId );
cmRC_t cmSpecDist2Final(cmSpecDist2_t* p );
cmRC_t cmSpecDist2Exec( cmSpecDist2_t* p, const cmSample_t* sp, unsigned sn );
const cmSample_t* cmSpecDist2Out( cmSpecDist2_t* p );
void cmSpecDist2Report( cmSpecDist2_t* p );
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmBinMtxFile file_desc:"Write a binary matrix which can be read by readBinFile.m." kw:[proc]} //( { label:cmBinMtxFile file_desc:"Write a binary matrix which can be read by readBinFile.m." kw:[proc]}
// Write a binary matrix file in the format acceppted by the octave function readBinFile.m // Write a binary matrix file in the format acceppted by the octave function readBinFile.m

View File

@ -5482,6 +5482,7 @@ cmDspClassConsFunc_t _cmDspClassBuiltInArray[] =
cmSegLineClassCons, cmSegLineClassCons,
cmKrClassCons, cmKrClassCons,
cmKr2ClassCons,
cmTimeLineClassCons, cmTimeLineClassCons,
cmScoreClassCons, cmScoreClassCons,
cmMidiFilePlayClassCons, cmMidiFilePlayClassCons,

View File

@ -281,6 +281,252 @@ cmDspClass_t* cmKrClassCons( cmDspCtx_t* ctx )
return &_cmKrDC; return &_cmKrDC;
} }
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmDspKr2 file_desc:"Spectral non-linear distortion effect." kw:[sunit] }
enum
{
kWndSmpCntKr2Id,
kHopFactKr2Id,
kCeilKr2Id,
kExpoKr2Id,
kThreshKr2Id,
kLwrSlopeKr2Id,
kUprSlopeKr2Id,
kMixKr2Id,
kWetKr2Id,
kAudioInKr2Id,
kAudioOutKr2Id
};
typedef struct
{
cmDspInst_t inst;
cmCtx* ctx;
cmSpecDist2_t* sdp;
} cmDspKr2_t;
cmDspClass_t _cmKr2DC;
cmDspInst_t* _cmDspKr2Alloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned storeSymId, unsigned instSymId, unsigned id, unsigned va_cnt, va_list vl )
{
cmDspVarArg_t args[] =
{
{ "wndn", kWndSmpCntKr2Id, 0, 0, kInDsvFl | kUIntDsvFl | kReqArgDsvFl, "Window sample count" },
{ "hopf", kHopFactKr2Id, 0, 0, kInDsvFl | kUIntDsvFl | kOptArgDsvFl, "Hop factor" },
{ "ceil", kCeilKr2Id, 0, 0, kInDsvFl | kDoubleDsvFl | kOptArgDsvFl, "Ceiling" },
{ "expo", kExpoKr2Id, 0, 0, kInDsvFl | kDoubleDsvFl | kOptArgDsvFl, "Exponent" },
{ "thrh", kThreshKr2Id, 0, 0, kInDsvFl | kDoubleDsvFl | kOptArgDsvFl, "Threshold" },
{ "lwrs", kLwrSlopeKr2Id, 0, 0, kInDsvFl | kDoubleDsvFl | kOptArgDsvFl, "Lower Slope"},
{ "uprs", kUprSlopeKr2Id, 0, 0, kInDsvFl | kDoubleDsvFl | kOptArgDsvFl, "Upper Slope"},
{ "mix", kMixKr2Id, 0, 0, kInDsvFl | kDoubleDsvFl | kOptArgDsvFl, "Mix"},
{ "wet", kWetKr2Id, 0, 0, kInDsvFl | kSampleDsvFl, "Wet mix level."},
{ "in", kAudioInKr2Id, 0, 0, kInDsvFl | kAudioBufDsvFl, "Audio Input" },
{ "out", kAudioOutKr2Id, 0, 1, kOutDsvFl | kAudioBufDsvFl, "Audio Output" },
{ NULL, 0, 0, 0, 0 }
};
cmDspKr2_t* p = cmDspInstAlloc(cmDspKr2_t,ctx,classPtr,args,instSymId,id,storeSymId,va_cnt,vl);
unsigned defWndSmpCnt = cmDspDefaultUInt(&p->inst,kWndSmpCntKr2Id);
unsigned wndSmpCnt = cmNextPowerOfTwo( defWndSmpCnt );
cmDspSetDefaultUInt( ctx,&p->inst, kWndSmpCntKr2Id, defWndSmpCnt, wndSmpCnt );
cmDspSetDefaultUInt( ctx,&p->inst, kHopFactKr2Id, 0, 4 );
cmDspSetDefaultDouble( ctx,&p->inst, kCeilKr2Id, 0, 20.0 );
cmDspSetDefaultDouble( ctx,&p->inst, kExpoKr2Id, 0, 2.0 );
cmDspSetDefaultDouble( ctx,&p->inst, kThreshKr2Id, 0, 60.0 );
cmDspSetDefaultDouble( ctx,&p->inst, kLwrSlopeKr2Id, 0, 2.0 );
cmDspSetDefaultDouble( ctx,&p->inst, kUprSlopeKr2Id, 0, 0.0 );
cmDspSetDefaultDouble( ctx,&p->inst, kMixKr2Id, 0, 0.0 );
cmDspSetDefaultSample( ctx,&p->inst, kWetKr2Id, 0, 1.0);
//_cmDspKr2CmInit(ctx,p); // initialize the cm library
p->ctx = cmCtxAlloc(NULL,ctx->rpt,ctx->lhH,ctx->stH);
return &p->inst;
}
cmDspRC_t _cmDspKr2Free(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
{
cmDspRC_t rc = kOkDspRC;
cmDspKr2_t* p = (cmDspKr2_t*)inst;
cmSpecDist2Free(&p->sdp);
cmCtxFree(&p->ctx);
//_cmDspKr2CmFinal(ctx,p); // finalize the cm library
return rc;
}
cmDspRC_t _cmDspKr2Setup(cmDspCtx_t* ctx, cmDspKr2_t* p )
{
cmDspRC_t rc = kOkDspRC;
unsigned wndSmpCnt = cmDspUInt(&p->inst,kWndSmpCntKr2Id);
unsigned hopFact = cmDspUInt(&p->inst,kHopFactKr2Id);
unsigned olaWndTypeId =kHannWndId;
cmSpecDist2Free(&p->sdp);
p->sdp = cmSpecDist2Alloc(p->ctx, NULL, cmDspSamplesPerCycle(ctx), cmDspSampleRate(ctx), wndSmpCnt, hopFact, olaWndTypeId);
assert(p->sdp != NULL );
if((rc = cmDspZeroAudioBuf(ctx,&p->inst,kAudioOutKr2Id)) != kOkDspRC )
return rc;
return rc;
}
cmDspRC_t _cmDspKr2Reset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
{
cmDspKr2_t* p = (cmDspKr2_t*)inst;
cmDspRC_t rc;
if((rc = cmDspApplyAllDefaults(ctx,inst)) != kOkDspRC )
return rc;
return _cmDspKr2Setup(ctx,p);
}
cmDspRC_t _cmDspKr2Exec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
{
cmDspKr2_t* p = (cmDspKr2_t*)inst;
cmDspRC_t rc = kOkDspRC;
unsigned iChIdx = 0;
const cmSample_t* ip = cmDspAudioBuf(ctx,inst,kAudioInKr2Id,iChIdx);
unsigned iSmpCnt = cmDspVarRows(inst,kAudioInKr2Id);
// if no connected
if( iSmpCnt == 0 )
return rc;
unsigned oChIdx = 0;
cmSample_t* op = cmDspAudioBuf(ctx,inst,kAudioOutKr2Id,oChIdx);
unsigned oSmpCnt = cmDspVarRows(inst,kAudioOutKr2Id);
const cmSample_t* sp;
cmSample_t wet = cmDspSample(inst,kWetKr2Id);
cmSpecDist2Exec(p->sdp,ip,iSmpCnt);
if((sp = cmSpecDist2Out(p->sdp)) != NULL )
{
cmVOS_MultVVS(op,oSmpCnt,sp,wet);
}
if( wet<1.0 )
cmVOS_MultSumVVS(op,oSmpCnt,ip,1.0-wet);
return rc;
}
cmDspRC_t _cmDspKr2Recv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
{
cmDspKr2_t* p = (cmDspKr2_t*)inst;
cmDspRC_t rc = kOkDspRC;
cmDspSetEvent(ctx,inst,evt);
switch( evt->dstVarId )
{
case kWndSmpCntKr2Id:
case kHopFactKr2Id:
_cmDspKr2Setup(ctx,p);
// THIS IS A HACK
// WHEN WND OR HOP CHANGE THE RESULTING CHANGES
// SHOULD BE ISOLATED IN cmSpecDist() AND THE
// CURRENT STATE OF THE PARAMETERS SHOULD NOT BE
// LOST - IF THE CHANGES WERE ISOLATED WITHIN PVANL
// AND PVSYN IT MIGHT BE POSSIBLE TO DO WITH
// MINIMAL AUDIO INTERUPTION.
p->sdp->ceiling = cmDspDouble(inst,kCeilKr2Id);
p->sdp->expo = cmDspDouble(inst,kExpoKr2Id);
p->sdp->thresh = cmDspDouble(inst,kThreshKr2Id);
p->sdp->uprSlope = cmDspDouble(inst,kUprSlopeKr2Id);
p->sdp->lwrSlope = cmDspDouble(inst,kLwrSlopeKr2Id);
p->sdp->mix = cmDspDouble(inst,kMixKr2Id);
printf("wsn:%i hsn:%i\n",p->sdp->wndSmpCnt,p->sdp->hopSmpCnt);
break;
case kCeilKr2Id:
p->sdp->ceiling = cmDspDouble(inst,kCeilKr2Id);
break;
case kExpoKr2Id:
p->sdp->expo = cmDspDouble(inst,kExpoKr2Id);
break;
case kThreshKr2Id:
p->sdp->thresh = cmDspDouble(inst,kThreshKr2Id);
break;
case kUprSlopeKr2Id:
p->sdp->uprSlope = cmDspDouble(inst,kUprSlopeKr2Id);
break;
case kLwrSlopeKr2Id:
p->sdp->lwrSlope = cmDspDouble(inst,kLwrSlopeKr2Id);
break;
case kMixKr2Id:
p->sdp->mix = cmDspDouble(inst,kMixKr2Id);
break;
case kWetKr2Id:
break;
default:
{ assert(0); }
}
cmSpecDist2Report(p->sdp);
return rc;
}
cmDspClass_t* cmKr2ClassCons( cmDspCtx_t* ctx )
{
cmDspClassSetup(&_cmKr2DC,ctx,"Kr2",
NULL,
_cmDspKr2Alloc,
_cmDspKr2Free,
_cmDspKr2Reset,
_cmDspKr2Exec,
_cmDspKr2Recv,
NULL,NULL,
"Fourier based non-linear transformer two.");
return &_cmKr2DC;
}
//------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
//) //)
//( { label:cmDspTimeLine file_desc:"Time line user interface unit." kw:[sunit] } //( { label:cmDspTimeLine file_desc:"Time line user interface unit." kw:[sunit] }

View File

@ -6,6 +6,7 @@ extern "C" {
#endif #endif
struct cmDspClass_str* cmKrClassCons( cmDspCtx_t* ctx ); struct cmDspClass_str* cmKrClassCons( cmDspCtx_t* ctx );
struct cmDspClass_str* cmKr2ClassCons( cmDspCtx_t* ctx );
struct cmDspClass_str* cmTimeLineClassCons( cmDspCtx_t* ctx ); struct cmDspClass_str* cmTimeLineClassCons( cmDspCtx_t* ctx );
struct cmDspClass_str* cmScoreClassCons( cmDspCtx_t* ctx ); struct cmDspClass_str* cmScoreClassCons( cmDspCtx_t* ctx );
struct cmDspClass_str* cmMidiFilePlayClassCons( cmDspCtx_t* ctx ); struct cmDspClass_str* cmMidiFilePlayClassCons( cmDspCtx_t* ctx );

View File

@ -36,6 +36,9 @@
#include "cmDspPgmKrChain.h" #include "cmDspPgmKrChain.h"
#undef KR2
cmDspRC_t krLoadRsrc(cmDspSysH_t h, cmErr_t* err, krRsrc_t* r) cmDspRC_t krLoadRsrc(cmDspSysH_t h, cmErr_t* err, krRsrc_t* r)
{ {
cmDspRC_t rc; cmDspRC_t rc;
@ -71,7 +74,7 @@ const cmChar_t* _mlbl(const cmChar_t* prefix, unsigned ch )
#define mlbl(a) _mlbl(a,mch) #define mlbl(a) _mlbl(a,mch)
#define lbl(a) cmDspSysPrintLabel(a,ach) #define lbl(a) cmDspSysPrintLabel(a,ach)
#ifndef KR2
void _cmDspSys_TlXformChain( cmDspSysH_t h, cmDspTlXform_t* c, unsigned preGrpSymId, unsigned cmpPreGrpSymId, cmDspInst_t* modp, unsigned ach, unsigned mch ) void _cmDspSys_TlXformChain( cmDspSysH_t h, cmDspTlXform_t* c, unsigned preGrpSymId, unsigned cmpPreGrpSymId, cmDspInst_t* modp, unsigned ach, unsigned mch )
{ {
unsigned measRtrChCnt = 6; // note: router channel 6 is not connected unsigned measRtrChCnt = 6; // note: router channel 6 is not connected
@ -361,4 +364,186 @@ void _cmDspSys_TlXformChain( cmDspSysH_t h, cmDspTlXform_t* c, unsigned preGrpS
c->cmp = cmp; c->cmp = cmp;
} }
#endif
//=======================================================================================================================
//=======================================================================================================================
// KR2 Modeless Transform based on cmDspKr2 and cmSpecDist2
//=======================================================================================================================
//=======================================================================================================================
#ifdef KR2
void _cmDspSys_TlXformChain( cmDspSysH_t h, cmDspTlXform_t* c, unsigned preGrpSymId, unsigned cmpPreGrpSymId, cmDspInst_t* modp, unsigned ach, unsigned mch )
{
unsigned measRtrChCnt = 6; // note: router channel 6 is not connected
int krWndSmpCnt = 2048;
int krHopFact = 4;
unsigned xfadeChCnt = 2;
double xfadeMs = 50;
bool xfadeInitFl = true;
double mixGain = 1.0;
bool cmpBypassFl = false;
double cmpInGain = 3.0;
double cmpThreshDb = -40.0;
double cmpRatio_num = 5.0;
double cmpAtkMs = 20.0;
double cmpRlsMs = 100.0;
double cmpMakeup = 1.0;
double cmpWndMaxMs = 1000.0;
double cmpWndMs = 200.0;
cmDspInst_t* achan = cmDspSysAllocInst(h, "AvailCh", NULL, 1, xfadeChCnt );
// Parameter-> kr routers (routers used to cross-fade between the two kr units)
unsigned paramRtChCnt = 2;
cmDspInst_t* wnd_rt = cmDspSysAllocInst(h, "Router", NULL, 2, paramRtChCnt, paramRtChCnt-1 );
cmDspInst_t* hop_rt = cmDspSysAllocInst(h, "Router", NULL, 2, paramRtChCnt, paramRtChCnt-1 );
cmDspInst_t* ceil_rt = cmDspSysAllocInst(h, "Router", NULL, 2, paramRtChCnt, paramRtChCnt-1 );
cmDspInst_t* expo_rt = cmDspSysAllocInst(h, "Router", NULL, 2, paramRtChCnt, paramRtChCnt-1 );
cmDspInst_t* mix_rt = cmDspSysAllocInst(h, "Router", NULL, 2, paramRtChCnt, paramRtChCnt-1 );
cmDspInst_t* thr_rt = cmDspSysAllocInst(h, "Router", NULL, 2, paramRtChCnt, paramRtChCnt-1 );
cmDspInst_t* upr_rt = cmDspSysAllocInst(h, "Router", NULL, 2, paramRtChCnt, paramRtChCnt-1 );
cmDspInst_t* lwr_rt = cmDspSysAllocInst(h, "Router", NULL, 2, paramRtChCnt, paramRtChCnt-1 );
cmDspInst_t* wet_rt = cmDspSysAllocInst(h, "Router", NULL, 2, paramRtChCnt, paramRtChCnt-1 );
// Audio processors
cmDspInst_t* kr0 = cmDspSysAllocInst(h, "Kr2", NULL, 2, krWndSmpCnt, krHopFact );
cmDspInst_t* kr1 = cmDspSysAllocInst(h, "Kr2", NULL, 2, krWndSmpCnt, krHopFact );
cmDspInst_t* xfad = cmDspSysAllocInst(h, "Xfader", NULL, 3, xfadeChCnt, xfadeMs, xfadeInitFl );
cmDspInst_t* mix = cmDspSysAllocInst(h, "AMix", NULL, 3, xfadeChCnt, mixGain, mixGain );
cmDspInst_t* cmp = cmDspSysAllocInst(h, "Compressor", NULL, 8, cmpBypassFl, cmpThreshDb, cmpRatio_num, cmpAtkMs, cmpRlsMs, cmpMakeup, cmpWndMs, cmpWndMaxMs );
// Internal audio connections
cmDspSysConnectAudio(h, kr0, "out", xfad, "in-0");
cmDspSysConnectAudio(h, kr1, "out", xfad, "in-1");
cmDspSysConnectAudio(h, xfad, "out-0", mix, "in-0");
cmDspSysConnectAudio(h, xfad, "out-1", mix, "in-1");
cmDspSysConnectAudio(h, mix, "out", cmp, "in" );
// active channel <-> cross-fade connections
cmDspSysInstallCb(h, achan, "reset", xfad, "reset", NULL);
cmDspSysInstallCb(h, achan, "gate-0", xfad, "gate-0", NULL );
cmDspSysInstallCb(h, achan, "gate-1", xfad, "gate-1", NULL );
cmDspSysInstallCb(h, xfad, "state-0", achan, "dis-0", NULL );
cmDspSysInstallCb(h, xfad, "state-1", achan, "dis-1", NULL );
// Parameter number controls
cmDspInst_t* wnd_ctl = cmDspSysAllocMsgListP(h,preGrpSymId,NULL, lbl("WndSmpCnt"), NULL, "wndSmpCnt", 2);
cmDspInst_t* hop_ctl = cmDspSysAllocMsgListP(h,preGrpSymId,NULL, lbl("HopFact"), NULL, "hopFact", 2);
cmDspInst_t* ceil_ctl= cmDspSysAllocScalarP( h,preGrpSymId,NULL, lbl("Ceiling"), 0.0, 100.0, 0.1, 30.0 );
cmDspInst_t* expo_ctl= cmDspSysAllocScalarP( h,preGrpSymId,NULL, lbl("Expo"), -10.0, 10.0, 0.01, 2.0 );
cmDspInst_t* mix_ctl = cmDspSysAllocScalarP( h,preGrpSymId,NULL, lbl("Mix"), 0.0, 1.0, 0.01, 0.0 );
cmDspInst_t* thr_ctl = cmDspSysAllocScalarP( h,preGrpSymId,NULL, lbl("Threshold"), 0.0, 100.0, 0.1, 60.0 );
cmDspInst_t* upr_ctl = cmDspSysAllocScalarP( h,preGrpSymId,NULL, lbl("Upr slope"), -10.0, 10.0, 0.01, 0.0 );
cmDspInst_t* lwr_ctl = cmDspSysAllocScalarP( h,preGrpSymId,NULL, lbl("Lwr slope"), -10.0, 10.0, 0.01, 2.0 );
cmDspInst_t* wet_ctl = cmDspSysAllocScalarP( h,preGrpSymId,NULL, lbl("Wet Dry"), 0.0, 1.0, 0.001, 1.0 );
cmDspSysInstallCb(h, wnd_ctl, "out", wnd_rt, "f-in", NULL );
cmDspSysInstallCb(h, achan, "ch", wnd_rt, "sel", NULL ); // ach->rt sel
cmDspSysInstallCb(h, wnd_rt, "f-out-0", kr0, "wndn", NULL ); // wndn->kr
cmDspSysInstallCb(h, wnd_rt, "f-out-1", kr1, "wndn", NULL ); // wndn->kr
cmDspSysInstallCb(h, hop_ctl, "out", hop_rt, "f-in", NULL );
cmDspSysInstallCb(h, achan, "ch", hop_rt, "sel", NULL ); // ach->rt sel
cmDspSysInstallCb(h, hop_rt, "f-out-0", kr0, "hopf", NULL ); // hopf->kr
cmDspSysInstallCb(h, hop_rt, "f-out-1", kr1, "hopf", NULL ); // hopf->kr
cmDspSysInstallCb(h, ceil_ctl, "val", ceil_rt, "f-in", NULL );
cmDspSysInstallCb(h, achan, "ch", ceil_rt, "sel", NULL ); // ach->rt sel
cmDspSysInstallCb(h, ceil_rt, "f-out-0", kr0, "ceil", NULL ); // ceil->kr
cmDspSysInstallCb(h, ceil_rt, "f-out-1", kr1, "ceil", NULL ); // ceil->kr
cmDspSysInstallCb(h, expo_ctl, "val", expo_rt, "f-in", NULL );
cmDspSysInstallCb(h, achan, "ch", expo_rt, "sel", NULL ); // ach->rt sel
cmDspSysInstallCb(h, expo_rt, "f-out-0", kr0, "expo", NULL ); // expo->kr
cmDspSysInstallCb(h, expo_rt, "f-out-1", kr1, "expo", NULL ); // expo->kr
cmDspSysInstallCb(h, mix_ctl, "val", mix_rt, "f-in", NULL );
cmDspSysInstallCb(h, achan, "ch", mix_rt, "sel", NULL ); // ach->rt sel
cmDspSysInstallCb(h, mix_rt, "f-out-0", kr0, "mix", NULL ); // mix->kr
cmDspSysInstallCb(h, mix_rt, "f-out-1", kr1, "mix", NULL ); // mix->kr
cmDspSysInstallCb(h, thr_ctl, "val", thr_rt, "f-in", NULL );
cmDspSysInstallCb(h, achan, "ch", thr_rt, "sel", NULL ); // ach->rt sel
cmDspSysInstallCb(h, thr_rt, "f-out-0", kr0, "thrh", NULL ); // thr->kr
cmDspSysInstallCb(h, thr_rt, "f-out-1", kr1, "thrh", NULL ); // thr->kr
cmDspSysInstallCb(h, upr_ctl, "val", upr_rt, "f-in", NULL );
cmDspSysInstallCb(h, achan, "ch", upr_rt, "sel", NULL ); // ach->rt sel
cmDspSysInstallCb(h, upr_rt, "f-out-0", kr0, "uprs", NULL ); // upr->kr
cmDspSysInstallCb(h, upr_rt, "f-out-1", kr1, "uprs", NULL ); // upr->kr
cmDspSysInstallCb(h, lwr_ctl, "val", lwr_rt, "f-in", NULL );
cmDspSysInstallCb(h, achan, "ch", lwr_rt, "sel", NULL ); // ach->rt sel
cmDspSysInstallCb(h, lwr_rt, "f-out-0", kr0, "lwrs", NULL ); // lwr->kr
cmDspSysInstallCb(h, lwr_rt, "f-out-1", kr1, "lwrs", NULL ); // lwr->kr
cmDspSysInstallCb(h, wet_ctl, "val", wet_rt, "f-in", NULL );
cmDspSysInstallCb(h, achan, "ch", wet_rt, "sel", NULL ); // ach->rt sel
cmDspSysInstallCb(h, wet_rt, "f-out-0", kr0, "wet", NULL ); // wet->kr
cmDspSysInstallCb(h, wet_rt, "f-out-1", kr1, "wet", NULL ); // wet->kr
cmDspSysNewColumn(h,0);
cmDspInst_t* cmp_byp = cmDspSysAllocCheckP( h, cmpPreGrpSymId, NULL, lbl("Bypass"), 1.0 );
cmDspInst_t* cmp_igain = cmDspSysAllocScalarP( h, cmpPreGrpSymId, NULL, lbl("In Gain"), 0.0, 10.0, 0.1, cmpInGain);
cmDspInst_t* cmp_thr = cmDspSysAllocScalarP( h, cmpPreGrpSymId, NULL, lbl("ThreshDb"), -100.0, 0.0, 0.1, cmpThreshDb);
cmDspInst_t* cmp_rat = cmDspSysAllocScalarP( h, cmpPreGrpSymId, NULL, lbl("Ratio"), 0.1, 100, 0.1, cmpRatio_num);
cmDspInst_t* cmp_atk = cmDspSysAllocScalarP( h, cmpPreGrpSymId, NULL, lbl("Atk Ms"), 0.0, 1000.0, 0.1, cmpAtkMs);
cmDspInst_t* cmp_rls = cmDspSysAllocScalarP( h, cmpPreGrpSymId, NULL, lbl("Rls Ms"), 0.0, 1000.0, 0.1, cmpRlsMs);
cmDspInst_t* cmp_mkup = cmDspSysAllocScalarP( h, cmpPreGrpSymId, NULL, lbl("Makeup"), 0.0, 10.0, 0.01, cmpMakeup);
cmDspInst_t* cmp_wnd = cmDspSysAllocScalarP( h, cmpPreGrpSymId, NULL, lbl("Wnd Ms"), 1.0, cmpWndMaxMs, 1.0, cmpWndMs );
cmDspInst_t* cmp_mtr = cmDspSysAllocInst(h,"Meter",lbl("Env"), 3, 0.0, 0.0, 1.0);
cmDspSysInstallCb(h, cmp_byp, "out", cmp, "bypass", NULL );
cmDspSysInstallCb(h, cmp_igain,"val", cmp, "igain", NULL );
cmDspSysInstallCb(h, cmp_thr, "val", cmp, "thr", NULL );
cmDspSysInstallCb(h, cmp_rat, "val", cmp, "ratio", NULL );
cmDspSysInstallCb(h, cmp_atk, "val", cmp, "atk", NULL );
cmDspSysInstallCb(h, cmp_rls, "val", cmp, "rls", NULL );
cmDspSysInstallCb(h, cmp_mkup, "val", cmp, "ogain", NULL );
cmDspSysInstallCb(h, cmp_wnd, "val", cmp, "wnd", NULL );
cmDspSysInstallCb(h, cmp, "env", cmp_mtr, "in", NULL );
cmDspSysInstallCb(h, modp, mlbl("cbyp"), cmp_byp, "in", NULL );
cmDspSysInstallCb(h, modp, mlbl("cigain"), cmp_igain,"val", NULL );
cmDspSysInstallCb(h, modp, mlbl("cthrsh"), cmp_thr, "val", NULL );
cmDspSysInstallCb(h, modp, mlbl("cratio"), cmp_rat, "val", NULL );
cmDspSysInstallCb(h, modp, mlbl("catkms"), cmp_atk, "val", NULL );
cmDspSysInstallCb(h, modp, mlbl("crlsms"), cmp_rls, "val", NULL );
cmDspSysInstallCb(h, modp, mlbl("cmakeup"), cmp_mkup, "val", NULL );
cmDspSysInstallCb(h, modp, mlbl("cwndms"), cmp_wnd, "val", NULL );
//
cmDspInst_t* xfadMs = cmDspSysAllocInst(h,"Scalar", lbl("Xfade Ms"), 5, kNumberDuiId, 0.0, 1000.0,0.01, 50.0 );
cmDspSysInstallCb(h, xfadMs, "val", xfad, "ms", NULL );
cmDspSysInstallCb(h, modp, mlbl("xfad"), xfadMs, "val", NULL);
cmDspSysInstallCb(h, modp, mlbl("win"), wnd_ctl, "sel", NULL );
cmDspSysInstallCb(h, modp, mlbl("hop"), hop_ctl, "sel", NULL );
cmDspSysInstallCb(h, modp, mlbl("ceil"), ceil_ctl, "val", NULL );
cmDspSysInstallCb(h, modp, mlbl("expo"), expo_ctl, "val", NULL );
cmDspSysInstallCb(h, modp, mlbl("mix"), mix_ctl, "val", NULL );
cmDspSysInstallCb(h, modp, mlbl("thr"), thr_ctl, "val", NULL );
cmDspSysInstallCb(h, modp, mlbl("upr"), upr_ctl, "val", NULL );
cmDspSysInstallCb(h, modp, mlbl("lwr"), lwr_ctl, "val", NULL );
cmDspSysInstallCb(h, modp, mlbl("wet"), wet_ctl, "val", NULL );
cmDspSysInstallCb(h, modp, mlbl("sw"), achan, "trig", NULL ); // See also: amp.sfloc->achan.trig
c->achan = achan;
c->kr0 = kr0;
c->kr1 = kr1;
c->cmp = cmp;
}
#endif