hound/
read.rs

1// Hound -- A wav encoding and decoding library in Rust
2// Copyright (C) 2015 Ruud van Asseldonk
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// A copy of the License has been included in the root of the repository.
7// Unless required by applicable law or agreed to in writing, software
8// distributed under the License is distributed on an "AS IS" BASIS,
9// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10// See the License for the specific language governing permissions and
11// limitations under the License.
12
13use std::cmp;
14use std::fs;
15use std::io;
16use std::marker;
17use std::path;
18use super::{Error, Result, Sample, SampleFormat, WavSpec, WavSpecEx};
19
20/// Extends the functionality of `io::Read` with additional methods.
21///
22/// The methods may be used on any type that implements `io::Read`.
23pub trait ReadExt: io::Read {
24    /// Reads as many bytes as `buf` is long.
25    ///
26    /// This may issue multiple `read` calls internally. An error is returned
27    /// if `read` read 0 bytes before the buffer is full.
28    //  TODO: There is an RFC proposing a method like this for the standard library.
29    fn read_into(&mut self, buf: &mut [u8]) -> io::Result<()>;
30
31    /// Reads 4 bytes and returns them in an array.
32    fn read_4_bytes(&mut self) -> io::Result<[u8; 4]>;
33
34    /// Skip over `n` bytes.
35    fn skip_bytes(&mut self, n: usize) -> io::Result<()>;
36
37    /// Reads a single byte and interprets it as an 8-bit signed integer.
38    fn read_i8(&mut self) -> io::Result<i8>;
39
40    /// Reads a single byte and interprets it as an 8-bit unsigned integer.
41    fn read_u8(&mut self) -> io::Result<u8>;
42
43    /// Reads two bytes and interprets them as a little-endian 16-bit signed integer.
44    fn read_le_i16(&mut self) -> io::Result<i16>;
45
46    /// Reads two bytes and interprets them as a little-endian 16-bit unsigned integer.
47    fn read_le_u16(&mut self) -> io::Result<u16>;
48
49    /// Reads three bytes and interprets them as a little-endian 24-bit signed integer.
50    ///
51    /// The sign bit will be extended into the most significant byte.
52    fn read_le_i24(&mut self) -> io::Result<i32>;
53
54    /// Reads four bytes and interprets them as a little-endian 24-bit signed integer.
55    ///
56    /// The sign bit will be extended into the most significant byte.
57    fn read_le_i24_4(&mut self) -> io::Result<i32>;
58
59    /// Reads three bytes and interprets them as a little-endian 24-bit unsigned integer.
60    ///
61    /// The most significant byte will be 0.
62    fn read_le_u24(&mut self) -> io::Result<u32>;
63
64    /// Reads four bytes and interprets them as a little-endian 32-bit signed integer.
65    fn read_le_i32(&mut self) -> io::Result<i32>;
66
67    /// Reads four bytes and interprets them as a little-endian 32-bit unsigned integer.
68    fn read_le_u32(&mut self) -> io::Result<u32>;
69
70    /// Reads four bytes and interprets them as a little-endian 32-bit IEEE float.
71    fn read_le_f32(&mut self) -> io::Result<f32>;
72}
73
74impl<R> ReadExt for R
75    where R: io::Read
76{
77    #[inline(always)]
78    fn read_into(&mut self, buf: &mut [u8]) -> io::Result<()> {
79        let mut n = 0;
80        while n < buf.len() {
81            let progress = try!(self.read(&mut buf[n..]));
82            if progress > 0 {
83                n += progress;
84            } else {
85                return Err(io::Error::new(io::ErrorKind::Other, "Failed to read enough bytes."));
86            }
87        }
88        Ok(())
89    }
90
91    #[inline(always)]
92    fn skip_bytes(&mut self, n: usize) -> io::Result<()> {
93        // Read from the input in chunks of 1024 bytes at a time, and discard
94        // the result. 1024 is a tradeoff between doing a lot of calls, and
95        // using too much stack space. This method is not in a hot path, so it
96        // can afford to do this.
97        let mut n_read = 0;
98        let mut buf = [0u8; 1024];
99        while n_read < n {
100            let end = cmp::min(n - n_read, 1024);
101            let progress = try!(self.read(&mut buf[0..end]));
102            if progress > 0 {
103                n_read += progress;
104            } else {
105                return Err(io::Error::new(io::ErrorKind::Other, "Failed to read enough bytes."));
106            }
107        }
108        Ok(())
109    }
110
111    #[inline(always)]
112    fn read_4_bytes(&mut self) -> io::Result<[u8; 4]> {
113        let mut buf = [0_u8; 4];
114        try!(self.read_into(&mut buf[..]));
115        Ok(buf)
116    }
117
118    #[inline(always)]
119    fn read_i8(&mut self) -> io::Result<i8> {
120        self.read_u8().map(|x| x as i8)
121    }
122
123    #[inline(always)]
124    fn read_u8(&mut self) -> io::Result<u8> {
125        let mut buf = [0u8; 1];
126        try!(self.read_into(&mut buf));
127        Ok(buf[0])
128    }
129
130    #[inline(always)]
131    fn read_le_i16(&mut self) -> io::Result<i16> {
132        self.read_le_u16().map(|x| x as i16)
133    }
134
135    #[inline(always)]
136    fn read_le_u16(&mut self) -> io::Result<u16> {
137        let mut buf = [0u8; 2];
138        try!(self.read_into(&mut buf));
139        Ok((buf[1] as u16) << 8 | (buf[0] as u16))
140    }
141
142    #[inline(always)]
143    fn read_le_i24(&mut self) -> io::Result<i32> {
144        self.read_le_u24().map(|x|
145            // Test the sign bit, if it is set, extend the sign bit into the
146            // most significant byte.
147            if x & (1 << 23) == 0 {
148                x as i32
149            } else {
150                (x | 0xff_00_00_00) as i32
151            }
152        )
153    }
154
155    #[inline(always)]
156    fn read_le_i24_4(&mut self) -> io::Result<i32> {
157        self.read_le_u32().map(|x|
158            // Test the sign bit, if it is set, extend the sign bit into the
159            // most significant byte. Otherwise, mask out the top byte.
160            if x & (1 << 23) == 0 {
161                (x & 0x00_ff_ff_ff) as i32
162            } else {
163                (x | 0xff_00_00_00) as i32
164            }
165        )
166    }
167
168    #[inline(always)]
169    fn read_le_u24(&mut self) -> io::Result<u32> {
170        let mut buf = [0u8; 3];
171        try!(self.read_into(&mut buf));
172        Ok((buf[2] as u32) << 16 | (buf[1] as u32) << 8 | (buf[0] as u32))
173    }
174
175    #[inline(always)]
176    fn read_le_i32(&mut self) -> io::Result<i32> {
177        self.read_le_u32().map(|x| x as i32)
178    }
179
180    #[inline(always)]
181    fn read_le_u32(&mut self) -> io::Result<u32> {
182        let mut buf = [0u8; 4];
183        try!(self.read_into(&mut buf));
184        Ok((buf[3] as u32) << 24 | (buf[2] as u32) << 16 |
185           (buf[1] as u32) << 8  | (buf[0] as u32) << 0)
186    }
187
188    #[inline(always)]
189    fn read_le_f32(&mut self) -> io::Result<f32> {
190        let mut buf = [0u8; 4];
191        try!(self.read_into(&mut buf));
192        Ok(f32::from_le_bytes(buf))
193    }
194}
195
196/// The different chunks that a WAVE file can contain.
197enum ChunkKind {
198    Fmt,
199    Fact,
200    Data,
201    Unknown,
202}
203
204/// Describes the structure of a chunk in the WAVE file.
205struct ChunkHeader {
206    pub kind: ChunkKind,
207    pub len: u32,
208}
209
210/// A reader that reads the WAVE format from the underlying reader.
211///
212/// A `WavReader` is a streaming reader. It reads data from the underlying
213/// reader on demand, and it reads no more than strictly necessary. No internal
214/// buffering is performed on the underlying reader, but this can easily be
215/// added by wrapping the reader in an `io::BufReader`. The `open` constructor
216/// takes care of this for you.
217pub struct WavReader<R> {
218    /// Specification of the file as found in the fmt chunk.
219    spec: WavSpec,
220
221    /// The number of bytes used to store a sample in the stream.
222    bytes_per_sample: u16,
223
224    /// The number of samples in the data chunk.
225    ///
226    /// The data chunk is limited to a 4 GiB length because its header has a
227    /// 32-bit length field. A sample takes at least one byte to store, so the
228    /// number of samples is always less than 2^32.
229    num_samples: u32,
230
231    /// The number of samples read so far.
232    samples_read: u32,
233
234    /// The reader from which the WAVE format is read.
235    reader: R,
236}
237
238/// An iterator that yields samples of type `S` read from a `WavReader`.
239///
240/// The type `S` must have at least as many bits as the bits per sample of the
241/// file, otherwise every iteration will return an error.
242pub struct WavSamples<'wr, R, S>
243    where R: 'wr
244{
245    reader: &'wr mut WavReader<R>,
246    phantom_sample: marker::PhantomData<S>,
247}
248
249/// An iterator that yields samples of type `S` read from a `WavReader`.
250///
251/// The type `S` must have at least as many bits as the bits per sample of the
252/// file, otherwise every iteration will return an error.
253pub struct WavIntoSamples<R, S> {
254    reader: WavReader<R>,
255    phantom_sample: marker::PhantomData<S>,
256}
257
258/// Reads the RIFF WAVE header, returns the supposed file size.
259///
260/// This function can be used to quickly check if the file could be a wav file
261/// by reading 12 bytes of the header. If an `Ok` is returned, the file is
262/// likely a wav file. If an `Err` is returned, it is definitely not a wav
263/// file.
264///
265/// The returned file size cannot be larger than 2<sup>32</sup> + 7 bytes.
266pub fn read_wave_header<R: io::Read>(reader: &mut R) -> Result<u64> {
267    // Every WAVE file starts with the four bytes 'RIFF' and a file length.
268    // TODO: the old approach of having a slice on the stack and reading
269    // into it is more cumbersome, but also avoids a heap allocation. Is
270    // the compiler smart enough to avoid the heap allocation anyway? I
271    // would not expect it to be.
272    if b"RIFF" != &try!(reader.read_4_bytes())[..] {
273        return Err(Error::FormatError("no RIFF tag found"));
274    }
275
276    let file_len = try!(reader.read_le_u32());
277
278    // Next four bytes indicate the file type, which should be WAVE.
279    if b"WAVE" != &try!(reader.read_4_bytes())[..] {
280        return Err(Error::FormatError("no WAVE tag found"));
281    }
282
283    // The stored file length does not include the "RIFF" magic and 4-byte
284    // length field, so the total size is 8 bytes more than what is stored.
285    Ok(file_len as u64 + 8)
286}
287
288/// Reads chunks until a data chunk is encountered.
289///
290/// Returns the information from the fmt chunk and the length of the data
291/// chunk in bytes. Afterwards, the reader will be positioned at the first
292/// content byte of the data chunk.
293pub fn read_until_data<R: io::Read>(mut reader: R) -> Result<(WavSpecEx, u32)> {
294    let mut spec_opt = None;
295
296    loop {
297        let header = try!(WavReader::read_chunk_header(&mut reader));
298        match header.kind {
299            ChunkKind::Fmt => {
300                let spec = try!(WavReader::read_fmt_chunk(&mut reader, header.len));
301                spec_opt = Some(spec);
302            }
303            ChunkKind::Fact => {
304                // All (compressed) non-PCM formats must have a fact chunk
305                // (Rev. 3 documentation). The chunk contains at least one
306                // value, the number of samples in the file.
307                //
308                // The number of samples field is redundant for sampled
309                // data, since the Data chunk indicates the length of the
310                // data. The number of samples can be determined from the
311                // length of the data and the container size as determined
312                // from the Format chunk.
313                // http://www-mmsp.ece.mcgill.ca/documents/audioformats/wave/wave.html
314                let _samples_per_channel = reader.read_le_u32();
315            }
316            ChunkKind::Data => {
317                // The "fmt" chunk must precede the "data" chunk. Any
318                // chunks that come after the data chunk will be ignored.
319                if let Some(spec) = spec_opt {
320                    return Ok((spec, header.len));
321                } else {
322                    return Err(Error::FormatError("missing fmt chunk"));
323                }
324            }
325            ChunkKind::Unknown => {
326                // Ignore the chunk; skip all of its bytes.
327                try!(reader.skip_bytes(header.len as usize));
328            }
329        }
330        // If no data chunk is ever encountered, the function will return
331        // via one of the try! macros that return an Err on end of file.
332    }
333}
334
335impl<R> WavReader<R>
336    where R: io::Read
337{
338    /// Attempts to read an 8-byte chunk header.
339    fn read_chunk_header(reader: &mut R) -> Result<ChunkHeader> {
340        let mut kind_str = [0; 4];
341        try!(reader.read_into(&mut kind_str));
342        let len = try!(reader.read_le_u32());
343
344        let kind = match &kind_str[..] {
345            b"fmt " => ChunkKind::Fmt,
346            b"fact" => ChunkKind::Fact,
347            b"data" => ChunkKind::Data,
348            _ => ChunkKind::Unknown,
349        };
350
351        Ok(ChunkHeader { kind: kind, len: len })
352    }
353
354    /// Reads the fmt chunk of the file, returns the information it provides.
355    fn read_fmt_chunk(reader: &mut R, chunk_len: u32) -> Result<WavSpecEx> {
356        // A minimum chunk length of at least 16 is assumed. Note: actually,
357        // the first 14 bytes contain enough information to fully specify the
358        // file. I have not encountered a file with a 14-byte fmt section
359        // though. If you ever encounter such file, please contact me.
360        if chunk_len < 16 {
361            return Err(Error::FormatError("invalid fmt chunk size"));
362        }
363
364        // Read the WAVEFORMAT struct, as defined at
365        // https://msdn.microsoft.com/en-us/library/ms713498.aspx.
366        // ```
367        // typedef struct {
368        //     WORD  wFormatTag;
369        //     WORD  nChannels;
370        //     DWORD nSamplesPerSec;
371        //     DWORD nAvgBytesPerSec;
372        //     WORD  nBlockAlign;
373        // } WAVEFORMAT;
374        // ```
375        // The WAVEFORMATEX struct has two more members, as defined at
376        // https://msdn.microsoft.com/en-us/library/ms713497.aspx
377        // ```
378        // typedef struct {
379        //     WORD  wFormatTag;
380        //     WORD  nChannels;
381        //     DWORD nSamplesPerSec;
382        //     DWORD nAvgBytesPerSec;
383        //     WORD  nBlockAlign;
384        //     WORD  wBitsPerSample;
385        //     WORD  cbSize;
386        // } WAVEFORMATEX;
387        // ```
388        // There is also PCMWAVEFORMAT as defined at
389        // https://msdn.microsoft.com/en-us/library/dd743663.aspx.
390        // ```
391        // typedef struct {
392        //   WAVEFORMAT wf;
393        //   WORD       wBitsPerSample;
394        // } PCMWAVEFORMAT;
395        // ```
396        // In either case, the minimal length of the fmt section is 16 bytes,
397        // meaning that it does include the `wBitsPerSample` field. (The name
398        // is misleading though, because it is the number of bits used to store
399        // a sample, not all of the bits need to be valid for all versions of
400        // the WAVE format.)
401        let format_tag = try!(reader.read_le_u16());
402        let n_channels = try!(reader.read_le_u16());
403        let n_samples_per_sec = try!(reader.read_le_u32());
404        let n_bytes_per_sec = try!(reader.read_le_u32());
405        let block_align = try!(reader.read_le_u16());
406        let bits_per_sample = try!(reader.read_le_u16());
407
408        if n_channels == 0 {
409            return Err(Error::FormatError("file contains zero channels"));
410        }
411
412        let bytes_per_sample = block_align / n_channels;
413        // We allow bits_per_sample to be less than bytes_per_sample so that
414        // we can support things such as 24 bit samples in 4 byte containers.
415        if Some(bits_per_sample) > bytes_per_sample.checked_mul(8) {
416            return Err(Error::FormatError("sample bits exceeds size of sample"));
417        }
418
419        // This field is redundant, and may be ignored. We do validate it to
420        // fail early for ill-formed files.
421        if Some(n_bytes_per_sec) != (block_align as u32).checked_mul(n_samples_per_sec) {
422            return Err(Error::FormatError("inconsistent fmt chunk"));
423        }
424
425        // The bits per sample for a WAVEFORMAT struct is the number of bits
426        // used to store a sample. Therefore, it must be a multiple of 8.
427        if bits_per_sample % 8 != 0 {
428            return Err(Error::FormatError("bits per sample is not a multiple of 8"));
429        }
430
431        if bits_per_sample == 0 {
432            return Err(Error::FormatError("bits per sample is 0"));
433        }
434
435        let mut spec = WavSpec {
436            channels: n_channels,
437            sample_rate: n_samples_per_sec,
438            bits_per_sample: bits_per_sample,
439            sample_format: SampleFormat::Int,
440        };
441
442        // The different format tag definitions can be found in mmreg.h that is
443        // part of the Windows SDK. The vast majority are esoteric vendor-
444        // specific formats. We handle only a few. The following values could
445        // be of interest:
446        const PCM: u16 = 0x0001;
447        const ADPCM: u16 = 0x0002;
448        const IEEE_FLOAT: u16 = 0x0003;
449        const EXTENSIBLE: u16 = 0xfffe;
450        // We may update our WavSpec based on more data we read from the header.
451        match format_tag {
452            PCM => try!(WavReader::read_wave_format_pcm(reader, chunk_len, &spec)),
453            ADPCM => return Err(Error::Unsupported),
454            IEEE_FLOAT => try!(WavReader::read_wave_format_ieee_float(reader, chunk_len, &mut spec)),
455            EXTENSIBLE => try!(WavReader::read_wave_format_extensible(reader, chunk_len, &mut spec)),
456            _ => return Err(Error::Unsupported),
457        };
458
459        Ok(WavSpecEx {
460            spec: spec,
461            bytes_per_sample: bytes_per_sample,
462        })
463    }
464
465    fn read_wave_format_pcm(mut reader: R, chunk_len: u32, spec: &WavSpec) -> Result<()> {
466        // When there is a PCMWAVEFORMAT struct, the chunk is 16 bytes long.
467        // The WAVEFORMATEX structs includes two extra bytes, `cbSize`.
468        let is_wave_format_ex = match chunk_len {
469            16 => false,
470            18 => true,
471            // Other sizes are unexpected, but such files do occur in the wild,
472            // and reading these files is still possible, so we allow this.
473            40 => true,
474            _ => return Err(Error::FormatError("unexpected fmt chunk size")),
475        };
476
477        if is_wave_format_ex {
478            // `cbSize` can be used for non-PCM formats to specify the size of
479            // additional data. However, for WAVE_FORMAT_PCM, the member should
480            // be ignored, see https://msdn.microsoft.com/en-us/library/ms713497.aspx.
481            // Nonzero values do in fact occur in practice.
482            let _cb_size = try!(reader.read_le_u16());
483
484            // For WAVE_FORMAT_PCM in WAVEFORMATEX, only 8 or 16 bits per
485            // sample are valid according to
486            // https://msdn.microsoft.com/en-us/library/ms713497.aspx.
487            // 24 bits per sample is explicitly not valid inside a WAVEFORMATEX
488            // structure, but such files do occur in the wild nonetheless, and
489            // there is no good reason why we couldn't read them.
490            match spec.bits_per_sample {
491                8 => {}
492                16 => {}
493                24 => {}
494                _ => return Err(Error::FormatError("bits per sample is not 8 or 16")),
495            }
496        }
497
498        // If the chunk len was longer than expected, ignore the additional bytes.
499        if chunk_len == 40 {
500            try!(reader.skip_bytes(22));
501        }
502        Ok(())
503    }
504
505    fn read_wave_format_ieee_float(mut reader: R, chunk_len: u32, spec: &mut WavSpec) -> Result<()> {
506        // When there is a PCMWAVEFORMAT struct, the chunk is 16 bytes long.
507        // The WAVEFORMATEX structs includes two extra bytes, `cbSize`.
508        let is_wave_format_ex = chunk_len == 18;
509
510        if !is_wave_format_ex && chunk_len != 16 {
511            return Err(Error::FormatError("unexpected fmt chunk size"));
512        }
513
514        if is_wave_format_ex {
515            // For WAVE_FORMAT_IEEE_FLOAT which we are reading, there should
516            // be no extra data, so `cbSize` should be 0.
517            let cb_size = try!(reader.read_le_u16());
518            if cb_size != 0 {
519                return Err(Error::FormatError("unexpected WAVEFORMATEX size"));
520            }
521        }
522
523        // For WAVE_FORMAT_IEEE_FLOAT, the bits_per_sample field should be
524        // set to `32` according to
525        // https://msdn.microsoft.com/en-us/library/windows/hardware/ff538799(v=vs.85).aspx.
526        //
527        // Note that some applications support 64 bits per sample. This is
528        // not yet supported by hound.
529        if spec.bits_per_sample != 32 {
530            return Err(Error::FormatError("bits per sample is not 32"));
531        }
532
533        spec.sample_format = SampleFormat::Float;
534        Ok(())
535    }
536
537    fn read_wave_format_extensible(mut reader: R, chunk_len: u32, spec: &mut WavSpec) -> Result<()> {
538        // 16 bytes were read already, there must be two more for the `cbSize`
539        // field, and `cbSize` itself must be at least 22, so the chunk length
540        // must be at least 40.
541        if chunk_len < 40 {
542            return Err(Error::FormatError("unexpected fmt chunk size"));
543        }
544
545        // `cbSize` is the last field of the WAVEFORMATEX struct.
546        let cb_size = try!(reader.read_le_u16());
547
548        // `cbSize` must be at least 22, but in this case we assume that it is
549        // 22, because we would not know how to handle extra data anyway.
550        if cb_size != 22 {
551            return Err(Error::FormatError("unexpected WAVEFORMATEXTENSIBLE size"));
552        }
553
554        // What follows is the rest of the `WAVEFORMATEXTENSIBLE` struct, as
555        // defined at https://msdn.microsoft.com/en-us/library/ms713496.aspx.
556        // ```
557        // typedef struct {
558        //   WAVEFORMATEX  Format;
559        //   union {
560        //     WORD  wValidBitsPerSample;
561        //     WORD  wSamplesPerBlock;
562        //     WORD  wReserved;
563        //   } Samples;
564        //   DWORD   dwChannelMask;
565        //   GUID    SubFormat;
566        // } WAVEFORMATEXTENSIBLE, *PWAVEFORMATEXTENSIBLE;
567        // ```
568        let valid_bits_per_sample = try!(reader.read_le_u16());
569        let _channel_mask = try!(reader.read_le_u32()); // Not used for now.
570        let mut subformat = [0u8; 16];
571        try!(reader.read_into(&mut subformat));
572
573        // Several GUIDS are defined. At the moment, only the following are supported:
574        //
575        // * KSDATAFORMAT_SUBTYPE_PCM (PCM audio with integer samples).
576        // * KSDATAFORMAT_SUBTYPE_IEEE_FLOAT (PCM audio with floating point samples).
577        let sample_format = match subformat {
578            super::KSDATAFORMAT_SUBTYPE_PCM => SampleFormat::Int,
579            super::KSDATAFORMAT_SUBTYPE_IEEE_FLOAT => SampleFormat::Float,
580            _ => return Err(Error::Unsupported),
581        };
582
583        // Fallback to bits_per_sample if the valid_bits_per_sample is obviously wrong to support non standard headers found in the wild.
584        if valid_bits_per_sample > 0 {
585            spec.bits_per_sample = valid_bits_per_sample;
586        }
587
588        spec.sample_format = sample_format;
589        Ok(())
590    }
591
592    /// Attempts to create a reader that reads the WAVE format.
593    ///
594    /// The header is read immediately. Reading the data will be done on
595    /// demand.
596    pub fn new(mut reader: R) -> Result<WavReader<R>> {
597        try!(read_wave_header(&mut reader));
598        let (spec_ex, data_len) = try!(read_until_data(&mut reader));
599
600        let num_samples = data_len / spec_ex.bytes_per_sample as u32;
601
602        // It could be that num_samples * bytes_per_sample < data_len.
603        // If data_len is not a multiple of bytes_per_sample, there is some
604        // trailing data. Either somebody is playing some steganography game,
605        // but more likely something is very wrong, and we should refuse to
606        // decode the file, as it is invalid.
607        if num_samples * spec_ex.bytes_per_sample as u32 != data_len {
608            let msg = "data chunk length is not a multiple of sample size";
609            return Err(Error::FormatError(msg));
610        }
611
612        // The number of samples must be a multiple of the number of channels,
613        // otherwise the last inter-channel sample would not have data for all
614        // channels.
615        if num_samples % spec_ex.spec.channels as u32 != 0 {
616            return Err(Error::FormatError("invalid data chunk length"));
617        }
618
619        let wav_reader = WavReader {
620            spec: spec_ex.spec,
621            bytes_per_sample: spec_ex.bytes_per_sample,
622            num_samples: num_samples,
623            samples_read: 0,
624            reader: reader,
625        };
626
627        Ok(wav_reader)
628    }
629
630    /// Returns information about the WAVE file.
631    pub fn spec(&self) -> WavSpec {
632        self.spec
633    }
634
635    /// Returns an iterator over all samples.
636    ///
637    /// The channel data is interleaved. The iterator is streaming. That is,
638    /// if you call this method once, read a few samples, and call this method
639    /// again, the second iterator will not start again from the beginning of
640    /// the file, it will continue where the first iterator stopped.
641    ///
642    /// The type `S` must have at least `spec().bits_per_sample` bits,
643    /// otherwise every iteration will return an error. All bit depths up to
644    /// 32 bits per sample can be decoded into an `i32`, but if you know
645    /// beforehand that you will be reading a file with 16 bits per sample, you
646    /// can save memory by decoding into an `i16`.
647    ///
648    /// The type of `S` (int or float) must match `spec().sample_format`,
649    /// otherwise every iteration will return an error.
650    pub fn samples<'wr, S: Sample>(&'wr mut self) -> WavSamples<'wr, R, S> {
651        WavSamples {
652            reader: self,
653            phantom_sample: marker::PhantomData,
654        }
655    }
656
657    /// Same as `samples`, but takes ownership of the `WavReader`.
658    ///
659    /// See `samples()` for more info.
660    pub fn into_samples<S: Sample>(self) -> WavIntoSamples<R, S> {
661        WavIntoSamples {
662            reader: self,
663            phantom_sample: marker::PhantomData,
664        }
665    }
666
667    /// Returns the duration of the file in samples.
668    ///
669    /// The duration is independent of the number of channels. It is expressed
670    /// in units of samples. The duration in seconds can be obtained by
671    /// dividing this number by the sample rate. The duration is independent of
672    /// how many samples have been read already.
673    pub fn duration(&self) -> u32 {
674        self.num_samples / self.spec.channels as u32
675    }
676
677    /// Returns the number of values that the sample iterator will yield.
678    ///
679    /// The length of the file is its duration (in samples) times the number of
680    /// channels. The length is independent of how many samples have been read
681    /// already. To get the number of samples left, use `len()` on the
682    /// `samples()` iterator.
683    pub fn len(&self) -> u32 {
684        self.num_samples
685    }
686
687    /// Destroys the `WavReader` and returns the underlying reader.
688    pub fn into_inner(self) -> R {
689        self.reader
690    }
691
692    /// Seek to the given time within the file.
693    ///
694    /// The given time is measured in number of samples (independent of the
695    /// number of channels) since the beginning of the audio data. To seek to
696    /// a particular time in seconds, multiply the number of seconds with
697    /// `WavSpec::sample_rate`. The given time should not exceed the duration of
698    /// the file (returned by `duration()`). The behavior when seeking beyond
699    /// `duration()` depends on the reader's `Seek` implementation.
700    ///
701    /// This method requires that the inner reader `R` implements `Seek`.
702    pub fn seek(&mut self, time: u32) -> io::Result<()>
703        where R: io::Seek,
704    {
705        let bytes_per_sample = self.spec.bits_per_sample / 8;
706        let sample_position = time * self.spec.channels as u32;
707        let offset_samples = sample_position as i64 - self.samples_read as i64;
708        let offset_bytes = offset_samples * bytes_per_sample as i64;
709        try!(self.reader.seek(io::SeekFrom::Current(offset_bytes)));
710        self.samples_read = sample_position;
711        Ok(())
712    }
713}
714
715impl WavReader<io::BufReader<fs::File>> {
716    /// Attempts to create a reader that reads from the specified file.
717    ///
718    /// This is a convenience constructor that opens a `File`, wraps it in a
719    /// `BufReader` and then constructs a `WavReader` from it.
720    pub fn open<P: AsRef<path::Path>>(filename: P) -> Result<WavReader<io::BufReader<fs::File>>> {
721        let file = try!(fs::File::open(filename));
722        let buf_reader = io::BufReader::new(file);
723        WavReader::new(buf_reader)
724    }
725}
726
727fn iter_next<R, S>(reader: &mut WavReader<R>) -> Option<Result<S>>
728    where R: io::Read,
729          S: Sample
730{
731    if reader.samples_read < reader.num_samples {
732        reader.samples_read += 1;
733        let sample = Sample::read(&mut reader.reader,
734                                  reader.spec.sample_format,
735                                  reader.bytes_per_sample,
736                                  reader.spec.bits_per_sample);
737        Some(sample.map_err(Error::from))
738    } else {
739        None
740    }
741}
742
743fn iter_size_hint<R>(reader: &WavReader<R>) -> (usize, Option<usize>) {
744    let samples_left = reader.num_samples - reader.samples_read;
745    (samples_left as usize, Some(samples_left as usize))
746}
747
748impl<'wr, R, S> Iterator for WavSamples<'wr, R, S>
749    where R: io::Read,
750          S: Sample
751{
752    type Item = Result<S>;
753
754    fn next(&mut self) -> Option<Result<S>> {
755        iter_next(&mut self.reader)
756    }
757
758    fn size_hint(&self) -> (usize, Option<usize>) {
759        iter_size_hint(&self.reader)
760    }
761}
762
763impl<'wr, R, S> ExactSizeIterator for WavSamples<'wr, R, S>
764    where R: io::Read,
765          S: Sample
766{
767}
768
769impl<R, S> Iterator for WavIntoSamples<R, S>
770    where R: io::Read,
771          S: Sample
772{
773    type Item = Result<S>;
774
775    fn next(&mut self) -> Option<Result<S>> {
776        iter_next(&mut self.reader)
777    }
778
779    fn size_hint(&self) -> (usize, Option<usize>) {
780        iter_size_hint(&self.reader)
781    }
782}
783
784impl<R, S> ExactSizeIterator for WavIntoSamples<R, S>
785    where R: io::Read,
786          S: Sample
787{
788}
789
790#[test]
791fn duration_and_len_agree() {
792    let files = &["testsamples/pcmwaveformat-16bit-44100Hz-mono.wav",
793                  "testsamples/waveformatex-16bit-44100Hz-stereo.wav",
794                  "testsamples/waveformatextensible-32bit-48kHz-stereo.wav"];
795
796    for fname in files {
797        let reader = WavReader::open(fname).unwrap();
798        assert_eq!(reader.spec().channels as u32 * reader.duration(),
799                   reader.len());
800    }
801}
802
803/// Tests reading a wave file with the PCMWAVEFORMAT struct.
804#[test]
805fn read_wav_pcm_wave_format_pcm() {
806    let mut wav_reader = WavReader::open("testsamples/pcmwaveformat-16bit-44100Hz-mono.wav")
807        .unwrap();
808
809    assert_eq!(wav_reader.spec().channels, 1);
810    assert_eq!(wav_reader.spec().sample_rate, 44100);
811    assert_eq!(wav_reader.spec().bits_per_sample, 16);
812    assert_eq!(wav_reader.spec().sample_format, SampleFormat::Int);
813
814    let samples: Vec<i16> = wav_reader.samples()
815        .map(|r| r.unwrap())
816        .collect();
817
818    // The test file has been prepared with these exact four samples.
819    assert_eq!(&samples[..], &[2, -3, 5, -7]);
820}
821
822#[test]
823fn read_wav_skips_unknown_chunks() {
824    // The test samples are the same as without the -extra suffix, but ffmpeg
825    // has kindly added some useless chunks in between the fmt and data chunk.
826    let files = ["testsamples/pcmwaveformat-16bit-44100Hz-mono-extra.wav",
827                 "testsamples/waveformatex-16bit-44100Hz-mono-extra.wav"];
828
829    for file in &files {
830        let mut wav_reader = WavReader::open(file).unwrap();
831
832        assert_eq!(wav_reader.spec().channels, 1);
833        assert_eq!(wav_reader.spec().sample_rate, 44100);
834        assert_eq!(wav_reader.spec().bits_per_sample, 16);
835        assert_eq!(wav_reader.spec().sample_format, SampleFormat::Int);
836
837        let sample = wav_reader.samples::<i16>().next().unwrap().unwrap();
838        assert_eq!(sample, 2);
839    }
840}
841
842#[test]
843fn read_wav_0_valid_bits_fallback() {
844    let mut wav_reader = WavReader::open("testsamples/nonstandard-02.wav")
845        .unwrap();
846
847    assert_eq!(wav_reader.spec().channels, 2);
848    assert_eq!(wav_reader.spec().sample_rate, 48000);
849    assert_eq!(wav_reader.spec().bits_per_sample, 32);
850    assert_eq!(wav_reader.spec().sample_format, SampleFormat::Int);
851
852    let samples: Vec<i32> = wav_reader.samples()
853        .map(|r| r.unwrap())
854        .collect();
855
856    // The test file has been prepared with these exact four samples.
857    assert_eq!(&samples[..], &[19, -229373, 33587161, -2147483497]);
858}
859
860#[test]
861fn len_and_size_hint_are_correct() {
862    let mut wav_reader = WavReader::open("testsamples/pcmwaveformat-16bit-44100Hz-mono.wav")
863        .unwrap();
864
865    assert_eq!(wav_reader.len(), 4);
866
867    {
868        let mut samples = wav_reader.samples::<i16>();
869
870        assert_eq!(samples.size_hint(), (4, Some(4)));
871        samples.next();
872        assert_eq!(samples.size_hint(), (3, Some(3)));
873    }
874
875    // Reading should not affect the initial length.
876    assert_eq!(wav_reader.len(), 4);
877
878    // Creating a new iterator resumes where the previous iterator stopped.
879    {
880        let mut samples = wav_reader.samples::<i16>();
881
882        assert_eq!(samples.size_hint(), (3, Some(3)));
883        samples.next();
884        assert_eq!(samples.size_hint(), (2, Some(2)));
885    }
886}
887
888#[test]
889fn size_hint_is_exact() {
890    let files = &["testsamples/pcmwaveformat-16bit-44100Hz-mono.wav",
891                  "testsamples/waveformatex-16bit-44100Hz-stereo.wav",
892                  "testsamples/waveformatextensible-32bit-48kHz-stereo.wav"];
893
894    for fname in files {
895        let mut reader = WavReader::open(fname).unwrap();
896        let len = reader.len();
897        let mut iter = reader.samples::<i32>();
898        for i in 0..len {
899            let remaining = (len - i) as usize;
900            assert_eq!(iter.size_hint(), (remaining, Some(remaining)));
901            assert!(iter.next().is_some());
902        }
903        assert!(iter.next().is_none());
904    }
905}
906
907#[test]
908fn samples_equals_into_samples() {
909    let wav_reader_val = WavReader::open("testsamples/pcmwaveformat-8bit-44100Hz-mono.wav").unwrap();
910    let mut wav_reader_ref = WavReader::open("testsamples/pcmwaveformat-8bit-44100Hz-mono.wav").unwrap();
911
912    let samples_val: Vec<i16> = wav_reader_val.into_samples()
913                                              .map(|r| r.unwrap())
914                                              .collect();
915
916    let samples_ref: Vec<i16> = wav_reader_ref.samples()
917                                              .map(|r| r.unwrap())
918                                              .collect();
919
920    assert_eq!(samples_val, samples_ref);
921}
922
923/// Tests reading a wave file with the WAVEFORMATEX struct.
924#[test]
925fn read_wav_wave_format_ex_pcm() {
926    let mut wav_reader = WavReader::open("testsamples/waveformatex-16bit-44100Hz-mono.wav")
927        .unwrap();
928
929    assert_eq!(wav_reader.spec().channels, 1);
930    assert_eq!(wav_reader.spec().sample_rate, 44100);
931    assert_eq!(wav_reader.spec().bits_per_sample, 16);
932    assert_eq!(wav_reader.spec().sample_format, SampleFormat::Int);
933
934    let samples: Vec<i16> = wav_reader.samples()
935                                      .map(|r| r.unwrap())
936                                      .collect();
937
938    // The test file has been prepared with these exact four samples.
939    assert_eq!(&samples[..], &[2, -3, 5, -7]);
940}
941
942#[test]
943fn read_wav_wave_format_ex_ieee_float() {
944    let mut wav_reader = WavReader::open("testsamples/waveformatex-ieeefloat-44100Hz-mono.wav")
945        .unwrap();
946
947    assert_eq!(wav_reader.spec().channels, 1);
948    assert_eq!(wav_reader.spec().sample_rate, 44100);
949    assert_eq!(wav_reader.spec().bits_per_sample, 32);
950    assert_eq!(wav_reader.spec().sample_format, SampleFormat::Float);
951
952    let samples: Vec<f32> = wav_reader.samples()
953                                      .map(|r| r.unwrap())
954                                      .collect();
955
956    // The test file has been prepared with these exact four samples.
957    assert_eq!(&samples[..], &[2.0, 3.0, -16411.0, 1019.0]);
958}
959
960#[test]
961fn read_wav_stereo() {
962    let mut wav_reader = WavReader::open("testsamples/waveformatex-16bit-44100Hz-stereo.wav")
963        .unwrap();
964
965    assert_eq!(wav_reader.spec().channels, 2);
966    assert_eq!(wav_reader.spec().sample_rate, 44100);
967    assert_eq!(wav_reader.spec().bits_per_sample, 16);
968    assert_eq!(wav_reader.spec().sample_format, SampleFormat::Int);
969
970    let samples: Vec<i16> = wav_reader.samples()
971                                      .map(|r| r.unwrap())
972                                      .collect();
973
974    // The test file has been prepared with these exact eight samples.
975    assert_eq!(&samples[..], &[2, -3, 5, -7, 11, -13, 17, -19]);
976
977}
978
979#[test]
980fn read_wav_pcm_wave_format_8bit() {
981    let mut wav_reader = WavReader::open("testsamples/pcmwaveformat-8bit-44100Hz-mono.wav")
982                                   .unwrap();
983
984    assert_eq!(wav_reader.spec().channels, 1);
985    assert_eq!(wav_reader.spec().bits_per_sample, 8);
986    assert_eq!(wav_reader.spec().sample_format, SampleFormat::Int);
987
988    let samples: Vec<i16> = wav_reader.samples()
989                                      .map(|r| r.unwrap())
990                                      .collect();
991
992    // The test file has been prepared with these exact four samples.
993    assert_eq!(&samples[..], &[19, -53, 89, -127]);
994}
995
996/// Test reading 24 bit samples in a 4 byte container using the pcmwaveformat header. This is
997/// technically a non-compliant wave file, but it is the sort of file generated by
998/// 'arecord -f S24_LE -r 48000 -c 2 input.wav' so it should be supported.
999#[test]
1000fn read_wav_pcm_wave_format_24bit_4byte() {
1001    let mut wav_reader = WavReader::open("testsamples/pcmwaveformat-24bit-4byte-48kHz-stereo.wav")
1002        .unwrap();
1003
1004    assert_eq!(wav_reader.spec().channels, 2);
1005    assert_eq!(wav_reader.spec().sample_rate, 48_000);
1006    assert_eq!(wav_reader.spec().bits_per_sample, 24);
1007    assert_eq!(wav_reader.spec().sample_format, SampleFormat::Int);
1008
1009    let samples: Vec<i32> = wav_reader.samples()
1010                                      .map(|r| r.unwrap())
1011                                      .collect();
1012
1013    // The test file has been prepared with these exact four samples.
1014    assert_eq!(&samples[..], &[-96, 23_052, 8_388_607, -8_360_672]);
1015}
1016
1017/// Regression test for a real-world wav file encountered in Quake.
1018#[test]
1019fn read_wav_wave_format_ex_8bit() {
1020    let mut wav_reader = WavReader::open("testsamples/waveformatex-8bit-11025Hz-mono.wav").unwrap();
1021
1022    assert_eq!(wav_reader.spec().channels, 1);
1023    assert_eq!(wav_reader.spec().bits_per_sample, 8);
1024    assert_eq!(wav_reader.spec().sample_format, SampleFormat::Int);
1025
1026    let samples: Vec<i32> = wav_reader.samples()
1027                                      .map(|r| r.unwrap())
1028                                      .collect();
1029
1030    // The audio data has been zeroed out, but for 8-bit files, a zero means a
1031    // sample value of 128.
1032    assert_eq!(&samples[..], &[-128, -128, -128, -128]);
1033}
1034
1035/// This test sample tests both reading the WAVEFORMATEXTENSIBLE header, and 24-bit samples.
1036#[test]
1037fn read_wav_wave_format_extensible_pcm_24bit() {
1038    let mut wav_reader = WavReader::open("testsamples/waveformatextensible-24bit-192kHz-mono.wav")
1039        .unwrap();
1040
1041    assert_eq!(wav_reader.spec().channels, 1);
1042    assert_eq!(wav_reader.spec().sample_rate, 192_000);
1043    assert_eq!(wav_reader.spec().bits_per_sample, 24);
1044    assert_eq!(wav_reader.spec().sample_format, SampleFormat::Int);
1045
1046    let samples: Vec<i32> = wav_reader.samples()
1047                                      .map(|r| r.unwrap())
1048                                      .collect();
1049
1050    // The test file has been prepared with these exact four samples.
1051    assert_eq!(&samples[..], &[-17, 4_194_319, -6_291_437, 8_355_817]);
1052}
1053
1054/// This test sample tests both reading the WAVEFORMATEXTENSIBLE header, and 24-bit samples with a
1055/// 4 byte container size.
1056#[test]
1057fn read_wav_wave_format_extensible_pcm_24bit_4byte() {
1058    let mut wav_reader = WavReader::open("testsamples/waveformatextensible-24bit-4byte-48kHz-stereo.wav")
1059        .unwrap();
1060
1061    assert_eq!(wav_reader.spec().channels, 2);
1062    assert_eq!(wav_reader.spec().sample_rate, 48_000);
1063    assert_eq!(wav_reader.spec().bits_per_sample, 24);
1064    assert_eq!(wav_reader.spec().sample_format, SampleFormat::Int);
1065
1066    let samples: Vec<i32> = wav_reader.samples()
1067                                      .map(|r| r.unwrap())
1068                                      .collect();
1069
1070    // The test file has been prepared with these exact four samples.
1071    assert_eq!(&samples[..], &[-96, 23_052, 8_388_607, -8_360_672]);
1072}
1073
1074#[test]
1075fn read_wav_32bit() {
1076    let mut wav_reader = WavReader::open("testsamples/waveformatextensible-32bit-48kHz-stereo.wav")
1077                                   .unwrap();
1078
1079    assert_eq!(wav_reader.spec().bits_per_sample, 32);
1080    assert_eq!(wav_reader.spec().sample_format, SampleFormat::Int);
1081
1082    let samples: Vec<i32> = wav_reader.samples()
1083                                      .map(|r| r.unwrap())
1084                                      .collect();
1085
1086    // The test file has been prepared with these exact four samples.
1087    assert_eq!(&samples[..], &[19, -229_373, 33_587_161, -2_147_483_497]);
1088}
1089
1090#[test]
1091fn read_wav_wave_format_extensible_ieee_float() {
1092    let mut wav_reader =
1093        WavReader::open("testsamples/waveformatextensible-ieeefloat-44100Hz-mono.wav").unwrap();
1094
1095    assert_eq!(wav_reader.spec().channels, 1);
1096    assert_eq!(wav_reader.spec().sample_rate, 44100);
1097    assert_eq!(wav_reader.spec().bits_per_sample, 32);
1098    assert_eq!(wav_reader.spec().sample_format, SampleFormat::Float);
1099
1100    let samples: Vec<f32> = wav_reader.samples()
1101                                      .map(|r| r.unwrap())
1102                                      .collect();
1103
1104    // The test file has been prepared with these exact four samples.
1105    assert_eq!(&samples[..], &[2.0, 3.0, -16411.0, 1019.0]);
1106}
1107
1108#[test]
1109fn read_wav_nonstandard_01() {
1110    // The test sample here is adapted from a file encountered in the wild (data
1111    // chunk replaced with two zero samples, some metadata dropped, and the file
1112    // length in the header fixed). It is not a valid file according to the
1113    // standard, but many players can deal with it nonetheless. (The file even
1114    // contains some metadata; open it in a hex editor if you would like to know
1115    // which program created it.) The file contains a regular PCM format tag,
1116    // but the size of the fmt chunk is one that would be expected of a
1117    // WAVEFORMATEXTENSIBLE chunk. The bits per sample is 24, which is invalid
1118    // for WAVEFORMATEX, but we can read it nonetheless.
1119    let mut wav_reader = WavReader::open("testsamples/nonstandard-01.wav").unwrap();
1120
1121    assert_eq!(wav_reader.spec().bits_per_sample, 24);
1122    assert_eq!(wav_reader.spec().sample_format, SampleFormat::Int);
1123
1124    let samples: Vec<i32> = wav_reader.samples()
1125                                      .map(|r| r.unwrap())
1126                                      .collect();
1127
1128    assert_eq!(&samples[..], &[0, 0]);
1129}
1130
1131#[test]
1132fn wide_read_should_signal_error() {
1133    let mut reader24 = WavReader::open("testsamples/waveformatextensible-24bit-192kHz-mono.wav")
1134        .unwrap();
1135
1136    // Even though we know the first value is 17, and it should fit in an `i8`,
1137    // a general 24-bit sample will not fit in an `i8`, so this should fail.
1138    // 16-bit is still not wide enough, but 32-bit should do the trick.
1139    assert!(reader24.samples::<i8>().next().unwrap().is_err());
1140    assert!(reader24.samples::<i16>().next().unwrap().is_err());
1141    assert!(reader24.samples::<i32>().next().unwrap().is_ok());
1142
1143    let mut reader32 = WavReader::open("testsamples/waveformatextensible-32bit-48kHz-stereo.wav")
1144        .unwrap();
1145
1146    // In general, 32-bit samples will not fit in anything but an `i32`.
1147    assert!(reader32.samples::<i8>().next().unwrap().is_err());
1148    assert!(reader32.samples::<i16>().next().unwrap().is_err());
1149    assert!(reader32.samples::<i32>().next().unwrap().is_ok());
1150}
1151
1152#[test]
1153fn sample_format_mismatch_should_signal_error() {
1154    let mut reader_f32 = WavReader::open("testsamples/waveformatex-ieeefloat-44100Hz-mono.wav")
1155        .unwrap();
1156
1157    assert!(reader_f32.samples::<i8>().next().unwrap().is_err());
1158    assert!(reader_f32.samples::<i16>().next().unwrap().is_err());
1159    assert!(reader_f32.samples::<i32>().next().unwrap().is_err());
1160    assert!(reader_f32.samples::<f32>().next().unwrap().is_ok());
1161
1162    let mut reader_i8 = WavReader::open("testsamples/pcmwaveformat-8bit-44100Hz-mono.wav").unwrap();
1163
1164    assert!(reader_i8.samples::<i8>().next().unwrap().is_ok());
1165    assert!(reader_i8.samples::<i16>().next().unwrap().is_ok());
1166    assert!(reader_i8.samples::<i32>().next().unwrap().is_ok());
1167    assert!(reader_i8.samples::<f32>().next().unwrap().is_err());
1168}
1169
1170#[test]
1171fn fuzz_crashes_should_be_fixed() {
1172    use std::fs;
1173    use std::ffi::OsStr;
1174
1175    // This is a regression test: all crashes and other issues found through
1176    // fuzzing should not cause a crash.
1177    let dir = fs::read_dir("testsamples/fuzz").ok()
1178                 .expect("failed to enumerate fuzz test corpus");
1179    for path in dir {
1180        let path = path.ok().expect("failed to obtain path info").path();
1181        let is_file = fs::metadata(&path).unwrap().file_type().is_file();
1182        if is_file && path.extension() == Some(OsStr::new("wav")) {
1183            println!("    testing {} ...", path.to_str()
1184                                               .expect("unsupported filename"));
1185            let mut reader = match WavReader::open(path) {
1186                Ok(r) => r,
1187                Err(..) => continue,
1188            };
1189            match reader.spec().sample_format {
1190                SampleFormat::Int => {
1191                    for sample in reader.samples::<i32>() {
1192                        match sample {
1193                            Ok(..) => { }
1194                            Err(..) => break,
1195                        }
1196                    }
1197                }
1198                SampleFormat::Float => {
1199                    for sample in reader.samples::<f32>() {
1200                        match sample {
1201                            Ok(..) => { }
1202                            Err(..) => break,
1203                        }
1204                    }
1205                }
1206            }
1207        }
1208    }
1209}
1210
1211#[test]
1212fn seek_is_consistent() {
1213    let files = &["testsamples/pcmwaveformat-16bit-44100Hz-mono.wav",
1214                  "testsamples/waveformatex-16bit-44100Hz-stereo.wav",
1215                  "testsamples/waveformatextensible-32bit-48kHz-stereo.wav"];
1216    for fname in files {
1217        let mut reader = WavReader::open(fname).unwrap();
1218
1219        // Seeking back to the start should "reset" the reader.
1220        let count = reader.samples::<i32>().count();
1221        reader.seek(0).unwrap();
1222        assert_eq!(reader.samples_read, 0);
1223        assert_eq!(count, reader.samples::<i32>().count());
1224
1225        // Seek to the last sample.
1226        let last_time = reader.duration() - 1;
1227        let channels = reader.spec.channels;
1228        reader.seek(last_time).unwrap();
1229        {
1230            let mut samples = reader.samples::<i32>();
1231            for _ in 0..channels {
1232                assert!(samples.next().is_some());
1233            }
1234            assert!(samples.next().is_none());
1235        }
1236
1237        // Seeking beyond the audio data produces no samples.
1238        let num_samples = reader.len();
1239        reader.seek(num_samples).unwrap();
1240        assert!(reader.samples::<i32>().next().is_none());
1241        reader.seek(::std::u32::MAX / channels as u32).unwrap();
1242        assert!(reader.samples::<i32>().next().is_none());
1243    }
1244}