libwave/
chunks.rs

1use nom::Endianness;
2use nom::*;
3use sample::*;
4
5#[derive(Debug)]
6pub struct ChunkHeader<'a> {
7    id: &'a str,
8    size:u32,
9}
10#[derive(Debug)]
11pub struct MasterChunk<'a> {
12    pub header: ChunkHeader<'a>,
13    pub format: &'a str
14}
15#[derive(Debug)]
16pub struct FmtChunk<'a> {
17    pub header : ChunkHeader<'a>,
18    audio_format: u16,
19    num_channels: u16,
20    sample_rate : u32,
21    byte_rate: u32,
22    block_align: u16,
23    bits_per_sample: u16
24}
25
26#[derive(Debug)]
27pub struct DataChunk<'a> {
28    header: ChunkHeader<'a>,
29    channels: Channels //sample set of multi track
30}
31
32
33#[derive(Debug)]
34pub struct WAVE<'a> {
35    pub master: MasterChunk<'a>,
36    pub fmt : FmtChunk<'a>,
37    pub data : DataChunk<'a>
38}
39
40
41named!(chunk_header<&[u8],ChunkHeader>,
42    do_parse!(
43        id: take_str!(4) >>
44        size: u32!(Endianness::Little) >>
45        (ChunkHeader{id,size})
46    )
47);
48
49named!(master_chunk<&[u8],MasterChunk>,
50    do_parse!(
51       header : chunk_header >>
52       format : take_str!(4) >>
53       (MasterChunk{header,format})
54    )
55);
56
57named!(fmt_chunk<&[u8],FmtChunk>,
58    do_parse!(
59        header: chunk_header >>
60        audio_format: u16!(Endianness::Little) >>
61        num_channels: u16!(Endianness::Little) >>
62        sample_rate: u32!(Endianness::Little) >>
63        byte_rate: u32!(Endianness::Little) >>
64        block_align: u16!(Endianness::Little) >>
65        bits_per_sample: u16!(Endianness::Little) >>
66        take_str!(header.size - (2+2+4+4+2+2)) >>
67        (FmtChunk{header,audio_format,num_channels,sample_rate,byte_rate,block_align,bits_per_sample})
68    )
69);
70
71
72
73fn data_chunk<'a>(input:&'a[u8],fmt:&FmtChunk) -> IResult<&'a[u8],DataChunk<'a>> {
74    let h:ChunkHeader;
75    let c:Channels;
76    let mut next = input;
77
78    {
79        let ret = chunk_header(next);
80        if ret.is_err() {
81            return Err(ret.err().unwrap());
82        }else{
83            let (i,t) = ret.unwrap();
84            next = i;
85            h = t;
86        }
87    }
88
89    println!("{:?}",h);
90
91    {
92        let ret = channels(next,h.size as usize,fmt.num_channels as u32,fmt.bits_per_sample as u32);
93        if ret.is_err() {
94            return Err(ret.err().unwrap());
95        }else{
96            let (i,t) = ret.unwrap();
97            next = i;
98            c = t;
99        }
100    }
101    Ok((next,DataChunk{header:h,channels:c}))
102}
103
104named!(pub parse_wave<&[u8],WAVE>,
105    do_parse!(
106        master: master_chunk >>
107        fmt : fmt_chunk >>
108        data : call!(data_chunk,&fmt) >>
109        (WAVE{master:master,fmt:fmt,data:data})
110    )
111);
112
113#[test]
114fn test_header() {
115   let f = include_bytes!("../samples/a2002011001-e02.wav");
116
117    let ret = parse_wave(f);
118    let (i,mut instance) = ret.unwrap();
119
120    assert_eq!(instance.master.header.id,"RIFF");
121    assert_eq!(instance.master.format,"WAVE");
122    assert_eq!(instance.fmt.header.id,"fmt ");
123    assert_eq!(instance.fmt.header.size,18);
124    assert_eq!(instance.fmt.audio_format,1);
125    assert_eq!(instance.fmt.num_channels,2);
126    assert_eq!(instance.fmt.sample_rate,44100);
127    assert_eq!(instance.fmt.byte_rate,176400);
128    assert_eq!(instance.fmt.block_align,4);
129    assert_eq!(instance.fmt.bits_per_sample,16);
130}