1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#![deny(missing_docs)]
pub fn play(file: &str) {
use cpal::traits::{DeviceTrait, HostTrait, EventLoopTrait};
let image = image::open(file).unwrap().to_rgba();
let n = 16;
let mut hilbert: Vec<Vec<usize>> = vec![vec![0; n]; n];
let n2 = n as usize * n as usize;
for i in 0..n2 {
let (x, y) = hilbert_curve::convert_1d_to_2d(i, n2);
hilbert[y][x] = i;
}
let mut amplitudes: Vec<f64> = vec![0.0; n2];
let (w, h) = image.dimensions();
let cell = w.min(h) / n as u32;
for (x, y, pixel) in image.enumerate_pixels() {
let x = x / cell;
let y = y / cell;
if x >= n as u32 || y >= n as u32 {continue}
let image::Rgba([r, g, b, _]) = pixel;
let frequency = hilbert[y as usize][x as usize];
let amplitude = (*r as f64 + *g as f64 + *b as f64) / 255.0 / 3.0;
amplitudes[frequency] += amplitude / (cell as f64 * cell as f64);
}
let host = cpal::default_host();
let event_loop = host.event_loop();
let device = host.default_output_device().expect("no output device available");
let mut supported_formats_range = device.supported_output_formats()
.expect("error while querying formats");
let format = supported_formats_range.next()
.expect("no supported format?!")
.with_max_sample_rate();
let stream_id = event_loop.build_output_stream(&device, &format).unwrap();
event_loop.play_stream(stream_id).expect("failed to play_stream");
let tau: f64 = 6.283185307179586;
let mut t: f64 = 0.0;
let volume = 0.2;
std::thread::spawn(move || {
event_loop.run(move |stream_id, stream_result| {
use cpal::{StreamData, UnknownTypeOutputBuffer};
let stream_data = match stream_result {
Ok(data) => data,
Err(err) => {
eprintln!("an error occurred on stream {:?}: {}", stream_id, err);
return;
}
};
match stream_data {
StreamData::Output { buffer: UnknownTypeOutputBuffer::F32(mut buffer) } => {
for elem in buffer.iter_mut() {
let mut s: f64 = 0.0;
for (i, amp) in amplitudes.iter().enumerate() {
let fi = i as f64 / n2 as f64;
let f = 4.5 * fi + 0.25;
s += *amp * (t * f * tau + i as f64).sin();
}
*elem = volume * s as f32;
t += 0.005;
}
},
_ => (),
}
});
});
std::thread::sleep(std::time::Duration::from_secs_f64(2.0))
}