{
   module_args: {	    
      proc_cfg_fname: "~/src/cwtest/src/libcw/flow/proc_dict.cfg",
      subnet_cfg_fname:"~/src/cwtest/src/libcw/flow/subnet_dict.cfg",
      },
      
   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:{out:0} args:{ in:48000.0f } },
	      tmr:   { class: timer,      in: { srate:srate.out},   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:{out:0} args:{ in:48000f } },
	      tmr: {  class: timer,    in: { srate:srate.out},     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:{out:0} args:{ in:2 }},
	      x1v: {  class: number,                               log:{out:0} args:{ in:3 }},	      
	      add:  { class: add,     in: { in0:x0v.out, in1:x1v.out, in2:cnt.out }, log:{out:0} args:{ otype:int }} 
	    }
	  }
	}

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

            procs: {
	      srate: { class: number,                              log:{in:0} args:{ in:48000.0f} },
	      tmr:   { class: timer,      in: { srate:srate.out }  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.out }, 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.out }}	      
	      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: audio_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: audio_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: audio_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"}}	     
	    }
	  }
       }

        // 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:2, 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:{out:0}, args:{ in:1 }},
	      b:   { class: number,                             log:{out:0}, args:{ in:2 }},
	      add: { class: add,  in: { in0:a.out, in1:b.out }, log:{out:0},   args:{ otype:int }}
	    }
	  }
	},

	/*
	
	This test is broken because the only time that 'add' outputs a value
	is when one of it's inputs changes value, and in this case that is
	that only occurs when 'add' is being constructed - prior to the
	feedback connection being created.
	
        // Test the 'out' statement to set feedback connections.
        test_12: {
          maxCycleCount:    10,

          network: {
            procs: {
	      a:   { class: number,  log:{out:0}, args:{ in:1 }},
	      b:   { class: number,  log:{out:0}, args:{ in0:0, in1:2 }},
	      
	      add: { class: add,  in: { in0:a.out, in1:b.out }, out: { out:b.in0 }, 
	                          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:{out:0} args:{ in:48000.0f }} ,
	      tmr:   { class: timer,      in: { srate:srate.out }    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.out }, 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.out }}	      
	      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"] }}
	  }
	}
      }

      //------------------ caw example test cases

      // Demonstrate a simple two processor network.
      demo_01_sine_file: {

        durLimitSecs:5.0,

        network: {

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


      // Demonstrate simple signal processing and how to apply a processor class prefix.
      demo_02_mod_sine: {

        durLimitSecs:5.0,

        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, preset:mono, in:{ hz:sh.out } },         
            af:    { class: audio_file_out,         in: { in:osc.out } args:{  fname:"$/out.wav"} }
          }
        }
      }

      // Demonstrate applying a preset at initialization time.
      demo_03_presets: {

        durLimitSecs:5.0,
        preset: "a",

        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 } },         
            af:    { class: audio_file_out, in: { in:osc.out } args:{  fname:"$/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: a880 },
            d: [ a,b,0.5 ]

          }
        }
      }

      // Demonstrate the `print` processor and event programming.
      demo_04_program: {

          durLimitSecs: 10.0,

          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:modulo } },
                print: { class: print,    in: { in:cnt.out, eol_fl:cnt.out }, args:{ text:["my","count"] }}
            }
          }
        }

      // Demonstrate 'mult' inputs.
      demo_05_mult_inputs: {

          durLimitSecs: 10.0,

          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:modulo } },
                numb:  { class: number,                              args:{ in:3 }},
                sum:   { class: add,      in: { in0:cnt.out, in1:numb.out } },
                print: { class: print,    in: { in0:cnt.out, in1:sum.out, eol_fl:sum.out }, args:{ text:["cnt","add","count"] }}
            }
          }
      }

      // Demonstrate different forms of the in-stmt
      demo_06_mult_conn: {
        durLimitSecs: 5.0,

        network: {
          procs: {
           osc:    { class: sine_tone, args: { chCnt:6, hz:[110,220,440,880,1760, 3520] }},
           split:  { class: audio_split, in:{ in:osc.out }, args: { select:[ 0,0, 1,1, 2,2 ] } },

           // Create merge.in0,in1,in2 by iterating across all outputs of 'split'.
           merge_a: { class: audio_merge, in:{ in_:split.out_ } },
           af_a:    { class: audio_file_out, in:{ in:merge_a.out },  args:{ fname:"$/out_a.wav" }}

          // Create merge.in0,in1 and connect them to split.out0 and split.out1
          merge_b:  { class: audio_merge, in:{ in_:split.out0_2 } },
          af_b:     { class: audio_file_out, in:{ in:merge_b.out },  args:{ fname:"$/out_b.wav" }}

          // Create merge.in0,in1 and connect them both to split.out1
          merge_c:  { class: audio_merge, in:{ in0_2:split.out1 } },
          af_c:     { class: audio_file_out, in:{ in:merge_c.out },  args:{ fname:"$/out_c.wav" }}

          }
        } 
      }

      // Demonstrate creating processors with explicit sfx-ids and connecting to them with a single in-stmt.
      demo_07_proc_suffix: {
        durLimitSecs: 5.0,

        network: {
          procs: {
            osc:    { class: sine_tone, args: { chCnt:6, hz:[110,220,440,880,1760, 3520] }},
            split:  { class: audio_split, in:{ in:osc.out }, args: { select:[ 0,0, 1,1, 2,2 ] } },

	    // Create 3 audio gain controls with explicit sfx-ids
            g0: { class:audio_gain, in:{ in:split0.out0 }, args:{ gain:0.9} },
            g1: { class:audio_gain, in:{ in:split0.out1 }, args:{ gain:0.5} },
            g2: { class:audio_gain, in:{ in:split0.out2 }, args:{ gain:0.1} },

	    // Create audio-merge inputs and connect them to 3 consecutive gain controls
	    // by iterating the in-stmt over the source proc sfx-id.
            merge: { class: audio_merge, in:{ in_:g_.out } },
            af:    { class: audio_file_out, in:{ in:merge.out },  args:{ fname:"$/out_a.wav" }}


         }
       } 
     }

      // Demonstrate instantiating 'mult' variables from the an 'args' statement.
      demo_08_mix: {

        durLimitSecs:5.0,
      
        network: {

          procs: {
            osc_a:  { class: sine_tone, args: { hz:110 } },
	    osc_b:  { class: sine_tone, args: { hz:220 } },

	    // Instantiate gain:0 and gain:1 to control the input gain of in:0 and in:1.
	    mix:   { class: audio_mix, in: { in0:osc_a.out, in1:osc_b.out }, args:{ igain0:[0.8, 0], igain1:[0, 0.2] } },
            af:    { class: audio_file_out, in: { in:mix.out } args:{  fname:"$/out.wav"} }
          } 
        }          
      }

      // Demonstrate a network with a polyphonic subnet.
      demo_09_simple_poly: {
   
        durLimitSecs: 5.0,

        network: {

          procs: {

            g_list:  { class: list, args: { in:0, list:[ 110f,220f,440f ]}},
	    dc_list: { class: list, args: { in:0, list:[ 220f,440f,880f ]}},
	  
            osc_poly: {
	       class: poly,
	       args: { count:3 },  // Create 3 instances of 'network'.
	   
	       network: {
	         procs: {
	           lfo:  { class: sine_tone,   in:{ _.dc:_.dc_list.value_, _.gain:_.g_list.value_ }  args: { chCnt:1, hz:3 }},
	           sh:   { class: sample_hold, in:{ in:lfo.out }},
	           osc:  { class: sine_tone,   in:{ hz: sh.out }},
	         }
	       }       	    
	     }

             // Iterate over the instances of `osc_poly.osc_.out` to create one `audio_merge`
	     // input for every output from the polyphonic network.
	     merge: { class: audio_merge,    in:{ in_:osc_poly.osc_.out}, args:{ gain:1, out_gain:0.5 }},
	     af:    { class: audio_file_out, in:{ in:merge.out }          args:{ fname:"$/out.wav"} }
          }
        }
      }



  }
}
