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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
use autd::modulation::Modulation;
use autd::{consts::MOD_BUF_SIZE, Configuration};
use hound::SampleFormat;
use std::ffi::OsString;
use std::{error::Error, vec};
pub struct WavModulation {
raw_buf: Vec<u8>,
buffer: Vec<u8>,
sample_rate: u32,
sent: usize,
}
impl WavModulation {
pub fn create(
path: &OsString,
bits_per_sample: u16,
sample_format: SampleFormat,
) -> Result<Self, Box<dyn Error>> {
let mut reader = hound::WavReader::open(path)?;
let sample_rate = reader.spec().sample_rate;
let sample_iter: Vec<u8> = match (sample_format, bits_per_sample) {
(SampleFormat::Int, 8) => reader
.samples::<i32>()
.map(|i| i.unwrap() as i32)
.map(|i| (i - std::i8::MIN as i32) as u8)
.collect(),
(SampleFormat::Int, 16) => reader
.samples::<i32>()
.map(|i| (i.unwrap() as i32) / (i32::pow(2, 8)))
.map(|i| (i - std::i8::MIN as i32) as u8)
.collect(),
(SampleFormat::Int, 24) => reader
.samples::<i32>()
.map(|i| (i.unwrap() as i32) / (i32::pow(2, 16)))
.map(|i| (i - std::i8::MIN as i32) as u8)
.collect(),
(SampleFormat::Int, 32) => reader
.samples::<i32>()
.map(|i| i.unwrap() / i32::pow(2, 24))
.map(|i| (i - std::i8::MIN as i32) as u8)
.collect(),
(SampleFormat::Float, 32) => reader
.samples::<f32>()
.map(|i| i.unwrap())
.map(|i| ((i + 1.0) / 2.0 * 255.0) as u8)
.collect(),
_ => return Err(From::from("Not supported format.")),
};
let size = std::cmp::min(MOD_BUF_SIZE as usize, sample_iter.len());
let mut buffer = Vec::with_capacity(size);
buffer.extend_from_slice(&sample_iter[0..size]);
Ok(Self {
raw_buf: buffer,
buffer: vec![],
sample_rate,
sent: 0,
})
}
}
impl Modulation for WavModulation {
fn build(&mut self, config: Configuration) {
let mod_sf = config.sampling_frequency() as usize;
let mod_buf_size = config.buf_size() as usize;
let freq_ratio = mod_sf as f64 / self.sample_rate as f64;
let mut buffer_size = (self.raw_buf.len() as f64 * freq_ratio) as usize;
if buffer_size > mod_buf_size {
buffer_size = mod_buf_size;
}
let mut sample_buf = Vec::with_capacity(buffer_size);
for i in 0..self.raw_buf.len() {
let idx = (i as f64 / freq_ratio) as usize;
sample_buf.push(self.raw_buf[idx]);
}
self.buffer = sample_buf;
}
fn buffer(&self) -> &[u8] {
&self.buffer
}
fn sent(&mut self) -> &mut usize {
&mut self.sent
}
}