diff --git a/src/cwtest/cfg/flow/flow_proc_dict.cfg b/src/cwtest/cfg/flow/flow_proc_dict.cfg new file mode 100644 index 0000000..07e816a --- /dev/null +++ b/src/cwtest/cfg/flow/flow_proc_dict.cfg @@ -0,0 +1,636 @@ +{ + balance: { + vars: { + in: { type:coeff, value:0.5, doc:"Input vaue" }, + out: { type:coeff, doc:"Ouput value. Same as input value."}, + inv_out: { type:coeff, doc:"1.0 minus output value."} + } + } + + audio_in: { + vars: { + dev_label: { type:string, doc:"Audio device label." }, + out: { type:audio, doc:"Audio output" }, + } + } + + audio_out: { + vars: { + dev_label: { type:string, doc:"Audio device label." }, + in: { type:audio, flags:["src"], doc:"Audio input." } + } + } + + audio_file_in: { + vars: { + fname: { type:string, doc:"Audio file name." }, + out:{ type:audio, doc:"Audio file output" }, + on_off:{ type:bool, value:false, doc:"1=on 0=off" },, + seekSecs:{ type:ftime, value:0.0, doc:"Seek to the specified seconds offset." } + eofFl:{ type:bool, eofFl: true, doc:"Set the system 'halt' flag when the audio is completely read."}, + } + } + + audio_file_out: { + vars: { + fname: { type:string, doc:"Audio file name." }, + bits: { type:uint, value:32u, doc:"Audio file word width. (8,16,24,32,0=float32)."}, + in: { type:audio, flags:["src"], doc:"Audio file input." } + } + } + + audio_gain: { + vars: { + in: { type:audio, flags:["src"], doc:"Audio input." }, + gain: { type:coeff, value:1.0, doc:"Gain coefficient." } + out: { type:audio, doc:"Audio output." }, + } + } + + audio_split: { + vars: { + in: { type:audio, flags:["src"], doc:"Audio input." }, + select: { type:int, doc:"Give a list of integers where each integer selects an output channel for the associated input channel." } + igain: { type:coeff, value:1.0, doc:"Audio gain for each input channel." } + ogain: { type:coeff, value:1.0, doc:"Audio gain for each output channel." } + out: { type:audio, doc:"Audio output." }, + } + + presets: + { + mute_off: { gain:1 }, + mute_on: { gain:0 }, + } + } + + audio_duplicate: { + vars: { + in: { type:audio, flags:["src"], doc:"Audio input."}, + duplicate: { type: uint, doc:"Count of times to repeat this channel." }, + gain: { type: coeff, value:1.0, doc:"Audio gain." }, + out: { type:audio, doc:"Audio output containing repeat * input channel count channels."} + } + } + + audio_merge: { + vars: { + in0: { type:audio, flags:["src"], doc:"First audio input." }, + in1: { type:audio, flags:["src"], doc:"Second audio input." }, + in2: { type:audio, flags:["src","src_opt"], doc:"Third audio input." }, + in3: { type:audio, flags:["src","src_opt"], doc:"Fourth audio input." }, + in4: { type:audio, flags:["src","src_opt"], doc:"Fifth audio input." }, + in5: { type:audio, flags:["src","src_opt"], doc:"Sixth audio input." }, + in6: { type:audio, flags:["src","src_opt"], doc:"Seventh audio input." }, + in7: { type:audio, flags:["src","src_opt"], doc:"Eigth audio input." }, + gain: { type:coeff, value:1.0, doc:"Audio gain for each selected (output) channel." } + out: { type:audio, doc:"Audio output. Channel count is the sum of the input channel count." }, + } + } + + audio_mix: { + vars: { + in0: { type:audio, flags:["src"], doc:"First audio input." }, + in1: { type:audio, flags:["src"], doc:"Second audio input." }, + gain0: { type:coeff, value:0.5, doc:"Audio gain for input 0." }, + gain1: { type:coeff, value:0.5, doc:"Audio gain for input 1." }, + out: { type:audio, doc:"Audio output. Channel count is max of the input signal channels." }, + } + } + + audio_delay: { + vars: { + in: { type:audio, flags:["src"], doc:"Audio input." }, + maxDelayMs: { type:ftime, value:1000.0 doc:"Maximum possible delay in milliseconds." }, + delayMs: { type:ftime, doc:"Delay in milliseconds." }, + out: { type:audio, doc:"Audio output." }, + } + } + + + sine_tone: { + vars: { + srate: { type:srate, value:0, doc:"Sine tone sample rate. 0=Use default system sample rate"} + chCnt: { type:uint, value:2, doc:"Output signal channel count."}, + hz: { type:coeff, value:440.0, doc:"Frequency in Hertz."}, + phase: { type:coeff, value:0.0, doc:"Offset phase in radians."}, + dc: { type:coeff, value:0.0, doc:"DC offset applied after gain."}, + gain: { type:coeff, value:0.8, doc:"Signal frequency."}, + out: { type:audio, doc:"Audio output" }, + } + + presets: { + a220 : { hz:220 }, + a440 : { hz:440 }, + a880 : { hz:880 }, + } + } + + pv_analysis: { + vars: { + in: { type:audio, flags:["src"], doc:"Audio input." }, + maxWndSmpN: { type:uint, value: 512, doc:"Maximum window sample count." }, + wndSmpN: { type:uint, value: 512, doc:"Window sample count." }, + hopSmpN: { type:uint, value: 128, doc:"Hop sample count." }, + hzFl: { type:bool, value: false, doc:"Calculate frequency via the method of phase changeof each bin." }, + out: { type:spectrum, doc:"Spectrum output." } + } + + presets: { + + dry: { + wndSmpN: 512, + hopSmpN: 128 + } + + kc: { + wndSmpN: 512, + hopSmpN: 128 + } + + a: { + wndSmpN: 512, + hopSmpN: 128 + } + + b: { + wndSmpN: 512, + hopSmpN: 128 + } + + c: { + wndSmpN: 512, + hopSmpN: 128 + } + + d: { + wndSmpN: 512, + hopSmpN: 128 + } + + f_1: { + wndSmpN: 512, + hopSmpN: 128 + } + + f_2: { + wndSmpN: 512, + hopSmpN: 128 + } + + f_3: { + wndSmpN: 512, + hopSmpN: 128 + } + + f_4: { + wndSmpN: 512, + hopSmpN: 128 + } + + g: { + wndSmpN: 512, + hopSmpN: 128 + } + + g_a: { + wndSmpN: 512, + hopSmpN: 128 + } + + g_1_a: { + wndSmpN: 512, + hopSmpN: 128 + } + + g_1_d: { + wndSmpN: 512, + hopSmpN: 128 + } + } + } + + pv_synthesis: { + vars: { + in: { type:spectrum, flags:["src"], doc:"Spectrum input." }, + out: { type:audio, doc:"Audio output." } + } + } + + spec_dist: { + vars: { + in: { type:spectrum, flags:["src"], doc:"Spectrum input." }, + + bypass: { type:bool, value: false, doc:"Copy input to output without transform."}, + ceiling: { type:coeff, value: 30.0, doc:"Ceiling parameter."}, + expo: { type:coeff, value: 2.0, doc:"Exponent parameter."}, + thresh: { type:coeff, value: 54.0, doc:"Threshold parameter."}, + upr: { type:coeff, value: -0.7, doc:"Upper slope parameter."}, + lwr: { type:coeff, value: 2.0, doc:"Lower slope parameter."}, + mix: { type:coeff, value: 0.0, doc:"Basic/Bump Mix parameter."}, + + out: { type:spectrum, doc:"Spectrum output." }, + + } + + presets: { + + dry: { + + } + + kc: { + ceiling: 20.0, + expo: 2.0, + thresh: 65.0, + upr: 0.0, + lwr: 2.0, + mix: 0.0 + } + + a: { + ceiling: 20.0 + expo: 2.0 + thresh: 60.0 + upr: [ -1.1, -0.99], + lwr: 2.0 + mix: 0.0 + } + + b: { + ceiling: 20.0 + expo: 2.0 + thresh: [ 77.0, 74.0 ], + upr: -0.5 + lwr: [ 3.0, 2.0 ], + mix: 0.0 + } + + c: { + ceiling: 20.0 + expo: 2.0 + thresh: 80.0 + upr: -0.5 + lwr: 5.0 + mix: 0.0 + } + + d: { + ceiling: 20.0 + expo: 2.0 + thresh: 70.0 + upr: [ -3.9, 04.5] + lwr: 4.0 + mix: 0.0 + } + + f_1: { + ceiling: 20.0 + expo: 2.0 + thresh: 50.0 + upr: -3.0 + lwr: 1.0 + mix: 0.0 + } + + f_2: { + ceiling: 20.0 + expo: 2.0 + thresh: 60.0 + upr: -3.0 + lwr: 1.0 + mix: 0.0 + } + + f_3: { + ceiling: 20.0 + expo: 2.0 + thresh: 55.0 + upr: -3.0 + lwr: 1.0 + mix: 0.0 + } + + f_4: { + ceiling: 20.0 + expo: 2.0 + thresh: 55.0 + upr: -5.0 + lwr: 1.0 + mix: 0.0 + } + + g: { + ceiling: 40.0 + expo: 8.0 + thresh: [60.0 64.0] + upr: -0.7 + lwr: 8.0 + mix: 1.0 + } + + g_a: { + ceiling: 40.0 + expo: 2.0 + thresh: [50.0 54.0] + upr: -0.7 + lwr: 2.0 + mix: 1.0 + } + + g_1_a: { + ceiling: 20.0 + expo: 2.0 + thresh: [50.0 54.0] + upr: -0.7 + lwr: 8.0 + mix: 1.0 + } + + g_1_d: { + ceiling: [60.0 64.0] + expo: [ 7.0 5.0] + thresh: [40.0 34.0] + upr: [-0.4 -0.3] + lwr: [ 7.0 5.0] + mix: 1.0 + } + } + } + + + compressor: { + vars: { + in: { type:audio, flags:["src"] true, doc:"Audio input." }, + bypass: { type:bool, value: false, doc:"Bypass the compressor."}, + igain: { type:coeff, value: 1.0, doc:"Input gain."}, + thresh: { type:coeff, value: 90.0, doc:"Attack threshold in dB."}, + ratio: { type:coeff, value: 2.0, doc:"Compression ratio."}, + atk_ms: { type:coeff, value: 20.0, doc:"Attack time in milliseconds."}, + rls_ms: { type:coeff, value: 20.0, doc:"Release time in milliseconds."}, + wnd_ms: { type:coeff, value: 200.0, doc:"RMS calc. window length in milliseconds."}, + maxWnd_ms: { type:coeff, value: 1000.0, doc:"Maximim (allocated) window length in milliseconds."}, + ogain: { type:coeff, value: 1.0, doc:"Output gain."}, + out: { type:audio, doc:"Audio output." }, + } + + presets: { + dflt: { + igain: 3.0 + thresh: 60.0 + ratio: 5.0 + atk_ms: 5.0 + rls_ms: 20.0 + wnd_ms:100.0 + ogain: 1.0 + } + + kc: { + bypass: false + igain: 3.0 + thresh: 80.0 + ratio: 2.0 + atk_ms: 20.0 + rls_ms: 1000.0 + wnd_ms: 200.0 + ogain: 1.0 + } + + input: { + bypass: false + igain: 2.0 + thresh: 30.0 + ratio: 12.0 + atk_ms: 5.0 + rls_ms: 20.0 + wnd_ms: 20.0 + ogain: 0.5 + } + + dry: { + + } + + a: { + igain: 6.0 + ogain: 1.0 + } + + b: { + igain: 10.0 + ogain: 1.0 + } + + c: { + igain: 11.0 + ogain: 1.0 + } + + d: { + igain: 9.0 + ogain: 1.0 + } + + f_1: { + igain: 6.0 + ogain: 1.0 + } + + f_2: { + igain: 6.0 + ogain: 1.0 + } + + f_3: { + igain: 6.0 + ogain: 1.0 + } + + f_4: { + igain: 6.0 + ogain: 1.0 + } + + g: { + igain: 10.0 + ogain: 0.75 + } + + g_a: { + igain: 10.0 + ogain: 0.75 + } + + g_1_a: { + igain: 10.0 + ogain: 0.75 + } + + g_1_d: { + igain: 10.0 + ogain: 0.75 + } + + + } + } + + limiter: { + vars: { + in: { type:audio, flags:["src"] true, doc:"Audio input." }, + bypass: { type:bool, value: false, doc:"Bypass the limiter."}, + igain: { type:coeff, value: 1.0, doc:"Input gain."}, + thresh: { type:coeff, value: 0.0, doc:"Linear (0.0-1.0) threshold."}, + ogain: { type:coeff, value: 1.0, doc:"Output gain."}, + out: { type:audio, doc:"Audio output." }, + } + + presets: { + dflt: { + bypass: false, + igain: 1.0 + thresh: 0.9, + ogain: 1.0 + } + + } + } + + dc_filter: { + vars: { + in: { type:audio, flags:["src"], doc:"Audio input." }, + bypass: { type:bool, value: false, doc:"Bypass the DC filter."}, + gain: { type:coeff, value: 1.0, doc:"Output gain."}, + out: { type:audio, doc:"Audio output." }, + } + + presets: { + dflt: { + bypass: false, + gain: 1.0 + } + + } + } + + audio_meter: { + vars: { + in: { type:audio, flags:["src"], doc:"Audio input." }, + dbFl: { type:bool, value: true, doc:"Output in Decibels." }, + wndMs: { type:ftime, value: 100.0, doc:"RMS window length." }, + peakDb: { type:coeff, value: -10.0, doc:"Peak threshold." }, + out: { type:coeff, value: 0.0, doc:"Meter output." }, + peakFl: { type:bool, value: false, doc:"Peak output." } + clipFl: { type:bool, value: false, doc:"Clip indicator output."} + } + } + + subnet: { + vars: { + } + } + + poly: { + vars: { + count: { type:uint, doc:"Count of network duplicates." }, + order: { type:string, value:"net", doc:"Execution order 'net'=net first 'proc'=proc first" } + } + } + + sample_hold: { + vars: { + in: { type:audio, flags:["src"], doc:"Audio input source." }, + period_ms: { type:ftime, value:50, doc:"Sample period in milliseconds." }, + out: { type:sample, value:0.0, doc:"First value in the sample period." }, + mean: { type:sample, value:0.0, doc:"Mean value of samples in period." }, + } + } + + + number: { + vars: { + value: { type:numeric, value:0.0, doc:"Input and output value."}, + store: { type:numeric, value:0.0, doc:"Store but don't emit until the next exec."} + } + } + + timer: { + vars: { + srate: { type:srate, value:0, flags["src"], doc:"Sample rate to use as the time base. 0=Use default system sample rate." }, + period_ms: { type:ftime, value:100, doc:"Timer period in milliseconds." }, + out: { type:bool, value:false, doc:"Output pulse." }, + } + } + + counter: { + vars: { + trigger: { type:bool, flags["src"], doc:"Counter increments with each toggle of trigger." }, + reset: { type:bool, value:false, doc:"Reset the counter to the initial value." }, + init: { type:numeric, value:0.0, doc:"Counter initial value." }, + min: { type:numeric, value:0.0, doc:"Minimum output value." }, + max: { type:numeric, value:10.0, doc:"Maximum output value." }, + inc: { type:numeric, value:1.0, doc:"Incrment value." }, + repeat_fl: { type:bool, value:true, doc:"Repeat on reaching the limits." }, + mode: { type:string, value:"modulo", doc:"limit mode: 'modulo'=wrap, 'reverse'=count in opposite direction, 'clip'=repeat limit value."}, + out_type: { type:string, value:double, flags["init"], doc:"The type of the output value." }, + out: { type:runtime, value:0.0, doc:"Counter output value."}, + } + } + + // All elements of the list must belong to the same of three possible types: + // string,cfg,numeric (uint,int,float,double) + list: { + vars: { + in: { type:uint, flags:["src"], doc:"List selection index." }, + list: { type:cfg, doc:"List as a 'cfg' object." }, + out: { type:runtime, doc:"List output value." }, + value:{ type:runtime, flags["mult"], doc:"List 'mult' output per list value." }, + } + } + + add: { + vars: { + in: { type:numeric, flags:["src","mult"], doc:"Operands" }, + otype: { type:string, value:double, flags:["init"], doc:"The type of the output value." }, + out: { type:runtime, flags:["no_src"], doc:"Result" }, + } + } + + preset: { + vars: { + in: { type:string, flags:["src"], doc:"Preset to select." }, + } + } + + + xfade_ctl: { + + poly_limit_cnt: 1, + + // Notes: + // 1. It would be better to setup the source net-proc as a 'in' variable with type 'net'. + // 2. The only purpose for the 'srateSrc' is to get the sample rate of the system. + + vars: { + net: { type:string, doc:"Proc name of the poly network."}, + netSfxId: { type:uint, value: 0, doc:"Label sfx id of the source poly instance."}, + srateSrc: { type:audio, flags:["src"], doc:"Audio source to derive the sample rate."}, + durMs: { type:uint, value:1000, doc:"Cross-fade duration in milliseconds" }, + trigger: { type:all, doc:"Start cross-fade." }, + preset: { type:string, doc:"Preset to apply to the poly network." }, + + gain: { type:coeff, flags:["mult"], value:0, doc:"Cross-fade gain output." } + } + }, + + poly_merge: { + + vars: { + in: { type:audio, flags:["src", "mult"], doc:"Audio input channel." }, + gain: { type:coeff, value: 0, flags:["src", "mult"], doc:"Input channel gain." }, + out_gain: { type:coeff, value: 1, doc:"Output gain" }, + out: { type:audio, doc:"Audio output." }, + } + } + + +} diff --git a/src/cwtest/cfg/flow/flow_subnet_dict.cfg b/src/cwtest/cfg/flow/flow_subnet_dict.cfg new file mode 100644 index 0000000..9833db2 --- /dev/null +++ b/src/cwtest/cfg/flow/flow_subnet_dict.cfg @@ -0,0 +1,34 @@ +{ + mod_osc: { + + vars: { + hz: { proxy:hz_lfo.dc, doc:"Audio frequency" }, + hz_mod_hz: { proxy:hz_lfo.hz, doc:"Frequency modulator hz" }, + hz_mod_depth: { proxy:hz_lfo.gain, doc:"Frequency modulator depth" }, + amp_mod_hz: { proxy:amp_lfo.hz, doc:"Amplitude modulator hz" }, + amp_mod_depth: { proxy:amp_lfo.gain, doc:"Amplutide modulator depth."}, + mo_out: { proxy:ogain.out flags:[out] doc:"Oscillator output."}, + }, + + network: { + procs: { + hz_lfo: { class: sine_tone, args: { default:{ chCnt:1 }}} + hz_sh: { class: sample_hold, in:{ in:hz_lfo.out }} + + amp_lfo: { class: sine_tone, args: { default:{ chCnt:1 }}} + amp_sh: { class: sample_hold, in:{ in:amp_lfo.out }} + + osc: { class: sine_tone, in:{ hz: hz_sh.out }} + ogain: { class: audio_gain, in:{ in:osc.out, gain:amp_sh.out}} + } + + presets: { + net_a: { hz_lfo: { dc:220, gain:55 }, amp_lfo: { gain:0.8 } }, + net_b: { hz_lfo: { dc:110, gain:25 }, amp_lfo: { gain:0.7 } }, + } + } + } + + + +} \ No newline at end of file diff --git a/src/cwtest/cfg/flow/flow_test.cfg b/src/cwtest/cfg/flow/flow_test.cfg new file mode 100644 index 0000000..ea4acca --- /dev/null +++ b/src/cwtest/cfg/flow/flow_test.cfg @@ -0,0 +1,359 @@ +{ + test: { + flow_test: { + + proc_cfg_fname: "~/src/cwtest/src/cwtest/cfg/flow/flow_proc_dict.cfg", + subnet_cfg_fname:"~/src/cwtest/src/cwtest/cfg/flow/flow_subnet_dict.cfg", + project_dir:"~/src/cwtest/src/cwtest/cfg/flow/ttest", + test_ref_dir:"~/src/cwtest/src/cwtest/cfg/flow/test", + cmp_enable_fl: false, + + test_cases: { + + test_0: { + framesPerCycle:64, + maxCycleCount:3750, // 5 seconds + printNetworkFl: false, // print the network instance + printClassDictFl: false, // print the class description dictionary + + network: { + + procs: { + osc: { class: sine_tone }, + afout: { class: audio_file_out, in: { in:osc.out } args:{ default:{fname:"$/audio_flow_out.wav"} } + } + } + } + } + + test_1: { + framesPerCycle: 64, + maxCycleCount: 1500, + + network: { + + procs: { + lfo: { class: sine_tone, args:{ default:{hz:3, dc:440, gain:110 }}} + sh: { class: sample_hold, in:{ in:lfo.out } } + osc: { class: sine_tone, in:{ hz:sh.out } }, + afout: { class: audio_file_out, in: { in:osc.out } args:{ default:{fname:"/home/kevin/temp/audio_flow_out.wav"} }} + } + } + } + + test_2: { + framesPerCycle: 64, + maxCycleCount: 7500, + + network: { + + procs: { + srate: { class: number, log:{value:0} args:{ default:{ value:48000f } } }, + tmr: { class: timer, in: { srate:srate.value}, log:{out:0} args:{ default:{ period_ms:1000.0 } } }, + cnt: { class: counter, in: { trigger:tmr.out }, log:{out:0} args:{ default:{ min:0, max:3, inc:1, init:0, mode:clip, out_type:uint, repeat_fl:false } } }, + list: { class: list, in: { in:cnt.out }, log:{out:0} args:{ default:{ list:[a,b,c,d] }}} + } + } + } + + + test_3: { + framesPerCycle: 64, + maxCycleCount: 7500, + + network: { + + procs: { + srate: { class: number, log:{value:0} args:{ default:{ value:48000f } } }, + tmr: { class: timer, in: { srate:srate.value}, log:{out:0} args:{ default:{ period_ms:1000.0 } } }, + cnt: { class: counter, in: { trigger:tmr.out }, log:{out:0} args:{ default:{ min:0, max:3, inc:1, init:0, mode:clip, repeat_fl:false, out_type:uint } } }, + x0v: { class: number, log:{value:0} args:{ default:{ value:2 }}}, + x1v: { class: number, log:{value:0} args:{ default:{ value:3 }}}, + add: { class: add, in: { in0:x0v.value, in1:x1v.value, in2:cnt.out }, log:{out:0} args:{ default:{ otype:int }} } + } + } + } + + test_4: { + framesPerCycle: 64, + maxCycleCount: 15000, + + network: { + + procs: { + srate: { class: number, log:{value:0} args:{ default:{ value:48000.0} } }, + tmr: { class: timer, in: { srate:srate.value } log:{srate:0} args:{ default:{ period_ms:2000 } }}, + cnt: { class: counter, in: { trigger:tmr.out }, args:{ default:{ min:0, max:2, inc:1, init:0, mode:clip, out_type:uint }}} + list: { class: list, in: { in:cnt.out }, args:{ default:{ list:[ a,b,c ] }}}, + ps: { class: preset, in: { in:list.out } } + + lfo: { class: sine_tone, in:{ srate:srate.value }, log:{srate:0} args: { default:{hz:3, dc:440, gain:110 }}} + sh: { class: sample_hold, in:{ in:lfo.out } } + osc: { class: sine_tone, in:{ hz:sh.out, srate:srate.value }} + afout: { class: audio_file_out, in:{ in:osc.out } args:{ default:{fname:"$/audio_flow_out.wav"} }} + } + + presets: { + a: { lfo: { hz:1, dc:880 }, osc: { gain:0.95 } }, + b: { lfo: { hz:2, dc:220 }, osc: { gain:0.75 } }, + c: { lfo: a220 }, + } + } + } + + // Same as test_4 but using the system sample rate + test_5: { + framesPerCycle: 64, + maxCycleCount: 15000, + sample_rate: 48000, + + network: { + + procs: { + tmr: { class: timer, log:{srate:0}, args:{ default:{ period_ms:2000 } }}, + cnt: { class: counter, in: { trigger:tmr.out }, args:{ default:{ min:0, max:2, inc:1, init:0, mode:clip, out_type:uint }}} + list: { class: list, in: { in:cnt.out }, args:{ default:{ list:[ a,b,c ] }}}, + ps: { class: preset, in: { in:list.out } } + + lfo: { class: sine_tone, log:{srate:0} args: { default:{ chCnt:1, hz:3, dc:440, gain:110 }}} + sh: { class: sample_hold, in:{ in:lfo.out } } + osc: { class: sine_tone, in:{ hz:sh.out } log:{srate:0} } + afout: { class: audio_file_out, in: { in:osc.out } args:{ default:{fname:"$/audio_flow_out.wav"} }} + } + + presets: { + a: { lfo: { hz:1, dc:880 }, osc: { gain:0.95 } }, + b: { lfo: { hz:2, dc:220 }, osc: { gain:0.75 } }, + c: { lfo: a220 }, + } + } + } + + // Simple poly + test_6: { + framesPerCycle: 64, + maxCycleCount: 7500, + sample_rate: 48000, + printNetworkFl: false, // print the network instance + printClassDictFl: false, // print the class description dictionary + + network: { + + procs: { + + osc_poly: { + class: poly, + args: { default:{ count:3 }} + + + network: { + procs: { + lfo: { class: sine_tone, args: { default:{ chCnt:1, hz:3, dc:440, gain:110 }}} + sh: { class: sample_hold, in:{ in:lfo.out }} + osc: { class: sine_tone, in:{ hz: sh.out }} + } + + presets: { + a: { lfo: { hz:1, dc:880 }, osc: { gain:0.95 } }, + b: { lfo: { hz:2, dc:220 }, osc: { gain:0.75 } }, + c: { lfo: a220 }, + } + } + } + + poly_merge: { class: poly_merge, in:{ in_:osc_poly.osc_.out}, args:{ default:{ gain:1, out_gain:0.5 }}}, + afout: { class: audio_file_out, in: { in:poly_merge.out } args:{ default:{fname:"$/audio_flow_out.wav"} }} + } + + presets: { + } + } + } + + // Test using xfade_ctl to cross-fade and assign presets. + test_7: { + framesPerCycle: 64, + maxCycleCount: 7500, + sample_rate: 48000, + printNetworkFl: false, // print the network instance + printClassDictFl: false, // print the class description dictionary + + network: { + + procs: { + + tmr: { class: timer, args:{ default:{ period_ms:2000 } }}, + cnt: { class: counter, in: { trigger:tmr.out }, args:{ default:{ min:0, max:2, inc:1, init:0, mode:reverse, out_type:uint }}} + list: { class: list, in: { in:cnt.out }, args:{ default:{ list:[ a,b,c ] }}}, + + osc_poly: { + class: poly, + args: { default:{ count:3 }} + + + network: { + procs: { + lfo: { class: sine_tone, args: { default:{ chCnt:1, hz:3, dc:440, gain:110 }}} + sh: { class: sample_hold, in:{ in:lfo.out }} + osc: { class: sine_tone, in:{ hz: sh.out }} + } + + presets: { + a: { lfo: { hz:1, dc:880 }, osc: { gain:0.95 } }, + b: { lfo: { hz:2, dc:220 }, osc: { gain:0.75 } }, + c: { lfo: a220 }, + } + } + } + + + xfade_ctl: { class: xfade_ctl, in:{ srateSrc:osc_poly.osc.out, preset:list.out, trigger:list.out }, + log:{trigger:0}, + args:{ default:{ net:osc_poly, durMs:1000, preset:a }} }, + + poly_merge: { class: poly_merge, in:{ in_:osc_poly.osc_.out, gain_:xfade_ctl.gain_ }, + args:{ default:{ out_gain:0.5 }}}, + + afout: { class: audio_file_out, in:{ in:poly_merge.out } + args:{ default:{fname:"$/audio_flow_out.wav"} }} + + + } + + presets: { + } + } + } + + // Test using xfade_ctl to assign presets and connecting poly procs + // to non-poly procs using the poly index to select sources. + // See `in:{ lfo_.dc:dc_list.value_}` + test_8: { + framesPerCycle: 64, + maxCycleCount: 7500, + sample_rate: 48000, + printNetworkFl: false, // print the network instance + printClassDictFl: false, // print the class description dictionary + + network: { + + procs: { + + tmr: { class: timer, args:{ default:{ period_ms:2000 } }}, + cnt: { class: counter, in: { trigger:tmr.out }, args:{ default:{ min:0, max:2, inc:1, init:0, mode:reverse, out_type:uint }}} + list: { class: list, in: { in:cnt.out }, args:{ default:{ list:[ a,b,c ] }}}, + + dc_list: { class: list, args: { default:{ in:0, list:[ 110f,220f,440f ]}}} + + osc_poly: { + class: poly, + args: { default:{ count:3 }} + + + network: { + procs: { + lfo: { class: sine_tone, in:{ _.dc:_.dc_list.value_}, args: { default:{ chCnt:1, hz:3, gain:110 }}} + sh: { class: sample_hold, in:{ in:lfo.out }} + osc: { class: sine_tone, in:{ hz: sh.out }} + } + + presets: { + a: { lfo: { hz:1 }, osc: { gain:0.95 } }, + b: { lfo: { hz:2 }, osc: { gain:0.75 } }, + c: { lfo: a220 }, + } + } + } + + + xfade_ctl: { class: xfade_ctl, in:{ srateSrc:osc_poly.osc.out, preset:list.out, trigger:list.out }, + log:{trigger:0}, + args:{ default:{ net:osc_poly, durMs:1000, preset:a }} }, + + poly_merge: { class: poly_merge, in:{ in_:osc_poly.osc_.out, gain_:xfade_ctl.gain_ }, + args:{ default:{ out_gain:0.5 }}}, + + afout: { class: audio_file_out, in:{ in:poly_merge.out } + args:{ default:{fname:"$/audio_flow_out.wav"} }} + + + } + + presets: { + } + } + } + + // Test using a subnet. + test_9 : { + framesPerCycle: 64, + maxCycleCount: 7500, + sample_rate: 48000, + printNetworkFl: false, // print the network instance + printClassDictFl: false, // print the class description dictionary + + network: { + procs: { + sub_osc: { class: mod_osc args:{ default:{ hz:220, hz_mod_hz:3, hz_mod_depth:55, amp_mod_hz:2, amp_mod_depth:0.5 }}}, + afout: { class: audio_file_out, in:{ in:sub_osc.mo_out } + args:{ default:{fname:"$/audio_flow_out.wav"}}} + } + } + + presets: { + } + } + + // Testing using proc instances with explicit suffix ids. + // See: list0 and list1 + test_10: { + framesPerCycle: 64, + maxCycleCount: 15000, + + network: { + + procs: { + tmr: { class: timer, args:{ default:{ period_ms:1000.0 }}}, + cnt: { class: counter, in: { trigger:tmr.out }, log:{out:0}, args:{ default:{ min:0, max:1, inc:1, init:0, mode:clip, repeat_fl:false, out_type:uint }}}, + list0: { class: list, args:{ default:{ in:2 list:[1,2,3] }}}, + list1: { class: list, args:{ default:{ in:0, list:[10,20,30] }}}, + add: { class: add, in: { in0:list0.out, in1:list1.out, in2:cnt.out }, log:{out:0} args:{ default:{ otype:int }} } + } + } + }, + + + // Test with no exec cycles. + // This network only runs the initialization pass. + test_11: { + framesPerCycle: 64, + maxCycleCount: 0, + + network: { + procs: { + a: { class: number, log:{value:0}, args:{ default:{ value:1 }}}, + b: { class: number, log:{value:0}, args:{ default:{ value:2 }}}, + add: { class: add, in: { in0:a.value, in1:b.value }, log:{out:0}, args:{ default:{ otype:int }}} + } + } + }, + + // Test the 'out' statement to set feedback connections. + test_12: { + framesPerCycle: 64, + maxCycleCount: 10, + + network: { + procs: { + a: { class: number, log:{value:0}, args:{ default:{ value:1 }}}, + b: { class: number, log:{value:0}, args:{ default:{ value:2 }}}, + + add: { class: add, in: { in0:a.value, in1:b.value }, out: { out:b.store }, + log:{out:0}, args:{ default:{ otype:int }}} + } + } + }, + + } + } +}