{
  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_ref",
      
      test_cases: {

        test_0: {
          maxCycleCount:3750,       // 5 seconds

          network: {

            procs: {
	      osc:   { class: sine_tone },
	      afout: { class: audio_file_out, in: { in:osc.out } args:{  fname:"$/audio_flow_out.wav"} 
	      }
	    }
          }	 
        }

        test_1: {
          maxCycleCount:    1500,
	  printNetworkFl:   false,  // print the network instance
          network: {

            procs: {
	      lfo:   { class: sine_tone, args:{ 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:{  fname:"$/audio_flow_out.wav"} }
	    }

	    presets: {
	      a: { lfo:a220,                osc: { gain:0.8 } },
	      b: { lfo:{ dc:220, gain:25 }, osc: { gain:0.5 } }
	    }
          }	 
       }

        test_2: {
          maxCycleCount:    7500,	  

          network: {

            procs: {
	      srate: { class: number,                               log:{value:0} args:{ value:48000f } },
	      tmr:   { class: timer,      in: { srate:srate.value}, log:{out:0}   args:{ period_ms:1000.0 } },
	      cnt:   { class: counter,    in: { trigger:tmr.out },  log:{out:0}   args:{ 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:{ list:[a,b,c,d] }}
	    }
	  }
	}


        test_3: {
          maxCycleCount:    7500,

          network: {

            procs: {
	      srate: { class: number,                              log:{value:0} args:{ value:48000f } },
	      tmr: {  class: timer,    in: { srate:srate.value},   log:{out:0}   args:{ period_ms:1000.0 } },
	      cnt: {  class: counter,  in: { trigger:tmr.out },    log:{out:0}   args:{ min:0, max:3, inc:1, init:0, mode:clip, repeat_fl:false, out_type:uint } },
	      x0v: {  class: number,                               log:{value:0} args:{ value:2 }},
	      x1v: {  class: number,                               log:{value:0} args:{ value:3 }},	      
	      add:  { class: add,     in: { in0:x0v.value, in1:x1v.value, in2:cnt.out }, log:{out:0} args:{ otype:int }} 
	    }
	  }
	}

        test_4: {
          maxCycleCount:    15000,
	  printNetworkFl: false,
	  
          network: {

            procs: {
	      srate: { class: number,                                log:{value:0} args:{ value:48000.0} },
	      tmr:   { class: timer,      in: { srate:srate.value }  log:{srate:0} args:{ period_ms:2000 } },
	      cnt:   { class: counter,    in: { trigger:tmr.out },   args:{ min:0, max:2, inc:1, init:0, mode:clip, out_type:uint }}
	      list:  { class: list,       in: { in:cnt.out },        args:{ list:[ a,b,c ] }},
	      ps:    { class: preset,     in: { in:list.out } }
	      
	      lfo:   { class: sine_tone,      in:{ srate:srate.value }, log:{srate:0} args: { 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:{  fname:"$/audio_flow_out.wav"} }
	    }

            presets: {
	      a: { lfo: { hz:1.0, dc:880 }, osc: { gain:0.95 } },
	      b: { lfo: { hz:2.0, dc:220 }, osc: { gain:0.75 } },
	      c: { lfo: a220 }
	    }
          }	 
       }

        // Same as test_4 but using the system sample rate
        test_5: {   
          maxCycleCount:    15000,
	  sample_rate:      48000,

          network: {

            procs: {
	      tmr:   { class: timer,                                 log:{srate:0}, args:{ period_ms:2000 } },
	      cnt:   { class: counter,    in: { trigger:tmr.out },   args:{ min:0, max:2, inc:1, init:0, mode:clip, out_type:uint }}
	      list:  { class: list,       in: { in:cnt.out },        args:{ list:[ a,b,c ] }},
	      ps:    { class: preset,     in: { in:list.out } }
	      
	      lfo:   { class: sine_tone,                         log:{srate:0} args: { 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:{  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: {
          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: { count:3 }

		
		network: {
		  procs: {
	            lfo:   { class: sine_tone,   args: { chCnt:1, hz:3, dc:440, gain:110 }}
	            sh:    { class: sample_hold, in:{ in:lfo.out }}
	            osc:   { class: sine_tone,   in:{ hz: sh.out }}
		  }
		  
		  // Note the use of the trailing underscore to create matching presets
		  // on all poly channels.  Without the underscore the presets would only
		  // be applied to poly channel 0.
		  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:{ gain:1, out_gain:0.5 }},
	      afout:      { class: audio_file_out, in: { in:poly_merge.out }    args:{ fname:"$/audio_flow_out.wav"} }
            }
	    
	    presets: {
	    }
          }
       }

       // Test using xfade_ctl to cross-fade and assign presets.
       test_7: {
          maxCycleCount:    7500,
	  sample_rate:      48000,
          printNetworkFl:   false,  // print the network instance
          printClassDictFl: false,  // print the class description dictionary

          network: {

            procs: {

	      tmr:   { class: timer,                            args:{ period_ms:2000 } },
	      cnt:   { class: counter, in: { trigger:tmr.out }, args:{ min:0, max:2, inc:1, init:0, mode:reverse, out_type:uint }}
	      list:  { class: list,    in: { in:cnt.out },      args:{ list:[ a,b,c ] }},

	      osc_poly: {
	  	class: poly,
		args: { count:3 }

		
		network: {
		  procs: {
	            lfo:   { class: sine_tone,   args: { chCnt:1, hz:3, dc:440, gain:110 }}
	            sh:    { class: sample_hold, in:{ in:lfo.out }}
	            osc:   { class: sine_tone,   in:{ hz: sh.out }}
		  }

		  // Note the use of the trailing underscore to create matching presets
		  // on all poly channels.  Without the underscore the presets would only
		  // be applied to poly channel 0.
		  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:{ net:osc_poly,  durMs:1000, preset:a }} ,
			    
	      poly_merge: { class: poly_merge,     in:{ in_:osc_poly.osc_.out, gain_:xfade_ctl.gain_ },
	                    args:{ out_gain:0.5 }},
			    
	      afout:      { class: audio_file_out, in:{ in:poly_merge.out }
	                    args:{ 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: {
          maxCycleCount:    7500,
	  sample_rate:      48000,
          printNetworkFl:   false,  // print the network instance
          printClassDictFl: false,  // print the class description dictionary

          network: {

            procs: {

	      tmr:   { class: timer,                            args:{ period_ms:2000 } },
	      cnt:   { class: counter, in: { trigger:tmr.out }, args:{ min:0, max:2, inc:1, init:0, mode:reverse, out_type:uint }}
	      list:  { class: list,    in: { in:cnt.out },      args:{ list:[ a,b,c ] }},

	      dc_list: { class: list,  args: { in:0, list:[ 110f,220f,440f ]}}

	      osc_poly: {
	  	class: poly,
		args: { count:3 }

		
		network: {
		  procs: {
	            lfo:   { class: sine_tone,   in:{ _.dc:_.dc_list.value_}, args: { chCnt:1, hz:3,  gain:110 }}
	            sh:    { class: sample_hold, in:{ in:lfo.out }}
	            osc:   { class: sine_tone,   in:{ hz: sh.out }}
		  }
		  
		  // Note the use of the trailing underscore to create matching presets
		  // on all poly channels.  Without the underscore the presets would only
		  // be applied to poly channel 0.
		  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:{ net:osc_poly,  durMs:1000, preset:a }},
			    
	      poly_merge: { class: poly_merge,     in:{ in_:osc_poly.osc_.out, gain_:xfade_ctl.gain_ },
	                    args:{ out_gain:0.5 }},
			    
	      afout:      { class: audio_file_out, in:{ in:poly_merge.out }
	                    args:{ fname:"$/audio_flow_out.wav"} }
	      
	      
            }
	    
	    presets: {
	    }
          }
       }

       // Test using a subnet.
       test_9 : {
          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:{ 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:{ fname:"$/audio_flow_out.wav"}}	     
	    }
	  }
	  
	  presets: {
	  }
       }

        // Testing using proc instances with explicit suffix ids.
	// See: list0 and list1 
        test_10: {
          maxCycleCount:    15000,

          network: {

            procs: {
	      tmr:   { class: timer,                            args:{ period_ms:1000.0 }},
	      cnt:   { class: counter, in: { trigger:tmr.out }, log:{out:0}, args:{ min:0, max:1, inc:1, init:0, mode:clip, repeat_fl:false, out_type:uint }},
	      list0: { class: list,                             args:{ in:2  list:[1,2,3] }},
	      list1: { class: list,                             args:{ in:0, list:[10,20,30] }},
	      add:   { class: add,     in: { in0:list0.out, in1:list1.out, in2:cnt.out }, log:{out:0} args:{ otype:int }} 
	    }
	  }
	},


        // Test with no exec cycles.
	// This network only runs the initialization pass.
        test_11: {
          maxCycleCount:    0,

          network: {
            procs: {
	      a:   { class: number,                                 log:{value:0}, args:{ value:1 }},
	      b:   { class: number,                                 log:{value:0}, args:{ value:2 }},
	      add: { class: add,  in: { in0:a.value, in1:b.value }, log:{out:0},   args:{ otype:int }}
	    }
	  }
	},

        // Test the 'out' statement to set feedback connections.
        test_12: {
          maxCycleCount:    10,

          network: {
            procs: {
	      a:   { class: number,  log:{value:0}, args:{ value:1 }},
	      b:   { class: number,  log:{value:0}, args:{ value:2 }},
	      
	      add: { class: add,  in: { in0:a.value, in1:b.value }, out: { out:b.store }, 
	                          log:{out:0},   args:{ otype:int }}
	    }
	  }
	},


        // Same as test_4 but with a dual-preset. See preset 'd'.
        test_13: {
          maxCycleCount:    15000,
	  printNetworkFl: false,
	  
          network: {

            procs: {
	      srate: { class: number,                                log:{value:0} args:{ value:48000.0 }} ,
	      tmr:   { class: timer,      in: { srate:srate.value }  log:{srate:0} args:{ period_ms:2000 }},
	      cnt:   { class: counter,    in: { trigger:tmr.out },   args:{ min:0, max:3, inc:1, init:0, mode:clip, out_type:uint }}
	      list:  { class: list,       in: { in:cnt.out },        args:{ list:[ a,b,c,d ] }},
	      ps:    { class: preset,     in: { in:list.out } }
	      
	      lfo:   { class: sine_tone,      in:{ srate:srate.value }, log:{srate:0,hz:0,dc:0} args: { 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:{  fname:"$/audio_flow_out.wav"} }
	    }

            presets: {
	      a: { lfo: { hz:1.0, dc:880 }, osc: { gain:0.95 } },
	      b: { lfo: { hz:2.0, dc:220 }, osc: { gain:0.75 } },
	      c: { lfo: a220 },
	      d: [ a,b,0.5 ]
	    }
          }	 
       }

      test_14: {
        maxCycleCount: 3750,
	
	network {
	  procs: {
	      tmr:   { class: timer,                               args:{ period_ms:1000.0 }},
	      cnt:   { class: counter,  in: { trigger:tmr.out },   args:{ min:0, max:3, inc:1, init:0, mode:clip, out_type:uint }}
	      add:   { class: add,      in: { in0:cnt.out, in1:cnt.out }, }
	      
	      log:   { class: print,    in: { in0:cnt.out, in1:add.out, eol_fl:add.out }, args:{ text:["a","b","c"] }}
	  }
	}
      }
    }     
  }   
}
