{
   "name" : "Compar",
   "author" : "LFSaw",
   "ancestor_list" : [],
   "description" : "Compar is a feed-forward resonator network featuring three ComplexRes nodes (available from https://github.com/supercollider/sc3-plugins ).\r\nThis code example accompanies the paper \"Dynamic FM synthesis using a network of complex resonator filters\" by Julian Parker and Till Bovermann. \r\n\r\nsee http://tai-studio.org/index.php/projects/complexres/ for details.",
   "labels" : [
      "ndef",
      "feedforward network",
      "resonator",
      "complexres",
      "plugin"
   ],
   "is_private" : null,
   "id" : "1-4V5",
   "code" : "(\r\nNdef(\\compar, {|in = 0|\r\n\tvar ctlLag = \\ctlLag.kr(0.1);\r\n\r\n\tvar src, dst, filterIn, mods, env, tmpIter;\r\n\tvar ampEnvs;\r\n\r\n\t// number of FM neurons\r\n\tvar numNodes = 3;\r\n\r\n\t// controls\r\n\tvar preAmp = \\preAmp.kr(0.1, ctlLag);\r\n\tvar postAmp = \\postAmp.kr(0.1, ctlLag);\r\n\tvar dryAmp = \\dryAmp.kr(1, ctlLag);\r\n\tvar filterWet = \\filterWet.kr(0.9, ctlLag);\r\n\tvar reverbWet = \\reverbWet.kr(0.9, ctlLag);\r\n\r\n\tvar freqs = numNodes.collect{|i|\r\n\t\t(\"freq\"++i).asSymbol.kr((500 + (i * 100)), ctlLag)\r\n\t}.flat;\r\n\tvar amps = numNodes.collect{|i|\r\n\t\t(\"amp\"++i).asSymbol.kr(1, ctlLag)\r\n\t}.flat;\r\n\tvar fms = numNodes.collect{|i|\r\n\t\t(\"fm\"++i).asSymbol.kr(1, ctlLag)\r\n\t}.flat;\r\n\tvar decays = numNodes.collect{|i|\r\n\t\t(\"decay\" ++i).asSymbol.kr(0.1, ctlLag)\r\n\t}.flat;\r\n\t\r\n\t\r\n\t// signal preparation\r\n\tsrc = LeakDC.ar(SoundIn.ar(in));\r\n\tfilterIn = preAmp * src;\r\n\t\r\n\t// FM network\r\n\tdst = freqs.inject([filterIn, 0], {|in, freq, i|\r\n\t\ttmpIter = ComplexRes.ar( \r\n\t\t\tfilterIn,\r\n\t\t\tfreq \r\n\t\t\t+ (fms[i] * in[0]),\r\n\t\t\tdecays[i]\r\n\t\t);\r\n\t\t\t\t\t\r\n\t\t[\r\n\t\t\ttmpIter * amps[i],\r\n\t\t\tin[1] + tmpIter\r\n\t\t]\r\n\t});\r\n\tdst = Mix.ar(dst * [1,  amps.sum * numNodes.reciprocal]);\r\n\r\n\r\n\t// dryWet\r\n\tdst = SelectX.ar(filterWet, [\r\n\t\tOnePole.ar(dryAmp * src, \\lpCoeff.kr(0.3, 0.1)), \r\n\t\tpostAmp * LeakDC.ar(dst)\r\n\t]);\r\n\r\n\t// compressor\r\n\tdst = Compander.ar(dst,dst,\r\n\t\tthresh: \\compThresh.kr(0.5,0.1),\r\n\t\tslopeBelow: 1 ,\r\n\t\tslopeAbove: \\compRatio.kr(0.3, 0.1),\r\n\t\tclampTime: 0.0001,\r\n\t\trelaxTime: 0.1\r\n\t);\r\n\r\n\t// reverb + gp limiting\r\n\tLimiter.ar(\r\n\t\tSelectX.ar(reverbWet, [dst, AdCVerb.ar(0.1 * dst, 10)])\r\n\t);\r\n});\r\n)\r\n\r\n\r\n(\r\n// control range specifications\r\nSpec.add(\\freq0, [1, 20000, \\exp]);\r\nSpec.add(\\freq1, \\freq0);\r\nSpec.add(\\freq2, \\freq0);\r\nSpec.add(\\in, [0, 2, \\lin, 1, 1]);\r\nSpec.add(\\amp0, [0, 1]);\r\nSpec.add(\\amp1, \\amp0);\r\nSpec.add(\\amp2, \\amp0);\r\nSpec.add(\\fm0, [0, 10000]);\r\nSpec.add(\\fm1, \\fm0);\r\nSpec.add(\\fm2, \\fm0);\r\nSpec.add(\\decay0, [0.01, 5, \\exp]);\r\nSpec.add(\\decay1, \\decay0);\r\nSpec.add(\\decay2, \\decay0);\r\nSpec.add(\\filterWet, [0, 1]);\r\nSpec.add(\\reverbWet, [0, 1]);\r\nSpec.add(\\preAmp, [0.5, 5, \\exp]);\r\nSpec.add(\\dryAmp, [0.5, 5, \\exp]);\r\nSpec.add(\\postAmp, [0.5, 50, \\exp]);\r\nSpec.add(\\lpCoeff, [0, 1]);\r\n)\r\n\r\n(\r\n// GUI\r\nNdef(\\compar).gui;\r\n)"
}
