use crate::*; from_edn!("sampler" => |jack: &Arc>, args| -> crate::Sampler { let mut name = String::new(); let mut dir = String::new(); let mut samples = BTreeMap::new(); edn!(edn in args { Edn::Map(map) => { if let Some(Edn::Str(n)) = map.get(&Edn::Key(":name")) { name = String::from(*n); } if let Some(Edn::Str(n)) = map.get(&Edn::Key(":dir")) { dir = String::from(*n); } }, Edn::List(args) => match args.first() { Some(Edn::Symbol("sample")) => { let (midi, sample) = MidiSample::from_edn((jack, &dir), &args[1..])?; if let Some(midi) = midi { samples.insert(midi, sample); } else { panic!("sample without midi binding: {}", sample.read().unwrap().name); } }, _ => panic!("unexpected in sampler {name}: {args:?}") }, _ => panic!("unexpected in sampler {name}: {edn:?}") }); Self::new(jack, &name) }); type MidiSample = (Option, Arc>); from_edn!("sample" => |(_jack, dir): (&Arc>, &str), args| -> MidiSample { let mut name = String::new(); let mut file = String::new(); let mut midi = None; let mut start = 0usize; edn!(edn in args { Edn::Map(map) => { if let Some(Edn::Str(n)) = map.get(&Edn::Key(":name")) { name = String::from(*n); } if let Some(Edn::Str(f)) = map.get(&Edn::Key(":file")) { file = String::from(*f); } if let Some(Edn::Int(i)) = map.get(&Edn::Key(":start")) { start = *i as usize; } if let Some(Edn::Int(m)) = map.get(&Edn::Key(":midi")) { midi = Some(u7::from(*m as u8)); } }, _ => panic!("unexpected in sample {name}"), }); let (end, data) = Sample::read_data(&format!("{dir}/{file}"))?; Ok((midi, Arc::new(RwLock::new(crate::Sample { name, start, end, channels: data, rate: None, gain: 1.0 })))) }); from_edn!("plugin/lv2" => |jack: &Arc>, args| -> Plugin { let mut name = String::new(); let mut path = String::new(); edn!(edn in args { Edn::Map(map) => { if let Some(Edn::Str(n)) = map.get(&Edn::Key(":name")) { name = String::from(*n); } if let Some(Edn::Str(p)) = map.get(&Edn::Key(":path")) { path = String::from(*p); } }, _ => panic!("unexpected in lv2 '{name}'"), }); Plugin::new_lv2(jack, &name, &path) }); const SYM_NAME: &str = ":name"; const SYM_GAIN: &str = ":gain"; const SYM_SAMPLER: &str = "sampler"; const SYM_LV2: &str = "lv2"; from_edn!("mixer/track" => |jack: &Arc>, args| -> MixerTrack { let mut _gain = 0.0f64; let mut track = MixerTrack { name: String::new(), audio_ins: vec![], audio_outs: vec![], devices: vec![], }; edn!(edn in args { Edn::Map(map) => { if let Some(Edn::Str(n)) = map.get(&Edn::Key(SYM_NAME)) { track.name = n.to_string(); } if let Some(Edn::Double(g)) = map.get(&Edn::Key(SYM_GAIN)) { _gain = f64::from(*g); } }, Edn::List(args) => match args.first() { // Add a sampler device to the track Some(Edn::Symbol(SYM_SAMPLER)) => { track.devices.push( Box::new(Sampler::from_edn(jack, &args[1..])?) as Box ); panic!( "unsupported in track {}: {:?}; tek_mixer not compiled with feature \"sampler\"", &track.name, args.first().unwrap() ) }, // Add a LV2 plugin to the track. Some(Edn::Symbol(SYM_LV2)) => { track.devices.push( Box::new(Plugin::from_edn(jack, &args[1..])?) as Box ); panic!( "unsupported in track {}: {:?}; tek_mixer not compiled with feature \"plugin\"", &track.name, args.first().unwrap() ) }, None => panic!("empty list track {}", &track.name), _ => panic!("unexpected in track {}: {:?}", &track.name, args.first().unwrap()) }, _ => {} }); Ok(track) }); //impl ArrangerScene { ////TODO ////pub fn from_edn <'a, 'e> (args: &[Edn<'e>]) -> Usually { ////let mut name = None; ////let mut clips = vec![]; ////edn!(edn in args { ////Edn::Map(map) => { ////let key = map.get(&Edn::Key(":name")); ////if let Some(Edn::Str(n)) = key { ////name = Some(*n); ////} else { ////panic!("unexpected key in scene '{name:?}': {key:?}") ////} ////}, ////Edn::Symbol("_") => { ////clips.push(None); ////}, ////Edn::Int(i) => { ////clips.push(Some(*i as usize)); ////}, ////_ => panic!("unexpected in scene '{name:?}': {edn:?}") ////}); ////Ok(ArrangerScene { ////name: Arc::new(name.unwrap_or("").to_string().into()), ////color: ItemColor::random(), ////clips, ////}) ////} //}