Copyright (C) Kevin Larke 2009-2020

This file is part of libcm.

libcm is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

libcm is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

See the GNU General Public License distributed with the libcm package or look here: .


cmDspPgm : 'snap' programs.
#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 "cmPrefs.h"
#include "cmDspValue.h"
#include "cmMsgProtocol.h"
#include "cmThread.h"
#include "cmUdpPort.h"
#include "cmUdpNet.h"
#include "cmSerialPort.h"
#include "cmTime.h"
#include "cmAudioSys.h"
#include "cmProcObj.h"
#include "cmPP_NARG.h"
#include "cmDspCtx.h"
#include "cmDspClass.h"
#include "cmDspSys.h"
#include "cmDspPgm.h"
#include "cmDspPgmPP.h"
#include "cmDspPgmKr.h"
cmDspPgm_ReflecCalc : Acoustic time-of-flight measurement program.

cmDspRC_t _cmDspSysPgm_ReflectCalc( cmDspSysH_t h, void** userPtrPtr )
{
  
  // audio inputs
  cmDspInst_t* ai0  = cmDspSysAllocInst(h,"AudioIn", NULL,   1, 0 );
  cmDspInst_t* ai1  = cmDspSysAllocInst(h,"AudioIn", NULL,   1, 1 );
  
  cmDspInst_t* rc0   = cmDspSysAllocInst(h,"ReflectCalc", NULL, 0 );
  //cmDspInst_t* rc1   = cmDspSysAllocInst(h,&quotReflectCalc&quot, NULL, 0 );
  
  // audio outputs
  cmDspInst_t* ao0 = cmDspSysAllocInst(h,"AudioOut",NULL,   1, 0 );
  cmDspInst_t* ao1 = cmDspSysAllocInst(h,"AudioOut",NULL,   1, 1 );
  
  // input meters
  cmDspInst_t* im0 = cmDspSysAllocInst(h,"AMeter","In 0",  0);
  cmDspInst_t* im1 = cmDspSysAllocInst(h,"AMeter","In 1",  0);
  
  // output meters
  //cmDspInst_t* om0 = cmDspSysAllocInst(h,&quotAMeter&quot,&quotOut 0&quot, 0);
  //cmDspInst_t* om1 = cmDspSysAllocInst(h,&quotAMeter&quot,&quotOut 1&quot,0);  
  
  // gain controls
  cmDspInst_t* igain = cmDspSysAllocInst( h,"Scalar", "In Gain",  5, kNumberDuiId, 0.0,  4.0, 0.01,  1.0);
  cmDspInst_t* ogain = cmDspSysAllocInst( h,"Scalar", "Out Gain", 5, kNumberDuiId, 0.0,  4.0, 0.01,  3.0);
  
  cmDspSysConnectAudio(h, ai0, "out", im0, "in");            // ain0 -&gt imtr0
  cmDspSysConnectAudio(h, ai1, "out", im1, "in");            // ain1 -&gt imtr1
  
  cmDspSysInstallCb(   h, igain,"val", ai0, "gain", NULL);   // igain -&gt ain0
  cmDspSysInstallCb(   h, igain,"val", ai1, "gain", NULL);   // igain -&gt ain0
  
  cmDspSysInstallCb(   h, ogain,"val", ao0, "gain", NULL);   // igain -&gt ain0
  cmDspSysInstallCb(   h, ogain,"val", ao1, "gain", NULL);   // igain -&gt ain0
  
  
  cmDspSysConnectAudio(h, ai0,"out", rc0, "in" );  
  cmDspSysConnectAudio(h, rc0,"out", ao0, "in" );
  
  cmDspSysConnectAudio(h, ai1,"out", ao1, "in" );
  
  return kOkDspRC;
}


cmDspPgm_SyncRecd : Generate MIDI / Audio synchronization data with cmDspSyncRecd.

cmDspRC_t _cmDspSysPgm_SyncRecd(  cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t rc = kOkDspRC;
  unsigned audioFileBits = 24;
  
  cmDspInst_t* ai0p   = cmDspSysAllocInst(h,"AudioIn", NULL,   1, 0 );
  cmDspInst_t* ai1p   = cmDspSysAllocInst(h,"AudioIn", NULL,   1, 1 );
  cmDspInst_t* mip    = cmDspSysAllocInst(h,"MidiIn",  NULL,   0 );
  cmDspInst_t* srp    = cmDspSysAllocInst(h,"SyncRecd",NULL,   3, "/home/kevin/temp/kr/sr","sr","audio",audioFileBits);
  cmDspInst_t* am0p   = cmDspSysAllocInst(h,"AMeter",  "Left", 0);
  cmDspInst_t* am1p   = cmDspSysAllocInst(h,"AMeter",  "Right",0);
  cmDspInst_t* ao0p   = cmDspSysAllocInst(h,"AudioOut", NULL,  1, 0 );
  cmDspInst_t* ao1p   = cmDspSysAllocInst(h,"AudioOut", NULL,  1, 1 );
  
  cmDspInst_t* chk    = cmDspSysAllocInst(h,"Checkbox","recd", 5, "Recd","open","close", 1.0, 0.0);
  cmDspInst_t* gain0 = cmDspSysAllocInst(h,"Scalar", "In Gain-0",    5, kNumberDuiId, 0.0,   10.0,0.01,   1.0 );  
  cmDspInst_t* gain1 = cmDspSysAllocInst(h,"Scalar", "In Gain-1",    5, kNumberDuiId, 0.0,   10.0,0.01,   1.0 );  
  
  
  // check for allocation errors
  if((rc = cmDspSysLastRC(h)) != kOkDspRC )
    goto errLabel;
  
  cmDspSysInstallCb(h, mip,   "status", srp, "status", NULL);
  cmDspSysInstallCb(h, mip,   "d0",     srp, "d0",     NULL);
  cmDspSysInstallCb(h, mip,   "d1",     srp, "d1",     NULL);
  cmDspSysInstallCb(h, mip,   "sec",    srp, "sec",    NULL);
  cmDspSysInstallCb(h, mip,   "nsec",   srp, "nsec",   NULL);
  cmDspSysInstallCb(h, chk,   "sym",    srp, "cmd",    NULL);
  cmDspSysInstallCb(h, gain0, "val",   ai0p, "gain",   NULL);
  cmDspSysInstallCb(h, gain1, "val",   ai1p, "gain",   NULL);
  
  cmDspSysConnectAudio(h, ai0p, "out", srp,  "ain-0");
  cmDspSysConnectAudio(h, ai1p, "out", srp,  "ain-1");
  cmDspSysConnectAudio(h, ai0p, "out", am0p, "in");
  cmDspSysConnectAudio(h, ai1p, "out", am1p, "in");
  cmDspSysConnectAudio(h, ai0p, "out", ao0p, "in");
  cmDspSysConnectAudio(h, ai1p, "out", ao1p, "in");
  
  errLabel:
  return rc;
  
}


cmDspPgm_MidiFilePlay : MIDI file player example program.
cmDspRC_t _cmDspSysPgm_MidiFilePlay( cmDspSysH_t h, void** userPtrPtr )
{
  
  cmDspRC_t rc = kOkDspRC;
  
  
  const cmChar_t* deviceName = "Scarlett 18i20 USB";
  const cmChar_t* portName   = "Scarlett 18i20 USB MIDI 1";
  
  //const cmChar_t* deviceName = &quotFastlane"
  //const cmChar_t* portName   = &quotFastlane MIDI A"  
  
  //const cmChar_t* deviceName = &quotDKV-M4"
  //const cmChar_t* portName   = &quotDKV-M4 MIDI 1"  
  
  const char*     fn0   = "media/audio/midi/988-v25.mid";
  const cmChar_t* fn    = cmFsMakeFn(cmFsUserDir(),fn0,NULL,NULL );
  cmDspInst_t* fnp =  cmDspSysAllocInst(h,"Fname",    NULL,  3, false,"MIDI Files (*.mid)\tMIDI Files (*.{mid})",fn);
  
  cmDspInst_t* ignp = cmDspSysAllocInst( h,"Scalar", "In Gain",  5, kNumberDuiId, 0.0,  4.0, 0.01,  1.0);
  
  cmDspInst_t* ai0p = cmDspSysAllocInst(h,"AudioIn", NULL,   1, 2 );
  cmDspInst_t* ai1p = cmDspSysAllocInst(h,"AudioIn", NULL,   1, 3 );
  
  cmDspInst_t* mfp   = cmDspSysAllocInst(h,"MidiFilePlay",NULL,  0 );
  cmDspInst_t* pic   = cmDspSysAllocInst(h,"Picadae",     NULL,  0 );
  cmDspInst_t* mop   = cmDspSysAllocInst( h,"MidiOut",    NULL,  2, deviceName, portName);
  
  cmDspInst_t* start = cmDspSysAllocInst( h,"Button", "start",    2, kButtonDuiId, 0.0 );
  cmDspInst_t* stop  = cmDspSysAllocInst( h,"Button", "stop",     2, kButtonDuiId, 0.0 );
  cmDspInst_t* cont  = cmDspSysAllocInst( h,"Button", "continue", 2, kButtonDuiId, 0.0 );
  
  cmDspInst_t* beg = cmDspSysAllocInst(h,"Scalar", "Beg Samp",    5, kNumberDuiId, 0.0, 1000000000.0, 1.0,   0.0 );  
  cmDspInst_t* end = cmDspSysAllocInst(h,"Scalar", "End Samp",    5, kNumberDuiId, 0.0, 1000000000.0, 1.0,   1000000000.0 );  
  
  cmDspInst_t* ao0p = cmDspSysAllocInst(h,"AudioOut",NULL,   1, 2 );
  cmDspInst_t* ao1p = cmDspSysAllocInst(h,"AudioOut",NULL,   1, 3 );
  cmDspInst_t* ao2p = cmDspSysAllocInst(h,"AudioOut",NULL,   1, 4 );
  cmDspInst_t* ao3p = cmDspSysAllocInst(h,"AudioOut",NULL,   1, 5 );
  
  cmDspInst_t* im0p = cmDspSysAllocInst(h,"AMeter","In 0",  0);
  cmDspInst_t* im1p = cmDspSysAllocInst(h,"AMeter","In 1", 0);
  
  cmDspInst_t* om0p = cmDspSysAllocInst(h,"AMeter","Out 0", 0);
  cmDspInst_t* om1p = cmDspSysAllocInst(h,"AMeter","Out 1",0);
  cmDspInst_t* om2p = cmDspSysAllocInst(h,"AMeter","Out 2", 0);
  cmDspInst_t* om3p = cmDspSysAllocInst(h,"AMeter","Out 3",0);
  
  
  // check for allocation errors
  if((rc = cmDspSysLastRC(h)) != kOkDspRC )
    goto errLabel;
  
  cmDspSysInstallCb(   h, fnp, "out", mfp, "fn", NULL);    
  
  
  cmDspSysInstallCb(   h, start, "sym",   beg, "send",   NULL);
  cmDspSysInstallCb(   h, beg,   "val",   mfp, "bsi",    NULL);
  
  cmDspSysInstallCb(   h, start, "sym",   end, "send",   NULL);
  cmDspSysInstallCb(   h, end,   "val",   mfp, "esi",    NULL);
  
  cmDspSysInstallCb(   h, start, "sym",   mfp, "sel",    NULL);
  cmDspSysInstallCb(   h, stop,  "sym",   mfp, "sel",    NULL);
  cmDspSysInstallCb(   h, cont,  "sym",   mfp, "sel",    NULL);
  
  bool usePicadaeFl = false;
  
  if( usePicadaeFl )
  {
    cmDspSysInstallCb(   h, mfp,  "d1",     pic, "d1",     NULL);
    cmDspSysInstallCb(   h, mfp,  "d0",     pic, "d0",     NULL);
    cmDspSysInstallCb(   h, mfp,  "status", pic, "status", NULL);
    
    cmDspSysInstallCb(   h, pic,  "d1",     mop, "d1",     NULL);
    cmDspSysInstallCb(   h, pic,  "d0",     mop, "d0",     NULL);
    cmDspSysInstallCb(   h, pic,  "status", mop, "status", NULL);
  }
  else
  {
    cmDspSysInstallCb(   h, mfp,  "d1",     mop, "d1",     NULL);
    cmDspSysInstallCb(   h, mfp,  "d0",     mop, "d0",     NULL);
    cmDspSysInstallCb(   h, mfp,  "status", mop, "status", NULL);
  }
  
  //cmDspSysConnectAudio(h, ai0p, &quotout&quot, ao0p, &quotin&quot); 
  //cmDspSysConnectAudio(h, ai1p, &quotout&quot, ao1p, &quotin&quot);   
  
  cmDspSysConnectAudio(h, ai0p, "out", im0p, "in");          // ain0 -&gt imtr0
  cmDspSysConnectAudio(h, ai1p, "out", im1p, "in");          // ain1 -&gt imtr1
  
  cmDspSysInstallCb(   h, ignp,"val", ai0p, "gain", NULL);   // igain -&gt ain0
  cmDspSysConnectAudio(h, ai0p,"out", ao0p, "in" );          // ain0 -&gt aout0 
  cmDspSysConnectAudio(h, ai0p,"out", om0p, "in" );          // ain0 -&gt omtr0 
  
  cmDspSysInstallCb(   h, ignp,"val", ai1p, "gain", NULL);   // igain -&gt ain1
  cmDspSysConnectAudio(h, ai1p,"out", ao1p, "in" );          // ain1 -&gt aout1 
  cmDspSysConnectAudio(h, ai1p,"out", om1p, "in" );          // ain1 -&gt omtr1 
  
  cmDspSysConnectAudio(h, ai0p,"out", ao2p, "in" );          // ain0 -&gt aout2 
  cmDspSysConnectAudio(h, ai0p,"out", om2p, "in" );          // ain0 -&gt omtr0
  
  cmDspSysConnectAudio(h, ai1p,"out", ao3p, "in" );          // ain1 -&gt aout3 
  cmDspSysConnectAudio(h, ai1p,"out", om3p, "in" );          // ain0 -&gt omtr0 
  
  errLabel:
  
  cmFsFreeFn(fn);
  
  return rc;
}



cmDspPgm_Test_Midi : MIDI input/output example program.
cmDspRC_t _cmDspSysPgm_Test_Midi( cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t rc = kOkDspRC;
  
  const cmChar_t* deviceName = "Fastlane";
  const cmChar_t* portName   = "Fastlane MIDI A";
  
  #ifdef OS_OSX
  
  deviceName = "MOTU - FastLane USB";
  portName   = "Port A";
  
  //deviceName = &quotRME - Fireface UFX (23148636)"
  //portName   = &quotPort 2"  
  
  #endif
  
  cmDspInst_t* sendBtn = cmDspSysAllocInst( h,"Button", "Send",    2, kButtonDuiId, 0.0 );
  cmDspInst_t* status  = cmDspSysAllocInst( h,"Scalar", "Status",  5, kNumberDuiId, 0.0,  127.0, 1.0, 144.0);
  cmDspInst_t* d0      = cmDspSysAllocInst( h,"Scalar", "D0",      5, kNumberDuiId, 0.0,  127.0, 1.0,  64.0);
  cmDspInst_t* d1      = cmDspSysAllocInst( h,"Scalar", "D1",      5, kNumberDuiId, 0.0,  127.0, 1.0,  64.0);
  cmDspInst_t* midiOut = cmDspSysAllocInst( h,"MidiOut", NULL,     2, deviceName, portName);
  
  cmDspInst_t* midiIn  = cmDspSysAllocInst( h,"MidiIn",  NULL,     0 );
  //cmDspInst_t* printer = cmDspSysAllocInst( h,&quotPrinter&quot, NULL,     1, &quot&gt&quot );
  cmDspInst_t* prst = cmDspSysAllocInst( h,"Printer", NULL,     1, "st>" );
  cmDspInst_t* prd0 = cmDspSysAllocInst( h,"Printer", NULL,     1, "d0>" );
  cmDspInst_t* prd1 = cmDspSysAllocInst( h,"Printer", NULL,     1, "d1>" );
  
  // check for allocation errors
  if((rc = cmDspSysLastRC(h)) != kOkDspRC )
    goto errLabel;
  
  cmDspSysInstallCb(   h, sendBtn, "out", d1,      "send", NULL);
  cmDspSysInstallCb(   h, sendBtn, "out", d0,      "send", NULL);
  cmDspSysInstallCb(   h, sendBtn, "out", status,  "send", NULL);
  
  cmDspSysInstallCb(   h, status,  "val", midiOut, "status",NULL);
  cmDspSysInstallCb(   h, d0,      "val", midiOut, "d0",    NULL);
  cmDspSysInstallCb(   h, d1,      "val", midiOut, "d1",    NULL);
  
  cmDspSysInstallCb(   h, midiIn,  "status", prst, "in", NULL);
  cmDspSysInstallCb(   h, midiIn,  "d0",     prd0, "in", NULL);
  cmDspSysInstallCb(   h, midiIn,  "d1",     prd1, "in", NULL);
  //cmDspSysInstallCb(   h, midiIn,  &quotsmpidx&quot, printer, &quotin&quot, NULL);
  
  errLabel:
  return rc;
  
}


cmDspPgm_Test_Pedals : MIDI input/output example program.
cmDspRC_t _cmDspSysPgm_Test_Pedals( cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t rc = kOkDspRC;
  
  //const cmChar_t* deviceName = &quotFastlane"
  //const cmChar_t* portName   = &quotFastlane MIDI A"  
  
  const cmChar_t* deviceName = "Apple Inc. - IAC Driver";
  const cmChar_t* portName   = "Bus 1";
  
  //deviceName = &quotMOTU - FastLane USB"
  //portName   = &quotPort A"  
  
  //deviceName = &quotRME - Fireface UFX (23148636)"
  //portName   = &quotPort 2"  
  
  cmDspInst_t* ai0 = cmDspSysAllocInst(h,"AudioIn", NULL,   1, 0 );
  cmDspInst_t* ai1 = cmDspSysAllocInst(h,"AudioIn", NULL,   1, 1 );
  
  cmDspInst_t* on0 = cmDspSysAllocButton( h, "Note On 1", 1.0 );
  cmDspInst_t* of0 = cmDspSysAllocButton( h, "Off 1    ", 2.0 );
  cmDspInst_t* on1 = cmDspSysAllocButton( h, "Note On 2", 3.0 );
  cmDspInst_t* of1 = cmDspSysAllocButton( h, "Off 2    ", 4.0 );
  cmDspInst_t* dm1 = cmDspSysAllocButton( h, "Damp On  ", 5.0 );
  cmDspInst_t* dm0 = cmDspSysAllocButton( h, "Damp Off ", 6.0 );
  cmDspInst_t* sf1 = cmDspSysAllocButton( h, "Soft On  ", 5.0 );
  cmDspInst_t* sf0 = cmDspSysAllocButton( h, "Soft Off ", 6.0 );
  cmDspInst_t* so1 = cmDspSysAllocButton( h, "Sost On  ", 5.0 );
  cmDspInst_t* so0 = cmDspSysAllocButton( h, "Sost Off ", 6.0 );
  
  cmDspInst_t* lst = cmDspSysAllocInst(   h, "MsgList","Seq", 1, "note_list");  
  cmDspInst_t* mop = cmDspSysAllocInst(   h, "MidiOut",  NULL, 2, deviceName, portName);
  
  cmDspInst_t* ao0 = cmDspSysAllocInst(h,"AudioOut", NULL,   1, 2 );
  cmDspInst_t* ao1 = cmDspSysAllocInst(h,"AudioOut", NULL,   1, 3 );
  
  //cmDspInst_t* prt = cmDspSysAllocInst( h,&quotPrinter&quot, NULL, 1, &quot&quot );
  
  // check for allocation errors
  if((rc = cmDspSysLastRC(h)) != kOkDspRC )
    goto errLabel;
  
  cmDspSysConnectAudio( h, ai0, "out", ao0, "in" );
  cmDspSysConnectAudio( h, ai1, "out", ao1, "in" );
  
  cmDspSysInstallCb(  h, on0, "out", lst, "sel", NULL );
  cmDspSysInstallCb(  h, of0, "out", lst, "sel", NULL );
  cmDspSysInstallCb(  h, on1, "out", lst, "sel", NULL );
  cmDspSysInstallCb(  h, of1, "out", lst, "sel", NULL );
  cmDspSysInstallCb(  h, dm1, "out", lst, "sel", NULL );
  cmDspSysInstallCb(  h, dm0, "out", lst, "sel", NULL );
  cmDspSysInstallCb(  h, sf1, "out", lst, "sel", NULL );
  cmDspSysInstallCb(  h, sf0, "out", lst, "sel", NULL );
  cmDspSysInstallCb(  h, so1, "out", lst, "sel", NULL );
  cmDspSysInstallCb(  h, so0, "out", lst, "sel", NULL );
  
  //cmDspSysInstallCb(   h, lst,     &quotd1&quot,     prt,     &quotin&quot, NULL );
  //cmDspSysInstallCb(   h, lst,     &quotd0&quot,     prt,     &quotin&quot, NULL );
  //cmDspSysInstallCb(   h, lst,     &quotstatus&quot, prt,     &quotin&quot, NULL );  
  
  
  cmDspSysInstallCb(   h, lst,  "d1",     mop, "d1",     NULL);
  cmDspSysInstallCb(   h, lst,  "d0",     mop, "d0",     NULL);
  cmDspSysInstallCb(   h, lst,  "status", mop, "status", NULL);
  
  
  errLabel:
  return rc;
  
}


cmDspPgm_Stereo_Through : Stereo audio through example program.
cmDspRC_t _cmDspSysPgm_Stereo_Through( cmDspSysH_t h, void** userPtrPtr )
{
  
  cmDspInst_t* ignp = cmDspSysAllocInst( h,"Scalar", "In Gain",  5, kNumberDuiId, 0.0,  4.0, 0.01,  0.0);
  //cmDspInst_t* ognp = cmDspSysAllocInst( h,&quotScalar&quot, &quotOut Gain&quot, 5, kNumberDuiId, 0.0,  4.0, 0.01,  1.0);
  cmDspInst_t* hzp  =  cmDspSysAllocInst(h,"Scalar", "Hz",       5, kNumberDuiId, 0.0, 10.0, 0.001, 1.0);
  
  cmDspInst_t* php =  cmDspSysAllocInst(h,"Phasor",   NULL,  0 );
  cmDspInst_t* wtp =  cmDspSysAllocInst(h,"WaveTable",NULL,  2, cmDspSysSampleRate(h), 2 );
  
  cmDspInst_t* ai0p = cmDspSysAllocInst(h,"AudioIn", NULL,   1, 2 );
  cmDspInst_t* ai1p = cmDspSysAllocInst(h,"AudioIn", NULL,   1, 3 );
  
  // MOTU Traveler: Use channels 2&amp3 (out plugs:3&amp4) because 0&amp1 do not show up on plugs 1&amp2.
  cmDspInst_t* ao0p = cmDspSysAllocInst(h,"AudioOut",NULL,   1, 2 );
  cmDspInst_t* ao1p = cmDspSysAllocInst(h,"AudioOut",NULL,   1, 3 );
  
  cmDspInst_t* im0p = cmDspSysAllocInst(h,"AMeter","In 0",  0);
  cmDspInst_t* im1p = cmDspSysAllocInst(h,"AMeter","In 1", 0);
  
  cmDspInst_t* om0p = cmDspSysAllocInst(h,"AMeter","Out 0", 0);
  cmDspInst_t* om1p = cmDspSysAllocInst(h,"AMeter","Out 1",0);
  
  //cmDspSysConnectAudio(h, ai0p, &quotout&quot, ao0p, &quotin&quot); 
  //cmDspSysConnectAudio(h, ai1p, &quotout&quot, ao1p, &quotin&quot);   
  
  cmDspSysConnectAudio(h, ai0p, "out", im0p, "in");          // ain0 -&gt imtr0
  cmDspSysConnectAudio(h, ai1p, "out", im1p, "in");          // ain1 -&gt imtr1
  
  if(0)
  {
    cmDspSysInstallCb(   h, hzp, "val", php, "mult", NULL);    // hz -&gt phs
    cmDspSysConnectAudio(h, php, "out", wtp, "phs" );          // phs -&gt wt
    cmDspSysConnectAudio(h, wtp, "out", ao0p, "in"  );         // wt -&gt aout0
    cmDspSysConnectAudio(h, wtp, "out", om0p, "in" );          // wt -&gt omtr0
  }
  else
  {
    cmDspSysInstallCb(   h, ignp,"val", ai0p, "gain", NULL);   // igain -&gt ain0
    cmDspSysConnectAudio(h, ai0p,"out", ao0p, "in" );          // ain0 -&gt aout0 
    cmDspSysConnectAudio(h, ai0p,"out", om0p, "in" );          // ain0 -&gt omtr0 
  }
  
  cmDspSysInstallCb(   h, ignp,"val", ai1p, "gain", NULL);   // igain -&gt ain1
  cmDspSysConnectAudio(h, ai1p,"out", ao1p, "in" );          // ain1 -&gt aout1 
  cmDspSysConnectAudio(h, ai1p,"out", om1p, "in" );          // ain1 -&gt omtr1 
  return kOkDspRC;
}


cmDspSysPgm_All_In_And_Out : Meter all the input channels and pass two channels to the output.
cmDspRC_t _cmDspSysPgm_All_In_And_Out( cmDspSysH_t h, void** userPtrPtr )
{
  cmDspInst_t* ignp = cmDspSysAllocInst( h,"Scalar", "In Gain",  5, kNumberDuiId, 0.0,  4.0, 0.01,  1.0);
  
  const unsigned inN = 18;
  
  cmDspInst_t* ainA[inN];
  cmDspInst_t* aoutA[inN];
  cmDspInst_t* imtrA[inN];
  
  int i;
  for(i=0;i<inN; ++i)
  {
    char label[32];
    snprintf(label,32,"in %i",i);
    ainA[i]  = cmDspSysAllocInst(h,"AudioIn", NULL,   1, i );
    imtrA[i] = cmDspSysAllocInst(h,"AMeter",label,  0);
    aoutA[i]  = cmDspSysAllocInst(h,"AudioOut", NULL,   1, i );
  }
  
  for(i=0; i<inN; ++i)
  {
    cmDspSysInstallCb(   h, ignp,   "val", ainA[i], "gain", NULL);   // igain -&gt ain
    cmDspSysConnectAudio(h, ainA[i],"out", imtrA[i], "in" );          // ain -&gt imtr 
    cmDspSysConnectAudio(h, ainA[i],"out", aoutA[i], "in" );          // ain -&gt aout 
  }
  
  
  return kOkDspRC;
}



cmDspPgm_Stereo_Fx : Stereo audio effects example program.
cmDspRC_t _cmDspSysPgm_Stereo_Fx( cmDspSysH_t h, void** userPtrPtr )
{
  bool useBuiltInFl = true;
  
  cmDspInst_t* ignp = cmDspSysAllocInst( h,"Scalar", "In Gain",  5, kNumberDuiId, 0.0,  4.0, 0.01,  1.0);
  cmDspInst_t* ognp = cmDspSysAllocInst( h,"Scalar", "Out Gain", 5, kNumberDuiId, 0.0,  4.0, 0.01,  1.0);
  
  //cmDspInst_t* fb0p = cmDspSysAllocInst( h,&quotScalar&quot, &quotFeeback 0&quot,  5, kNumberDuiId, 0.0,  1.0, 0.001,  0.0);
  //cmDspInst_t* fb1p = cmDspSysAllocInst( h,&quotScalar&quot, &quotFeedback 1&quot, 5, kNumberDuiId, 0.0,  1.0, 0.001,  0.0);  
  
  //cmDspInst_t* tm0p = cmDspSysAllocInst( h,&quotScalar&quot, &quotTime 0&quot,  5, kNumberDuiId, 0.0,  1000.0, 0.0001,  10.0);
  //cmDspInst_t* tm1p = cmDspSysAllocInst( h,&quotScalar&quot, &quotTime 1&quot,  5, kNumberDuiId, 0.0,  1000.0, 0.0001,  10.0);  
  
  cmDspInst_t* rt0p = cmDspSysAllocInst( h,"Scalar", "Ratio 0",  5, kNumberDuiId, 0.01,  10.0, 0.01,  1.0);
  cmDspInst_t* rt1p = cmDspSysAllocInst( h,"Scalar", "Ratio 1",  5, kNumberDuiId, 0.01,  10.0, 0.01,  1.0);
  
  cmDspInst_t* ai0p = cmDspSysAllocInst(h,"AudioIn", NULL,   1, useBuiltInFl ? 0 : 2 );
  cmDspInst_t* ai1p = cmDspSysAllocInst(h,"AudioIn", NULL,   1, useBuiltInFl ? 1 : 3 );
  
  cmDspInst_t* om0p = cmDspSysAllocInst(h,"AMeter","Out Left", 0);
  cmDspInst_t* om1p = cmDspSysAllocInst(h,"AMeter","Out Right",0);
  
  //cmDspInst_t* dy0p = cmDspSysAllocInst(h,&quotDelay&quot, NULL, 2, 1000.0, 0.5 );
  //cmDspInst_t* dy1p = cmDspSysAllocInst(h,&quotDelay&quot, NULL, 2, 2000.0, 0.7 );  
  
  cmDspInst_t* ps0p = cmDspSysAllocInst(h,"PShift", NULL, 0 );
  cmDspInst_t* ps1p = cmDspSysAllocInst(h,"PShift", NULL, 0 );
  
  // MOTU Traveler: Use channels 2&amp3 (out plugs:3&amp4) because 0&amp1 do not show up on plugs 1&amp2.
  cmDspInst_t* ao0p = cmDspSysAllocInst(h,"AudioOut",NULL,   1, useBuiltInFl ? 0 : 2 );
  cmDspInst_t* ao1p = cmDspSysAllocInst(h,"AudioOut",NULL,   1, useBuiltInFl ? 1 : 3 );
  
  
  
  cmDspSysConnectAudio(h, ai0p,"out", om0p, "in" );   // input meter connection
  cmDspSysConnectAudio(h, ai1p,"out", om1p, "in" );
  
  //cmDspSysConnectAudio(h, ai0p,&quotout&quot, dy0p, &quotin&quot );  // input -&gt delay
  //cmDspSysConnectAudio(h, ai1p,&quotout&quot, dy1p, &quotin&quot );  
  
  
  cmDspSysConnectAudio(h, ai0p,"out", ps0p, "in" );   // delay -&gt pshift
  cmDspSysConnectAudio(h, ai1p,"out", ps1p, "in" );
  
  cmDspSysConnectAudio(h, ps0p,"out", ao0p, "in" );  // pshift -&gt output
  cmDspSysConnectAudio(h, ps1p,"out", ao1p, "in" );
  
  //cmDspSysConnectAudio(h, dy0p,&quotout&quot, ao0p, &quotin&quot ); // delay -&gt output
  //cmDspSysConnectAudio(h, dy1p,&quotout&quot, ao1p, &quotin&quot );  
  
  cmDspSysInstallCb(   h, ignp,"val", ai0p, "gain", NULL);   // input gain
  cmDspSysInstallCb(   h, ignp,"val", ai1p, "gain", NULL);
  
  cmDspSysInstallCb(   h, ognp, "val", ao0p, "gain", NULL);   // output gain
  cmDspSysInstallCb(   h, ognp, "val", ao1p, "gain", NULL);  
  
  //cmDspSysInstallCb(   h, fb0p, &quotval&quot, dy0p, &quotfb&quot, NULL);  // feedback
  //cmDspSysInstallCb(   h, fb1p, &quotval&quot, dy1p, &quotfb&quot, NULL);    
  
  //cmDspSysInstallCb(   h, tm0p, &quotval&quot, dy0p, &quottime&quot, NULL);  // delay time
  //cmDspSysInstallCb(   h, tm1p, &quotval&quot, dy1p, &quottime&quot, NULL);    
  
  cmDspSysInstallCb(   h, rt0p, "val", ps0p, "ratio", NULL);   // pitch ratio
  cmDspSysInstallCb(   h, rt1p, "val", ps1p, "ratio", NULL);  
  
  return kOkDspRC;
}


cmDspPgm_PlaySine : Play a sine signal.
cmDspRC_t _cmDspSysPgm_PlaySine( cmDspSysH_t h, void** userPtrPtr )
{
  bool useBuiltInFl = true;
  double frqHz = 440.0;
  
  cmDspInst_t* chp = cmDspSysAllocInst( h,"Scalar", "Channel",  5, kNumberDuiId, 0.0,  100.0, 1.0,  0.0);
  cmDspInst_t* php =  cmDspSysAllocInst(h,"Phasor",    NULL,   2, cmDspSysSampleRate(h), frqHz );
  cmDspInst_t* wtp =  cmDspSysAllocInst(h,"WaveTable", NULL,   2, ((int)cmDspSysSampleRate(h)), 4);
  cmDspInst_t* ao0p = cmDspSysAllocInst(h,"AudioOut",  NULL,   1, useBuiltInFl ? 0 : 2 );
  cmDspInst_t* ao1p = cmDspSysAllocInst(h,"AudioOut",  NULL,   1, useBuiltInFl ? 1 : 3 );
  cmDspInst_t* om0p = cmDspSysAllocInst(h,"AMeter","Out", 0);
  
  cmDspInst_t* gain= cmDspSysAllocInst( h,"Scalar", "Gain",     5, kNumberDuiId, 0.0,  10.0,  0.01,  0.0);
  
  cmDspSysConnectAudio(h, php, "out", wtp,  "phs" );   // phasor -&gt wave table
  cmDspSysConnectAudio(h, wtp, "out", ao0p, "in" );    // wave table -&gt audio out
  cmDspSysConnectAudio(h, wtp, "out", ao1p, "in" );    
  cmDspSysConnectAudio(h, wtp, "out", om0p, "in" );
  
  cmDspSysInstallCb( h, chp, "val", ao0p, "ch", NULL);
  cmDspSysInstallCb( h, gain, "val", ao0p, "gain", NULL);
  cmDspSysInstallCb( h, gain, "val", ao1p, "gain", NULL);
  
  return kOkDspRC;
}

cmDspRC_t _cmDspSysPgm_PlayFile( cmDspSysH_t h, void** userPtrPtr )
{
  bool            useBuiltInFl = true;
  //const char*     fn0          = &quotmedia/audio/20110723-Kriesberg/Audio Files/Piano 3_01.wav&quot;
  const char*     fn0 = "media/audio/sourcetone/Ella & Louis - Under A Blanket Of Blue";
  //int             beg          = 6900826;
  //int             end          = 13512262;  
  const cmChar_t* fn           = cmFsMakeFn(cmFsUserDir(),fn0,NULL,NULL );
  
  cmDspInst_t* ofp =  cmDspSysAllocInst(h,"Scalar", "Offset",  5, kNumberDuiId, 0.0,  cmDspSysSampleRate(h)*600.0, 1.0,  0.0);
  cmDspInst_t* fnp =  cmDspSysAllocInst(h,"Fname",    NULL,  3, false,"Audio Files (*.wav,*.aiff,*.aif)\tAudio Files (*.{wav,aiff,aif})",fn);
  cmDspInst_t* php =  cmDspSysAllocInst(h,"Phasor",   NULL,  0 );
  cmDspInst_t* wtp =  cmDspSysAllocInst(h,"WaveTable",NULL,  2, ((int)cmDspSysSampleRate(h)), 1 );
  //cmDspInst_t* afp =  cmDspSysAllocInst(h,&quotAudioFileOut&quot,NULL,2,&quot/home/kevin/temp/record0.aif&quot,1);
  
  cmDspInst_t* ao0p = cmDspSysAllocInst(h,"AudioOut",NULL,   1, useBuiltInFl ? 0 : 2 );
  cmDspInst_t* ao1p = cmDspSysAllocInst(h,"AudioOut",NULL,   1, useBuiltInFl ? 1 : 3 );
  
  
  cmDspSysConnectAudio(h, php, "out", wtp,  "phs" );   // phasor -&gt wave table
  cmDspSysConnectAudio(h, wtp, "out", ao0p, "in" );    // wave table -&gt audio out
  cmDspSysConnectAudio(h, wtp, "out", ao1p, "in" );    
  
  //cmDspSysConnectAudio(h, wtp, &quotout&quot, afp,  &quotin0&quot); 
  
  cmDspSysInstallCb(h, ofp, "val", wtp, "beg", NULL ); 
  cmDspSysInstallCb(h, fnp, "out", wtp, "fn", NULL);    
  return kOkDspRC;
}



cmDspPgm_MultiOut : Play to multiple output channels example program.
cmDspRC_t _cmDspSysPgm_MultiOut( cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t    rc           = kOkDspRC;
  double       frqHz        = 440.0;
  unsigned     chCnt        = 8;
  unsigned     oneOfN_chCnt = 2;
  double       offs         = 34612504;
  cmDspInst_t* aout[chCnt];
  unsigned     i;
  
  const char*     fn0   = "media/audio/20110723-Kriesberg/Audio Files/Piano 3_23.wav";
  const cmChar_t* fn    = cmFsMakeFn(cmFsUserDir(),fn0,NULL,NULL );
  
  cmDspInst_t* f_phs = cmDspSysAllocInst(h,"Phasor",   NULL,  0 );
  cmDspInst_t* f_wt  = cmDspSysAllocInst(h,"WaveTable",NULL,  2, ((int)cmDspSysSampleRate(h)), 1 );
  cmDspInst_t* f_mtr = cmDspSysAllocInst(h,"AMeter",    "File Out",  0);
  
  cmDspInst_t* f_rew = cmDspSysAllocInst(h,"Button", "Rewind",  2, kButtonDuiId, 1.0 );
  cmDspInst_t* f_pts = cmDspSysAllocInst(h,"PortToSym", NULL, 1, "on" );
  cmDspInst_t* f_beg = cmDspSysAllocInst(h,"Scalar", "File Begin",  5, kNumberDuiId, 0.0,  cmDspSysSampleRate(h)*6000.0, 1.0,  offs);
  cmDspInst_t* f_nam = cmDspSysAllocInst(h,"Fname",    NULL,  3, false,"Audio Files (*.wav,*.aiff,*.aif)\tAudio Files (*.{wav,aiff,aif})",fn);
  
  
  cmDspInst_t* s_phs = cmDspSysAllocInst(h,"Phasor",    NULL,   2, cmDspSysSampleRate(h), frqHz );
  cmDspInst_t* s_wt  = cmDspSysAllocInst(h,"WaveTable", NULL,   2, ((int)cmDspSysSampleRate(h)), 4);
  cmDspInst_t* s_mtr = cmDspSysAllocInst(h,"AMeter",    "Tone Out",  0);
  
  cmDspInst_t* swtch = cmDspSysAllocInst(h,"1ofN",      NULL,   2, oneOfN_chCnt, 0 );
  
  for(i=0; i<chCnt; ++i)
    aout[i] = cmDspSysAllocInst(h,"AudioOut",NULL,   1, i );
  
  cmDspInst_t*  chck = cmDspSysAllocInst(h,"Checkbox", "Source", 5, "Tone","file","tone", 0.0, 1.0);
  cmDspInst_t** vol  = cmDspSysAllocInstArray(h,chCnt,"Scalar", "Gain", NULL, 5, kNumberDuiId, 0.0,  10.0, 0.01,  0.0 );
  
  // check for allocation errors
  if((rc = cmDspSysLastRC(h)) != kOkDspRC )
    goto errLabel;
  
  cmDspSysConnectAudio(     h, s_phs, "out",  s_wt,  "phs" );           // sine phasor -&gt wave table
  cmDspSysConnectAudio(     h, s_wt,  "out",  s_mtr, "in" );            // sine wave table -&gt meter
  cmDspSysConnectAudio(     h, s_wt,  "out",  swtch, "a-in-1");
  
  cmDspSysConnectAudio(     h, f_phs, "out", f_wt,  "phs" );           // file phasor -&gt wave table
  cmDspSysConnectAudio(     h, f_wt, "out",  f_mtr, "in" );            // file wave table -&gt meter
  cmDspSysConnectAudio(     h, f_wt, "out",  swtch, "a-in-0");
  
  cmDspSysConnectAudio11N1( h, swtch, "a-out", aout, "in",   chCnt );
  cmDspSysInstallCbN1N1(    h, vol,   "val",   aout, "gain", chCnt );
  
  cmDspSysInstallCb( h, chck,  "out", swtch, "chidx", NULL );
  cmDspSysInstallCb( h, f_nam, "out", f_wt,  "fn",    NULL );    
  cmDspSysInstallCb( h, f_beg, "val", f_wt,  "beg",   NULL ); 
  cmDspSysInstallCb( h, f_rew, "out", f_pts, "on",    NULL );
  cmDspSysInstallCb( h, f_pts, "on",  f_beg, "send",  NULL );
  cmDspSysInstallCb( h, f_pts, "on",  f_nam, "send",  NULL );
  cmDspSysInstallCb( h, f_pts, "on",  f_wt,  "cmd",   NULL );
  
  errLabel:
  return rc;
}


cmDspPgm_MultiIn : Multiple audio inputs example program.
cmDspRC_t _cmDspSysPgm_MultiIn(cmDspSysH_t h, void** userPtrPtr)
{
  int          chCnt = 8;
  cmDspInst_t* a[chCnt];
  int i;
  for(i=0; i<chCnt; ++i)
    a[i]   = cmDspSysAllocInst( h, "AudioIn", NULL,  1, i );
  
  cmDspInst_t* mxp   = cmDspSysAllocInst( h, "AMix",         NULL, chCnt+1, chCnt, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 );   
  cmDspInst_t* afp   = cmDspSysAllocInst( h, "AudioFileOut", NULL, 2,"/home/kevin/temp/at/test_in.aif",1);
  cmDspInst_t* aop   = cmDspSysAllocInst( h, "AudioOut",     NULL, 1, 0 );
  
  // AudioFileOut needs an open message to create the output file
  cmDspInst_t* btn   = cmDspSysAllocInst( h, "Button",      "open",  2, kButtonDuiId, 1.0 );
  cmDspSysAssignInstAttrSymbolStr(h, btn, "_reset" );
  cmDspInst_t* pts = cmDspSysAllocInst(h,"PortToSym", NULL, 1, "open" );
  
  
  cmDspSysConnectAudioN11N(h, a,   "out", mxp, "in", chCnt );
  cmDspSysConnectAudio(    h, mxp, "out", afp,  "in0" );
  cmDspSysConnectAudio(    h, mxp, "out", aop,  "in" );
  
  cmDspSysInstallCb( h, btn, "sym",  pts, "open", NULL );
  cmDspSysInstallCb( h, pts, "open", afp, "sel",  NULL );
  
  
  return kOkDspRC;
}



cmDspPgm_GateDetect : Gate detector example program.
cmDspRC_t _cmDspSysPgm_GateDetect( cmDspSysH_t h, void** userPtrPtr )
{
  bool            useBuiltInFl = true;
  //const char*     fn0          = &quotmedia/audio/20110723-Kriesberg/Audio Files/Piano 3_01.wav&quot;
  //int             beg          = 6900826;
  //int             end          = 13512262;
  //const char*     fn0          = &quotmedia/audio/McGill-3/1 Audio Track.aiff&quot;  
  const char*     fn0          = "temp/gate_detect0.aif";
  int             beg          = 0;
  int             end          = -1;
  const cmChar_t* fn           = cmFsMakeFn(cmFsUserDir(),fn0,NULL,NULL );
  const cmChar_t* tfn          = "/home/kevin/temp/test0.txt";
  
  cmDspInst_t* ofp =  cmDspSysAllocInst(h,"Scalar", "Offset",  5, kNumberDuiId, 0.0,  cmDspSysSampleRate(h)*600.0, 1.0,  0.0);
  //cmDspInst_t* fnp =  cmDspSysAllocInst(h,&quotFname&quot,     NULL,  3, false,&quotAudio Files (*.wav,*.aiff,*.aif)\tAudio Files (*.{wav,aiff,aif})&quot,fn);
  cmDspInst_t* php =  cmDspSysAllocInst(h,"Phasor",    NULL,  0 );
  cmDspInst_t* wtp =  cmDspSysAllocInst(h,"WaveTable", NULL,  6, ((int)cmDspSysSampleRate(h)), 1, fn, -1, beg, end );
  cmDspInst_t* gdp =  cmDspSysAllocInst(h,"GateDetect",NULL,  1, 20.0);
  cmDspInst_t* gmp =  cmDspSysAllocInst(h,"Meter",     NULL,  3,    0.0,    0.0, 1.0);
  cmDspInst_t* rmp =  cmDspSysAllocInst(h,"Meter",     NULL,  3, -100.0, -100.0, 0.0);
  cmDspInst_t* txp =  cmDspSysAllocInst(h,"TextFile",  NULL,  2, 3, tfn);
  
  cmDspInst_t* ao0p = cmDspSysAllocInst(h,"AudioOut",NULL,   1, useBuiltInFl ? 0 : 2 );
  cmDspInst_t* ao1p = cmDspSysAllocInst(h,"AudioOut",NULL,   1, useBuiltInFl ? 1 : 3 );
  
  
  cmDspSysConnectAudio(h, php, "out", wtp,  "phs" );   // phasor -&gt wave table
  cmDspSysConnectAudio(h, wtp, "out", ao0p, "in" );    // wave table -&gt audio out
  cmDspSysConnectAudio(h, wtp, "out", ao1p, "in" );    
  cmDspSysConnectAudio(h, wtp, "out", gdp,  "in" );
  
  cmDspSysInstallCb(h, ofp, "val", wtp, "beg", NULL ); 
  cmDspSysInstallCb(h, gdp, "gate", gmp, "in", NULL );
  cmDspSysInstallCb(h, gdp, "rms",  rmp, "in", NULL );
  cmDspSysInstallCb(h, gdp, "gate", txp, "in-0", NULL);
  cmDspSysInstallCb(h, gdp, "rms",  txp, "in-1", NULL);
  cmDspSysInstallCb(h, gdp, "mean", txp, "in-2", NULL);
  return kOkDspRC;
}


cmDspPgm_Record : Record audio to an audio file.
cmDspRC_t _cmDspSysPgm_Record(cmDspSysH_t h, void** userPtrPtr)
{
  int          chCnt = 8;
  cmDspInst_t* a[chCnt];
  int i;
  for(i=0; i<chCnt; ++i)
    a[i]   = cmDspSysAllocInst( h, "AudioIn", NULL,  1, i );
  
  cmDspInst_t* mxp   = cmDspSysAllocInst( h, "AMix",         NULL,       chCnt+1, chCnt, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 );   
  cmDspInst_t* afp   = cmDspSysAllocInst( h, "AudioFileOut", NULL,       2,"/home/kevin/temp/gate_detect.aif",1);
  cmDspInst_t* aop   = cmDspSysAllocInst( h, "AudioOut",     NULL,       1, 0 );
  cmDspInst_t* txp   = cmDspSysAllocInst( h, "TextFile",     NULL,       2, 1, "/home/kevin/temp/gate_detect.txt");
  cmDspInst_t* chp   = cmDspSysAllocInst( h, "Scalar",       "Channel",  5, kNumberDuiId, 0.0,  7.0, 1.0,  0.0);
  
  // AudioFileOut needs an open message to create the output file
  cmDspInst_t* btn   = cmDspSysAllocInst( h, "Button",      "open",  2, kButtonDuiId, 1.0 );
  cmDspSysAssignInstAttrSymbolStr(h, btn, "_reset" );
  cmDspInst_t* pts = cmDspSysAllocInst(h,"PortToSym", NULL, 1, "open" );
  
  for(i=0; i<chCnt; ++i)
  {
    cmChar_t lbl[15];
    snprintf(lbl,15,"in-%i",i);
    cmDspSysConnectAudio(h,a[i], "out", mxp, lbl);
  }
  
  cmDspSysConnectAudio(h, mxp, "out", afp,  "in0" );
  cmDspSysConnectAudio(h, mxp, "out", aop,  "in" );
  
  cmDspSysInstallCb(h, chp, "out", txp, "in-0", NULL);
  
  cmDspSysInstallCb( h, btn, "sym",  pts, "open", NULL );
  cmDspSysInstallCb( h, pts, "open", afp, "sel",  NULL );
  
  return kOkDspRC;
}


cmDspPgm_FtRecord : Record streaming audio input to an audio file.
cmDspRC_t _cmDspSysPgm_RtRecord(cmDspSysH_t h, void** userPtrPtr)
{
  cmDspInst_t* ai0   = cmDspSysAllocInst( h, "AudioIn", NULL,  1, 0 );
  cmDspInst_t* ai1   = cmDspSysAllocInst( h, "AudioIn", NULL,  1, 1 );  
  cmDspInst_t* afp   = cmDspSysAllocInst( h, "AudioFileOut", NULL,  2,"/Users/kevin/temp/test.aif",2);
  cmDspInst_t* ao0   = cmDspSysAllocInst( h, "AudioOut", NULL,  1, 2 );
  cmDspInst_t* ao1   = cmDspSysAllocInst( h, "AudioOut", NULL,  1, 3 );  
  
  // AudioFileOut needs an open message to create the output file
  cmDspInst_t* btn   = cmDspSysAllocInst( h, "Button",      "open",  2, kButtonDuiId, 1.0 );
  cmDspSysAssignInstAttrSymbolStr(h, btn, "_reset" );
  cmDspInst_t* pts = cmDspSysAllocInst(h,"PortToSym", NULL, 1, "open" );
  
  
  cmDspSysConnectAudio(h,ai0, "out", afp, "in0");
  cmDspSysConnectAudio(h,ai1, "out", afp, "in1");
  
  cmDspSysConnectAudio(h,ai0, "out", ao0, "in");
  cmDspSysConnectAudio(h,ai1, "out", ao1, "in");
  
  cmDspSysInstallCb( h, btn, "sym",  pts, "open", NULL );
  cmDspSysInstallCb( h, pts, "open", afp, "sel",  NULL );
  
  return kOkDspRC;
}



cmDspPgm_PitchShift : Pitch-shifter example program.
cmDspRC_t _cmDspSysPgm_PitchShiftFile( cmDspSysH_t h, void** userPtrPtr )
{
  bool            useBuiltInFl = true;
  const cmChar_t* fn0          = "media/audio/20110723-Kriesberg/Audio Files/Piano 3_01.wav";
  const cmChar_t* fn1          = "temp/record0.aif";
  int             beg          = 6900826;
  int             end          = 13512262;
  const cmChar_t* fn           = cmFsMakeFn(cmFsUserDir(),fn0,NULL,NULL );
  const cmChar_t* ofn          = cmFsMakeFn(cmFsUserDir(),fn1,NULL,NULL );
  
  cmDspInst_t* rt0p = cmDspSysAllocInst(h,"Scalar", "Ratio 0",  5, kNumberDuiId, 0.01,  10.0, 0.01,  1.0);
  cmDspInst_t* rt1p = cmDspSysAllocInst(h,"Scalar", "Ratio 1",  5, kNumberDuiId, 0.01,  10.0, 0.01,  1.0);
  cmDspInst_t* ofp =  cmDspSysAllocInst(h,"Scalar", "Offset",  5, kNumberDuiId, 0.0,  cmDspSysSampleRate(h)*600.0, 1.0,  0.0);
  //cmDspInst_t* fnp =  cmDspSysAllocInst(h,&quotFname&quot,    NULL,  3, false,&quotAudio Files (*.wav,*.aiff,*.aif)\tAudio Files (*.{wav,aiff,aif})&quot,fn);
  cmDspInst_t* php =  cmDspSysAllocInst(h,"Phasor",   NULL,  0 );
  cmDspInst_t* wtp =  cmDspSysAllocInst(h,"WaveTable",NULL,  6, ((int)cmDspSysSampleRate(h)), 1, fn, -1, beg, end );
  cmDspInst_t* afp =  cmDspSysAllocInst(h,"AudioFileOut",NULL,2,ofn,1);
  
  cmDspInst_t* ps0p = cmDspSysAllocInst(h,"PShift", NULL, 0 );
  cmDspInst_t* ps1p = cmDspSysAllocInst(h,"PShift", NULL, 0 );
  
  cmDspInst_t* ao0p = cmDspSysAllocInst(h,"AudioOut",NULL,   1, useBuiltInFl ? 0 : 2 );
  cmDspInst_t* ao1p = cmDspSysAllocInst(h,"AudioOut",NULL,   1, useBuiltInFl ? 1 : 3 );
  
  
  cmDspSysConnectAudio(h, php,  "out", wtp,  "phs" );   // phasor -&gt wave table
  cmDspSysConnectAudio(h, wtp,  "out", ps0p, "in" );    // wave table -&gt shift
  cmDspSysConnectAudio(h, wtp,  "out", ps1p, "in" );    
  
  cmDspSysConnectAudio(h, ps0p, "out", ao0p, "in" );    // shift -&gt audio out
  cmDspSysConnectAudio(h, ps1p, "out", ao1p, "in" );    
  cmDspSysConnectAudio(h, ps0p, "out", afp,  "in0");    
  
  cmDspSysInstallCb(h, ofp, "val", wtp, "beg", NULL ); 
  //cmDspSysInstallCb(h, fnp, &quotout&quot, wtp, &quotfn&quot, NULL);    
  
  cmDspSysInstallCb(h, rt0p, "val", ps0p, "ratio", NULL);    
  cmDspSysInstallCb(h, rt1p, "val", ps1p, "ratio", NULL);    
  return kOkDspRC;
}


cmDspPgm_LoopRecd : Loop-recorder example program.
cmDspRC_t _cmDspSysPgm_LoopRecd( cmDspSysH_t h, void** userPtrPtr )
{
  bool            useBuiltInFl = true;
  const cmChar_t* fn0          = "media/audio/20110723-Kriesberg/Audio Files/Piano 3_01.wav";
  const cmChar_t* fn           = cmFsMakeFn(cmFsUserDir(),fn0,NULL,NULL );
  int             beg          =  6900826;
  int             end          = 13512262;
  
  cmDspInst_t* rfl = cmDspSysAllocInst(h,"Button", "Recd",  2, kCheckDuiId, 0.0 );
  cmDspInst_t* pfl = cmDspSysAllocInst(h,"Button", "Play",  2, kButtonDuiId, 1.0 );
  cmDspInst_t* rtp = cmDspSysAllocInst(h,"Scalar", "Ratio",    5, kNumberDuiId, 0.0,  10.0, 0.01, 1.0 );
  cmDspInst_t* ofp =  cmDspSysAllocInst(h,"Scalar", "Offset",  5, kNumberDuiId, 0.0,  cmDspSysSampleRate(h)*600.0, 1.0,  0.0);
  //cmDspInst_t* fnp =  cmDspSysAllocInst(h,&quotFname&quot,    NULL,  3, false,&quotAudio Files (*.wav,*.aiff,*.aif)\tAudio Files (*.{wav,aiff,aif})&quot,fn);
  cmDspInst_t* php =  cmDspSysAllocInst(h,"Phasor",   NULL,  0 );
  cmDspInst_t* wtp =  cmDspSysAllocInst(h,"WaveTable",NULL,  6, ((int)cmDspSysSampleRate(h)), 1, fn, -1, beg, end );
  //cmDspInst_t* afp =  cmDspSysAllocInst(h,&quotAudioFileOut&quot,NULL,2,&quot/home/kevin/temp/record0.aif&quot,1);
  cmDspInst_t* lrp = cmDspSysAllocInst(h,"LoopRecd", NULL, 0 );
  cmDspInst_t* ao0p = cmDspSysAllocInst(h,"AudioOut",NULL,   1, useBuiltInFl ? 0 : 2 );
  cmDspInst_t* ao1p = cmDspSysAllocInst(h,"AudioOut",NULL,   1, useBuiltInFl ? 1 : 3 );
  
  cmDspSysConnectAudio(h, php,  "out", wtp,  "phs" );   // phasor -&gt wave table
  cmDspSysConnectAudio(h, wtp,  "out", lrp, "in" );    // wave table -&gt shift
  cmDspSysConnectAudio(h, lrp,  "out", ao0p, "in" );    // shift -&gt audio out
  cmDspSysConnectAudio(h, wtp,  "out", ao1p, "in" );    
  
  cmDspSysInstallCb(h, ofp, "val", wtp, "beg", NULL ); 
  //cmDspSysInstallCb(h, fnp, &quotout&quot, wtp, &quotfn&quot, NULL);    
  
  cmDspSysInstallCb(h, rfl, "out", lrp, "recd", NULL);    
  cmDspSysInstallCb(h, pfl, "out", lrp, "play", NULL);    
  cmDspSysInstallCb(h, rtp, "val", lrp, "ratio",NULL);
  return kOkDspRC;
}




cmDspPgm_UiTest : User Interface example program.
cmDspRC_t _cmDspSysPgm_UiTest(cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t rc        = kOkDspRC;
  
  cmDspInst_t* mdp = cmDspSysAllocInst(h,"Scalar", "Mode",      5, kNumberDuiId, 0.0, 4.0, 1.0, 1.0);
  cmDspInst_t* wsp = cmDspSysAllocInst(h,"MsgList","wndSmpCnt", 3, "wndSmpCnt", NULL, 2);
  cmDspInst_t* hfp = cmDspSysAllocInst(h,"MsgList","hopFact",   3, "hopFact",   NULL, 2);
  cmDspInst_t* thp = cmDspSysAllocInst(h,"Scalar", "threshold", 5, kNumberDuiId, 0.0, 1.0, 0.01, 0.5 );
  cmDspInst_t* trp = cmDspSysAllocInst(h,"Scalar", "target",    5, kNumberDuiId, 0.0, 1.0, 0.01, 0.5 );
  cmDspInst_t* btn = cmDspSysAllocInst(h,"Button", "btn",       2, kButtonDuiId, 12.3 );
  cmDspInst_t* chk = cmDspSysAllocInst(h,"Button", "check",     2, kCheckDuiId, 0 );
  cmDspInst_t* chb = cmDspSysAllocInst(h,"Checkbox","checkbox", 5, "Checker","up","down", 2.0, 1.0);
  cmDspInst_t* txt = cmDspSysAllocInst(h,"Text",   "text",      1, "Hello" );
  cmDspInst_t* prp = cmDspSysAllocInst(h,"Printer", NULL,   1, ">" );
  cmDspInst_t* mtp = cmDspSysAllocInst(h,"Meter", "meter",  3, 0.0,  0.0, 4.0);
  cmDspInst_t* ctp = cmDspSysAllocInst(h,"Counter", NULL,   3, 0.0, 10.0, 1.0 );
  cmDspInst_t* lbl = cmDspSysAllocInst(h,"Label",  "label1", 1, "label2");
  if((rc = cmDspSysLastRC(h)) != kOkDspRC )
    return rc;
  
  cmDspSysInstallCb(h, mdp, "val", thp, "val", NULL );
  
  cmDspSysInstallCb(h, mdp, "val", prp, "in", NULL );
  cmDspSysInstallCb(h, wsp, "out", prp, "in", NULL );
  cmDspSysInstallCb(h, hfp, "out", prp, "in", NULL );
  cmDspSysInstallCb(h, trp, "val", prp, "in", NULL );
  cmDspSysInstallCb(h, btn, "out", prp, "in", NULL );
  cmDspSysInstallCb(h, chk, "out", prp, "in", NULL );
  cmDspSysInstallCb(h, ctp, "out", prp, "in", NULL );
  
  cmDspSysInstallCb(h, mdp, "val", btn, "in", NULL );
  cmDspSysInstallCb(h, thp, "val", mtp, "in", NULL );
  cmDspSysInstallCb(h, thp, "val", trp, "val", NULL );
  
  cmDspSysInstallCb(h, btn, "sym", prp, "in", NULL );
  cmDspSysInstallCb(h, btn, "out", ctp, "next", NULL );
  
  cmDspSysInstallCb(h, txt, "val", prp, "in", NULL );
  
  cmDspSysInstallCb(h, chb, "out", prp, "in", NULL );
  cmDspSysInstallCb(h, chb, "sym", prp, "in", NULL );
  
  cmDspSysInstallCb(h, mdp, "val", lbl, "in", NULL );
  
  return rc;
  
}


cmDspPgm_Xfade : Cross fader example program.
cmDspRC_t _cmDspSysPgm_Xfade( cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t rc         = kOkDspRC;
  unsigned  leftChIdx  = 2;
  unsigned  rightChIdx = 3;
  unsigned  chCnt      = 2;
  double    xfadeMs    = 1000;   // cross fade time
  double    sgHz       = 500;
  unsigned  sgShapeId  = 1;
  double    sgGain     = 0.5;
  
  cmDspInst_t* sg  = cmDspSysAllocInst(   h, "SigGen", NULL, 3, sgHz, sgShapeId, sgGain );
  
  cmDspInst_t* xfp  = cmDspSysAllocInst(h,"Xfader", NULL,    2, chCnt, xfadeMs );
  
  cmDspInst_t* ao0p = cmDspSysAllocInst(h,"AudioOut",NULL,   1, leftChIdx );
  cmDspInst_t* ao1p = cmDspSysAllocInst(h,"AudioOut",NULL,   1, rightChIdx );
  
  cmDspInst_t* im0p = cmDspSysAllocInst(h,"AMeter","In 0",  0);
  cmDspInst_t* im1p = cmDspSysAllocInst(h,"AMeter","In 1",  0);
  
  cmDspInst_t* om0p = cmDspSysAllocInst(h,"AMeter","Out 0", 0);
  cmDspInst_t* om1p = cmDspSysAllocInst(h,"AMeter","Out 1", 0);
  
  cmDspInst_t* mstr = cmDspSysAllocInst(h,"Button", "Mstr",   2, kCheckDuiId, 0.0 );
  cmDspInst_t* btn0 = cmDspSysAllocInst(h,"Button", "Fade 0", 2, kCheckDuiId, 0.0 );
  cmDspInst_t* btn1 = cmDspSysAllocInst(h,"Button", "Fade 1", 2, kCheckDuiId, 1.0 );
  
  
  cmDspInst_t* gm0p = cmDspSysAllocInst(h,"Meter","Gain 0", 3, 0.0, 0.0, 1.0);
  cmDspInst_t* gm1p = cmDspSysAllocInst(h,"Meter","Gain 1", 3, 0.0, 0.0, 1.0);
  
  cmDspInst_t* pon = cmDspSysAllocInst(h,"Printer", NULL,   1, "on:" );
  cmDspInst_t* pof = cmDspSysAllocInst(h,"Printer", NULL,   1, "off:" );  
  
  if((rc = cmDspSysLastRC(h)) != kOkDspRC )
    return rc;
  
  cmDspSysConnectAudio(h, sg, "out", im0p, "in");   // ain -&gt meter
  cmDspSysConnectAudio(h, sg, "out", im1p, "in");   
  
  cmDspSysConnectAudio(h, sg, "out", xfp, "in-0");  // ain -&gt xfader
  cmDspSysConnectAudio(h, sg, "out", xfp, "in-1");
  
  cmDspSysConnectAudio(h, xfp, "out-0", om0p, "in" );    // xfade -&gt meter
  cmDspSysConnectAudio(h, xfp, "out-1", om1p, "in" );    
  
  cmDspSysConnectAudio(h, xfp, "out-0", ao0p, "in" );    // xfade -&gt aout
  cmDspSysConnectAudio(h, xfp, "out-1", ao1p, "in" );    
  
  cmDspSysInstallCb(h, btn0, "out", xfp, "gate-0", NULL );  // check -&gt xfade gate
  cmDspSysInstallCb(h, btn1, "out", xfp, "gate-1", NULL );
  cmDspSysInstallCb(h, mstr, "out", xfp, "mgate",  NULL );
  
  cmDspSysInstallCb(h, xfp, "gain-0", gm0p, "in", NULL );
  cmDspSysInstallCb(h, xfp, "gain-1", gm1p, "in", NULL );
  
  cmDspSysInstallCb(h, xfp, "on", pon, "in", NULL );
  cmDspSysInstallCb(h, xfp, "off", pof, "in", NULL );
  
  return cmDspSysLastRC(h);
}


cmDspPgm_Pgm6 : Stereo strectral non-linear distortion example.
cmDspRC_t _cmDspSysPgm6( cmDspSysH_t h, void* audioDir )
{
  cmDspRC_t rc        = kOkDspRC;
  int       wndSmpCnt = 2048;
  int       hopFact   = 4;
  
  //const char* afDir = &quot/Volumes/LaTetra0/media/audio/20110723-Kriesberg/Audio Files&quot;
  //const char* afDir = &quot/Users/administrator/Documents/kc&quot;  
  const char* afDir = "/home/kevin/media/audio/20110723-Kriesberg/Audio Files";
  
  cmDspInst_t* ph0p = cmDspSysAllocInst(h,"Phasor",  NULL,   0 );
  cmDspInst_t* wt0p = cmDspSysAllocInst(h,"WaveTable",NULL,  0  );
  cmDspInst_t* ro0p = cmDspSysAllocInst(h,"Reorder", NULL,   5, 3, 2, 0, 1, 2 );
  cmDspInst_t* kr0p = cmDspSysAllocInst(h,"Kr",      NULL,   2, wndSmpCnt, hopFact );
  cmDspInst_t* kr1p = cmDspSysAllocInst(h,"Kr",      NULL,   2, wndSmpCnt, hopFact );
  
  cmDspInst_t* prp = cmDspSysAllocInst(h,"Printer", NULL,   0 );
  
  bool useBuiltInFl = true;
  
  // MOTU Traveler: Use channels 2&amp3 (out plugs:3&amp4) because 0&amp1 do not show up on plugs 1&amp2.
  cmDspInst_t* ao0p = cmDspSysAllocInst(h,"AudioOut",NULL,   1, useBuiltInFl ? 0 : 2 );
  cmDspInst_t* ao1p = cmDspSysAllocInst(h,"AudioOut",NULL,   1, useBuiltInFl ? 1 : 3 );
  
  // BUG: If audio inputs are not connected a 'not an audio buffer' msg is generated.
  // This is a problem with type determination in the cmDspClass related code : see cmDspClass.c 833 
  // for a place that this error would be thrown in the following audio outputs were not connected
  // to audio sources.  
  cmDspInst_t* ao2p = NULL;
  cmDspInst_t* ao3p = NULL;
  
  if( !useBuiltInFl )
  {
    ao2p = cmDspSysAllocInst(h,"AudioOut",NULL,   1, 4 );
    ao3p = cmDspSysAllocInst(h,"AudioOut",NULL,   1, 5 );
  }
  
  cmDspInst_t* al0p = cmDspSysAllocInst(h,"MsgList","audFiles", 2, "audFiles",NULL);
  cmDspInst_t* fl0p = cmDspSysAllocInst(h,"MsgList","audFragsA", 2, "audFrags",NULL);
  cmDspInst_t* fn0p = cmDspSysAllocInst(h,"Sprintf","filename", 1, "%s/%s_%02i.wav");
  
  cmDspInst_t* md0p = cmDspSysAllocInst(h,"Scalar", "Mode",      5, kNumberDuiId, 0.0, 4.0, 1.0, 1.0);
  cmDspInst_t* ws0p = cmDspSysAllocInst(h,"MsgList","wndSmpCnt", 3, "wndSmpCnt", NULL, 2);
  cmDspInst_t* hf0p = cmDspSysAllocInst(h,"MsgList","hopFact",   3, "hopFact",   NULL, 2);
  cmDspInst_t* th0p = cmDspSysAllocInst(h,"Scalar", "threshold", 5, kNumberDuiId, 0.0, 100.0, 1.0,  60.0 );
  cmDspInst_t* us0p = cmDspSysAllocInst(h,"Scalar", "upr slope", 5, kNumberDuiId, 0.0,  10.0, 0.01,  0.0 ); 
  cmDspInst_t* ls0p = cmDspSysAllocInst(h,"Scalar", "lwr slope", 5, kNumberDuiId, 0.3,  10.0, 0.01,  2.0 );
  cmDspInst_t* of0p = cmDspSysAllocInst(h,"Scalar", "offset",    5, kNumberDuiId, 0.0, 100.0, 0.01, 30.0 );
  cmDspInst_t* iv0p = cmDspSysAllocInst(h,"Scalar", "invert",    5, kNumberDuiId, 0.0,   1.0, 1.0,   0.0 );  
  cmDspSysNewColumn(h,0);
  
  //cmDspInst_t* al1p = cmDspSysAllocInst(h,&quotMsgList&quot,&quotaudFiles&quot, 2, &quotaudFiles&quot,NULL);
  //cmDspInst_t* fl1p = cmDspSysAllocInst(h,&quotMsgList&quot,&quotaudFrags1&quot, 2, &quotaudFrags&quot,NULL);
  //cmDspInst_t* fn1p = cmDspSysAllocInst(h,&quotSprintf&quot,&quotfilename&quot, 1, &quot%s/%s_%02i.wav&quot);  
  cmDspInst_t* md1p = cmDspSysAllocInst(h,"Scalar", "Mode",      5, kNumberDuiId, 0.0, 4.0, 1.0, 1.0);
  cmDspInst_t* ws1p = cmDspSysAllocInst(h,"MsgList","wndSmpCnt", 3, "wndSmpCnt", NULL, 2);
  cmDspInst_t* hf1p = cmDspSysAllocInst(h,"MsgList","hopFact",   3, "hopFact",   NULL, 2);
  cmDspInst_t* th1p = cmDspSysAllocInst(h,"Scalar", "threshold", 5, kNumberDuiId, 0.0, 100.0, 1.0,  60.0 );
  cmDspInst_t* us1p = cmDspSysAllocInst(h,"Scalar", "upr slope", 5, kNumberDuiId, 0.0,  10.0, 0.01,  0.0 ); 
  cmDspInst_t* ls1p = cmDspSysAllocInst(h,"Scalar", "lwr slope", 5, kNumberDuiId, 0.3,  10.0, 0.01,  2.0 );
  cmDspInst_t* of1p = cmDspSysAllocInst(h,"Scalar", "offset",    5, kNumberDuiId, 0.0, 100.0, 0.01, 30.0 );
  cmDspInst_t* iv1p = cmDspSysAllocInst(h,"Scalar", "invert",    5, kNumberDuiId, 0.0,   1.0, 1.0,   0.0 );  
  
  cmDspSysNewColumn(h,0);
  cmDspInst_t* dnp = cmDspSysAllocInst(h,"Fname",  "audDir",   3, true,NULL,afDir);
  
  cmDspInst_t* mtp = cmDspSysAllocInst(h,"Meter","MyMeter", 3, 50.0, 0.0, 100.0);
  cmDspInst_t* atp = cmDspSysAllocInst(h,"AMeter","Audio Meter",0);
  
  
  if( (rc = cmDspSysLastRC(h)) != kOkDspRC )
    return rc;
  
  cmDspSysConnectAudio(h, ph0p, "out", wt0p, "phs");  // phasor-&gtwt:phs
  cmDspSysConnectAudio(h, wt0p, "out", kr0p, "in");   // wt-&gtkr
  cmDspSysConnectAudio(h, kr0p, "out", ao0p, "in");   // kr-&gtaout- 0
  cmDspSysConnectAudio(h, wt0p, "out", kr1p, "in");   // wt-&gtkr
  cmDspSysConnectAudio(h, kr1p, "out", ao1p, "in");   // kr-&gtaout - 1
  
  if( ao2p != NULL )
    cmDspSysConnectAudio(h, wt0p,"out", ao2p, "in");   // wt-&gtaout - 2
  
  if( ao3p != NULL )
    cmDspSysConnectAudio(h, wt0p,"out", ao3p, "in");   // wt-&gtaout - 3
  
  cmDspSysConnectAudio(h, wt0p,"out", atp, "in");       // wt-&gtmeter
  
  cmDspSysInstallCb(h, ws0p, "out", kr0p, "wndn", NULL );    // wndSmpCnt-&gtkr
  cmDspSysInstallCb(h, hf0p, "out", kr0p, "hopf", NULL );    // hopFact-&gtkr
  cmDspSysInstallCb(h, md0p, "val", kr0p, "mode", NULL );    // mode-&gtkr
  cmDspSysInstallCb(h, th0p, "val", kr0p, "thrh", NULL );    // thresh-&gtkr
  cmDspSysInstallCb(h, ls0p, "val", kr0p, "lwrs", NULL );    // lwrSlope-&gtkr
  cmDspSysInstallCb(h, us0p, "val", kr0p, "uprs", NULL );    // uprSlope-&gtkr
  cmDspSysInstallCb(h, of0p, "val", kr0p, "offs", NULL );    // offset-&gtkr
  cmDspSysInstallCb(h, iv0p, "val", kr0p, "invt", NULL );    // invert-&gtkr
  
  cmDspSysInstallCb(h, th0p, "val", mtp, "in", NULL ); 
  
  cmDspSysInstallCb(h, ws1p, "out", kr1p, "wndn", NULL );    // wndSmpCnt-&gtkr
  cmDspSysInstallCb(h, hf1p, "out", kr1p, "hopf", NULL );    // hopFact-&gtkr
  cmDspSysInstallCb(h, md1p, "val", kr1p, "mode", NULL );    // mode-&gtkr
  cmDspSysInstallCb(h, th1p, "val", kr1p, "thrh", NULL );    // thresh-&gtkr
  cmDspSysInstallCb(h, ls1p, "val", kr1p, "lwrs", NULL );    // lwrSlope-&gtkr
  cmDspSysInstallCb(h, us1p, "val", kr1p, "uprs", NULL );    // uprSlope-&gtkr
  cmDspSysInstallCb(h, of1p, "val", kr1p, "offs", NULL );    // offset-&gtkr
  cmDspSysInstallCb(h, iv1p, "val", kr1p, "invt", NULL );    // invert-&gtkr
  
  
  cmDspSysInstallCb(h, dnp,  "out",  fn0p, "in-0", NULL);     // dir-&gtfn:0
  cmDspSysInstallCb(h, al0p, "out",  fn0p, "in-1", NULL );    // fn-&gtfn:1
  cmDspSysInstallCb(h, fl0p, "take", fn0p, "in-2", NULL );    // take-&gtfn:2
  cmDspSysInstallCb(h, fn0p, "out",  ro0p, "in-0", NULL);     // fn-&gtprint
  
  cmDspSysInstallCb(h, fl0p, "beg",  ro0p, "in-1", NULL);   
  cmDspSysInstallCb(h, fl0p, "end",  ro0p, "in-2", NULL);   
  
  cmDspSysInstallCb(h, ro0p, "out-0", wt0p, "fn", NULL );    // fn-&gtwt:fn
  cmDspSysInstallCb(h, ro0p, "out-1", wt0p, "beg", NULL );   // beg-&gtwt:beg
  cmDspSysInstallCb(h, ro0p, "out-2", wt0p, "end", NULL );   // end-&gtwt:end
  
  cmDspSysInstallCb(h, ro0p, "out-1", prp, "in", NULL );  
  
  //cmDspSysInstallCb(h, dnp,  &quotout&quot,  fn1p, &quotin-0&quot, NULL);    // dir-&gtfn:0
  //cmDspSysInstallCb(h, al1p, &quotout&quot,  fn1p, &quotin-1&quot, NULL );   // fn-&gtfn:1
  //cmDspSysInstallCb(h, fl1p, &quottake&quot, fn1p, &quotin-2&quot, NULL );   // take-&gtfn:2
  //cmDspSysInstallCb(h, fn1p, &quotout&quot,  ro1p, &quotin-0&quot, NULL);    // fn-&gtprint  
  
  //cmDspSysInstallCb(h, fl1p, &quotbeg&quot,  ro1p, &quotin-1&quot, NULL);  //   
  //cmDspSysInstallCb(h, fl1p, &quotend&quot,  ro1p, &quotin-2&quot, NULL);  //  
  
  //cmDspSysInstallCb(h, ro1p, &quotout-0&quot, wt1p, &quotfn&quot, NULL );   // fn-&gtwt:fn
  //cmDspSysInstallCb(h, ro1p, &quotout-1&quot, wt1p, &quotbeg&quot, NULL );  // beg-&gtwt:beg
  //cmDspSysInstallCb(h, ro1p, &quotout-2&quot, wt1p, &quotend&quot, NULL );  // end-&gtwt:end  
  
  
  return cmDspSysLastRC(h);
}


cmDspPgm_Guitar : Similiar to Pgm6.
cmDspRC_t _cmDspSysPgmGuitar( cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t rc        = kOkDspRC;
  int       wndSmpCnt = 2048;
  int       hopFact   = 4;
  
  const char* afDir = "/Volumes/LaTetra0/media/audio/20110723-Kriesberg/Audio Files";
  //const char* afDir = &quot/Users/administrator/Documents/kc&quot;
  
  cmDspInst_t* ph0p = cmDspSysAllocInst(h,"Phasor",  NULL,   0 );
  cmDspInst_t* wt0p = cmDspSysAllocInst(h,"WaveTable",NULL,  0  );
  cmDspInst_t* ro0p = cmDspSysAllocInst(h,"Reorder", NULL,   5, 3, 2, 0, 1, 2 );
  cmDspInst_t* kr0p = cmDspSysAllocInst(h,"Kr",      NULL,   2, wndSmpCnt, hopFact );
  cmDspInst_t* kr1p = cmDspSysAllocInst(h,"Kr",      NULL,   2, wndSmpCnt, hopFact );
  
  cmDspInst_t* prp = cmDspSysAllocInst(h,"Printer", NULL,   0 );
  
  bool useBuiltInFl = true;
  
  // MOTU Traveler: Use channels 2&amp3 (out plugs:3&amp4) because 0&amp1 do not show up on plugs 1&amp2.
  cmDspInst_t* ao0p = cmDspSysAllocInst(h,"AudioOut",NULL,   1, useBuiltInFl ? 0 : 2 );
  cmDspInst_t* ao1p = cmDspSysAllocInst(h,"AudioOut",NULL,   1, useBuiltInFl ? 1 : 3 );
  
  // BUG: If audio inputs are not connected a 'not an audio buffer' msg is generated.
  // This is a problem with type determination in the cmDspClass related code : see cmDspClass.c 833 
  // for a place that this error would be thrown in the following audio outputs were not connected
  // to audio sources.  
  cmDspInst_t* ao2p = NULL;
  cmDspInst_t* ao3p = NULL;
  
  if( !useBuiltInFl )
  {
    ao2p = cmDspSysAllocInst(h,"AudioOut",NULL,   1, 4 );
    ao3p = cmDspSysAllocInst(h,"AudioOut",NULL,   1, 5 );
  }
  
  cmDspInst_t* al0p = cmDspSysAllocInst(h,"MsgList","audFiles", 2, "audFiles",NULL);
  cmDspInst_t* fl0p = cmDspSysAllocInst(h,"MsgList","audFragsA", 2, "audFrags",NULL);
  cmDspInst_t* fn0p = cmDspSysAllocInst(h,"Sprintf","filename", 1, "%s/%s_%02i.wav");
  
  cmDspInst_t* md0p = cmDspSysAllocInst(h,"Scalar", "Mode",      5, kNumberDuiId, 0.0, 4.0, 1.0, 1.0);
  cmDspInst_t* ws0p = cmDspSysAllocInst(h,"MsgList","wndSmpCnt", 3, "wndSmpCnt", NULL, 2);
  cmDspInst_t* hf0p = cmDspSysAllocInst(h,"MsgList","hopFact",   3, "hopFact",   NULL, 2);
  cmDspInst_t* th0p = cmDspSysAllocInst(h,"Scalar", "threshold", 5, kNumberDuiId, 0.0, 100.0, 1.0,  60.0 );
  cmDspInst_t* us0p = cmDspSysAllocInst(h,"Scalar", "upr slope", 5, kNumberDuiId, 0.0,  10.0, 0.01,  0.0 ); 
  cmDspInst_t* ls0p = cmDspSysAllocInst(h,"Scalar", "lwr slope", 5, kNumberDuiId, 0.3,  10.0, 0.01,  2.0 );
  cmDspInst_t* of0p = cmDspSysAllocInst(h,"Scalar", "offset",    5, kNumberDuiId, 0.0, 100.0, 0.01, 30.0 );
  cmDspInst_t* iv0p = cmDspSysAllocInst(h,"Scalar", "invert",    5, kNumberDuiId, 0.0,   1.0, 1.0,   0.0 );  
  cmDspSysNewColumn(h,0);
  
  //cmDspInst_t* al1p = cmDspSysAllocInst(h,&quotMsgList&quot,&quotaudFiles&quot, 2, &quotaudFiles&quot,NULL);
  //cmDspInst_t* fl1p = cmDspSysAllocInst(h,&quotMsgList&quot,&quotaudFrags1&quot, 2, &quotaudFrags&quot,NULL);
  //cmDspInst_t* fn1p = cmDspSysAllocInst(h,&quotSprintf&quot,&quotfilename&quot, 1, &quot%s/%s_%02i.wav&quot);  
  cmDspInst_t* md1p = cmDspSysAllocInst(h,"Scalar", "Mode",      5, kNumberDuiId, 0.0, 4.0, 1.0, 1.0);
  cmDspInst_t* ws1p = cmDspSysAllocInst(h,"MsgList","wndSmpCnt", 3, "wndSmpCnt", NULL, 2);
  cmDspInst_t* hf1p = cmDspSysAllocInst(h,"MsgList","hopFact",   3, "hopFact",   NULL, 2);
  cmDspInst_t* th1p = cmDspSysAllocInst(h,"Scalar", "threshold", 5, kNumberDuiId, 0.0, 100.0, 1.0,  60.0 );
  cmDspInst_t* us1p = cmDspSysAllocInst(h,"Scalar", "upr slope", 5, kNumberDuiId, 0.0,  10.0, 0.01,  0.0 ); 
  cmDspInst_t* ls1p = cmDspSysAllocInst(h,"Scalar", "lwr slope", 5, kNumberDuiId, 0.3,  10.0, 0.01,  2.0 );
  cmDspInst_t* of1p = cmDspSysAllocInst(h,"Scalar", "offset",    5, kNumberDuiId, 0.0, 100.0, 0.01, 30.0 );
  cmDspInst_t* iv1p = cmDspSysAllocInst(h,"Scalar", "invert",    5, kNumberDuiId, 0.0,   1.0, 1.0,   0.0 );  
  
  cmDspSysNewColumn(h,0);
  cmDspInst_t* dnp = cmDspSysAllocInst(h,"Fname",  "audDir",   3, true,NULL,afDir);
  
  cmDspInst_t* mtp = cmDspSysAllocInst(h,"Meter","MyMeter", 3, 50.0, 0.0, 100.0);
  cmDspInst_t* atp = cmDspSysAllocInst(h,"AMeter","Audio Meter",0);
  
  
  if( (rc = cmDspSysLastRC(h)) != kOkDspRC )
    return rc;
  
  cmDspSysConnectAudio(h, ph0p, "out", wt0p, "phs");  // phasor-&gtwt:phs
  cmDspSysConnectAudio(h, wt0p, "out", kr0p, "in");   // wt-&gtkr
  cmDspSysConnectAudio(h, kr0p, "out", ao0p, "in");   // kr-&gtaout- 0
  cmDspSysConnectAudio(h, wt0p, "out", kr1p, "in");   // wt-&gtkr
  cmDspSysConnectAudio(h, kr1p, "out", ao1p, "in");   // kr-&gtaout - 1
  
  if( ao2p != NULL )
    cmDspSysConnectAudio(h, wt0p,"out", ao2p, "in");   // wt-&gtaout - 2
  
  if( ao3p != NULL )
    cmDspSysConnectAudio(h, wt0p,"out", ao3p, "in");   // wt-&gtaout - 3
  
  cmDspSysConnectAudio(h, wt0p,"out", atp, "in");       // wt-&gtmeter
  
  cmDspSysInstallCb(h, ws0p, "out", kr0p, "wndn", NULL );    // wndSmpCnt-&gtkr
  cmDspSysInstallCb(h, hf0p, "out", kr0p, "hopf", NULL );    // hopFact-&gtkr
  cmDspSysInstallCb(h, md0p, "val", kr0p, "mode", NULL );    // mode-&gtkr
  cmDspSysInstallCb(h, th0p, "val", kr0p, "thrh", NULL );    // thresh-&gtkr
  cmDspSysInstallCb(h, ls0p, "val", kr0p, "lwrs", NULL );    // lwrSlope-&gtkr
  cmDspSysInstallCb(h, us0p, "val", kr0p, "uprs", NULL );    // uprSlope-&gtkr
  cmDspSysInstallCb(h, of0p, "val", kr0p, "offs", NULL );    // offset-&gtkr
  cmDspSysInstallCb(h, iv0p, "val", kr0p, "invt", NULL );    // invert-&gtkr
  
  cmDspSysInstallCb(h, th0p, "val", mtp, "in", NULL ); 
  
  cmDspSysInstallCb(h, ws1p, "out", kr1p, "wndn", NULL );    // wndSmpCnt-&gtkr
  cmDspSysInstallCb(h, hf1p, "out", kr1p, "hopf", NULL );    // hopFact-&gtkr
  cmDspSysInstallCb(h, md1p, "val", kr1p, "mode", NULL );    // mode-&gtkr
  cmDspSysInstallCb(h, th1p, "val", kr1p, "thrh", NULL );    // thresh-&gtkr
  cmDspSysInstallCb(h, ls1p, "val", kr1p, "lwrs", NULL );    // lwrSlope-&gtkr
  cmDspSysInstallCb(h, us1p, "val", kr1p, "uprs", NULL );    // uprSlope-&gtkr
  cmDspSysInstallCb(h, of1p, "val", kr1p, "offs", NULL );    // offset-&gtkr
  cmDspSysInstallCb(h, iv1p, "val", kr1p, "invt", NULL );    // invert-&gtkr
  
  
  cmDspSysInstallCb(h, dnp,  "out",  fn0p, "in-0", NULL);     // dir-&gtfn:0
  cmDspSysInstallCb(h, al0p, "out",  fn0p, "in-1", NULL );    // fn-&gtfn:1
  cmDspSysInstallCb(h, fl0p, "take", fn0p, "in-2", NULL );    // take-&gtfn:2
  cmDspSysInstallCb(h, fn0p, "out",  ro0p, "in-0", NULL);     // fn-&gtprint
  
  cmDspSysInstallCb(h, fl0p, "beg",  ro0p, "in-1", NULL);   
  cmDspSysInstallCb(h, fl0p, "end",  ro0p, "in-2", NULL);   
  
  cmDspSysInstallCb(h, ro0p, "out-0", wt0p, "fn", NULL );    // fn-&gtwt:fn
  cmDspSysInstallCb(h, ro0p, "out-1", wt0p, "beg", NULL );   // beg-&gtwt:beg
  cmDspSysInstallCb(h, ro0p, "out-2", wt0p, "end", NULL );   // end-&gtwt:end
  
  cmDspSysInstallCb(h, ro0p, "out-1", prp, "in", NULL );  
  
  //cmDspSysInstallCb(h, dnp,  &quotout&quot,  fn1p, &quotin-0&quot, NULL);    // dir-&gtfn:0
  //cmDspSysInstallCb(h, al1p, &quotout&quot,  fn1p, &quotin-1&quot, NULL );   // fn-&gtfn:1
  //cmDspSysInstallCb(h, fl1p, &quottake&quot, fn1p, &quotin-2&quot, NULL );   // take-&gtfn:2
  //cmDspSysInstallCb(h, fn1p, &quotout&quot,  ro1p, &quotin-0&quot, NULL);    // fn-&gtprint  
  
  //cmDspSysInstallCb(h, fl1p, &quotbeg&quot,  ro1p, &quotin-1&quot, NULL);  //   
  //cmDspSysInstallCb(h, fl1p, &quotend&quot,  ro1p, &quotin-2&quot, NULL);  //  
  
  //cmDspSysInstallCb(h, ro1p, &quotout-0&quot, wt1p, &quotfn&quot, NULL );   // fn-&gtwt:fn
  //cmDspSysInstallCb(h, ro1p, &quotout-1&quot, wt1p, &quotbeg&quot, NULL );  // beg-&gtwt:beg
  //cmDspSysInstallCb(h, ro1p, &quotout-2&quot, wt1p, &quotend&quot, NULL );  // end-&gtwt:end  
  
  
  return cmDspSysLastRC(h);
}




cmDspPgm_Pickups0 : 'fluxo' with loop-record, echo, rectify, and pitch-shift.

cmDspRC_t _cmDspSysPgm_Pickups0( cmDspSysH_t h, void** userPtrPtr )
{
  unsigned i;
  unsigned chCnt = 8;
  
  double delayFb    = 0.0;
  double delayMaxMs = 1000.0;
  cmDspInst_t* chArray[chCnt];
  
  cmDspInst_t* m_mxWet  = cmDspSysAllocInst(h,"Scalar", "Mstr Wet",      5, kNumberDuiId, 0.0,  2.0, 0.01, 1.0 ); 
  cmDspInst_t* m_mxDry  = cmDspSysAllocInst(h,"Scalar", "Mstr Dry",      5, kNumberDuiId, 0.0,  2.0, 0.01, 1.0 );
  cmDspSysNewColumn(h,0);
  cmDspInst_t* m_lpByp  = cmDspSysAllocInst(h,"Button", "Mstr Lp Byps",  2, kCheckDuiId, 0.0 );
  cmDspInst_t* m_lpRcd  = cmDspSysAllocInst(h,"Button", "Mstr Lp Recd",  2, kCheckDuiId, 0.0 );
  cmDspInst_t* m_lpRat  = cmDspSysAllocInst(h,"Scalar", "Mstr Lp Ratio", 5, kNumberDuiId, 0.0,  10.0, 0.01, 1.0 );
  cmDspSysNewColumn(h,0);
  cmDspInst_t* m_dlyByp = cmDspSysAllocInst(h,"Button", "Mstr Dly Byps", 2, kCheckDuiId, 0.0 );
  cmDspInst_t* m_dlyMs  = cmDspSysAllocInst(h,"Scalar", "Mstr Dly Time", 5, kNumberDuiId, 0.0,  delayMaxMs, 1.0,  0.0 );
  cmDspInst_t* m_dlyFb  = cmDspSysAllocInst(h,"Scalar", "Mstr Dly Fb",   5, kNumberDuiId, 0.0,  0.999,      0.01, 0.0 );
  cmDspSysNewColumn(h,0);
  cmDspInst_t* m_psByp = cmDspSysAllocInst(h,"Button", "Mstr PS Byps",   2, kCheckDuiId, 0.0 );
  cmDspInst_t* m_psRat = cmDspSysAllocInst(h,"Scalar", "Mstr PS Ratio",  5, kNumberDuiId, 0.0,  10.0, 0.01, 1.0 );
  cmDspSysNewColumn(h,0);
  cmDspInst_t* m_rcByp = cmDspSysAllocInst(h,"Button", "Mstr Rect Byps", 2, kCheckDuiId, 0.0 );
  
  cmDspSysInsertHorzBorder(h);
  
  for(i=0; i<chCnt; ++i)
  {
    int    chIdx      = i;
    
    cmDspInst_t* mxWet  = cmDspSysAllocInst(h,"Scalar", "Wet",        5, kNumberDuiId, 0.0,  2.0, 0.01, 1.0 ); 
    cmDspInst_t* mxDry  = cmDspSysAllocInst(h,"Scalar", "Dry",        5, kNumberDuiId, 0.0,  2.0, 0.01, 1.0 );
    cmDspInst_t* lpByp  = cmDspSysAllocInst(h,"Button", "Lp Byps",    2, kCheckDuiId,  0.0 );
    cmDspInst_t* lpRcd  = cmDspSysAllocInst(h,"Button", "Lp Recd",    2, kCheckDuiId,  0.0 );
    cmDspInst_t* lpRat  = cmDspSysAllocInst(h,"Scalar", "Lp Ratio",   5, kNumberDuiId, 0.0,  10.0, 0.01, 1.0 );
    cmDspInst_t* dlyByp = cmDspSysAllocInst(h,"Button", "Delay Byps", 2, kCheckDuiId,  0.0 );
    cmDspInst_t* dlyMs  = cmDspSysAllocInst(h,"Scalar", "Delay Time", 5, kNumberDuiId, 0.0,  delayMaxMs, 1.0,  0.0 );
    cmDspInst_t* dlyFb  = cmDspSysAllocInst(h,"Scalar", "Delay Fb",   5, kNumberDuiId, 0.0,  0.999,      0.01, 0.0 );
    cmDspInst_t* psByp  = cmDspSysAllocInst(h,"Button", "PS Byps",    2, kCheckDuiId, 0.0 );
    cmDspInst_t* psRat  = cmDspSysAllocInst(h,"Scalar", "PS Ratio",   5, kNumberDuiId, 0.0,  10.0, 0.01, 1.0 );
    cmDspInst_t* rcByp  = cmDspSysAllocInst(h,"Button", "Rect Byps",  2, kCheckDuiId, 0.0 );
    
    cmDspInst_t* ain  = cmDspSysAllocInst(h, "AudioIn",   NULL, 1, chIdx );
    cmDspInst_t* loop = cmDspSysAllocInst(h, "LoopRecd",  NULL, 0 );
    cmDspInst_t* dely = cmDspSysAllocInst(h, "Delay",     NULL, 2, delayMaxMs, delayFb );
    cmDspInst_t* pshf = cmDspSysAllocInst(h, "PShift",    NULL, 0 );
    cmDspInst_t* rect = cmDspSysAllocInst(h, "Rectify",   NULL, 0 );
    cmDspInst_t* amix = cmDspSysAllocInst(h, "AMix",      NULL, 1, 2 );
    //cmDspInst_t* aout = cmDspSysAllocInst(h, &quotAudioOut&quot, NULL, 1, chIdx );
    
    chArray[i] = amix;
    
    cmDspSysNewColumn(h,0);
    
    cmDspSysConnectAudio(h, ain,  "out", loop, "in");           // ain -&gt loop
    cmDspSysConnectAudio(h, loop, "out", dely, "in");           // loop -&gt delay
    cmDspSysConnectAudio(h, dely, "out", pshf, "in");           // delay -&gt pshf
    cmDspSysConnectAudio(h, pshf, "out", rect, "in");           // pshf -&gt rect
    cmDspSysConnectAudio(h, rect, "out", amix, "in-0");         // rect -&gt mix_wet
    cmDspSysConnectAudio(h, ain,  "out", amix, "in-1");         // ain -&gt mix_dry
    //cmDspSysConnectAudio(h, amix, &quotout&quot, aout, &quotin&quot);          // mix   -&gt out 
    
    cmDspSysInstallCb(h, mxWet, "val", amix, "gain-0", NULL );
    cmDspSysInstallCb(h, mxDry, "val", amix, "gain-1", NULL );
    cmDspSysInstallCb(h, lpByp, "out", loop, "bypass", NULL );
    cmDspSysInstallCb(h, lpRcd, "out", loop, "recd",   NULL );
    cmDspSysInstallCb(h, lpRat, "val", loop, "ratio",  NULL );
    cmDspSysInstallCb(h, dlyByp,"val", dely, "bypass", NULL );
    cmDspSysInstallCb(h, dlyMs, "val", dely, "time",   NULL );
    cmDspSysInstallCb(h, dlyFb, "out", dely, "fb",     NULL );
    cmDspSysInstallCb(h, psByp, "out", pshf, "bypass", NULL );
    cmDspSysInstallCb(h, psRat, "val", pshf, "ratio",  NULL );
    cmDspSysInstallCb(h, rcByp, "out", rect, "bypass", NULL );
    
    cmDspSysInstallCb(h, m_mxWet, "val", mxWet, "in",  NULL );
    cmDspSysInstallCb(h, m_mxDry, "val", mxDry, "in",  NULL );
    cmDspSysInstallCb(h, m_lpByp, "out", lpByp, "in",  NULL );
    cmDspSysInstallCb(h, m_lpRcd, "out", lpRcd, "in",  NULL );
    cmDspSysInstallCb(h, m_lpRat, "val", lpRat, "in",  NULL ); 
    cmDspSysInstallCb(h, m_dlyByp,"out", dlyByp,"in",  NULL );
    cmDspSysInstallCb(h, m_dlyMs, "val", dlyMs, "in",  NULL );
    cmDspSysInstallCb(h, m_dlyFb, "val", dlyFb, "in",  NULL );    
    cmDspSysInstallCb(h, m_psByp, "out", psByp, "in",  NULL );
    cmDspSysInstallCb(h, m_psRat, "val", psRat, "in",  NULL );   
    cmDspSysInstallCb(h, m_rcByp, "out", rcByp, "in",  NULL );
    
  }
  
  double dfltGain = 0.5;
  cmDspInst_t* omix = cmDspSysAllocInst(h,  "AMix",     NULL, 9, 8, dfltGain, dfltGain, dfltGain, dfltGain, dfltGain, dfltGain, dfltGain, dfltGain );
  cmDspInst_t* aout0 = cmDspSysAllocInst(h, "AudioOut", NULL, 1, 0 );
  cmDspInst_t* aout1 = cmDspSysAllocInst(h, "AudioOut", NULL, 1, 1 );
  cmDspInst_t* aout2 = cmDspSysAllocInst(h, "AudioOut", NULL, 1, 2 );
  cmDspInst_t* aout3 = cmDspSysAllocInst(h, "AudioOut", NULL, 1, 3 );
  
  
  for(i=0; i<chCnt; ++i)
  {
    char label[32];
    snprintf(label,32,"in-%i",i);
    cmDspSysConnectAudio(h, chArray[i], "out", omix, label);
  }
  
  cmDspSysConnectAudio(h, omix, "out", aout0, "in");
  cmDspSysConnectAudio(h, omix, "out", aout1, "in");
  cmDspSysConnectAudio(h, omix, "out", aout2, "in");
  cmDspSysConnectAudio(h, omix, "out", aout3, "in");
  
  return kOkDspRC;
}


cmDspPgm_AutoGain : 'fluxo' channel calibration program.

#include "cmAudioFile.h"
#include "cmProcObj.h"
#include "cmProc.h"
#include "cmProc3.h"

// Usage:
// 1) Push 'start'.
// 2) Select the first element in the Ch Cfg List UI.
// 3) Play several examples of the note.
// 4) Select the next element in the Ch Cfg List UI.
// 5) Go to 3) until all ch's have been played.
// 6) Push 'proc'. A new set of gains will be calc'd and sent to the audio input channels.
// Note that if a mistake is made while playing a set of notes in 3) then 
// push select the same element from the list again and replay.
// The order the notes are played in does not make any difference.

cmDspRC_t _cmDspSysPgm_AutoGain( cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t       rc              = kOkDspRC;
  unsigned        i;
  //unsigned        j;
  cmErr_t         err;  
  const cmChar_t* errLabelPtr     = NULL;
  cmCtx_t*        cmCtx           = cmDspSysPgmCtx(h);
  unsigned        chCnt           = 0;
  unsigned        nsChCnt         = 0;
  const cmChar_t* chCfgFn         = NULL;
  const cmChar_t* chCfgPath       = NULL;
  unsigned        agMedCnt        = 5;
  unsigned        agAvgCnt        = 9;
  unsigned        agSuprCnt       = 3;
  unsigned        agOffCnt        = 3;
  cmReal_t        agSuprCoeff     = 1.4;
  cmReal_t        agOnThreshDb    = -53.0;
  cmReal_t        agOffThreshDb   = -80.0;
  cmReal_t        agHopMs         = 25;
  //cmReal_t        cdMaxTimeSpanMs = 50;
  //cmReal_t        cdMinNoteCnt    = 3;  
  unsigned        labelCharCnt    = 31;
  char            label0[ labelCharCnt + 1];
  
  
  cmErrSetup(&err,&cmCtx->rpt,"Auto-gain");
  
  // get the name of channel cfg file
  if( cmJsonPathValues( cmDspSysPgmRsrcHandle(h),"cfg/",NULL,&errLabelPtr,
  "chCfgFn",             kStringTId, &chCfgFn,
  "agParms/hopMs",       kRealTId,   &agHopMs,
  "agParms/medCnt",      kIntTId,    &agMedCnt,
  "agParms/avgCnt",      kIntTId,    &agAvgCnt,
  "agParms/suprCnt",     kIntTId,    &agSuprCnt,
  "agParms/offCnt",      kIntTId,    &agOffCnt,
  "agParms/suprCoeff",   kRealTId,   &agSuprCoeff,
  "agParms/onThreshDb",  kRealTId,   &agOnThreshDb,
  "agParms/offThreshDb", kRealTId,   &agOffThreshDb,
  NULL) != kOkJsRC )
  {
    rc = cmErrMsg(&err,kPgmCfgFailDspRC,"An error occurred while reading the required auto-tune JSON parameters.");
    goto errLabel;
  }
  
  // get the count of channels from the ch. cfg. array
  if(( chCnt = cmChCfgChannelCount(cmCtx,chCfgFn,&nsChCnt)) == 0 )
  {
    rc = cmErrMsg(&err,kPgmCfgFailDspRC,"Unable to obtain the channel count from '%s'.",cmStringNullGuard(chCfgFn));
    goto errLabel;
  }
  
  // prepend the prefs directory to the ch. cfg filename 
  chCfgPath = cmFsMakeFn(cmFsPrefsDir(),chCfgFn,NULL,NULL);
  
  if( rc == kOkDspRC )
  {
    //mDspInst_t* ain[chCnt];
    cmDspInst_t* ef[chCnt];
    cmDspInst_t* mtr[chCnt];
    cmDspInst_t* amtr[chCnt];
    cmDspInst_t* on[chCnt];
    cmDspInst_t* off[chCnt];
    cmDspInst_t* rms[chCnt];
    ///cmDspInst_t* fdr0[chCnt];
    ///cmDspInst_t* fdr1[chCnt];
    ///cmDspInst_t* fdr2[chCnt];    
    
    // allocate the audio inputs
    //for(i=0; i&ltchCnt; ++i)
    //  ain[i] = cmDspSysAllocAudioIn(h,i,1.0);    
    unsigned inChCnt;
    cmDspInst_t** ain = cmDspSysAllocAudioInAR( h, "audioInMap", 1.0, &inChCnt );
    
    // allocate the auto-gain calibration object
    cmDspInst_t* ag     = cmDspSysAllocInst( h, "AutoGain",     NULL,     9, chCnt, agHopMs,agMedCnt,agAvgCnt,agSuprCnt,agOffCnt,agSuprCoeff,agOnThreshDb,agOffThreshDb );
    
    // allocate the command buttons
    cmDspInst_t* start  = cmDspSysAllocButton(h, "start",  0);
    cmDspInst_t* proc   = cmDspSysAllocButton(h, "proc",   0);
    cmDspInst_t* cancel = cmDspSysAllocButton(h, "cancel", 0);
    cmDspInst_t* write  = cmDspSysAllocButton(h, "write",  0);
    cmDspInst_t* print  = cmDspSysAllocButton(h, "print",  0);
    cmDspInst_t* chMenu = cmDspSysAllocMsgList(h, chCfgPath, "ch_array", 0 );
    cmDspInst_t* onThr  = cmDspSysAllocScalar(h,"On  Thresh",-100.0,0.0,0.1,-45.0);
    cmDspInst_t* offThr = cmDspSysAllocScalar(h,"Off Thresh",-100.0,0.0,0.1,-80.0);
    //cmDspInst_t* prt    = cmDspSysAllocInst(h,&quotPrinter&quot,NULL,1,&quotag&gt&quot);
    cmDspInst_t* sub    = cmDspSysAllocInst(h,"ScalarOp",NULL,6,2,"+","in-0",0.0,"in-1",-1.0);
    
    cmDspSysNewColumn(h,200);
    cmDspSysAllocLabel(h,"EF Gate",kLeftAlignDuiId);
    
    // allocate the envelope followers and meters
    for(i=0; i<chCnt; ++i )
    {
      snprintf(label0,labelCharCnt,"%2i",i);
      ef[i]   = cmDspSysAllocInst( h, "EnvFollow", NULL, 0 );
      mtr[i]  = cmDspSysAllocInst( h, "Meter",label0, 3, 0.0, 0.0, 1.0 );
    }
    
    cmDspSysNewColumn(h,200);
    cmDspSysAllocLabel(h,"Audio",kLeftAlignDuiId);
    
    // allocate the envelope followers and meters
    for(i=0; i<chCnt; ++i )
    {
      amtr[i]  = cmDspSysAllocInst( h, "AMeter", NULL, 0 );
    }
    
    // chord detector, note selector, mix0, mix1, mix2
    ///cmDspInst_t* cdp = cmDspSysAllocInst(h, &quotChordDetect&quot, NULL, 1, &quotcdSel&quot );
    ///cmDspInst_t* nsp = cmDspSysAllocInst(h, &quotNoteSelect&quot,  NULL, 1, chCnt );    
    
    // onset count display
    cmDspSysNewColumn(h,150);
    cmDspSysAllocLabel(h,"Onsets",kLeftAlignDuiId);
    for(i=0; i<chCnt; ++i)
      on[i] = cmDspSysAllocScalar(h,NULL,0,1,0,0);
    
    // offset count display
    cmDspSysNewColumn(h,150);
    cmDspSysAllocLabel(h,"Offsets",kLeftAlignDuiId);
    for(i=0; i<chCnt; ++i)
      off[i] = cmDspSysAllocScalar(h,NULL,0,1,0,0);
    
    // offset count display
    cmDspSysNewColumn(h,150);
    cmDspSysAllocLabel(h,"RMS",kLeftAlignDuiId);
    for(i=0; i<chCnt; ++i)
      rms[i] = cmDspSysAllocScalar(h,NULL,0,1,0,0);
    
    //
    //    // note select gate meters
    //    for(j=0; j&lt3; ++j)
    //    {
    //      snprintf(label0,labelCharCnt,&quotSet %i&quot,j);
    //      cmDspSysNewColumn(h,50);
    //      cmDspSysAllocLabel(h,label0,kLeftAlignDuiId );
    //
    //      
    //      for(i=0; i&ltchCnt; ++i)
    //      {
    //        cmDspInst_t* m = cmDspSysAllocInst(h, &quotMeter&quot, NULL, 3, 0.0, 0.0, 1.0 );
    //        switch(j)
    //        {
    //          case 0: fdr0[i] = m; break;
    //          case 1: fdr1[i] = m; break;
    //          case 2: fdr2[i] = m; break;
    //            
    //        }
    //      }
    //    }
    //    
    //    // chord detector parameters
    //    cmDspSysNewColumn(h,150);
    //    cmDspSysAllocLabel(h,&quotChord Detector&quot,kLeftAlignDuiId);
    //    cmDspInst_t* cdSpanMs  = cmDspSysAllocScalar(h,&quotSpan Ms&quot, 10.0,1000.0,1.0,cdMaxTimeSpanMs);
    //    cmDspInst_t* cdNoteCnt = cmDspSysAllocScalar(h,&quotNote Cnt&quot, 1.0, 100.0,1.0,cdMinNoteCnt );
    //    cmDspInst_t* cdCount   = cmDspSysAllocScalar(h,&quotCh. Count&quot,    0,1,0,0);
    //
    //    
    //    
    
    // allocate an audio mixer and two audio output channels
    cmDspInst_t* amix   = cmDspSysAllocInst( h, "AMix", NULL, 1, chCnt);
    cmDspInst_t* ao0    = cmDspSysAllocAudioOut(h,0,1.0);
    cmDspInst_t* ao1    = cmDspSysAllocAudioOut(h,1,1.0);
    
    // alloc chCfg last so that it's default outputs are applied to connected objects
    cmDspInst_t* chCfg  = cmDspSysAllocInst( h, "ChCfg",     NULL,     1, chCfgFn );
    
    if((rc = cmDspSysLastRC(h)) != kOkDspRC )
      goto errLabel;
    
    cmDspSysConnectAudioN11N(h,ain, "out", ag,   "in", chCnt);  // ain -&gt auto gain
    cmDspSysConnectAudioN11N(h,ain, "out", amix, "in", chCnt);  // ain -&gt amix
    cmDspSysConnectAudioN1N1(h,ain, "out", ef,   "in", chCnt);  // ain -&gt EF
    cmDspSysConnectAudioN1N1(h, ain,  "out", amtr, "in",chCnt);
    
    cmDspSysInstallCb1N1N(h, ag,    "gain",  chCfg, "gain", chCnt );  // ag -&gt chCfg (gain)
    cmDspSysInstallCb1NN1(h, chCfg, "gain",  ain,   "gain", chCnt );  // cgCfg -&gt ain (gain)
    cmDspSysInstallCb1NN1(h, chCfg, "ch",    ain,   "ch",   chCnt );  // cgCfg -&gt ain (ch)
    cmDspSysInstallCbN1N1(h, ef,    "gate",  mtr,   "in",   chCnt );  // EF gate -&gt meter
    
    cmDspSysInstallCb11N1(h, onThr,  "val",  ef,    "ondb",  chCnt );  
    cmDspSysInstallCb11N1(h, offThr, "val",  ef,    "offdb", chCnt );  
    cmDspSysInstallCbN1N1(h, ef,     "ons",  on,    "val",   chCnt );  // EF -&gt onset count
    cmDspSysInstallCbN1N1(h, ef,     "offs", off,   "val",   chCnt );  // EF -&gt offset count
    cmDspSysInstallCbN1N1(h, ef,     "rms",  rms,   "val",   chCnt );
    
    ///cmDspSysInstallCbN11N(h, ef,     &quotgate&quot, cdp,   &quotgate&quot, chCnt ); // EF -&gt CD gate
    ///cmDspSysInstallCbN11N(h, ef,     &quotrms&quot,  cdp,   &quotrms&quot,  chCnt ); // EF -&gt CD rms    
    
    ///cmDspSysInstallCb1N1N(h, cdp,    &quotgate&quot, nsp,   &quotgate&quot, chCnt ); // CD -&gt NS gate
    ///cmDspSysInstallCb1N1N(h, cdp,    &quotrms&quot,  nsp,   &quotrms&quot,  chCnt ); // CD -&gt NS rms
    ///cmDspSysInstallCb1NN1(h, nsp,    &quotgate-0&quot,fdr0,  &quotin&quot,   chCnt ); // NS -&gt Fader 0 gate
    ///cmDspSysInstallCb1NN1(h, nsp,    &quotgate-1&quot,fdr1,  &quotin&quot,   chCnt ); // NS -&gt Fader 1 gate
    ///cmDspSysInstallCb1NN1(h, nsp,    &quotgate-2&quot,fdr2,  &quotin&quot,   chCnt ); // NS -&gt Fader 2 gate       
    
    
    cmDspSysConnectAudio(h, amix, "out", ao0, "in");   // amix -&gt aout 0
    cmDspSysConnectAudio(h, amix, "out", ao1, "in");   // amix -&gt aout 1
    
    
    //cmDspSysInstallCb(h, chMenu, &quotch&quot,  ag,    &quotid&quot, NULL );
    cmDspSysInstallCb(h, chMenu, "sel", sub, "in-0", NULL );
    cmDspSysInstallCb(h, sub,    "out", ag, "id", NULL );
    
    cmDspSysInstallCb(h, start,  "sym", ag,    "sel", NULL );
    cmDspSysInstallCb(h, proc,   "sym", ag,    "sel", NULL );
    cmDspSysInstallCb(h, cancel, "sym", ag,    "sel", NULL );
    cmDspSysInstallCb(h, print,  "sym", ag,    "sel", NULL );  
    cmDspSysInstallCb(h, print,  "sym", chCfg, "sel", NULL );
    cmDspSysInstallCb(h, write,  "sym", chCfg, "sel", NULL );
    
    //
    //cmDspSysInstallCb(h, cdSpanMs,  &quotval&quot,    cdp,     &quotspan&quot,  NULL );
    //cmDspSysInstallCb(h, cdNoteCnt, &quotval&quot,    cdp,     &quotnotes&quot, NULL );
    //cmDspSysInstallCb(h, cdp,       &quotcount&quot,  cdCount, &quotval&quot,   NULL );
    //cmDspSysInstallCb(h, cdp,       &quotdetect&quot, nsp,     &quottrig&quot,  NULL );
    //    
    //    
  }
  errLabel:
  
  cmFsFreeFn(chCfgPath);
  
  return rc;
  
}


cmDspPgm_PickupFxFile : 'fluxo' noise shapers.
cmDspRC_t _cmDspSysPgm_PickupFxFile( cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t       rc        = kOkDspRC;
  cmErr_t         err;
  cmCtx_t*        cmCtx     = cmDspSysPgmCtx(h);
  unsigned        chCnt     = 0;
  unsigned        nsChCnt   = 0;
  const cmChar_t* chCfgPath = NULL;
  const cmChar_t* chCfgFn   = "pick_chs8.js";
  double          cfMinHz   = 20.0;
  double          cfAlpha   = 0.9;
  bool            cfFbFl    = true;
  unsigned        sgShapeId = 2;
  const cmChar_t* afn       = "/home/kevin/media/audio/gate_detect/gate_detect0.aif";
  double        abeg[]    = { 9.842046, 18.838291, 27.007957, 35.562079, 45.461793, 52.920218, 60.436312, 68.913543};
  double        aend[]    = {11.399088, 20.645229, 28.891786, 37.311349, 47.287954, 54.131251, 62.473923, 72.142964};
  bool            cfBypassFl  = false;
  unsigned        i;
  
  
  cmErrSetup(&err,&cmCtx->rpt,"Pickup Effects");
  
  // prepend the prefs directory to the ch. cfg filename 
  chCfgPath = cmFsMakeFn(cmFsPrefsDir(),chCfgFn,NULL,NULL);
  
  // get the count of channels from the ch. cfg. array
  if(( chCnt = cmChCfgChannelCount(cmCtx,chCfgFn,&nsChCnt)) == 0 )
  {
    rc = cmErrMsg(&err,kPgmCfgFailDspRC,"Unable to obtain the channel count from '%s'.",cmStringNullGuard(chCfgFn));
    goto errLabel;
  }
  
  if( rc == kOkDspRC )
  {
    cmDspInst_t* af[chCnt];
    //cmDspInst_t* aout[chCnt];
    cmDspInst_t* ef[chCnt];
    cmDspInst_t* cf[chCnt];
    cmDspInst_t* sg[chCnt];
    cmDspInst_t* mtr[chCnt];
    cmDspInst_t* mute[chCnt];
    
    cmDspInst_t* phs =  cmDspSysAllocInst(h,"Phasor",   NULL,  0 );
    
    // allocate the audio inputs
    for(i=0; i<chCnt; ++i)
    {
      unsigned labelCharCnt = 31;
      cmChar_t label[labelCharCnt+1];
      snprintf(label,labelCharCnt,"%i",i);
      
      int sbeg = floor(abeg[i] * cmDspSysSampleRate(h));
      int send = floor(aend[i] * cmDspSysSampleRate(h));
      
      //ain[i]  = cmDspSysAllocAudioIn( h,i,1.0);
      af[i]   = cmDspSysAllocInst(h,"WaveTable",NULL,  6, ((int)cmDspSysSampleRate(h)), 1, afn, -1, sbeg, send );
      //aout[i] = cmDspSysAllocAudioOut(h,i,1.0);      
      ef[i]   = cmDspSysAllocInst(h, "EnvFollow", NULL, 0 );
      sg[i]   = cmDspSysAllocInst(h, "SigGen",    NULL, 2, 1000.0, sgShapeId );
      cf[i]   = cmDspSysAllocInst(h, "CombFilt",  NULL, 5, cfBypassFl, cfMinHz, cfFbFl, cfMinHz, cfAlpha );
      mtr[i]  = cmDspSysAllocInst( h, "Meter",label, 3, 0.0, 0.0, 1.0 );
    }
    
    // allocate the ch cfg last so that it's default outputs initialize connected objects
    cmDspInst_t* chCfg  = cmDspSysAllocInst( h, "ChCfg",     NULL,     1, chCfgFn );  
    cmDspInst_t* mix    = cmDspSysAllocInst( h, "AMix",     NULL,      1, chCnt );
    
    cmDspSysNewColumn(h,50);
    for(i=0; i<chCnt; ++i)
      mute[i] = cmDspSysAllocCheck(h,"",0);
    
    // checkk for allocation errors
    if((rc = cmDspSysLastRC(h)) != kOkDspRC )
      goto errLabel;
    
    // 
    //cmDspSysConnectAudioN1N1(h, ain,   &quotout&quot,  aout,  &quotin&quot,   chCnt );    
    cmDspSysConnectAudio11N1(h, phs,   "out",  af,    "phs",  chCnt ); 
    cmDspSysConnectAudioN1N1(h, af,    "out",  ef,    "in",   chCnt );  // af -&gt EF 
    cmDspSysConnectAudioN1N1(h, sg,    "out",  cf,    "in",   chCnt );  // sg -&gt CF
    cmDspSysConnectAudioN11N(h, cf,    "out",  mix,   "in",   chCnt );  // CF -&gt mix
    //cmDspSysInstallCb1NN1(   h, chCfg, &quotgain&quot, ain,   &quotgain&quot, chCnt ); // chCfg -&gt ain gain
    cmDspSysInstallCb1NN1(   h, chCfg, "hz",   cf,    "hz",   chCnt );  // chCfg -&gt CF Hz
    //cmDspSysInstallCbN1N1(   h, ef,    &quotrms&quot,  aout,  &quotgain&quot, chCnt ); // EF  -&gt aout gain
    cmDspSysInstallCbN1N1(   h, ef,    "rms",  mtr,   "in",   chCnt );  // EF -&gt meter RMS
    cmDspSysInstallCbN11N(   h, ef,    "rms",  mix,   "gain", chCnt );
    cmDspSysInstallCbN11N(   h, mute,  "out",  mix,   "mute", chCnt );  // mute -&gt mix
  }
  
  errLabel:
  cmFsFreeFn(chCfgPath);
  
  return rc;
}


cmDspPgm_NoiseTails : 'fluxo' noise shapers.
cmDspRC_t _cmDspSysPgm_NoiseTails( cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t       rc        = kOkDspRC;
  cmErr_t         err;
  cmCtx_t*        cmCtx     = cmDspSysPgmCtx(h);
  unsigned        chCnt     = 0;
  unsigned        nsChCnt   = 0;
  const cmChar_t* chCfgPath = NULL;
  const cmChar_t* chCfgFn   = "pick_chs8.js";
  double          cfMinHz   = 20.0;
  double          cfHz      = 500;
  double          cfAlpha   = 0.9;
  bool            cfFbFl    = true;
  bool            cfBypassFl= false;
  unsigned        sgShapeId = 3;
  double          dfltDelayMs = 100;
  unsigned        i;
  
  
  cmErrSetup(&err,&cmCtx->rpt,"Noise Tails");
  
  // prepend the prefs directory to the ch. cfg filename 
  chCfgPath = cmFsMakeFn(cmFsPrefsDir(),chCfgFn,NULL,NULL);
  
  // get the count of channels from the ch. cfg. array
  if(( chCnt = cmChCfgChannelCount(cmCtx,chCfgFn,&nsChCnt)) == 0 )
  {
    rc = cmErrMsg(&err,kPgmCfgFailDspRC,"Unable to obtain the channel count from '%s'.",cmStringNullGuard(chCfgFn));
    goto errLabel;
  }
  
  if( rc == kOkDspRC )
  {
    cmDspInst_t* ain[chCnt];
    cmDspInst_t* ef[chCnt];
    cmDspInst_t* cf[chCnt];
    cmDspInst_t* sg[chCnt];
    cmDspInst_t* mtr[chCnt];
    cmDspInst_t* add[chCnt];
    cmDspInst_t* mul[chCnt];
    cmDspInst_t* dly[chCnt];
    
    // allocate the audio inputs
    for(i=0; i<chCnt; ++i)
    {
      unsigned labelCharCnt = 31;
      cmChar_t label[labelCharCnt+1];
      snprintf(label,labelCharCnt,"%i",i);
      
      ain[i]  = cmDspSysAllocAudioIn(  h, i, 1.0);
      ef[i]   = cmDspSysAllocInst( h, "EnvFollow", NULL, 0 );
      sg[i]   = cmDspSysAllocInst( h, "SigGen",    NULL, 2, 1000.0, sgShapeId );
      cf[i]   = cmDspSysAllocInst( h, "CombFilt",  NULL, 5, cfBypassFl, cfMinHz, cfFbFl, cfHz, cfAlpha );
      mtr[i]  = cmDspSysAllocInst( h, "Meter",label, 3, 0.0, 0.0, 1.0 );
      add[i]  = cmDspSysAllocInst( h, "ScalarOp", NULL, 6, 2, "+", "in-0", 0.0, "in-1", 0.0);
      mul[i]  = cmDspSysAllocInst( h, "ScalarOp", NULL, 6, 2, "*", "in-0", 0.0, "in-1", 0.99);
      dly[i]  = cmDspSysAllocInst( h, "MsgDelay", NULL, 2, 1000, dfltDelayMs );
    }
    
    // allocate the ch cfg last so that it's default outputs initialize connected objects
    cmDspInst_t* chCfg  = cmDspSysAllocInst( h, "ChCfg",    NULL,     1, chCfgFn );  
    cmDspInst_t* mix    = cmDspSysAllocInst( h, "AMix",     NULL,     1, chCnt );
    cmDspInst_t* ao0    = cmDspSysAllocAudioOut( h, 0, 1.0 );
    cmDspInst_t* ao1    = cmDspSysAllocAudioOut( h, 1, 1.0 );
    cmDspInst_t* alpha  = cmDspSysAllocScalar(   h, "alpha", -1.0, 1.0, 0.001, cfAlpha );
    cmDspInst_t* decay  = cmDspSysAllocScalar(   h, "decay", -1.0, 1.0, 0.001, 0.5);
    cmDspInst_t* delay  = cmDspSysAllocScalar(   h, "delay", 0.0,  1000.0, 1.0, dfltDelayMs );
    cmDspInst_t* zero   = cmDspSysAllocScalar(   h, "zero",  0.0,  0.0, 0.0, 0.0);
    
    // check for allocation errors
    if((rc = cmDspSysLastRC(h)) != kOkDspRC )
      goto errLabel;
    
    
    cmDspSysConnectAudioN1N1( h, ain, "out",  ef,  "in",   chCnt );  // ain -&gt EF 
    cmDspSysConnectAudioN1N1( h, sg,  "out",  cf,  "in",   chCnt );  // sg -&gt CF
    cmDspSysConnectAudioN11N( h, cf,  "out",  mix, "in",  chCnt );   // cf -&gt mix
    cmDspSysConnectAudio(     h, mix, "out",  ao0, "in");            // mix -&gt aout L 
    cmDspSysConnectAudio(     h, mix, "out",  ao1, "in");            // mix -&gt aout R
    
    cmDspSysInstallCb1NN1(   h, chCfg, "gain", ain,  "gain", chCnt );  // chCfg -&gt ain gain
    cmDspSysInstallCb1NN1(   h, chCfg, "hz",   cf,   "hz",   chCnt );    // chCfg -&gt CF Hz
    cmDspSysInstallCbN1N1(   h, ef,    "rms",  add,  "in-0", chCnt );    // EF -&gt mul 0
    cmDspSysInstallCbN1N1(   h, mul,   "out",  add,  "in-1", chCnt );    // mul -&gt add
    cmDspSysInstallCbN1N1(   h, add,   "out",  dly,  "in",   chCnt );    // add -&gt delay
    cmDspSysInstallCbN11N(   h, dly,   "out",  mix,  "gain", chCnt );    // delay -&gt mix gain
    cmDspSysInstallCbN1N1(   h, add,   "out",  mul,  "in-0", chCnt);     // add -&gt mul (feedback)
    cmDspSysInstallCb11N1(   h, decay, "val",  mul,  "in-1", chCnt );    // decay ctl
    cmDspSysInstallCbN1N1(   h, ef,    "gate", mtr,  "in",   chCnt );    // EF -&gt meter RMS
    cmDspSysInstallCb11N1(   h, alpha, "val",  cf,   "alpha",chCnt );    // CF alpha
    cmDspSysInstallCb11N1(   h, delay, "val",  dly,  "delay",chCnt );    // Delay ctl
    cmDspSysInstallCb111N(   h, zero,  "val",  mix,  "in",   chCnt );   
  }
  
  errLabel:
  cmFsFreeFn(chCfgPath);
  
  return rc;
}


cmDspPgm_NoiseTails2 : 'fluxo' noise shapers.
cmDspRC_t _cmDspSysPgm_NoiseTails2( cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t       rc           = kOkDspRC;
  cmErr_t         err;
  cmCtx_t*        cmCtx        = cmDspSysPgmCtx(h);
  unsigned        chCnt        = 0;
  unsigned        nsChCnt      = 0;
  const cmChar_t* chCfgPath    = NULL;
  const cmChar_t* chCfgFn      = "pick_chs8.js";
  double          cfMinHz      = 20.0;
  
  double          cfHz         = 500;
  double          cfAlpha      = 0.9;
  bool            cfFbFl       = true;
  bool            cfBypassFl   = false;
  unsigned        sgShapeId    = 3;
  
  double          adsrMaxMs    = 10000;
  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.0;
  
  unsigned        i;
  
  
  cmErrSetup(&err,&cmCtx->rpt,"Noise Tails");
  
  // prepend the prefs directory to the ch. cfg filename 
  chCfgPath = cmFsMakeFn(cmFsPrefsDir(),chCfgFn,NULL,NULL);
  
  // get the count of channels from the ch. cfg. array
  if(( chCnt = cmChCfgChannelCount(cmCtx,chCfgFn,&nsChCnt)) == 0 )
  {
    rc = cmErrMsg(&err,kPgmCfgFailDspRC,"Unable to obtain the channel count from '%s'.",cmStringNullGuard(chCfgFn));
    goto errLabel;
  }
  
  if( rc == kOkDspRC )
  {
    cmDspInst_t* ain[chCnt];
    cmDspInst_t* ef[chCnt];
    cmDspInst_t* cf[chCnt];
    cmDspInst_t* sg[chCnt];
    cmDspInst_t* mtr[chCnt];
    cmDspInst_t* add[chCnt];
    cmDspInst_t* mul[chCnt];
    cmDspInst_t* env[chCnt];
    cmDspInst_t* d2l[chCnt];
    cmDspInst_t* eq[chCnt];
    cmDspInst_t* mt[chCnt];
    
    // allocate the audio inputs
    for(i=0; i<chCnt; ++i)
    {
      unsigned labelCharCnt = 31;
      cmChar_t label[labelCharCnt+1];
      snprintf(label,labelCharCnt,"%i",i);
      
      ain[i]  = cmDspSysAllocAudioIn(  h, i, 1.0);
      ef[i]   = cmDspSysAllocInst( h, "EnvFollow", NULL, 0 );
      sg[i]   = cmDspSysAllocInst( h, "SigGen",    NULL, 2, 1000.0, sgShapeId );
      cf[i]   = cmDspSysAllocInst( h, "CombFilt",  NULL, 5, cfBypassFl, cfMinHz, cfFbFl, cfHz, cfAlpha );
      mtr[i]  = cmDspSysAllocInst( h, "Meter",label, 3, 0.0, 0.0, 1.0 );
      env[i]  = cmDspSysAllocInst( h, "Adsr",     NULL, 2, true, adsrMinLevel );
      d2l[i]  = cmDspSysAllocInst( h, "DbToLin",  NULL, 0 );
      add[i]  = cmDspSysAllocInst( h, "ScalarOp", NULL, 6, 2, "+", "in-0", 0.0, "in-1", 0.0);
      mul[i]  = cmDspSysAllocInst( h, "ScalarOp", NULL, 6, 2, "*", "in-0", 0.0, "in-1", 0.99);
      eq[i]   = cmDspSysAllocInst( h, "BiQuadEq", NULL, 5, eqBypassFl, eqModeSymId, eqF0hz, eqQ, eqFgain ); 
      mt[i]   = cmDspSysAllocInst( h, "MtDelay",  NULL, 9, mtBypassFl, mtTimeScale, mtFeedback,   20.0, 0.8,   15.0, 0.9,    12.0, 0.9 );  
    }
    
    // allocate the ch cfg last so that it's default outputs initialize connected objects
    cmDspInst_t* chCfg  = cmDspSysAllocInst(     h, "ChCfg",    NULL,     1, chCfgFn );  
    cmDspInst_t* mix    = cmDspSysAllocInst(     h, "AMix",     NULL,     1, chCnt );
    cmDspInst_t* ao0    = cmDspSysAllocAudioOut( h, 0, 1.0 );
    cmDspInst_t* ao1    = cmDspSysAllocAudioOut( h, 1, 1.0 );
    cmDspInst_t* alpha  = cmDspSysAllocScalar(   h, "alpha", -1.0, 1.0, 0.001, cfAlpha );
    cmDspInst_t* decay  = cmDspSysAllocScalar(   h, "decay", -1.0, 1.0, 0.001, 0.5);
    cmDspInst_t* zero   = cmDspSysAllocScalar(   h, "zero",   0.0, 0.0, 0.0,   0.0);
    // cmDspInst_t* print  = cmDspSysAllocButton(   h, &quotprint&quot, 0 );
    
    cmDspSysNewColumn(h,200);
    cmDspInst_t* dly   = cmDspSysAllocScalar( h, "Dly Ms",  adsrMinMs,   adsrMaxMs,   adsrIncMs, 0.0);
    cmDspInst_t* atk   = cmDspSysAllocScalar( h, "Atk Ms",  adsrMinMs,   adsrMaxMs,   adsrIncMs, 2000.0);
    cmDspInst_t* dcy   = cmDspSysAllocScalar( h, "Dcy Ms",  adsrMinMs,   adsrMaxMs,   adsrIncMs, 100.0);
    cmDspInst_t* hold  = cmDspSysAllocScalar( h, "Hold Ms", adsrMinMs,   adsrMaxMs,   adsrIncMs, 100.0);
    cmDspInst_t* rls   = cmDspSysAllocScalar( h, "Rls Ms",  adsrMinMs,   adsrMaxMs,   adsrIncMs, 4000.0);
    cmDspInst_t* alvl  = cmDspSysAllocScalar( h, "AdsrMax", adsrMinLevel,adsrMaxLevel,adsrIncLevel, adsrMaxLevel);  
    cmDspInst_t* sus   = cmDspSysAllocScalar( h, "Sustain", adsrMinLevel,adsrMaxLevel,adsrIncLevel, adsrSusLevel );  
    
    cmDspSysNewColumn(h,200);
    cmDspInst_t* onThr  = cmDspSysAllocScalar(h,"On  Thresh",-100.0,0.0,0.1,-55.0);
    cmDspInst_t* offThr = cmDspSysAllocScalar(h,"Off Thresh",-100.0,0.0,0.1,-80.0);
    
    cmDspInst_t* eqbyp   = cmDspSysAllocCheck(  h, "Eq Byp", 0 );
    cmDspInst_t* eqmode  = cmDspSysAllocInst(   h, "MsgList","Mode", 1, "biQuadEqMode");
    cmDspInst_t* eqq     = cmDspSysAllocScalar( h, "Q",          -100.0, 100.0, 0.1, eqQ);
    cmDspInst_t* eqfgn   = cmDspSysAllocScalar( h, "Filt Gain",   0.0,     1.0, 0.1, eqFgain);
    
    cmDspInst_t* mtfb   = cmDspSysAllocScalar( h, "Mt Feedback",   0.0,     1.0, 0.01, mtFeedback);
    cmDspInst_t* mtscale= cmDspSysAllocScalar( h, "Mt Time Scale",   0.01,   10.0, 0.01, mtTimeScale);
    
    // check for allocation errors
    if((rc = cmDspSysLastRC(h)) != kOkDspRC )
      goto errLabel;
    
    
    cmDspSysConnectAudioN1N1( h, ain, "out",  ef,  "in",   chCnt );  // ain -&gt EF 
    cmDspSysConnectAudioN1N1( h, sg,  "out",  cf,  "in",   chCnt );  // sg -&gt CF
    cmDspSysConnectAudioN1N1( h, cf,  "out",  eq,  "in",   chCnt );
    cmDspSysConnectAudioN1N1( h, eq,  "out",  mt,  "in",   chCnt );
    cmDspSysConnectAudioN11N( h, mt,  "out",  mix, "in",  chCnt );   // cf -&gt mix
    cmDspSysConnectAudio(     h, mix, "out",  ao0, "in");            // mix -&gt aout L 
    cmDspSysConnectAudio(     h, mix, "out",  ao1, "in");            // mix -&gt aout R
    
    cmDspSysInstallCb1NN1(   h, chCfg, "gain", ain,  "gain", chCnt );    // chCfg -&gt ain gain
    cmDspSysInstallCb1NN1(   h, chCfg, "hz",   cf,   "hz",   chCnt );    // chCfg -&gt CF Hz
    cmDspSysInstallCb1NN1(   h, chCfg, "hz",   eq,   "f0",   chCnt );    // chCfg -&gt Eq Hz
    cmDspSysInstallCbN1N1(   h, mul,   "out",  add,  "in-1", chCnt );    // mul -&gt add
    cmDspSysInstallCbN1N1(   h, ef,    "gate", env,  "gate", chCnt );    // EF -&gt adsr (gate)
    cmDspSysInstallCbN1N1(   h, ef,    "rms",  env,  "rms",  chCnt );    // EF -&gtadsr (rms)
    //cmDspSysInstallCb11N1(   h, print,   &quotout&quot,  env,  &quotcmd&quot,  chCnt );
    cmDspSysInstallCbN1N1(   h, env,   "out",  d2l,  "in", chCnt );
    cmDspSysInstallCbN11N(   h, d2l,   "out",  mix,  "gain", chCnt ); 
    cmDspSysInstallCbN1N1(   h, add,   "out",  mul,  "in-0", chCnt );    // add -&gt mul (feedback)
    cmDspSysInstallCb11N1(   h, decay, "val",  mul,  "in-1", chCnt );    // decay ctl
    cmDspSysInstallCbN1N1(   h, ef,    "gate", mtr,  "in",   chCnt );    // EF -&gt meter RMS
    cmDspSysInstallCb11N1(   h, alpha, "val",  cf,   "alpha",chCnt );    // CF alpha
    cmDspSysInstallCb111N(   h, zero,  "val",  mix,  "in",   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, onThr,  "val",  ef,    "ondb",  chCnt );  
    cmDspSysInstallCb11N1(   h, offThr, "val",  ef,    "offdb", 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 );
    
  }
  
  errLabel:
  cmFsFreeFn(chCfgPath);
  
  return rc;
}




cmDspPgm_CombFilt : Comb filter example program.
cmDspRC_t _cmDspSysPgm_CombFilt( cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t rc        = kOkDspRC;
  double    cfMinHz   = 20.0;
  double    cfAlpha   = 0.9;
  bool      cfFbFl    = true;
  bool      cfBypassFl= false;
  unsigned  sgShapeId = 2;
  
  cmDspInst_t* ao  = cmDspSysAllocAudioOut( h, 0, 1.0 );
  cmDspInst_t* sg  = cmDspSysAllocInst(   h, "SigGen",    NULL, 2, 1000.0, sgShapeId );
  cmDspInst_t* cf  = cmDspSysAllocInst(   h, "CombFilt",  NULL, 5, cfBypassFl, cfMinHz, cfFbFl, cfMinHz, cfAlpha );
  cmDspInst_t* hz  = cmDspSysAllocScalar( h, "Hz", 25, 10000, 1, 1000 );
  cmDspInst_t* a   = cmDspSysAllocScalar( h, "Alpha", 0.0, 2.0, 0.001, cfAlpha);
  
  // check for allocation errors
  if((rc = cmDspSysLastRC(h)) != kOkDspRC )
    goto errLabel;
  
  cmDspSysConnectAudio(h, sg, "out", cf, "in");
  cmDspSysConnectAudio(h, cf, "out", ao, "in");
  cmDspSysInstallCb(   h, hz, "val", cf, "hz", NULL);
  cmDspSysInstallCb(   h, a,  "val", cf, "alpha", NULL);
  errLabel:
  return rc;  
}


cmDspPgm_ScalarOp : Scalar operations example program.
cmDspRC_t _cmDspSysPgm_ScalarOp( cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t rc;
  
  cmDspInst_t* add   = cmDspSysAllocInst(   h, "ScalarOp", NULL,  6, 2, "+",  "in-0", 0.0, "in-1", 0.0 );
  cmDspInst_t* mul0  = cmDspSysAllocInst(   h, "ScalarOp", NULL,  6, 2, "*$", "in-0", 0.0, "in-1", 0.0 );
  cmDspInst_t* mul1  = cmDspSysAllocInst(   h, "ScalarOp", NULL,  6, 2, "*", "in-0", 0.0, "in-1", 0.0 );
  cmDspInst_t* in    = cmDspSysAllocScalar( h, "Input",      0.0, 10.0, 0.001, 0.0);
  cmDspInst_t* in_m  = cmDspSysAllocScalar( h, "Input_M",    0.0, 10.0, 0.001, 0.0);
  cmDspInst_t* fb    = cmDspSysAllocScalar( h, "Feedback",   0.0, 10.0, 0.001, 0.0);
  cmDspInst_t* fb_m  = cmDspSysAllocScalar( h, "Feedback_M", 0.0, 10.0, 0.001, 0.0);
  cmDspInst_t* out   = cmDspSysAllocScalar( h, "Out",        0.0, 10.0, 0.001, 0.0);
  
  // check for allocation errors
  if((rc = cmDspSysLastRC(h)) != kOkDspRC )
    goto errLabel;
  
  // Notice that changing 'in' or 'in_m' causes 'out' to be recomputed, but other
  // changes are cached prior to 'add'.  This prevents the program from going into
  // an infinite loop.
  //
  //     in   -&gt mult0
  //     in_m -&gt mult0--+
  // +--&gtfb   -&gt mult1  +----&gt add
  // |   fb_m -&gt mult1-------&gt add --------+------&gt out
  // |                                     |
  // +-------------------------------------+
  //  
  
  cmDspSysInstallCb( h, in,    "val", mul0, "in-0", NULL );
  cmDspSysInstallCb( h, in_m,  "val", mul0, "in-1", NULL );
  cmDspSysInstallCb( h, fb,    "val", mul1, "in-0", NULL );
  cmDspSysInstallCb( h, fb_m,  "val", mul1, "in-1", NULL );
  cmDspSysInstallCb( h, mul0,  "out", add,  "in-0", NULL );
  cmDspSysInstallCb( h, mul1,  "out", add,  "in-1", NULL );
  cmDspSysInstallCb( h, add,   "out", fb,   "val",  NULL );
  cmDspSysInstallCb( h, add,   "out", out,  "val",  NULL );
  
  errLabel:
  return rc;
}



cmDspPgm_RingMod : Ring modulation example program.
cmDspRC_t _cmDspSysPgm_RingMod( cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t       rc          = kOkDspRC;
  cmErr_t         err;
  cmCtx_t*        cmCtx       = cmDspSysPgmCtx(h);
  unsigned        chCnt       = 0;
  unsigned        nsChCnt     = 0;
  const cmChar_t* chCfgPath   = NULL;
  const cmChar_t* chCfgFn     = "pick_chs8.js";
  unsigned        groupCnt    = 3;
  unsigned        chsPerGroup = 2;
  cmReal_t        fadeTimeMs  = 25;
  unsigned        i,j,k;
  
  
  cmErrSetup(&err,&cmCtx->rpt,"Pickup Effects");
  
  // prepend the prefs directory to the ch. cfg filename 
  chCfgPath = cmFsMakeFn(cmFsPrefsDir(),chCfgFn,NULL,NULL);
  
  // get the count of channels from the ch. cfg. array
  if(( chCnt = cmChCfgChannelCount(cmCtx,chCfgFn,&nsChCnt)) == 0 )
  {
    rc = cmErrMsg(&err,kPgmCfgFailDspRC,"Unable to obtain the channel count from '%s'.",cmStringNullGuard(chCfgFn));
    goto errLabel;
  }
  
  if( rc == kOkDspRC )
  {
    cmDspInst_t* ain[chCnt];
    cmDspInst_t* ef[chCnt];
    cmDspInst_t* mtr[chCnt];
    cmDspInst_t* nom[groupCnt];
    cmDspInst_t* rm[groupCnt];
    cmDspInst_t* nm_mtr[groupCnt*chsPerGroup];
    unsigned labelCharCnt = 31;
    cmChar_t label[labelCharCnt+1];
    
    // allocate the audio inputs and envelope followers
    for(i=0; i<chCnt; ++i)
    {
      snprintf(label,labelCharCnt,"%i",i);
      
      ain[i]  = cmDspSysAllocAudioIn(  h, i, 1.0);
      ef[i]   = cmDspSysAllocInst( h, "EnvFollow", NULL, 0 );
      mtr[i]  = cmDspSysAllocInst( h, "Meter",     label, 3, 0.0, 0.0, 1.0 );
    }
    
    cmDspInst_t* gs = cmDspSysAllocInst( h, "GroupSel", NULL, 3, chCnt, groupCnt, chsPerGroup );
    
    for(i=0; i<groupCnt; ++i)
    {
      nom[i] = cmDspSysAllocInst(h, "AudioNofM", NULL, 3, chCnt, chsPerGroup, fadeTimeMs );
      rm[i]  = cmDspSysAllocInst(h, "RingMod",   NULL, 1, chsPerGroup );
    }
    
    for(i=0,k=0; i<groupCnt; ++i)
    {
      cmDspSysNewColumn(h,50);
      snprintf(label,labelCharCnt,"%i",i);
      cmDspSysAllocLabel(h,label,kLeftAlignDuiId );
      
      for(j=0; j<chsPerGroup; ++j,++k)
      {        
        snprintf(label,labelCharCnt,"%i",j);
        nm_mtr[k] = cmDspSysAllocInst(h, "Meter", label, 3, 0.0, 0.0, 1.0 );
      } 
    }
    assert(k==groupCnt*chsPerGroup);
    
    // allocate the ch cfg last so that it's default outputs initialize connected objects
    //cmDspInst_t* chCfg  = cmDspSysAllocInst( h, &quotChCfg&quot,    NULL,     1, chCfgFn );      
    cmDspInst_t* mix    = cmDspSysAllocInst( h, "AMix",     NULL,     1, groupCnt );
    cmDspInst_t* ao0    = cmDspSysAllocAudioOut( h, 0, 1.0 );
    cmDspInst_t* ao1    = cmDspSysAllocAudioOut( h, 1, 1.0 );
    
    // check for allocation errors
    if((rc = cmDspSysLastRC(h)) != kOkDspRC )
      goto errLabel;
    
    cmDspSysConnectAudioN1N1( h, ain, "out",  ef,  "in",   chCnt );  // ain -&gt EF 
    
    for(i=0; i<groupCnt; ++i)
    {
      cmDspSysConnectAudioN11N( h, ain,    "out", nom[i], "in", chCnt );
      cmDspSysConnectAudio1N1N( h, nom[i], "out", rm[i],  "in", chsPerGroup);
      
      snprintf(label,labelCharCnt,"gate-%i",i);
      cmDspSysInstallCb1N1N( h, gs, label, nom[i], "gate", chCnt );
      
      cmDspSysInstallCb1NN1( h, nom[i], "gain", nm_mtr + i * chsPerGroup, "in", chsPerGroup);
    }
    
    
    cmDspSysConnectAudioN11N( h, rm,  "out",  mix, "in", groupCnt );
    cmDspSysConnectAudio(     h, mix, "out",  ao0, "in");            // mix -&gt aout L 
    cmDspSysConnectAudio(     h, mix, "out",  ao1, "in");            // mix -&gt aout R
    
    cmDspSysInstallCbN11N(   h, ef, "gate",  gs,   "gate",   chCnt );    // EF -&gt grp_sel gate
    cmDspSysInstallCbN11N(   h, ef, "rms",   gs,   "rms",    chCnt );    // EF -&gt grp_sel RMS
    cmDspSysInstallCbN1N1(   h, ef, "gate",  mtr,  "in",     chCnt );
  }
  
  errLabel:
  cmFsFreeFn(chCfgPath);
  
  return rc;
}


cmDspPgm_RingMod2 : Ring modulation example program.
cmDspRC_t _cmDspSysPgm_RingMod2( cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t       rc          = kOkDspRC;
  cmErr_t         err;
  cmCtx_t*        cmCtx       = cmDspSysPgmCtx(h);
  unsigned        iChCnt       = 0;
  unsigned        oChCnt       = 0;
  unsigned        nsChCnt      = 0;
  const cmChar_t* chCfgPath   = NULL;
  const cmChar_t* chCfgFn     = "pick_chs8.js";
  unsigned        i;
  
  cmErrSetup(&err,&cmCtx->rpt,"Pickup Effects");
  
  // prepend the prefs directory to the ch. cfg filename 
  chCfgPath = cmFsMakeFn(cmFsPrefsDir(),chCfgFn,NULL,NULL);
  
  // get the count of channels from the ch. cfg. array
  if(( iChCnt = cmChCfgChannelCount(cmCtx,chCfgFn,&nsChCnt)) == 0 )
  {
    rc = cmErrMsg(&err,kPgmCfgFailDspRC,"Unable to obtain the channel count from '%s'.",cmStringNullGuard(chCfgFn));
    goto errLabel;
  }
  
  if( rc == kOkDspRC && iChCnt > 0 )
  {
    if( iChCnt % 2 )
      iChCnt -= 1;
    
    oChCnt = iChCnt/2;
    
    cmDspInst_t* ain[iChCnt];
    cmDspInst_t* ef[iChCnt];
    cmDspInst_t* mtr[iChCnt];
    cmDspInst_t* rm[oChCnt];
    unsigned     labelCharCnt = 31;
    cmChar_t     label[labelCharCnt+1];
    
    // allocate the audio inputs and envelope followers
    for(i=0; i<iChCnt; ++i)
    {
      snprintf(label,labelCharCnt,"%i",i);
      
      ain[i]  = cmDspSysAllocAudioIn(  h, i, 1.0);
      ef[i]   = cmDspSysAllocInst( h, "EnvFollow", NULL, 0 );
      mtr[i]  = cmDspSysAllocInst( h, "Meter",     label, 3, 0.0, 0.0, 1.0 );
    }
    
    for(i=0; i<oChCnt; ++i)
    {
      rm[i]   = cmDspSysAllocInst(   h, "RingMod", NULL, 1, 2 );
    }
    
    cmDspInst_t* gain   = cmDspSysAllocScalar( h, "RM Gain", 0.0, 10.0, 0.001, 1.0);
    cmDspInst_t* mix    = cmDspSysAllocInst( h, "AMix",     NULL,     1, oChCnt );
    cmDspInst_t* ao0    = cmDspSysAllocAudioOut( h, 0, 1.0 );
    cmDspInst_t* ao1    = cmDspSysAllocAudioOut( h, 1, 1.0 );
    
    // check for allocation errors
    if((rc = cmDspSysLastRC(h)) != kOkDspRC )
      goto errLabel;
    
    cmDspSysConnectAudioN1N1( h, ain, "out",  ef,  "in",   iChCnt );  // ain -&gt EF 
    cmDspSysInstallCbN1N1(    h, ef,  "gate", mtr, "in",   iChCnt );  // EF -&gt mtr (gate)
    
    for(i=0; i<oChCnt; ++i)
    {
      cmDspSysConnectAudio( h, ain[i*2+0], "out", rm[i], "in-0");    // ain -&gt rm 0
      cmDspSysConnectAudio( h, ain[i*2+1], "out", rm[i], "in-1");    // ain -&gt rm 1
      
      snprintf(label,labelCharCnt,"in-%i",i);              
      cmDspSysConnectAudio( h, rm[i],      "out", mix,   label);    // rm -&gt mix
      
      cmDspSysInstallCb(h, gain, "val", rm[i], "gain", NULL );      // gain -&gt rm gain
    }
    
    
    cmDspSysConnectAudio(     h, mix, "out",  ao0, "in");            // mix -&gt aout L 
    cmDspSysConnectAudio(     h, mix, "out",  ao1, "in");            // mix -&gt aout R
    
    
  }
  
  errLabel:
  cmFsFreeFn(chCfgPath);
  
  return rc;
}


cmDspPgm_MsgDelay : Message delay example program.
cmDspRC_t _cmDspSysPgm_MsgDelay( cmDspSysH_t h, void** userPtrPtr )
{
  
  cmDspRC_t rc              = kOkDspRC;
  double    dfltDelayTimeMs = 100.0;
  double    maxDelayTimeMs  = 10000.0;
  
  cmDspInst_t* ctl   = cmDspSysAllocScalar( h, "Delay", 0.0, maxDelayTimeMs, 1.0, dfltDelayTimeMs );
  cmDspInst_t* dly   = cmDspSysAllocInst(   h, "MsgDelay", NULL, 2, 1000, dfltDelayTimeMs );
  cmDspInst_t* print = cmDspSysAllocInst(   h, "Printer",  NULL, 1, ">");
  
  if( (rc = cmDspSysLastRC(h)) != kOkDspRC )
    return rc;
  
  cmDspSysInstallCb( h, ctl, "val",  dly,   "delay", NULL );
  cmDspSysInstallCb( h, ctl, "val",  dly,   "in",    NULL );
  cmDspSysInstallCb( h, dly,  "out", print, "in",    NULL );
  
  return rc;
}



cmDspPgm_Adsr : ADSR envelope generator example program.
cmDspRC_t _cmDspSysPgm_Adsr( cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t rc;
  bool   trigModeFl = true;
  double adsrMaxMs = 5000;
  double adsrMinMs = 0;
  double adsrIncMs = 1;
  double adsrMaxLevel = 100.0;  // 1.0;
  double adsrSusLevel =  80.0;  // 0.8;
  double adsrMinLevel =  0.0;  // 0.0;
  
  double adsrIncLevel = 0.001;
  const cmChar_t* fn = "/home/kevin/temp/adsr1.bin";
  
  cmDspInst_t* adsr = cmDspSysAllocInst(h, "Adsr", NULL, 2, trigModeFl, adsrMinLevel );
  cmDspInst_t* chck = cmDspSysAllocCheck(h,"Gate",0);
  cmDspInst_t* mtr   = cmDspSysAllocInst(h,"Meter","Out", 3, adsrMinLevel, adsrMinLevel, adsrMaxLevel );
  cmDspInst_t* bmf   = cmDspSysAllocInst(h,"BinMtxFile", NULL, 2, 1, fn );
  
  cmDspInst_t* dly   = cmDspSysAllocScalar( h, "Dly Ms",  adsrMinMs,   adsrMaxMs,   adsrIncMs, 0.0);
  cmDspInst_t* atk   = cmDspSysAllocScalar( h, "Atk Ms",  adsrMinMs,   adsrMaxMs,   adsrIncMs, 1000.0);
  cmDspInst_t* dcy   = cmDspSysAllocScalar( h, "Dcy Ms",  adsrMinMs,   adsrMaxMs,   adsrIncMs, 300.0);
  cmDspInst_t* hold  = cmDspSysAllocScalar( h, "Hold Ms", adsrMinMs,   adsrMaxMs,   adsrIncMs, 500.0);
  cmDspInst_t* rls   = cmDspSysAllocScalar( h, "Rls Ms",  adsrMinMs,   adsrMaxMs,   adsrIncMs, 1000.0);
  cmDspInst_t* alvl  = cmDspSysAllocScalar( h, "AdsrMax", adsrMinLevel,adsrMaxLevel,adsrIncLevel, adsrMaxLevel);  
  cmDspInst_t* sus   = cmDspSysAllocScalar( h, "Sustain", adsrMinLevel,adsrMaxLevel,adsrIncLevel, adsrSusLevel);  
  
  // check for allocation errors
  if((rc = cmDspSysLastRC(h)) != kOkDspRC )
    goto errLabel;
  
  cmDspSysInstallCb( h, dly,  "val", adsr, "dly",  NULL );
  cmDspSysInstallCb( h, atk,  "val", adsr, "atk",  NULL );
  cmDspSysInstallCb( h, dcy,  "val", adsr, "dcy",  NULL );
  cmDspSysInstallCb( h, hold, "val", adsr, "hold",  NULL );
  cmDspSysInstallCb( h, rls,  "val", adsr, "rls",  NULL );
  cmDspSysInstallCb( h, alvl, "val", adsr, "alvl", NULL );
  cmDspSysInstallCb( h, sus,  "val", adsr, "sus",  NULL );
  
  cmDspSysInstallCb( h, chck, "out", adsr, "gate", NULL );
  cmDspSysInstallCb( h, adsr, "out", mtr, "in",   NULL );
  cmDspSysInstallCb( h, adsr, "out", bmf,  "in", NULL );
  
  errLabel:
  return rc;
  
}




cmDspPgm_Adsr : Dynamics compressor example program.
cmDspRC_t _cmDspSysPgm_Compressor( cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t rc;
  const cmChar_t* ofn       = "/home/kevin/temp/adsr0.bin";
  const char*     afn0      = "media/audio/20110723-Kriesberg/Audio Files/Piano 3_01.wav";
  int             beg       = 6900826;
  int             end       = 13512262;
  const cmChar_t* afn       = cmFsMakeFn(cmFsUserDir(),afn0,NULL,NULL );
  bool            bypassFl  = false;
  double          inGain    = 1.0;
  double          threshDb  = -40.0;
  double          ratio_num = 4.0;
  double          atkMs     = 100.0;
  double          rlsMs     = 100.0;
  double          makeup    = 1.0;
  double          wndMaxMs  = 1000.0;
  double          wndMs     = 200.0;
  
  cmDspInst_t* off =  cmDspSysAllocInst(h,"Scalar", "Offset",  5, kNumberDuiId, 0.0,  cmDspSysSampleRate(h)*600.0, 1.0,  0.0);
  cmDspInst_t* phs =  cmDspSysAllocInst(h,"Phasor",   NULL,  0 );
  cmDspInst_t* wt  =  cmDspSysAllocInst(h,"WaveTable",NULL,  6, ((int)cmDspSysSampleRate(h)), 1, afn, -1, beg, end );
  cmDspInst_t* cmp =  cmDspSysAllocInst(h,"Compressor",NULL, 8, bypassFl, threshDb, ratio_num, atkMs, rlsMs, makeup, wndMs, wndMaxMs ); 
  
  cmDspInst_t* ao0   = cmDspSysAllocInst(h,"AudioOut",NULL,   1, 0 );
  cmDspInst_t* ao1   = cmDspSysAllocInst(h,"AudioOut",NULL,   1, 1 );
  cmDspInst_t* bmf   = cmDspSysAllocInst(h,"BinMtxFile", NULL, 2, 1, ofn );
  cmDspInst_t* mtr   = cmDspSysAllocInst(h,"Meter","Env", 3, 0.0, 0.0, 1.0);
  
  cmDspInst_t* igain = cmDspSysAllocScalar( h, "In Gain",  0.0,   10.0, 0.1, inGain);
  cmDspInst_t* thr   = cmDspSysAllocScalar( h, "ThreshDb", -100.0, 0.0, 0.1, threshDb);
  cmDspInst_t* rat   = cmDspSysAllocScalar( h, "Ratio",    0.1, 100, 0.1, ratio_num);
  cmDspInst_t* atk   = cmDspSysAllocScalar( h, "Atk Ms",   0.0, 1000.0, 0.1, atkMs);
  cmDspInst_t* rls   = cmDspSysAllocScalar( h, "Rls Ms",   0.0, 1000.0, 0.1, rlsMs);
  cmDspInst_t* mkup  = cmDspSysAllocScalar( h, "Makeup",   0.0, 10.0,   0.01, makeup);
  cmDspInst_t* wnd   = cmDspSysAllocScalar( h, "Wnd Ms",   1.0, wndMaxMs, 1.0, wndMs );
  
  // check for allocation errors
  if((rc = cmDspSysLastRC(h)) != kOkDspRC )
    goto errLabel;
  
  cmDspSysConnectAudio(h, phs, "out", wt,  "phs" );   // phasor -&gt wave table
  cmDspSysConnectAudio(h, wt,  "out", cmp, "in" );    // wave table -&gt cmp in
  cmDspSysConnectAudio(h, cmp, "out", ao0, "in" );    // comp -&gt aout
  cmDspSysConnectAudio(h, cmp, "out", ao1, "in" );    
  
  
  cmDspSysInstallCb(h, off,  "val", wt, "beg", NULL ); 
  cmDspSysInstallCb(h, igain,"val", cmp, "igain", NULL );
  cmDspSysInstallCb(h, thr,  "val", cmp, "thr", NULL );
  cmDspSysInstallCb(h, rat,  "val", cmp, "ratio", NULL );
  cmDspSysInstallCb(h, atk,  "val", cmp, "atk", NULL );
  cmDspSysInstallCb(h, rls,  "val", cmp, "rls", NULL );
  cmDspSysInstallCb(h, mkup, "val", cmp, "ogain", NULL );
  cmDspSysInstallCb(h, wnd,  "val", cmp, "wnd", NULL );
  cmDspSysInstallCb(h, cmp,  "env", bmf, "in", NULL );
  cmDspSysInstallCb(h, cmp,  "env", mtr, "in", NULL );
  errLabel:
  return rc;
  
}



cmDspPgm_BiQuadEq : Biquad EQ example program.
cmDspRC_t _cmDspSysPgm_BiQuadEq( cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t       rc        = kOkDspRC;
  const char*     afn0      = "media/audio/20110723-Kriesberg/Audio Files/Piano 3_01.wav";
  int             beg       = 6900826;
  int             end       = 13512262;
  const cmChar_t* afn       = cmFsMakeFn(cmFsUserDir(),afn0,NULL,NULL );
  bool            bypassFl  = false;
  unsigned        modeSymId = cmSymTblRegisterStaticSymbol(cmDspSysSymbolTable(h),"LP");
  double          f0hz      = 264.0;
  double          Q         = 1.0;
  double          fgain     = 1.0;
  
  cmDspInst_t* off =  cmDspSysAllocInst(h,"Scalar", "Offset",  5, kNumberDuiId, 0.0,  cmDspSysSampleRate(h)*600.0, 1.0,  0.0);
  cmDspInst_t* phs =  cmDspSysAllocInst(h,"Phasor",   NULL,  0 );
  cmDspInst_t* wt  =  cmDspSysAllocInst(h,"WaveTable",NULL,  6, ((int)cmDspSysSampleRate(h)), 1, afn, -1, beg, end );
  cmDspInst_t* flt =  cmDspSysAllocInst(h,"BiQuadEq",NULL,   5, bypassFl, modeSymId,f0hz, Q, fgain  ); 
  
  cmDspInst_t* ao0   = cmDspSysAllocInst(h,"AudioOut",NULL,   1, 0 );
  cmDspInst_t* ao1   = cmDspSysAllocInst(h,"AudioOut",NULL,   1, 1 );
  
  cmDspInst_t* mode  = cmDspSysAllocInst(   h, "MsgList","Mode", 1, "biQuadEqMode");
  cmDspInst_t* fhz   = cmDspSysAllocScalar( h, "Fc Hz",       0.0, 15000.0, 0.1, f0hz);
  cmDspInst_t* q     = cmDspSysAllocScalar( h, "Q",          -100.0, 100, 0.1,   Q);
  cmDspInst_t* fgn   = cmDspSysAllocScalar( h, "Filt Gain",   0.0, 1.0, 0.1, fgain);
  
  // check for allocation errors
  if((rc = cmDspSysLastRC(h)) != kOkDspRC )
    goto errLabel;
  
  cmDspSysConnectAudio(h, phs, "out", wt,  "phs" );   // phasor -&gt wave table
  cmDspSysConnectAudio(h, wt,  "out", flt, "in" );    // wave table -&gt cmp in
  cmDspSysConnectAudio(h, flt, "out", ao0, "in" );    // filter -&gt aout
  cmDspSysConnectAudio(h, flt, "out", ao1, "in" );    
  
  
  cmDspSysInstallCb(h, off, "val", wt,  "beg", NULL ); 
  cmDspSysInstallCb(h, mode,"mode",flt, "mode", NULL );
  cmDspSysInstallCb(h, fhz, "val", flt, "f0", NULL );
  cmDspSysInstallCb(h, q,   "val", flt, "Q", NULL );
  cmDspSysInstallCb(h, fgn, "val", flt, "gain", NULL );
  
  errLabel:
  return rc;
  
}



cmDspPgm_DistDs : Guitar distortion example program.
cmDspRC_t _cmDspSysPgm_DistDs( cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t       rc        = kOkDspRC;
  const char*     afn0      = "media/audio/20110723-Kriesberg/Audio Files/Piano 3_01.wav";
  int             beg       = 6900826;
  int             end       = 13512262;
  const cmChar_t* afn       = cmFsMakeFn(cmFsUserDir(),afn0,NULL,NULL );
  bool            bypassFl  = false;
  double          inGain    = 1.0;
  double          dsrate    = 44100.0;
  double          bits      = 24.0;
  bool            rectifyFl = false;
  bool            fullRectFl = false;
  double          clipDb     = -10.0;
  
  
  cmDspInst_t* off =  cmDspSysAllocInst(h,"Scalar", "Offset",  5, kNumberDuiId, 0.0,  cmDspSysSampleRate(h)*600.0, 1.0,  0.0);
  cmDspInst_t* phs =  cmDspSysAllocInst(h,"Phasor",   NULL,  0 );
  cmDspInst_t* wt  =  cmDspSysAllocInst(h,"WaveTable",NULL,  6, ((int)cmDspSysSampleRate(h)), 1, afn, -1, beg, end );
  cmDspInst_t* dst =  cmDspSysAllocInst(h,"DistDs",NULL,   3, bypassFl, inGain, dsrate, bits  ); 
  
  cmDspInst_t* ao0   = cmDspSysAllocInst(h,"AudioOut",NULL,   1, 0 );
  cmDspInst_t* ao1   = cmDspSysAllocInst(h,"AudioOut",NULL,   1, 1 );
  
  cmDspInst_t* ign   = cmDspSysAllocScalar( h, "In Gain",      0.0, 10.0, 0.01, 1.0);
  cmDspInst_t* rct   = cmDspSysAllocCheck(  h, "Rectify",   rectifyFl);
  cmDspInst_t* ful   = cmDspSysAllocCheck(  h, "Full/Half", fullRectFl);
  cmDspInst_t* dsr   = cmDspSysAllocScalar( h, "Srate",        0.0, 96000, 1.0, dsrate);
  cmDspInst_t* dbt   = cmDspSysAllocScalar( h, "bits",         2.0,  32.0, 1.0, bits);
  cmDspInst_t* clip  = cmDspSysAllocScalar( h, "Clip dB",   -100.0,   0.0, 0.1, clipDb);
  cmDspInst_t* ogn   = cmDspSysAllocScalar( h, "Out Gain",    0.0, 10.0, 0.01, 1.0);
  
  // check for allocation errors
  if((rc = cmDspSysLastRC(h)) != kOkDspRC )
    goto errLabel;
  
  cmDspSysConnectAudio(h, phs, "out", wt,  "phs" );   // phasor -&gt wave table
  cmDspSysConnectAudio(h, wt,  "out", dst, "in" );    // wave table -&gt cmp in
  cmDspSysConnectAudio(h, dst, "out", ao0, "in" );    // filter -&gt aout
  cmDspSysConnectAudio(h, dst, "out", ao1, "in" );    
  
  
  cmDspSysInstallCb(h, off,  "val", wt,  "beg", NULL ); 
  cmDspSysInstallCb(h, ign,  "val", dst, "igain", NULL );
  cmDspSysInstallCb(h, dsr,  "val", dst, "srate", NULL );
  cmDspSysInstallCb(h, dbt,  "val", dst, "bits", NULL );
  cmDspSysInstallCb(h, rct,  "out", dst, "rect", NULL );
  cmDspSysInstallCb(h, ful,  "out", dst, "full", NULL );
  cmDspSysInstallCb(h, clip, "val", dst, "clip", NULL );
  cmDspSysInstallCb(h, ogn,  "val", dst, "ogain", NULL );
  
  errLabel:
  return rc;
  
}


cmDspPgm_Seq : Message list 'seq' mode example program.
cmDspRC_t _cmDspSysPgm_Seq( cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t rc;
  double min = 1.0;
  double max = 10.0;
  double incr = 1.0;
  
  cmDspInst_t* btn = cmDspSysAllocButton( h, "smack", 0);
  cmDspInst_t* cnt = cmDspSysAllocInst(   h, "Counter", NULL,   3, min, max, incr );
  cmDspInst_t* lst = cmDspSysAllocInst(   h, "MsgList","Seq", 1, "seqTest");
  cmDspInst_t* prt = cmDspSysAllocInst(   h, "Printer", NULL, 1, ">");
  
  cmDspSysInstallCb(h, lst, "cnt",  cnt, "max",  NULL );
  cmDspSysInstallCb(h, btn, "out",  cnt, "next", NULL );
  cmDspSysInstallCb(h, cnt, "out",  lst, "sel",  NULL );
  cmDspSysInstallCb(h, lst, "midi", prt, "in", NULL );
  
  
  // check for allocation errors
  if((rc = cmDspSysLastRC(h)) != kOkDspRC )
    goto errLabel;
  
  errLabel:
  return rc;
}


cmDspPgm_ThunkNet : UDP network receiver example program.
cmDspRC_t _cmDspSysPgm_ThunkNet( cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t rc;
  cmDspInst_t* add   = cmDspSysAllocInst(   h, "ScalarOp", "adder-0",  6, 2, "+", "in-0", 0.0, "in-1", 0.0 );
  cmDspInst_t* in    = cmDspSysAllocScalar( h, "Input",      0.0, 10.0, 0.001, 0.0);
  cmDspInst_t* out   = cmDspSysAllocScalar( h, "Out",        0.0, 10.0, 0.001, 0.0);
  
  // check for allocation errors
  if((rc = cmDspSysLastRC(h)) != kOkDspRC )
    goto errLabel;
  
  cmDspSysInstallCb( h, in,    "val", add,  "in-1", NULL );
  cmDspSysInstallCb( h, add,   "out", out,  "val",  NULL );
  
  errLabel:
  return rc;
}


cmDspPgm_WhirlNet : UDP network sender example program.
cmDspRC_t _cmDspSysPgm_WhirlNet( cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t rc;
  
  cmDspInst_t* in    = cmDspSysAllocScalar( h, "Input",      0.0, 10.0, 0.001, 0.0);
  
  // check for allocation errors
  if((rc = cmDspSysLastRC(h)) != kOkDspRC )
    goto errLabel;
  
  cmDspSysInstallNetCb( h, in,    "val", "thunk",  "adder-0", "in-0" );
  
  errLabel:
  return rc;
  
}


cmDspPgm_NofM : Select NofM example program.
cmDspRC_t _cmDspSysPgm_NofM( cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t rc;
  unsigned iChCnt = 3;
  unsigned oChCnt = 2;
  unsigned sgShapeId = 0;
  double  sgGain = 0.4;
  double  xfadeMs = 1000;
  
  cmDspInst_t* onBtn = cmDspSysAllocButton( h, "on", 0 );
  cmDspInst_t* offBtn = cmDspSysAllocButton(h, "off", 0 );
  
  cmDspInst_t* sg0  = cmDspSysAllocInst(   h, "SigGen",    NULL, 3, 500.0, sgShapeId, sgGain );
  cmDspInst_t* sg1  = cmDspSysAllocInst(   h, "SigGen",    NULL, 3, 1000.0, sgShapeId, sgGain );
  cmDspInst_t* sg2  = cmDspSysAllocInst(   h, "SigGen",    NULL, 3, 2000.0, sgShapeId, sgGain );
  
  cmDspInst_t* nom  = cmDspSysAllocInst(   h,"NofM",     NULL,   3, iChCnt, oChCnt, xfadeMs );
  cmDspInst_t* mix  = cmDspSysAllocInst(   h, "AMix",    NULL, 1, oChCnt  );
  cmDspInst_t* ao   = cmDspSysAllocAudioOut(h, 0, 1.0 ); 
  
  
  cmDspInst_t* btn = cmDspSysAllocButton( h, "cfg", 0);
  
  
  cmDspInst_t* sel0 = cmDspSysAllocCheck(h,"Sel-0",0);
  cmDspInst_t* sel1 = cmDspSysAllocCheck(h,"Sel-1",0);
  cmDspInst_t* sel2 = cmDspSysAllocCheck(h,"Sel-2",0);
  
  cmDspInst_t* in0  = cmDspSysAllocScalar( h, "In-0",      0.0, 10.0, 0.001, 0.0);
  cmDspInst_t* in1  = cmDspSysAllocScalar( h, "In-1",      0.0, 10.0, 0.001, 0.0);
  cmDspInst_t* in2  = cmDspSysAllocScalar( h, "In-2",      0.0, 10.0, 0.001, 0.0);  
  
  cmDspInst_t* out0  = cmDspSysAllocScalar( h, "Out-0",      0.0, 10.0, 0.001, 0.0);
  cmDspInst_t* out1  = cmDspSysAllocScalar( h, "Out-1",      0.0, 10.0, 0.001, 0.0);
  
  
  // check for allocation errors
  if((rc = cmDspSysLastRC(h)) != kOkDspRC )
    goto errLabel;
  
  
  cmDspSysConnectAudio( h, sg0, "out", nom, "a-in-0" );
  cmDspSysConnectAudio( h, sg1, "out", nom, "a-in-1" );
  cmDspSysConnectAudio( h, sg2, "out", nom, "a-in-2" );
  cmDspSysConnectAudio( h, nom, "a-out-0", mix, "in-0" );
  cmDspSysConnectAudio( h, nom, "a-out-1", mix, "in-1" );
  cmDspSysConnectAudio( h, mix, "out",     ao,  "in" );
  
  cmDspSysInstallCb( h, btn,  "sym", nom, "cmd", NULL );
  
  cmDspSysInstallCb( h, sel0, "out", nom, "sel-0", NULL );
  cmDspSysInstallCb( h, sel1, "out", nom, "sel-1", NULL );
  cmDspSysInstallCb( h, sel2, "out", nom, "sel-2", NULL );
  
  cmDspSysInstallCb( h, in0, "val", nom, "f-in-0", NULL );
  cmDspSysInstallCb( h, in1, "val", nom, "f-in-1", NULL );
  cmDspSysInstallCb( h, in2, "val", nom, "f-in-2", NULL );
  
  cmDspSysInstallCb( h, nom, "f-out-0", out0, "val", NULL );
  cmDspSysInstallCb( h, nom, "f-out-1", out1, "val", NULL );
  
  cmDspSysInstallCb( h, onBtn, "sym", nom, "cmd", NULL );
  cmDspSysInstallCb( h, offBtn, "sym", nom, "cmd", NULL );
  
  errLabel:
  return rc;
}


cmDspPgm_1ofM : Select 1 of N example program.
cmDspRC_t _cmDspSysPgm_1ofN( cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t rc;
  unsigned inCnt = 3;
  unsigned initSel = 0;
  
  cmDspInst_t* oom = cmDspSysAllocInst(h,"1ofN", NULL,   2, inCnt, initSel );
  
  cmDspInst_t* sel  = cmDspSysAllocScalar( h, "Sel",      0, inCnt-1, 0.001, 0.0);
  
  cmDspInst_t* in0  = cmDspSysAllocScalar( h, "In-0",      0.0, 10.0, 0.001, 0.0);
  cmDspInst_t* in1  = cmDspSysAllocScalar( h, "In-1",      0.0, 10.0, 0.001, 0.0);
  cmDspInst_t* in2  = cmDspSysAllocScalar( h, "In-2",      0.0, 10.0, 0.001, 0.0);  
  
  cmDspInst_t* out  = cmDspSysAllocScalar( h, "Out",      0.0, 10.0, 0.001, 0.0);
  
  
  // check for allocation errors
  if((rc = cmDspSysLastRC(h)) != kOkDspRC )
    goto errLabel;
  
  
  cmDspSysInstallCb( h, sel, "val", oom, "chidx", NULL );
  
  cmDspSysInstallCb( h, in0, "val", oom, "f-in-0", NULL );
  cmDspSysInstallCb( h, in1, "val", oom, "f-in-1", NULL );
  cmDspSysInstallCb( h, in2, "val", oom, "f-in-2", NULL );
  
  cmDspSysInstallCb( h, oom, "f-out", out, "val", NULL );
  
  
  errLabel:
  return rc;
}


cmDspPgm_Router : Router example program.
cmDspRC_t _cmDspSysPgm_Router( cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t rc;
  unsigned inCnt = 3;
  unsigned initSel = 0;
  
  cmDspInst_t* rtr = cmDspSysAllocInst(h,"Router", NULL,   2, inCnt, initSel );
  
  cmDspInst_t* sel  = cmDspSysAllocScalar( h, "Sel",      0, inCnt-1, 1.0, 0.0);
  
  cmDspInst_t* in  = cmDspSysAllocScalar( h, "In",      0.0, 10.0, 0.001, 0.0);
  
  cmDspInst_t* out0  = cmDspSysAllocScalar( h, "Out-0",      0.0, 10.0, 0.001, 0.0);
  cmDspInst_t* out1  = cmDspSysAllocScalar( h, "Out-1",      0.0, 10.0, 0.001, 0.0);
  cmDspInst_t* out2  = cmDspSysAllocScalar( h, "Out-2",      0.0, 10.0, 0.001, 0.0);  
  
  
  
  // check for allocation errors
  if((rc = cmDspSysLastRC(h)) != kOkDspRC )
    goto errLabel;
  
  
  cmDspSysInstallCb( h, sel, "val", rtr, "sel", NULL );
  
  cmDspSysInstallCb( h, in, "val", rtr, "f-in", NULL );
  
  cmDspSysInstallCb( h, rtr, "f-out-0", out0, "val", NULL );
  cmDspSysInstallCb( h, rtr, "f-out-1", out1, "val", NULL );
  cmDspSysInstallCb( h, rtr, "f-out-2", out2, "val", NULL );
  
  
  
  
  errLabel:
  return rc;
}


cmDspPgm_Preset : Preset save/restore example program.
cmDspRC_t _cmDspSysPgm_Preset( cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t rc;
  
  unsigned        sgShapeId = 0;
  double          sgHz      = 500;
  double          sgGain    = 0.02;
  unsigned        grpSymId  = cmDspSysPresetRegisterGroup(h,"test");
  const cmChar_t* prefixLabel    = NULL;
  
  cmDspInst_t* sg  = cmDspSysAllocInst(   h, "SigGen",    NULL, 3, sgHz, sgShapeId, sgGain );
  cmDspInst_t* ao  =  cmDspSysAllocAudioOut( h, 0, 1.0 );
  
  cmDspInst_t* shapes = cmDspSysAllocMsgListP(h, grpSymId, prefixLabel, "Shape", NULL, "shapeList", 0 );
  cmDspInst_t* gains  = cmDspSysAllocMsgListP(h, grpSymId, prefixLabel, "Gains", NULL, "gainMenu", 0 );
  cmDspInst_t* hz     = cmDspSysAllocScalarP( h, grpSymId, prefixLabel, "Hz",        0.0, 10000.0, 0.01, sgHz);
  cmDspInst_t* gain   = cmDspSysAllocScalarP( h, grpSymId, prefixLabel, "Gain",      0.0, 1.0,     0.01, sgGain);
  
  cmDspInst_t* preset    = cmDspSysAllocInst(   h, "Preset", NULL, 1, grpSymId );
  cmDspInst_t* presetLbl = cmDspSysAllocInst(   h, "Text",   "Preset",      1, "" );
  cmDspInst_t* storeBtn  = cmDspSysAllocButton( h, "store",  0);
  cmDspInst_t* recallBtn = cmDspSysAllocButton( h, "recall", 0);
  
  // check for allocation errors
  if((rc = cmDspSysLastRC(h)) != kOkDspRC )
    goto errLabel;
  
  cmDspSysConnectAudio(h, sg,    "out", ao, "in" );
  cmDspSysInstallCb(   h, shapes,"out", sg, "shape", NULL );
  cmDspSysInstallCb(   h, hz,    "val", sg, "hz",    NULL );
  cmDspSysInstallCb(   h, gain,  "val", sg, "gain",  NULL );
  cmDspSysInstallCb(   h, gains, "out", gain, "val",  NULL );
  
  cmDspSysInstallCb(   h, presetLbl, "val", preset, "label",NULL);
  cmDspSysInstallCb(   h, storeBtn,  "sym", preset, "cmd", NULL );
  cmDspSysInstallCb(   h, recallBtn, "sym", preset, "cmd", NULL );
  errLabel:
  return rc;
}


cmDspPgm_RsrcWr : Set a resource value example program.
cmDspRC_t _cmDspSysPgm_RsrcWr( cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t    rc      = kOkDspRC;
  
  const cmChar_t* lbl1 = "rsrc1";
  const cmChar_t* lbl2 = "rsrc2";
  const cmChar_t* str1 = NULL;
  const cmChar_t* str2 = NULL;
  
  if( cmDspRsrcString(h,&str1, lbl1, NULL ) != kOkDspRC )
    str1 = "1";
  
  if( cmDspRsrcString(h,&str2, lbl2, NULL ) != kOkDspRC )
    str2 = "2";
  
  cmDspInst_t* rsrcWr  = cmDspSysAllocInst( h, "RsrcWr", NULL,    2, lbl1, lbl2 );
  cmDspInst_t* textUi0 = cmDspSysAllocInst( h, "Text",   "Value1",      1, str1 );
  cmDspInst_t* textUi1 = cmDspSysAllocInst( h, "Text",   "Value2",      1, str2 );
  
  if((rc = cmDspSysLastRC(h)) != kOkDspRC )
    goto errLabel;
  
  cmDspSysInstallCb( h, textUi0, "val", rsrcWr, "rsrc1", NULL );
  cmDspSysInstallCb( h, textUi1, "val", rsrcWr, "rsrc2", NULL );
  
  errLabel:
  return rc;
}


cmDspPgm_1Up : 1Up example program.
cmDspRC_t _cmDspSysPgm_1Up( cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t rc;
  unsigned chCnt = 3;
  double   maxIdx = chCnt - 1;
  unsigned initIdx = 2;
  
  cmDspInst_t* sel  = cmDspSysAllocScalar( h, "Chan", 0.0, maxIdx, 1.0, 0.0 );
  cmDspInst_t* up   = cmDspSysAllocInst( h, "1Up", NULL, 2, chCnt, initIdx );
  
  cmDspInst_t* pr0  = cmDspSysAllocInst( h, "Printer", NULL, 1, "0:" );
  cmDspInst_t* pr1  = cmDspSysAllocInst( h, "Printer", NULL, 1, "1:" );
  cmDspInst_t* pr2  = cmDspSysAllocInst( h, "Printer", NULL, 1, "2:" );
  
  // check for allocation errors
  if((rc = cmDspSysLastRC(h)) != kOkDspRC )
    goto errLabel;
  
  cmDspSysInstallCb(   h, sel, "val", up, "sel",NULL);
  cmDspSysInstallCb(   h, up,  "out-0", pr0, "in", NULL );
  cmDspSysInstallCb(   h, up,  "out-1", pr1, "in", NULL );
  cmDspSysInstallCb(   h, up,  "out-2", pr2, "in", NULL );
  
  errLabel:
  return rc;
}


cmDspPgm_PortToSym : PortToSym example program.
cmDspRC_t _cmDspSysPgm_PortToSym( cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t rc = kOkDspRC;
  
  inst_t* btn0  = button( "Btn0", 0.0 );
  inst_t* btn1  = button( "Btn1", 0.0 );
  inst_t* btn2  = button( "Btn2", 0.0 );  
  
  inst_t* pts   = inst( "PortToSym", NULL, "one", "two", "three");
  
  inst_t* pr0  = inst( "Printer", NULL,  "sym:" );
  inst_t* pr1  = inst( "Printer", NULL,  "btn:" );
  inst_t* pr2  = inst( "Printer", NULL,  "out:" );
  
  // check for allocation errors
  if((rc = cmDspSysLastRC(h)) != kOkDspRC )
    goto errLabel;
  
  event( btn0, out, pts, one );
  event( btn1, out, pts, two );
  event( btn2, out, pts, three );
  
  event( btn0, out, pr1, in );
  event( btn1, out, pr1, in );
  event( btn2, out, pr1, in );
  
  event( pts,  one,   pr0, in );
  event( pts,  two,   pr0, in );
  event( pts,  three, pr0, in );
  event( pts,  out,   pr2, in );
  
  errLabel:
  return rc;
}


cmDspPgm_IntToSym : IntToSym example program.
cmDspRC_t _cmDspSysPgm_IntToSym( cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t rc = kOkDspRC;
  
  inst_t* sel0   = scalar( "Sel0", 0.0, 10.0, 1.0, 1.0 );
  inst_t* sel1   = scalar( "Sel1", 0.0, 10.0, 1.0, 1.0 );
  inst_t* sel2   = scalar( "Sel2", 0.0, 10.0, 1.0, 1.0 );
  inst_t* val    = scalar( "Val",  0.0, 10.0, 1.0, 1.0 );
  
  inst_t* pts   = inst( "IntToSym", NULL, 0, "one", 0, "two", 0, "three");
  
  inst_t* pr0  = inst( "Printer", NULL,  "val:" );
  inst_t* pr1  = inst( "Printer", NULL,  "sym:" );
  inst_t* pr2  = inst( "Printer", NULL,  "out:" );
  
  // check for allocation errors
  if((rc = cmDspSysLastRC(h)) != kOkDspRC )
    goto errLabel;
  
  event( sel0, val, pts, one-int );
  event( sel1, val, pts, two-int );
  event( sel2, val, pts, three-int );
  
  event( val, val, pts, in );
  event( val, val, pr0, in );
  
  event( pts,  one,   pr1, in );
  event( pts,  two,   pr1, in );
  event( pts,  three, pr1, in );
  
  event( pts, out, pr2, in );
  
  errLabel:
  return rc;
}



cmDspPgm_Line : Line generator example program.
cmDspRC_t _cmDspSysPgm_Line( cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t rc = kOkDspRC;
  
  cmDspInst_t* beg   = cmDspSysAllocScalar( h, "beg", -10.0, 10.0, 1.0, 0.0 );
  cmDspInst_t* end   = cmDspSysAllocScalar( h, "end", -10.0, 10.0, 1.0, 1.0 );
  cmDspInst_t* dur   = cmDspSysAllocScalar( h, "dur", 0.0, 10000.0, 1.0, 0.0 );  
  cmDspInst_t* reset = cmDspSysAllocButton( h, "reset", 0.0 );
  cmDspInst_t* line  = cmDspSysAllocInst(   h, "Line", NULL, 3, 0.0, 10.0, 1000.0 );
  
  cmDspInst_t* mtr   = cmDspSysAllocInst( h, "Meter", NULL, 3, -10.0, 10.0, 0.0  );
  
  cmDspInst_t* pr1   = cmDspSysAllocInst( h, "Printer", NULL, 1, ">" );
  
  // check for allocation errors
  if((rc = cmDspSysLastRC(h)) != kOkDspRC )
    goto errLabel;
  
  cmDspSysInstallCb(   h, beg, "val", line, "beg", NULL);
  cmDspSysInstallCb(   h, end, "val", line, "end", NULL);
  cmDspSysInstallCb(   h, dur, "val", line, "dur", NULL);
  
  
  cmDspSysInstallCb(   h, line,  "out", mtr,  "in",  NULL );
  cmDspSysInstallCb(   h, reset, "sym", line, "cmd", NULL );
  cmDspSysInstallCb(   h, line,  "out", pr1,  "in",  NULL );
  
  errLabel:
  return rc;
}


cmDspPgm_Array : Array and pitch converter example program.
cmDspRC_t _cmDspSysPgm_Array( cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t       rc           = kOkDspRC;
  unsigned        cnt          = 0;
  const cmChar_t* rsrcLabelStr = "test";
  
  if( cmDspRsrcArrayCount( h, &cnt, rsrcLabelStr, NULL ) != kOkDspRC )
    return cmErrMsg(&cmDspSysPgmCtx(h)->err,kPgmCfgFailDspRC,"The resource '%s' could not be read.",rsrcLabelStr);
  
  cmDspInst_t*  printBtn = cmDspSysAllocButton(    h, "print", 0.0 );
  cmDspInst_t*  sendBtn  = cmDspSysAllocButton(    h, "send",  0.0 );
  cmDspInst_t*  cntBtn   = cmDspSysAllocButton(    h, "count", 0.0 );
  cmDspInst_t*  offsCtl  = cmDspSysAllocScalar(    h, "offset",0.0, 128.0, 1.0, 60.0 );
  cmDspInst_t*  array    = cmDspSysAllocInst(      h, "Array",    NULL, 1, rsrcLabelStr );
  cmDspInst_t** pcvt     = cmDspSysAllocInstArray( h, cnt, "PitchCvt", NULL, NULL,  0 );
  cmDspInst_t*  printer  = cmDspSysAllocInst(      h, "Printer",  NULL, 1, ">" );
  
  cmDspSysInstallCb(     h, printBtn, "sym",  array,   "cmd", NULL );
  cmDspSysInstallCb(     h, sendBtn,  "sym",  array,   "cmd", NULL );
  cmDspSysInstallCb(     h, cntBtn,   "sym",  array,   "cmd", NULL );
  cmDspSysInstallCb11N1( h, offsCtl,  "val",  pcvt,    "offs", cnt );
  cmDspSysInstallCb1NN1( h, array,    "out",  pcvt,    "midi", cnt );
  cmDspSysInstallCbN111( h, pcvt,     "midi", printer, "in",  cnt );
  cmDspSysInstallCb(     h, array,    "cnt",  printer, "in",  NULL );
  return rc;
}

cmDspRC_t _cmDspSysPgm_SegLine( cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t rc = kOkDspRC;
  
  cmDspInst_t*  btn     = cmDspSysAllocButton(    h, "Trig", 0.0 );
  cmDspInst_t*  sline   = cmDspSysAllocInst(      h, "SegLine", NULL, 1, "array" );
  cmDspInst_t*  printer = cmDspSysAllocInst(      h, "Printer",  NULL, 1, ">" );
  
  // check for allocation errors
  if((rc = cmDspSysLastRC(h)) != kOkDspRC )
    goto errLabel;
  
  cmDspSysInstallCb( h, btn,   "sym",  sline,   "trig", NULL );
  cmDspSysInstallCb( h, sline, "out", printer, "in",   NULL );
  
  errLabel:
  return rc;
}


cmDspPgm_AvailCh : AvailCh and XFader example program.
cmDspRC_t _cmDspSysPgm_AvailCh( cmDspSysH_t h, void** userPtrPtr )
{
  double   frqHz       = 440.0;
  unsigned xfadeChCnt  = 2;
  double   xfadeMs     = 250.0;
  bool     xfadeInitFl = false;
  
  const char*  fn    = "/Users/kevin/media/audio/20110723-Kriesberg/Audio Files/Piano 3_01.wav";
  
  cmDspInst_t* chk0   = cmDspSysAllocInst(h,"Button", "0",  2, kButtonDuiId, 0.0 );
  cmDspInst_t* hz     = cmDspSysAllocScalar( h, "hz",0.0, 10000.0, 0.01, 1.0 );
  
  //cmDspInst_t* chk1   = cmDspSysAllocInst(h,&quotButton&quot, &quot1&quot,  2, kCheckDuiId, 0.0 );
  
  cmDspInst_t* achp  = cmDspSysAllocInst( h, "AvailCh", NULL, 1, xfadeChCnt );
  
  cmDspInst_t* sphp  =  cmDspSysAllocInst( h, "Phasor",    NULL,   2, cmDspSysSampleRate(h), frqHz );
  cmDspInst_t* swtp  =  cmDspSysAllocInst( h, "WaveTable", NULL,   2, ((int)cmDspSysSampleRate(h)), 4);
  cmDspInst_t* fphp  =  cmDspSysAllocInst( h, "Phasor",    NULL,   1, cmDspSysSampleRate(h) );
  cmDspInst_t* fwtp  =  cmDspSysAllocInst( h, "WaveTable", NULL,   5, ((int)cmDspSysSampleRate(h)), 1, fn, -1, 7000000 );
  cmDspInst_t* fad0  =  cmDspSysAllocInst( h, "Xfader",    NULL,   3, xfadeChCnt,  xfadeMs, xfadeInitFl ); 
  
  cmDspInst_t*  prp   = cmDspSysAllocInst(  h, "Printer",  NULL, 1, "ch:" );
  cmDspInst_t*  prg0  = cmDspSysAllocInst(  h, "Printer",  NULL, 1, "g0:" );
  cmDspInst_t*  prg1  = cmDspSysAllocInst(  h, "Printer",  NULL, 1, "g1:" );
  
  cmDspInst_t* ao0p = cmDspSysAllocInst(h,"AudioOut",  NULL,   1, 0 );
  cmDspInst_t* ao1p = cmDspSysAllocInst(h,"AudioOut",  NULL,   1, 1 );
  
  
  // phasor-&gtsine-&gtfad-0-&gtaout
  cmDspSysConnectAudio(h, sphp, "out",   swtp, "phs" );
  cmDspSysConnectAudio(h, swtp, "out",   fad0, "in-0" ); 
  cmDspSysConnectAudio(h, fad0, "out-0", ao0p, "in" );
  
  // phasor-&gtfile-&gtfad-1-&gtaout
  cmDspSysConnectAudio(h, fphp, "out",   fwtp, "phs" );
  cmDspSysConnectAudio(h, fwtp, "out",   fad0, "in-1" ); 
  cmDspSysConnectAudio(h, fad0, "out-1", ao1p, "in" ); 
  
  //cmDspSysInstallCb(h, chk0, &quotout&quot, fad0, &quotgate-0&quot, NULL);
  //cmDspSysInstallCb(h, chk1, &quotout&quot, fad0, &quotgate-1&quot, NULL);  
  
  cmDspSysInstallCb(h, chk0, "sym",     achp, "trig",   NULL);  // btn-&gtavailCh.trig
  cmDspSysInstallCb(h, achp, "ch",      prp,  "in",     NULL);  // availCh.ch -&gt printer
  
  
  cmDspSysInstallCb(h, achp, "gate-0",  fad0, "gate-0", NULL );   // availCh.gate-&gtxfad.gate 
  cmDspSysInstallCb(h, fad0, "state-0", achp, "dis-0",  NULL );   // xfad-&gtstate -&gtavailCh.dis
  
  cmDspSysInstallCb(h, achp, "gate-1",  fad0, "gate-1", NULL );
  cmDspSysInstallCb(h, fad0, "state-1", achp, "dis-1",  NULL );
  
  cmDspSysInstallCb(h, hz,   "val",     sphp, "mult",   NULL );
  
  cmDspSysInstallCb(h, achp, "gate-0",  prg0, "in", NULL ); 
  cmDspSysInstallCb(h, achp, "gate-1",  prg1, "in", NULL ); 
  
  return kOkDspRC;
  
}


cmDspPgm_Goertzel : Goertzel detector example program.
cmDspRC_t _cmDspSysPgm_Goertzel( cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t rc;
  const unsigned chCnt        = 8;
  unsigned       hopFact      = 2;
  double         dfltHz       = 18000.0;
  unsigned       sigGenMode   = 2;  // sine
  double         sigGenGain   = 0.9;
  double         dfltMixGain  = 1.0/chCnt;
  double         fcHzV[chCnt];
  unsigned       i;
  
  for(i=0; i<chCnt; ++i)
    fcHzV[i] = 18000.0 + (20000.0-18000.0) * i /chCnt;
  
  
  cmDspInst_t*  ain   = cmDspSysAllocAudioIn(  h, 0, 1.0);
  cmDspInst_t*  amtr  = cmDspSysAllocInst(     h, "AMeter", "In", 0 );
  
  cmDspInst_t*  goer  = cmDspSysAllocInst(     h, "Goertzel",  NULL,   3, hopFact, chCnt, fcHzV );
  
  cmDspSysNewColumn(h,0);
  cmDspInst_t** mtrV  = cmDspSysAllocInstArray(h, chCnt, "Meter",  "Mtr", NULL,  3, 0.0, 0.0, 1.0 );  
  cmDspInst_t** sgV   = cmDspSysAllocInstArray(h, chCnt, "SigGen", "SG",  NULL,  2, dfltHz, sigGenMode, sigGenGain, 0 );
  cmDspInst_t*  mix   = cmDspSysAllocInst(     h, "AMix", NULL,1, chCnt );
  cmDspInst_t*  ao0   = cmDspSysAllocAudioOut( h, 0, 1.0);
  cmDspInst_t*  ao1   = cmDspSysAllocAudioOut( h, 0, 1.0);
  
  cmDspSysNewColumn(h,0);
  cmDspInst_t**  hzV   = cmDspSysAllocInstArray( h, chCnt, "Scalar", "Hz",   NULL, 5, kNumberDuiId, 0.0, 22000.0, 100.0, dfltHz );
  
  cmDspSysNewColumn(h,0);
  cmDspInst_t**  gnV   = cmDspSysAllocInstArray( h, chCnt, "Scalar", "Gain", NULL, 5, kNumberDuiId, 0.0, 1.0, 0.01, dfltMixGain );
  cmDspInst_t*   igain = cmDspSysAllocScalar(    h, "igain", 0.0,  3.0, 0.01, 1.0 );
  cmDspInst_t*   hop   = cmDspSysAllocScalar(    h, "hop",   0.0, 16.0, 1.0,  4.0 );
  
  //cmDspInst_t* prnt = cmDspSysAllocInst( h,&quotPrinter&quot, NULL,     1, &quot&gt&quot );
  
  // check for allocation errors
  if((rc = cmDspSysLastRC(h)) != kOkDspRC )
    goto errLabel;
  
  cmDspSysConnectAudio(h,ain,"out", goer, "in" );
  cmDspSysConnectAudio(h,ain,"out", amtr, "in" );
  
  cmDspSysConnectAudioN11N(h,sgV, "out", mix, "in", chCnt );
  cmDspSysConnectAudio(h,mix,"out", ao0, "in" );
  cmDspSysConnectAudio(h,mix,"out", ao1, "in" );
  
  cmDspSysInstallCb( h, igain, "val", ain, "gain", NULL);
  cmDspSysInstallCbN1N1( h, hzV, "val", sgV, "hz",   chCnt);
  cmDspSysInstallCbN11N( h, hzV, "val", goer, "hz",  chCnt );
  cmDspSysInstallCbN11N( h, gnV, "val", mix, "gain", chCnt); 
  cmDspSysInstallCb1NN1( h, goer, "out", mtrV, "in", chCnt );
  cmDspSysInstallCb(     h, hop, "val",  goer, "hop", NULL ); 
  
  errLabel:
  return rc;
}


cmDspPgm_TakeSeqBldr : Take sequence builder example program.
cmDspRC_t _cmDspSysPgm_TakeSeqBldr( cmDspSysH_t h, void** userPtrPtr )
{  
  cmDspRC_t       rc         = kOkDspRC;
  //const cmChar_t* tksbFn     = &quot/User/kevin/src/cmkc/src/kc/data/takeSeqBldr0.js&quot;
  const cmChar_t* tksbFn     =  "/Users/kevin/src/cmkc/src/kc/data/takeSeqBldr_osx.js";
  const cmChar_t* deviceName = "MOTU - Traveler mk3";  // &quotFastlane&quot;
  const cmChar_t* portName   = "MIDI Port";            // &quotFastlane MIDI A&quot;
  
  //const cmChar_t* deviceName = &quotDKV-M4&quot;
  //const cmChar_t* portName   = &quotDKV-M4 MIDI 1&quot;  
  
  const cmChar_t* fn  = cmFsMakeFn(cmFsUserDir(),tksbFn,NULL,NULL );
  
  cmDspInst_t* tsb   = cmDspSysAllocInst( h,"TakeSeqBldr", NULL, 1, tksbFn );
  cmDspInst_t* tsr   = cmDspSysAllocInst( h,"TakeSeqRend", NULL, 0 );
  cmDspInst_t* nano  = cmDspSysAllocInst( h,"NanoMap",     NULL, 0 );
  cmDspInst_t* mop   = cmDspSysAllocInst( h,"MidiOut",     NULL, 2, deviceName, portName);
  
  cmDspSysNewPage(h,"Controls");
  
  //cmDspInst_t* fnp   =  cmDspSysAllocInst(h,&quotFname&quot,       NULL,  3, false,&quotJS Files (*.js)\tJS Files (*.{js})&quot,fn);
  
  cmDspInst_t* start = cmDspSysAllocInst( h,"Button", "start",    2, kButtonDuiId, 0.0 );
  cmDspInst_t* stop  = cmDspSysAllocInst( h,"Button", "stop",     2, kButtonDuiId, 0.0 );
  cmDspInst_t* cont  = cmDspSysAllocInst( h,"Button", "continue", 2, kButtonDuiId, 0.0 );
  
  cmDspInst_t* prt  = cmDspSysAllocInst(  h, "Printer",  NULL, 1, ">" );
  
  // check for allocation errors
  if((rc = cmDspSysLastRC(h)) != kOkDspRC )
    goto errLabel;
  
  cmDspSysInstallCb(   h, tsb,    "bldr",  tsr,    "bldr", NULL);    
  cmDspSysInstallCb(   h, tsb, "refresh",  tsr, "refresh", NULL );
  cmDspSysInstallCb(   h, tsb,     "sel",  tsr,     "sel", NULL );
  
  cmDspSysInstallCb(   h, start,   "sym",   tsr,    "cmd", NULL);
  cmDspSysInstallCb(   h, stop,    "sym",   tsr,    "cmd", NULL);
  cmDspSysInstallCb(   h, cont,    "sym",   tsr,    "cmd", NULL);
  
  cmDspSysInstallCb(   h, tsr,  "d1",     nano, "d1",     NULL);
  cmDspSysInstallCb(   h, tsr,  "d0",     nano, "d0",     NULL);
  cmDspSysInstallCb(   h, tsr,  "status", nano, "status", NULL);
  
  cmDspSysInstallCb(   h, nano, "d1",     mop,  "d1",     NULL);
  cmDspSysInstallCb(   h, nano, "d0",     mop,  "d0",     NULL);
  cmDspSysInstallCb(   h, nano, "status", mop,  "status", NULL);
  
  //cmDspSysInstallCb(   h, tsb, &quotsel&quot, prt, &quotin&quot, NULL );
  cmDspSysInstallCb(   h, tsb, "refresh", prt, "in", NULL);
  errLabel:
  
  cmFsFreeFn(fn);
  
  return rc;
}



cmDspPgm_TwoD : Two dimensional controller example program.
cmDspRC_t _cmDspSysPgm_TwoD( cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t       rc         = kOkDspRC;
  
  cmDspInst_t* twod = cmDspSysAllocInst(h,"twod", NULL, 0);
  cmDspInst_t* aprt  = cmDspSysAllocInst(h,"Printer",NULL, 1, "a: ");
  cmDspInst_t* rprt  = cmDspSysAllocInst(h,"Printer",NULL, 1, "r: ");
  
  // check for allocation errors
  if((rc = cmDspSysLastRC(h)) != kOkDspRC )
    goto errLabel;
  
  cmDspSysInstallCb(h, twod, "angle",  aprt, "in", NULL );
  cmDspSysInstallCb(h, twod, "radius", rprt, "in", NULL );
  
  errLabel:
  return rc;
}


cmDspPgm_BinEnc : HRTF binaural encoder example program.
cmDspRC_t _cmDspSysPgm_BinEnc( cmDspSysH_t h, void** userPtrPtr )
{
  cmDspRC_t       rc         = kOkDspRC;
  
  double durMs    = 10000.0;  
  double lineHz   = 0.2;
  double maxDurMs = 60000.0;
  double azimBeg  =     0.0;
  double azimEnd  =   360.0;
  //const char* fn1 = &quotmedia/audio/sourcetone/Jazz/Ella &amp Louis - Under A Blanket Of Blue&quot;
  const char* fn0 = "temp/comhear/drw/monty.wav";
  
  cmDspInst_t* twod = cmDspSysAllocInst( h, "twod",       NULL, 0);
  cmDspInst_t* php  = cmDspSysAllocInst( h, "Phasor",     NULL, 0 );
  cmDspInst_t* wtp  = cmDspSysAllocInst( h, "WaveTable",  NULL, 2, ((int)cmDspSysSampleRate(h)), 1 );
  cmDspInst_t* bep  = cmDspSysAllocInst( h, "BinauralEnc",NULL, 1, 0);
  
  cmDspInst_t* ao0p = cmDspSysAllocInst( h, "AudioOut", NULL, 1, 0  );
  cmDspInst_t* ao1p = cmDspSysAllocInst( h, "AudioOut", NULL, 1, 1  );
  
  
  cmDspSysNewPage(h,"Controls");  
  
  const cmChar_t* fn    = cmFsMakeFn(cmFsUserDir(),fn0,NULL,NULL );
  cmDspInst_t*    fnp   = cmDspSysAllocInst(   h,"Fname", NULL,  3, false,"Audio Files (*.wav,*.aiff,*.aif)\tAudio Files (*.{wav,aiff,aif})",fn);
  cmDspInst_t*    beg   = cmDspSysAllocScalar( h, "beg", 0.0, azimEnd,  1.0, azimBeg );
  cmDspInst_t*    end   = cmDspSysAllocScalar( h, "end", 0.0, azimEnd,  1.0, azimEnd );
  cmDspInst_t*    dur   = cmDspSysAllocScalar( h, "dur", 0.0, maxDurMs, 1.0, durMs );  
  cmDspInst_t*    reset = cmDspSysAllocButton( h, "reset", 0.0 );
  cmDspInst_t*    azm   = cmDspSysAllocScalar( h, "azimuth", azimBeg, azimEnd, 1.0, 0.0 );
  cmDspInst_t*    angle = cmDspSysAllocScalar( h, "angle",   azimBeg, azimEnd, 1.0, 0.0 );
  cmDspInst_t*    mode  = cmDspSysAllocScalar( h, "mode", 0.0, 1.0, 1.0, 0.0 );
  cmDspInst_t*    gain  = cmDspSysAllocScalar( h, "gain", 0.0,10.0, 0.01, 1.0 );
  
  cmDspInst_t* line  = cmDspSysAllocInst(   h, "Line", NULL, 3, azimBeg, azimEnd, durMs, lineHz );
  cmDspInst_t* prt   = cmDspSysAllocInst(   h, "Printer",  NULL, 1, ">" );
  
  // check for allocation errors
  if((rc = cmDspSysLastRC(h)) != kOkDspRC )
    goto errLabel;
  
  cmDspSysConnectAudio(h, php,  "out",  wtp,  "phs" );   // phasor -&gt wave table
  cmDspSysConnectAudio(h, wtp,  "out",  bep,  "in" );
  cmDspSysConnectAudio(h, bep,  "out0", ao0p, "in" );    // wave table -&gt audio out
  cmDspSysConnectAudio(h, bep,  "out1", ao1p, "in" );    
  
  cmDspSysInstallCb(   h, fnp,  "out", wtp,  "fn", NULL);    
  
  cmDspSysInstallCb(   h, beg,  "val", line, "beg", NULL);
  cmDspSysInstallCb(   h, end,  "val", line, "end", NULL);
  cmDspSysInstallCb(   h, dur,  "val", line, "dur", NULL);
  cmDspSysInstallCb(   h, reset,"sym", line, "cmd", NULL );
  
  cmDspSysInstallCb(   h, line, "out",   azm, "val",  NULL );
  cmDspSysInstallCb(   h, azm,  "val",   bep, "azim", NULL );
  
  cmDspSysInstallCb(   h, twod, "angle", angle,"val", NULL );
  cmDspSysInstallCb(   h, angle,"val",   bep, "azim", NULL );
  
  cmDspSysInstallCb(   h, mode, "val",   bep, "mode", NULL );
  
  cmDspSysInstallCb(   h, twod, "angle", prt, "in", NULL );
  cmDspSysInstallCb(   h, gain, "val",   ao0p, "gain", NULL );
  cmDspSysInstallCb(   h, gain, "val",   ao1p, "gain", NULL );
  
  return kOkDspRC;
  
  
  
  errLabel:
  return rc;
}
_cmDspSysPgm_t _cmDspSysPgmArray[] = 
{
  { "reflect",           _cmDspSysPgm_ReflectCalc,    NULL, NULL },
  { "tksblite",          _cmDspSysPgm_TksbLite,       NULL, NULL }, 
  { "tksb",              _cmDspSysPgm_Tksb,           NULL, NULL },
  { "time_line",         _cmDspSysPgm_TimeLine,       NULL, NULL },
  { "time_line_lite",    _cmDspSysPgm_TimeLineLite,   NULL, NULL },
  { "time_line_lite_af", _cmDspSysPgm_TimeLineLiteAf, NULL, NULL },
  { "seq-bldr",          _cmDspSysPgm_TakeSeqBldr,    NULL, NULL },
  { "multi-out",         _cmDspSysPgm_MultiOut,       NULL, NULL },
  { "multi-in",          _cmDspSysPgm_MultiIn,        NULL, NULL },
  { "goertzel",          _cmDspSysPgm_Goertzel,       NULL, NULL },
  { "main",              _cmDspSysPgm_Main,           NULL, NULL },
  { "array",             _cmDspSysPgm_Array,          NULL, NULL },
  { "line",              _cmDspSysPgm_Line,           NULL, NULL },
  { "1Up",               _cmDspSysPgm_1Up,            NULL, NULL },
  { "PortToSym",         _cmDspSysPgm_PortToSym,      NULL, NULL },
  { "IntToSym",          _cmDspSysPgm_IntToSym,       NULL, NULL },
  { "preset",            _cmDspSysPgm_Preset,         NULL, NULL },
  { "rsrcWr",            _cmDspSysPgm_RsrcWr,         NULL, NULL },
  { "router",            _cmDspSysPgm_Router,         NULL, NULL },
  { "1ofN",              _cmDspSysPgm_1ofN,           NULL, NULL },
  { "NofM",              _cmDspSysPgm_NofM,           NULL, NULL },
  { "whirl_net",         _cmDspSysPgm_WhirlNet,       NULL, NULL },
  { "thunk_net",         _cmDspSysPgm_ThunkNet,       NULL, NULL },
  { "seq",               _cmDspSysPgm_Seq,            NULL, NULL },
  { "dist_ds",           _cmDspSysPgm_DistDs,         NULL, NULL },
  { "bi_quad_eq",        _cmDspSysPgm_BiQuadEq,       NULL, NULL },
  { "compressor",        _cmDspSysPgm_Compressor,     NULL, NULL },
  { "adsr",              _cmDspSysPgm_Adsr,           NULL, NULL },
  { "msg delay",         _cmDspSysPgm_MsgDelay,       NULL, NULL },
  { "pickup rmod2",      _cmDspSysPgm_RingMod2,       NULL, NULL },
  { "pickup rmod",       _cmDspSysPgm_RingMod,        NULL, NULL },
  { "pickup tails",      _cmDspSysPgm_NoiseTails,     NULL, NULL },
  { "tails_2",           _cmDspSysPgm_NoiseTails2,    NULL, NULL },
  { "pickups",           _cmDspSysPgm_Pickups0,       NULL, NULL },
  { "sync_recd",         _cmDspSysPgm_SyncRecd,       NULL, NULL },
  { "midi_test",         _cmDspSysPgm_Test_Midi,      NULL, NULL },
  { "pedal_test",        _cmDspSysPgm_Test_Pedals,    NULL, NULL },
  { "midi_file",         _cmDspSysPgm_MidiFilePlay,   NULL, NULL },
  { "2_thru",            _cmDspSysPgm_Stereo_Through, NULL, NULL },
  { "all_in_out",        _cmDspSysPgm_All_In_And_Out, NULL, NULL },
  { "guitar",            _cmDspSysPgmGuitar,          NULL, NULL },
  { "2_fx",              _cmDspSysPgm_Stereo_Fx,      NULL, NULL },
  { "sine",              _cmDspSysPgm_PlaySine,       NULL, NULL },
  { "file",              _cmDspSysPgm_PlayFile,       NULL, NULL },
  { "gate_detect",       _cmDspSysPgm_GateDetect,     NULL, NULL },
  { "rt_record",         _cmDspSysPgm_RtRecord,       NULL, NULL },
  { "record",            _cmDspSysPgm_Record,         NULL, NULL },
  { "pitch_shift",       _cmDspSysPgm_PitchShiftFile, NULL, NULL },
  { "loop_recd",         _cmDspSysPgm_LoopRecd,       NULL, NULL },
  { "ui_test",           _cmDspSysPgm_UiTest,         NULL, NULL },
  { "xfade_test",        _cmDspSysPgm_Xfade,          NULL, NULL },
  { "auto_gain",         _cmDspSysPgm_AutoGain,       NULL, NULL },
  { "comb filt",         _cmDspSysPgm_CombFilt,       NULL, NULL },
  { "scalar op",         _cmDspSysPgm_ScalarOp,       NULL, NULL },
  { "seg_line",          _cmDspSysPgm_SegLine,        NULL, NULL },
  { "avail_ch",          _cmDspSysPgm_AvailCh,        NULL, NULL },
  { "two-d",             _cmDspSysPgm_TwoD,           NULL, NULL },
  { "bin-enc",           _cmDspSysPgm_BinEnc,         NULL, NULL },
  { NULL ,                                            NULL, NULL, NULL }
};

_cmDspSysPgm_t* _cmDspSysPgmArrayBase()
{
  return _cmDspSysPgmArray;
}