wav_io/
header.rs

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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/// WAV file Header

/// Sample Rate - CD
pub const SAMPLE_RATE_CD: u32 = 44_100;
/// Sample Rate - DVD Audio
pub const SAMPLE_RATE_DVD_AUDIO: u32 = 48_000;
/// Sample Rate - AM Radio
pub const SAMPLE_RATE_AM_RADIO: u32 = 22_000;
/// Sample Rate - FM Radio
pub const SAMPLE_RATE_FM_AUDIO: u32 = 32_000;
/// Sample Rate - Tel
pub const SAMPLE_RATE_TEL: u32 = 8_000;

/// Sample Format
#[derive(Debug,Copy,Clone,PartialEq)]
pub enum SampleFormat {
    Int,
    Float,
    WaveFromatALaw,
    WaveFormatMuLaw,
    SubFormat,
}

/// List Chunk Item
#[derive(Debug,Clone,PartialEq)]
pub struct ListChunkItem {
    pub id: String,
    pub value: String,
}
/// List Chunk Data
#[derive(Debug,Clone,PartialEq)]
pub struct ListChunk {
    pub items: Vec<ListChunkItem>,
}
impl ListChunk {
    pub fn make_block(&self) -> Vec<u8> {
        let mut block = Vec::new();
        for it in self.items.iter() {
            // chunk tag
            let chunk_tag_bytes = it.id.as_bytes();
            let mut chunk_tag: [u8; 4] = [32u8; 4];
            for (i, c) in chunk_tag_bytes.iter().enumerate() {
                if i >= 4 { break; }
                chunk_tag[i] = *c;
            }
            block.append(&mut chunk_tag.to_vec());
            // chunk size
            let mut flag_a = false;
            let mut chunk_size: u32 = it.value.len() as u32 + 1;
            if chunk_size % 2 != 0 {
                chunk_size += 1;
                flag_a = true;
            }
            block.append(&mut chunk_size.to_le_bytes().to_vec());
            // chunk value
            let bytes = it.value.as_bytes();
            // println!("chunk_size={}::bytes={}", chunk_size, bytes.len());
            block.append(&mut bytes.to_vec());
            block.push(0); // null
            if flag_a { block.push(0); }
        }
        block
    }
}

/// Wav file header
#[derive(Debug,Clone,PartialEq)]
pub struct WavHeader {
    pub sample_format: SampleFormat, // pcm=1
    pub channels: u16, // mono=1, stereo=2
    pub sample_rate: u32, // 44100Hz etc
    pub bits_per_sample: u16,
    pub list_chunk: Option<ListChunk>,
}

impl WavHeader {
    /// create WavHeader
    pub fn new() -> Self {
        Self::new_mono()
    }
    pub fn new_mono_i16_cd() -> Self {
        Self {
            sample_format: SampleFormat::Int,
            channels: 1,
            sample_rate: SAMPLE_RATE_CD,
            bits_per_sample: 16,
            list_chunk: None,
        }
    }
    pub fn new_mono_i16_radio() -> Self {
        Self {
            sample_format: SampleFormat::Int,
            channels: 1,
            sample_rate: SAMPLE_RATE_AM_RADIO,
            bits_per_sample: 16,
            list_chunk: None,
        }
    }
    pub fn new_mono_f32_cd() -> Self {
        Self {
            sample_format: SampleFormat::Float,
            channels: 1,
            sample_rate: SAMPLE_RATE_CD,
            bits_per_sample: 32,
            list_chunk: None,
        }
    }
    pub fn new_mono() -> Self {
        Self {
            sample_format: SampleFormat::Float,
            channels: 1,
            sample_rate: 44100,
            bits_per_sample: 32,
            list_chunk: None,
        }
    }
    pub fn new_stereo() -> Self {
        Self {
            sample_format: SampleFormat::Float,
            channels: 2,
            sample_rate: SAMPLE_RATE_CD,
            bits_per_sample: 32,
            list_chunk: None,
        }
    }
    pub fn set_int_format(&mut self) {
        self.sample_format = SampleFormat::Int;
    }
    pub fn set_float_format(&mut self) {
        self.sample_format = SampleFormat::Float;
    }
}

/// Wav Data
#[derive(Debug,Clone,PartialEq)]
pub struct WavData {
    pub header: WavHeader,
    pub samples: Vec<f32>,
}

impl WavData {
    pub fn new(header: WavHeader, samples: Vec<f32>) -> Self {
        Self {header, samples}
    }
}