au_host_test/
au_host_test.rs1use mkaudiolibrary::host::{PluginFormat, load, scan_au};
7use mkaudiolibrary::processor::AudioIO;
8
9fn main() {
10 let found = scan_au();
11 println!("Found {} Audio Units", found.len());
12 for d in found.iter().take(5) {
13 println!(
14 " [{}] {} - {} ({})",
15 d.format, d.vendor, d.name, d.category
16 );
17 }
18
19 let effect = found
20 .iter()
21 .find(|d| d.category == "Effect")
22 .expect("no Effect-type Audio Unit found to test against");
23 println!("\nLoading: {} - {}", effect.vendor, effect.name);
24 assert_eq!(effect.format, PluginFormat::Au);
25
26 let mut plugin = load(effect).expect("failed to load AU");
27 println!(
28 "Loaded '{}' by '{}': {} in / {} out, {} parameters",
29 plugin.name(),
30 plugin.vendor(),
31 plugin.num_inputs(),
32 plugin.num_outputs(),
33 plugin.num_parameters()
34 );
35
36 plugin.prepare(48000, 512).expect("prepare failed");
37 plugin.set_active(true).expect("set_active failed");
38
39 let in_channels = plugin.num_inputs();
40 let out_channels = plugin.num_outputs().max(1);
41
42 let mut input_storage = vec![vec![0.0f32; 512]; in_channels];
45 let mut output_storage = vec![vec![0.0f32; 512]; out_channels];
46
47 for channel in &mut input_storage {
49 for (i, sample) in channel.iter_mut().enumerate() {
50 *sample = (i as f32 / 48000.0 * 440.0 * std::f32::consts::TAU).sin() * 0.25;
51 }
52 }
53
54 let input: Vec<&[f32]> = input_storage.iter().map(Vec::as_slice).collect();
55 let mut output: Vec<&mut [f32]> = output_storage.iter_mut().map(Vec::as_mut_slice).collect();
56 let mut audio = AudioIO::new(Some(&input), &mut output, None, None);
57
58 plugin.process(&mut audio);
59
60 let mut peak = 0.0f32;
61 let mut nonzero = false;
62 for channel in &output_storage {
63 for &s in channel.iter() {
64 if s != 0.0 {
65 nonzero = true;
66 }
67 peak = peak.max(s.abs());
68 }
69 }
70
71 println!("Output peak: {:.6}, nonzero: {}", peak, nonzero);
72 println!(
73 "OK: AU host rendered a real block of audio through '{}'.",
74 plugin.name()
75 );
76
77 println!("\nSearching for an Effect with exposed parameters...");
80 for candidate in found.iter().filter(|d| d.category == "Effect").take(40) {
81 let Ok(mut p) = load(candidate) else {
82 continue;
83 };
84 if p.prepare(48000, 512).is_err() {
85 continue;
86 }
87 if p.num_parameters() == 0 {
88 continue;
89 }
90
91 println!(
92 " {} - {}: {} parameters",
93 candidate.vendor,
94 candidate.name,
95 p.num_parameters()
96 );
97 for i in 0..p.num_parameters().min(3) {
98 let before = p.get_parameter(i);
99 p.set_parameter(i, 0.75);
100 let after = p.get_parameter(i);
101 println!(
102 " [{}] '{}': {:.4} -> set 0.75 -> {:.4}",
103 i,
104 p.parameter_name(i),
105 before,
106 after
107 );
108 }
109 break;
110 }
111}