1use std::io::prelude::*;
3use std::io::{BufReader, BufWriter};
4use std::fmt;
5use std::fmt::{Formatter, Display};
6use std::str;
7use std::str::FromStr;
8use std::error::Error;
9use std::fs;
10use std::fs::File;
11use byteorder::{ReadBytesExt, WriteBytesExt, LittleEndian};
12
13const TEXT_BIN_FILE_SIZE_MEAN_RATE: &'static usize = &13;
14const DSX_AMP: i16 = i16::max_value();
15const DFX_AMP: f32 = 10000.;
16const DDX_AMP: f64 = 10000.;
17
18pub enum DType {
20 DSA,
21 DFA,
22 DDA,
23 DSB,
24 DFB,
25 DDB,
26}
27
28impl Display for DType {
29 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
30 match *self {
31 DType::DSA => write!(f, "DSA"),
32 DType::DFA => write!(f, "DFA"),
33 DType::DDA => write!(f, "DDA"),
34 DType::DSB => write!(f, "DSB"),
35 DType::DFB => write!(f, "DFB"),
36 DType::DDB => write!(f, "DDB"),
37 }
38 }
39}
40
41impl FromStr for DType {
42 type Err = &'static str;
43
44 fn from_str(s: &str) -> Result<Self, Self::Err> {
45 match s {
46 "DSA" => Ok(DType::DSA),
47 "DFA" => Ok(DType::DFA),
48 "DDA" => Ok(DType::DDA),
49 "DSB" => Ok(DType::DSB),
50 "DFB" => Ok(DType::DFB),
51 "DDB" => Ok(DType::DDB),
52 _ => Err("invalid string")
53 }
54 }
55}
56
57impl DType {
58 pub fn from_filename(filename: &str) -> Result<DType, &'static str> {
60 let suffix = match filename.split(".").last() {
61 Some(s) => s,
62 None => return Err("invalid file name") };
64 DType::from_str(suffix)
65 }
66
67 pub fn byte_width(&self) -> u32 {
69 match *self {
70 DType::DSA | DType::DSB => 2,
71 DType::DFA | DType::DFB => 4,
72 DType::DDA | DType::DDB => 8,
73 }
74 }
75
76 pub fn bits_width(&self) -> u32 {
78 match *self {
79 DType::DSA | DType::DSB => 16,
80 DType::DFA | DType::DFB => 32,
81 DType::DDA | DType::DDB => 64,
82 }
83 }
84}
85
86pub fn len_file(filename: &str) -> Result<u64, Box<dyn Error>> {
88 let meta = fs::metadata(filename)?;
89 Ok(meta.len())
90}
91
92pub fn read_file(filename: &str) -> Result<Vec<f64>, Box<dyn Error>> {
96 let mut f = File::open(filename)?;
97 let file_size = f.metadata()?.len() as usize;
98 let dtype = DType::from_filename(filename)?;
99
100 match dtype {
101 DType::DSA |
102 DType::DFA |
103 DType::DDA => read_dxa(&mut f, file_size),
104
105 DType::DSB => read_dsb(&mut f, file_size),
106 DType::DFB => read_dfb(&mut f, file_size),
107 DType::DDB => read_ddb(&mut f, file_size),
108 }
109}
110
111
112fn read_dxa<T: Read>(src: &mut T, size: usize) -> Result<Vec<f64>, Box<dyn Error>> {
113 let mut ret: Vec<f64> = Vec::with_capacity(size / *TEXT_BIN_FILE_SIZE_MEAN_RATE);
114 for result in BufReader::new(src).lines() {
115 let line = result?;
116 let buf: f64 = line.parse::<f64>()?;
117 ret.push(buf);
118 }
119 Ok(ret)
120}
121
122fn read_dsb<T: Read>(src: &mut T, size: usize) -> Result<Vec<f64>, Box<dyn Error>> {
123 let byte_width = DType::DSB.byte_width();
124 let mut buf: Vec<i16> = vec![0; size / byte_width as usize];
125 let mut reader = BufReader::new(src);
126 reader.read_i16_into::<LittleEndian>(&mut buf)?;
127 Ok(buf.iter().map(|x| f64::from(*x)).collect())
128}
129
130fn read_dfb<T: Read>(src: &mut T, size: usize) -> Result<Vec<f64>, Box<dyn Error>> {
131 let byte_width = DType::DFB.byte_width();
132 let mut buf: Vec<f32> = vec![0.; size / byte_width as usize];
133 let mut reader = BufReader::new(src);
134 reader.read_f32_into::<LittleEndian>(&mut buf)?;
135 Ok(buf.iter().map(|x| f64::from(*x)).collect())
136}
137
138fn read_ddb<T: Read>(src: &mut T, size: usize) -> Result<Vec<f64>, Box<dyn Error>> {
139 let byte_width = DType::DDB.byte_width();
140 let mut buf: Vec<f64> = vec![0.; size / byte_width as usize];
141 let mut reader = BufReader::new(src);
142 reader.read_f64_into::<LittleEndian>(&mut buf)?;
143 Ok(buf.iter().map(|x| f64::from(*x)).collect())
144}
145
146pub fn write_file(filename: &str, src: Vec<f64>) -> Result<(), Box<dyn Error>> {
149 let mut f = File::create(filename)?;
150 let dtype = DType::from_filename(filename)?;
151
152 match dtype {
153 DType::DSA => write_dxa(&mut f, f64s_to_i16s(&src, DSX_AMP)),
154 DType::DFA => write_dxa(&mut f, f64s_to_f32s(&src, DFX_AMP)),
155 DType::DDA => write_dxa(&mut f, normalize_f64s(src, DDX_AMP)),
156
157 DType::DSB => write_dsb(&mut f, f64s_to_i16s(&src, DSX_AMP)),
158 DType::DFB => write_dfb(&mut f, f64s_to_f32s(&src, DFX_AMP)),
159 DType::DDB => write_ddb(&mut f, normalize_f64s(src, DDX_AMP)),
160 }
161}
162
163fn write_dxa<T: Write, U: std::fmt::Display>(dst: T, src: Vec<U>) -> Result<(), Box<dyn Error>> {
164 let mut writer = BufWriter::new(dst);
165 for x in src {
166 writeln!(writer, "{}", x)?;
167 }
168 Ok(())
169}
170
171fn write_dsb<T: Write>(dst: T, src: Vec<i16>) -> Result<(), Box<dyn Error>> {
172 let mut writer = BufWriter::new(dst);
173 for x in src {
174 writer.write_i16::<LittleEndian>(x)?;
175 }
176 Ok(())
177}
178
179fn write_dfb<T: Write>(dst: T, src: Vec<f32>) -> Result<(), Box<dyn Error>> {
180 let mut writer = BufWriter::new(dst);
181 for x in src {
182 writer.write_f32::<LittleEndian>(x)?;
183 }
184 Ok(())
185}
186
187fn write_ddb<T: Write>(dst: T, src: Vec<f64>) -> Result<(), Box<dyn Error>> {
188 let mut writer = BufWriter::new(dst);
189 for x in src {
190 writer.write_f64::<LittleEndian>(x)?;
191 }
192 Ok(())
193}
194
195fn normalize_f64s(src: Vec<f64>, amp: f64) -> Vec<f64> {
196 let abs_src: Vec<f64> = src.iter().map(|x| x.clone().abs()).collect();
197 let max = max_f64s(&abs_src);
198 src.iter().map(|x| (x / max * amp)).collect()
199}
200
201fn f64s_to_i16s(src: &Vec<f64>, amp: i16) -> Vec<i16> {
202 let abs_src: Vec<f64> = src.iter().map(|x| x.clone().abs()).collect();
203 let max = max_f64s(&abs_src);
204 src.iter().map(|x| (x / max * amp as f64) as i16).collect()
205}
206
207fn f64s_to_f32s(src: &Vec<f64>, amp: f32) -> Vec<f32> {
208 let abs_src: Vec<f64> = src.iter().map(|x| x.clone().abs()).collect();
209 let max = max_f64s(&abs_src);
210 src.iter().map(|x| (x / max * amp as f64) as f32).collect()
211}
212
213fn max_f64s(src: &Vec<f64>) -> f64 {
214 src.iter().fold(0.0 / 0.0, |m, v| v.max(m))
215}
216
217#[cfg(test)]
218mod tests {
219 use crate::*;
220
221 #[test]
222 fn test_f64s_to_i16s() {
223 let src: Vec<f64> = vec![5., -2., 4., -3.];
224 assert_eq!(f64s_to_i16s(&src, DSX_AMP), vec![32767, -13106, 26213, -19660]);
225 }
226
227 #[test]
228 fn test_write_file() {
229 let src: Vec<f64> = vec![5., -2., 4., -3.];
230 write_file("a.DSA", src).unwrap();
231 let src: Vec<f64> = vec![5., -2., 4., -3.];
232 write_file("a.DFA", src).unwrap();
233 let src: Vec<f64> = vec![5., -2., 4., -3.];
234 write_file("a.DDA", src).unwrap();
235 let src: Vec<f64> = vec![5., -2., 4., -3.];
236 write_file("a.DSB", src).unwrap();
237 let src: Vec<f64> = vec![5., -2., 4., -3.];
238 write_file("a.DFB", src).unwrap();
239 let src: Vec<f64> = vec![5., -2., 4., -3.];
240 write_file("a.DDB", src).unwrap();
241 }
242
243 #[test]
244 fn test_convert() {
245 let data = read_file("sine.DSB").unwrap();
246 write_file("sine.DSA", data).unwrap();
247 let data = read_file("sine.DSB").unwrap();
248 write_file("sine.DFA", data).unwrap();
249 let data = read_file("sine.DSB").unwrap();
250 write_file("sine.DFB", data).unwrap();
251 let data = read_file("sine.DSB").unwrap();
252 write_file("sine.DDA", data).unwrap();
253 let data = read_file("sine.DSB").unwrap();
254 write_file("sine.DDB", data).unwrap();
255 let data = read_file("sine.DSA").unwrap();
256 write_file("sine1.DSB", data).unwrap();
257 }
258}