2012-10-30 03:52:39 +00:00
# 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 "cmText.h"
# include "cmFileSys.h"
# include "cmSymTbl.h"
# include "cmJson.h"
# include "cmPrefs.h"
# include "cmDspValue.h"
# include "cmMsgProtocol.h"
# include "cmThread.h"
# include "cmUdpPort.h"
# include "cmUdpNet.h"
2013-12-15 23:14:27 +00:00
# include "cmTime.h"
2012-10-30 03:52:39 +00:00
# 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"
# include "cmVectOps.h"
/*
subnet [ aout ] = fx_chain ( ain , hzV )
{
cmpThreshDb = - 40.0 ;
cmpRatio = 4 ;
cmpAtkMs = 30.0 ;
cmpRlsMs = 100.0 ;
dstInGain = 1.0 ;
dstDSrate = 44100.0 ;
dstBits = 24 ;
eqMode = " LP " ;
eqHz = hzV [ _i ] ;
dlyMaxMs = 10000.0 ;
dlyFb = 0.8 ;
loop = loopRecd ( ) ;
ps = pitchShift ( ) ;
cmp = compressor ( cmpThreshDb , cmpRatio , cmpAtkMs , cmpRlsMs ) ;
dst = distortion ( dstInGain , dstDSrate , dstBits ) ;
eq = eq ( eqMode , eqHz ) ;
dly = delay ( dlyMaxMs , dlyFb ) ;
ain - > in . loop . out - > in . ps . out - > in . ps . out
loop . out - > ps . in ;
ps . out - > cmp . in ;
cmp . out - > dst . in ;
dst . out - > eq . in ;
eq . out - > dly . in ;
dly . out - > aout
}
audInMapV = [ 0 , 1 , 0 , 1 ] ;
audOutMapV = [ 0 , 1 ] ;
hzV = [ 110 220 440 880 ] ;
ain = audioInput ( audioInMap , 1.0 ) [ chCnt ] ;
ef = envFollower ( ) [ chCnt ] ;
mtr = meter ( 0.0 , 1.0 , 0.0 ) [ chCnt ] ;
fx = fx_chain ( ain ) ( hzV ) [ chCnt ] ;
aout = audioOutput ( audioOutMap , 1.0 ) [ chCnt ] ;
ain . out - > ef . in
ef . rms - > mtr . in
*/
// Use the resource int arrays 'pitchList' and 'groupList' to create
// the following resource int arrays:
// CDmidi - MIDI pitch of all chord notes
// CD0midi - MIDI pitch of all low/high chord notes
// CD1midi - MIDI pitch of all middle chord notes
// NONmidi - MIDI pitch of all non-chord notes.
// CDchan - channel index of all chord notes
// CD0chan - channel index of all low/high chord notes
// CD1chan - channel index of all middle chord notes
// NONchan - channel index of all non-chord notes.
//
cmDspRC_t _cmDspPgm_Main_ProcRsrc ( cmDspSysH_t h , cmErr_t * err )
{
cmDspRC_t rc ;
unsigned * midiList = NULL ;
unsigned midiCnt = 0 ;
unsigned * groupList = NULL ;
unsigned groupCnt = 0 ;
const cmChar_t * midiListRsrcLabel = " midiList " ;
const cmChar_t * groupListRsrcLabel = " groupList " ;
cmJsonH_t jsH = cmDspSysPgmRsrcHandle ( h ) ;
unsigned i , j , k ;
if ( ( rc = cmDspRsrcUIntArray ( h , & midiCnt , & midiList , midiListRsrcLabel , NULL ) ) ! = kOkDspRC )
{
rc = cmErrMsg ( err , kRsrcNotFoundDspRC , " The resource '%s' could not be read. " , midiListRsrcLabel ) ;
goto errLabel ;
}
if ( ( rc = cmDspRsrcUIntArray ( h , & groupCnt , & groupList , groupListRsrcLabel , NULL ) ) ! = kOkDspRC )
{
rc = cmErrMsg ( err , kRsrcNotFoundDspRC , " The resource '%s' could not be read. " , groupListRsrcLabel ) ;
goto errLabel ;
}
if ( midiCnt ! = groupCnt )
{
rc = cmErrMsg ( err , kInvalidStateDspRC , " The resource arrays:%s and %s were not the same length. " , midiListRsrcLabel , groupListRsrcLabel ) ;
goto errLabel ;
}
for ( i = 0 ; i < 4 ; + + i )
{
int midi [ midiCnt ] ;
int chan [ midiCnt ] ;
const cmChar_t * label = NULL ;
const cmChar_t * label1 ;
for ( j = 0 , k = 0 ; j < midiCnt ; + + j )
{
if ( ( i < = 2 & & groupList [ j ] = = i ) | | ( i = = 3 & & groupList [ j ] ! = 0 ) )
{
midi [ k ] = midiList [ j ] ;
chan [ k ] = j ;
+ + k ;
}
}
switch ( i )
{
case 0 :
label = " NON " ;
break ;
case 1 :
label = " CD0 " ;
break ;
case 2 :
label = " CD1 " ;
break ;
case 3 :
label = " CD " ;
break ;
}
if ( cmJsonInsertPairIntArray ( jsH , cmJsonRoot ( jsH ) , label1 = cmTsPrintfS ( " %smidi " , label ) , k , midi ) ! = kOkJsRC )
{
rc = cmErrMsg ( err , kJsonFailDspRC , " The chord detector pitch resource '%s' could not be created. " , cmStringNullGuard ( label1 ) ) ;
goto errLabel ;
}
if ( cmJsonInsertPairIntArray ( jsH , cmJsonRoot ( jsH ) , label1 = cmTsPrintfS ( " %schan " , label ) , k , chan ) ! = kOkJsRC )
{
rc = cmErrMsg ( err , kJsonFailDspRC , " The chord detector channel index resource '%s' could not be created. " , cmStringNullGuard ( label1 ) ) ;
goto errLabel ;
}
}
errLabel :
return rc ;
}
// Use the resource int arrays 'MidiList',"MachineList", "ChordList" and 'GroupList' to create
// the resource int arrays. XXXchan arrays contain indexes between 0 and 15. When used with
// the chord detector this the 'local' channels are 0-15 and the remote channels are 16-31.
// NLCDmidi - MIDI pitch of all local chord notes
// NLCD0midi - MIDI pitch of all local low single notes
// NLCD1midi - MIDI pitch of all local middle single notes
// NLEEmidi - MIDI pitch of all local e-e single notes.
// NLCDchan - channel index of all local chord notes
// NLCD0chan - channel index of all local high single notes
// NLCD1chan - channel index of all local middle single notes
// NLEEchan - channel index of all local e-e single notes.
// NRCDmidi - MIDI pitch of all remote chord notes
// NRCD0midi - MIDI pitch of all remote low single notes
// NRCD1midi - MIDI pitch of all remote middle single notes
// NREEmidi - MIDI pitch of all remote e-e single notes.
// NRCDchan - channel index of all remote chord notes
// NRCD0chan - channel index of all remote high single notes
// NRCD1chan - channel index of all remote middle single notes
// NREEchan - channel index of all remote e-e single notes.
// 'local' refers to the machine running the chord detector
// 'remote' refers to the machine not running the chord detector
cmDspRC_t _cmDspPgm_Main_NetProcRsrc ( cmDspSysH_t h , cmErr_t * err )
{
cmDspRC_t rc = kOkDspRC ;
const cmChar_t * midiListRsrcLabel = " MidiList " ;
unsigned * midiList = NULL ;
unsigned midiCnt = 0 ;
const cmChar_t * machListRsrcLabel = " MachineList " ;
unsigned * machList = NULL ;
unsigned machCnt = 0 ;
const cmChar_t * groupListRsrcLabel = " GroupList " ;
unsigned * groupList = NULL ;
unsigned groupCnt = 0 ;
const cmChar_t * chordListRsrcLabel = " ChordList " ;
unsigned * chordList = NULL ;
unsigned chordCnt = 0 ;
cmJsonH_t jsH = cmDspSysPgmRsrcHandle ( h ) ;
const cmChar_t * localNetNodeLabel = NULL ;
unsigned localNetNodeId = cmInvalidId ;
bool verboseFl = false ;
unsigned i , j , k , m ;
// get the network node id of this machine
if ( ( cmDspRsrcString ( h , & localNetNodeLabel , " cdLocalNetNode " , NULL ) ) ! = kOkDspRC )
{
rc = cmErrMsg ( err , kRsrcNotFoundDspRC , " The resource 'cdLocalNetNode' could not be read. " ) ;
goto errLabel ;
}
if ( ( localNetNodeId = cmDspSysNetNodeLabelToId ( h , localNetNodeLabel ) ) = = cmInvalidId )
{
cmErrMsg ( err , kInvalidArgDspRC , " The network node label '%s' is not valid. " , cmStringNullGuard ( localNetNodeLabel ) ) ;
goto errLabel ;
}
// get the pitch assigned to each channel
if ( ( rc = cmDspRsrcUIntArray ( h , & midiCnt , & midiList , midiListRsrcLabel , NULL ) ) ! = kOkDspRC )
{
rc = cmErrMsg ( err , kRsrcNotFoundDspRC , " The resource '%s' could not be read. " , midiListRsrcLabel ) ;
goto errLabel ;
}
// get the network node id of each channel
if ( ( rc = cmDspRsrcUIntArray ( h , & machCnt , & machList , machListRsrcLabel , NULL ) ) ! = kOkDspRC )
{
rc = cmErrMsg ( err , kRsrcNotFoundDspRC , " The resource '%s' could not be read. " , machListRsrcLabel ) ;
goto errLabel ;
}
// get the group id of each channel
if ( ( rc = cmDspRsrcUIntArray ( h , & groupCnt , & groupList , groupListRsrcLabel , NULL ) ) ! = kOkDspRC )
{
rc = cmErrMsg ( err , kRsrcNotFoundDspRC , " The resource '%s' could not be read. " , groupListRsrcLabel ) ;
goto errLabel ;
}
// get the chord detector flag for each channel
if ( ( rc = cmDspRsrcUIntArray ( h , & chordCnt , & chordList , chordListRsrcLabel , NULL ) ) ! = kOkDspRC )
{
rc = cmErrMsg ( err , kRsrcNotFoundDspRC , " The resource '%s' could not be read. " , chordListRsrcLabel ) ;
goto errLabel ;
}
if ( midiCnt ! = groupCnt | | midiCnt ! = machCnt )
{
rc = cmErrMsg ( err , kInvalidStateDspRC , " The resource arrays:%s, %s and %s were not all the same length. " , midiListRsrcLabel , machListRsrcLabel , groupListRsrcLabel ) ;
goto errLabel ;
}
if ( 1 )
{
const cmChar_t * label1 ;
unsigned ten = 10 ;
int nsChSelChV [ midiCnt ] ; // note selector chord port [0, 5]
int nsChSelChIdxV [ midiCnt ] ; // index on note selector port
int nsNcSelChV [ midiCnt ] ; // note selector single-note port [ 2, 3, 4, 7,8,9 ]
int nsNcSelChIdxV [ midiCnt ] ; // index on note selector single-note port
unsigned chIdxCntV [ ten ] ; // next index for each note selector port
cmVOU_Fill ( chIdxCntV , ten , 0 ) ;
for ( i = 0 ; i < midiCnt ; + + i )
{
unsigned localFl = i < 16 ;
unsigned selIdx = localFl ? 0 : 5 ; // chord port
unsigned chordChFl = chordList [ i ] ! = 0 ; // is this a chord channel
nsChSelChV [ i ] = cmInvalidIdx ;
nsChSelChIdxV [ i ] = cmInvalidIdx ;
if ( chordChFl )
{
nsChSelChV [ i ] = selIdx ;
nsChSelChIdxV [ i ] = chIdxCntV [ selIdx ] ;
chIdxCntV [ selIdx ] + = 1 ;
}
switch ( groupList [ i ] )
{
case 0 : selIdx = localFl ? 4 : 9 ; break ; // e-e group
case 1 : selIdx = localFl ? 2 : 7 ; break ; // hi/lo group
case 2 : selIdx = localFl ? 3 : 8 ; break ; // mid group
default :
{ assert ( 0 ) ; }
}
assert ( selIdx < ten ) ;
nsNcSelChV [ i ] = selIdx ;
nsNcSelChIdxV [ i ] = chIdxCntV [ selIdx ] ;
chIdxCntV [ selIdx ] + = 1 ;
}
if ( verboseFl )
{
cmVOI_PrintL ( " nsChSelChV " , err - > rpt , 1 , midiCnt , nsChSelChV ) ;
cmVOI_PrintL ( " nsChSelChIdxV " , err - > rpt , 1 , midiCnt , nsChSelChIdxV ) ;
cmVOI_PrintL ( " nsNcSelChV " , err - > rpt , 1 , midiCnt , nsNcSelChV ) ;
cmVOI_PrintL ( " nsNcSelChIdxV " , err - > rpt , 1 , midiCnt , nsNcSelChIdxV ) ;
}
if ( cmJsonInsertPairIntArray ( jsH , cmJsonRoot ( jsH ) , label1 = " nsChSelChV " , midiCnt , nsChSelChV ) ! = kOkJsRC )
{
rc = cmErrMsg ( err , kJsonFailDspRC , " The note selector resource '%s' could not be created. " , cmStringNullGuard ( label1 ) ) ;
goto errLabel ;
}
if ( cmJsonInsertPairIntArray ( jsH , cmJsonRoot ( jsH ) , label1 = " nsChSelChIdxV " , midiCnt , nsChSelChIdxV ) ! = kOkJsRC )
{
rc = cmErrMsg ( err , kJsonFailDspRC , " The note selector resource '%s' could not be created. " , cmStringNullGuard ( label1 ) ) ;
goto errLabel ;
}
if ( cmJsonInsertPairIntArray ( jsH , cmJsonRoot ( jsH ) , label1 = " nsNcSelChV " , midiCnt , nsNcSelChV ) ! = kOkJsRC )
{
rc = cmErrMsg ( err , kJsonFailDspRC , " The note selector resource '%s' could not be created. " , cmStringNullGuard ( label1 ) ) ;
goto errLabel ;
}
if ( cmJsonInsertPairIntArray ( jsH , cmJsonRoot ( jsH ) , label1 = " nsNcSelChIdxV " , midiCnt , nsNcSelChIdxV ) ! = kOkJsRC )
{
rc = cmErrMsg ( err , kJsonFailDspRC , " The note selector resource '%s' could not be created. " , cmStringNullGuard ( label1 ) ) ;
goto errLabel ;
}
for ( i = 0 ; i < ten ; + + i )
{
int midi [ midiCnt ] ;
int chan [ midiCnt ] ;
for ( j = 0 , k = 0 ; j < midiCnt ; + + j )
{
m = i ;
if ( m = = 1 | | m = = 6 )
m - = 1 ;
if ( nsChSelChV [ j ] = = m )
{
midi [ k ] = midiList [ j ] ;
chan [ k ] = j > 15 ? j - 16 : j ;
assert ( k = = nsChSelChIdxV [ j ] ) ;
+ + k ;
}
if ( nsNcSelChV [ j ] = = m )
{
midi [ k ] = midiList [ j ] ;
chan [ k ] = j > 15 ? j - 16 : j ;
assert ( k = = nsNcSelChIdxV [ j ] ) ;
+ + k ;
}
}
if ( cmJsonInsertPairIntArray ( jsH , cmJsonRoot ( jsH ) , label1 = cmTsPrintfS ( " nsMidi-%i " , i ) , k , midi ) ! = kOkJsRC )
{
rc = cmErrMsg ( err , kJsonFailDspRC , " The note selector resource '%s' could not be created. " , cmStringNullGuard ( label1 ) ) ;
goto errLabel ;
}
if ( verboseFl )
cmVOI_PrintL ( label1 , err - > rpt , 1 , k , midi ) ;
if ( cmJsonInsertPairIntArray ( jsH , cmJsonRoot ( jsH ) , label1 = cmTsPrintfS ( " nsChan-%i " , i ) , k , chan ) ! = kOkJsRC )
{
rc = cmErrMsg ( err , kJsonFailDspRC , " The note selector resource '%s' could not be created. " , cmStringNullGuard ( label1 ) ) ;
goto errLabel ;
}
if ( verboseFl )
cmVOI_PrintL ( label1 , err - > rpt , 1 , k , chan ) ;
}
}
errLabel :
return rc ;
}
const cmChar_t * _cmDspPP_SelCheckTitle ( cmDspSysH_t h , unsigned i )
{ return _cmDspPP_CircuitDesc ( i ) - > title ; }
cmDspRC_t _cmDspSysPgm_Main ( cmDspSysH_t h , void * * userPtrPtr )
{
cmDspRC_t rc = kOkDspRC ;
const cmChar_t * chCfgFn = NULL ;
cmCtx_t * cmCtx = cmDspSysPgmCtx ( h ) ;
double efOnThrDb = - 40 ;
double efOffThrDb = - 70 ;
double efMaxDb = - 15 ;
unsigned circuitCnt = _cmDspPP_CircuitDescCount ( ) ;
unsigned resetSymId = cmDspSysRegisterStaticSymbol ( h , " _reset " ) ;
bool inFileFl = false ;
cmErr_t err ;
_cmDspPP_Ctx_t ctx ;
cmDspPP_CircuitSwitch_t sw ;
memset ( & sw , 0 , sizeof ( sw ) ) ;
// set up the global context record
memset ( & ctx , 0 , sizeof ( ctx ) ) ;
ctx . oChCnt = 2 ;
ctx . err = & err ;
cmErrSetup ( & err , & cmCtx - > rpt , " PP Main " ) ;
// create the individual non-networked chord detector resource arrays from the base resource arrays
if ( ( rc = _cmDspPgm_Main_ProcRsrc ( h , & err ) ) ! = kOkDspRC )
goto errLabel ;
// create the individual networked chord detector resource arrays from the base resource arrays
if ( ( rc = _cmDspPgm_Main_NetProcRsrc ( h , & err ) ) ! = kOkDspRC )
goto errLabel ;
// get the channel cfg configuration file name
if ( cmJsonPathToString ( cmDspSysPgmRsrcHandle ( h ) , NULL , NULL , " chCfgFn " , & chCfgFn ) ! = kOkJsRC )
{
rc = cmErrMsg ( & err , kRsrcNotFoundDspRC , " The 'chCfgFn' resource was not found. " ) ;
goto errLabel ;
}
// get the count of channels from the ch. cfg. array
if ( ( ctx . iChCnt = cmChCfgChannelCount ( cmCtx , chCfgFn , & ctx . nsCnt ) ) = = 0 )
{
rc = cmErrMsg ( & err , kPgmCfgFailDspRC , " Unable to obtain the channel count from '%s'. " , cmStringNullGuard ( chCfgFn ) ) ;
goto errLabel ;
}
if ( rc = = kOkDspRC )
{
unsigned inChCnt , outChCnt ;
// channel cfg
ctx . chCfg = cmDspSysAllocInst ( h , " ChCfg " , NULL , 1 , chCfgFn ) ;
// global printer
ctx . print = cmDspSysAllocInst ( h , " Printer " , NULL , 1 , " > " ) ;
cmDspInst_t * * ain ;
cmDspInst_t * phs ;
// audio input
if ( inFileFl )
{
unsigned wtSmpCnt = ( unsigned ) cmDspSysSampleRate ( h ) ;
unsigned wtMode = 1 ; //file mode
const cmChar_t * fn = " /home/kevin/media/audio/gate_detect/gate_detect2.aif " ;
phs = cmDspSysAllocInst ( h , " Phasor " , NULL , 0 ) ;
ain = cmDspSysAllocInstArray ( h , ctx . iChCnt , " WaveTable " , NULL , NULL , 3 , wtSmpCnt , wtMode , fn ) ;
inChCnt = ctx . iChCnt ;
}
else
{
ain = cmDspSysAllocAudioInAR ( h , " audioInMap " , 1.0 , & inChCnt ) ;
}
// envelope followers and RMS meters
cmDspSysAllocLabel ( h , " EF Gates " , kLeftAlignDuiId ) ;
cmDspInst_t * * ef = cmDspSysAllocInstArray ( h , ctx . iChCnt , " EnvFollow " , NULL , NULL , 0 ) ;
cmDspInst_t * * mtr = cmDspSysAllocInstArray ( h , ctx . iChCnt , " Meter " , " mtr " , NULL , 3 , 0.0 , 0.0 , 1.0 ) ;
// Level meters
cmDspSysNewColumn ( h , 200 ) ;
cmDspSysAllocLabel ( h , " Level " , kLeftAlignDuiId ) ;
cmDspInst_t * * lvl = cmDspSysAllocInstArray ( h , ctx . iChCnt , " Meter " , " lvl " , NULL , 3 , 0.0 , 0.0 , 1.0 ) ;
assert ( inChCnt = = ctx . iChCnt ) ;
// Onset count displays
cmDspSysNewColumn ( h , 200 ) ;
cmDspInst_t * * onn = cmDspSysAllocInstArray ( h , ctx . iChCnt , " Scalar " , " on " , NULL , 5 , kNumberDuiId , 0.0 , 10000.0 , 1.0 , 0.0 ) ;
cmDspSysNewColumn ( h , 200 ) ;
// program reset button
cmDspInst_t * resetBtn = cmDspSysAllocButton ( h , " reset " , 0 ) ;
cmDspSysAssignInstAttrSymbol ( h , resetBtn , resetSymId ) ;
// circuit selection check-boxes
cmDspInst_t * * csel = cmDspSysAllocInstArray ( h , circuitCnt , " Button " , NULL , _cmDspPP_SelCheckTitle , 2 , kCheckDuiId , 0.0 ) ;
cmDspSysNewColumn ( h , 200 ) ;
cmDspSysAllocLabel ( h , " Out Gains " , kLeftAlignDuiId ) ;
// output gain controls
cmDspInst_t * * ogain = cmDspSysAllocInstArray ( h , ctx . oChCnt , " Scalar " , " mgain " , NULL , 5 , kNumberDuiId , 0.0 , 10.0 , 0.01 , 1.0 ) ;
// envelope follower parameters
cmDspInst_t * onThr = cmDspSysAllocScalar ( h , " On Thresh " , - 100.0 , 0.0 , 0.1 , efOnThrDb ) ;
cmDspInst_t * offThr = cmDspSysAllocScalar ( h , " Off Thresh " , - 100.0 , 0.0 , 0.1 , efOffThrDb ) ;
cmDspInst_t * maxDb = cmDspSysAllocScalar ( h , " Max Db " , - 100.0 , 0.0 , 0.1 , efMaxDb ) ;
// switcher and circuits
_cmDspPP_CircuitSwitchAlloc ( h , & ctx , & sw , resetBtn , csel , ain , ef ) ;
// audio output
cmDspInst_t * * aout = cmDspSysAllocAudioOutAR ( h , " audioOutMap " , 1.0 , & outChCnt ) ;
assert ( outChCnt = = ctx . oChCnt ) ;
//cmDspInst_t* prt = cmDspSysAllocInst( h, "Printer", NULL, 2, "", 250 );
// check for errors
if ( ( rc = cmDspSysLastRC ( h ) ) ! = kOkDspRC )
goto doneLabel ;
if ( inFileFl )
{
cmDspSysConnectAudio11N1 ( h , phs , " out " , ain , " phs " , ctx . iChCnt ) ; // phs -> wt
cmDspSysConnectAudioN1N1 ( h , ain , " out " , ef , " in " , ctx . iChCnt ) ; // wt -> EF
}
else
{
cmDspSysConnectAudioN1N1 ( h , ain , " out " , ef , " in " , ctx . iChCnt ) ; // ain -> EF
}
cmDspSysInstallCb1NN1 ( h , ctx . chCfg , " gain " , ain , " gain " , ctx . iChCnt ) ; // chCfg -> ain (gain)
cmDspSysConnectAudioN1N1 ( h , sw . omix , " out " , aout , " in " , ctx . oChCnt ) ; // Sw.mix -> aout
cmDspSysInstallCbN1N1 ( h , ogain , " val " , aout , " gain " , ctx . oChCnt ) ; // gain -> aout
cmDspSysInstallCb ( h , resetBtn , " sym " , ctx . chCfg , " sel " , NULL ) ; // reset -> chCfg
cmDspSysInstallCbN1N1 ( h , ef , " gate " , mtr , " in " , ctx . iChCnt ) ; // EF -> meter (gate)
cmDspSysInstallCbN1N1 ( h , ef , " level " , lvl , " in " , ctx . iChCnt ) ; // EF -> meter (level)
cmDspSysInstallCbN1N1 ( h , ef , " ons " , onn , " val " , ctx . iChCnt ) ;
cmDspSysInstallCb11N1 ( h , onThr , " val " , ef , " ondb " , ctx . iChCnt ) ; // EF sensivity settings
cmDspSysInstallCb11N1 ( h , offThr , " val " , ef , " offdb " , ctx . iChCnt ) ; //
cmDspSysInstallCb11N1 ( h , maxDb , " val " , ef , " maxdb " , ctx . iChCnt ) ; //
//cmDspSysInstallCbN111( h, ef, "level", prt, "in", ctx.iChCnt );
doneLabel :
_cmDspPP_CircuitSwitchFree ( h , & sw ) ;
}
errLabel :
if ( rc ! = kOkDspRC )
cmErrMsg ( & err , rc , " 'main' construction failed. " ) ;
return rc ;
}