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 }
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}