1use std::cmp;
14use std::fs;
15use std::io;
16use std::marker;
17use std::path;
18use super::{Error, Result, Sample, SampleFormat, WavSpec};
19
20pub trait ReadExt: io::Read {
24 fn read_into(&mut self, buf: &mut [u8]) -> io::Result<()>;
30
31 fn read_bytes(&mut self, n: usize) -> io::Result<Vec<u8>>;
33
34 fn skip_bytes(&mut self, n: usize) -> io::Result<()>;
36
37 fn read_i8(&mut self) -> io::Result<i8>;
39
40 fn read_u8(&mut self) -> io::Result<u8>;
42
43 fn read_le_i16(&mut self) -> io::Result<i16>;
45
46 fn read_le_u16(&mut self) -> io::Result<u16>;
48
49 fn read_le_i24(&mut self) -> io::Result<i32>;
53
54 fn read_le_u24(&mut self) -> io::Result<u32>;
58
59 fn read_le_i32(&mut self) -> io::Result<i32>;
61
62 fn read_le_u32(&mut self) -> io::Result<u32>;
64
65 fn read_le_f32(&mut self) -> io::Result<f32>;
67}
68
69impl<R> ReadExt for R
70 where R: io::Read
71{
72 #[inline(always)]
73 fn read_into(&mut self, buf: &mut [u8]) -> io::Result<()> {
74 let mut n = 0;
75 while n < buf.len() {
76 let progress = self.read(&mut buf[n..])?;
77 if progress > 0 {
78 n += progress;
79 } else {
80 return Err(io::Error::new(io::ErrorKind::Other, "Failed to read enough bytes."));
81 }
82 }
83 Ok(())
84 }
85
86 #[inline(always)]
87 fn skip_bytes(&mut self, n: usize) -> io::Result<()> {
88 let mut n_read = 0;
93 let mut buf = [0u8; 1024];
94 while n_read < n {
95 let end = cmp::min(n - n_read, 1024);
96 let progress = self.read(&mut buf[0..end])?;
97 if progress > 0 {
98 n_read += progress;
99 } else {
100 return Err(io::Error::new(io::ErrorKind::Other, "Failed to read enough bytes."));
101 }
102 }
103 Ok(())
104 }
105
106 #[inline(always)]
107 fn read_bytes(&mut self, n: usize) -> io::Result<Vec<u8>> {
108 let mut buf = Vec::with_capacity(n);
113 unsafe { buf.set_len(n); }
114 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 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 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 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_u24(&mut self) -> io::Result<u32> {
157 let mut buf = [0u8; 3];
158 self.read_into(&mut buf)?;
159 Ok((buf[2] as u32) << 16 | (buf[1] as u32) << 8 | (buf[0] as u32))
160 }
161
162 #[inline(always)]
163 fn read_le_i32(&mut self) -> io::Result<i32> {
164 self.read_le_u32().map(|x| x as i32)
165 }
166
167 #[inline(always)]
168 fn read_le_u32(&mut self) -> io::Result<u32> {
169 let mut buf = [0u8; 4];
170 self.read_into(&mut buf)?;
171 Ok((buf[3] as u32) << 24 | (buf[2] as u32) << 16 |
172 (buf[1] as u32) << 8 | (buf[0] as u32))
173 }
174
175 #[inline(always)]
176 fn read_le_f32(&mut self) -> io::Result<f32> {
177 self.read_le_u32().map(|u| { f32::from_bits(u) })
178 }
179}
180
181enum ChunkKind {
183 Fmt,
184 Clm,
185 Uhwt,
186 Srge,
187 Srgo,
188 Cue,
189 Smpl,
190 Fact,
191 Data,
192 Unknown,
193}
194
195struct ChunkHeader {
197 pub kind: ChunkKind,
198 pub len: u32,
199}
200
201#[derive(Debug,Clone, Copy)]
203pub struct WavSpecEx {
204 pub spec: WavSpec,
209
210 pub bytes_per_sample: u16,
212}
213
214#[derive(Debug,Clone, Copy)]
216pub struct ClmSpec {
217 pub len: i32,
218
219}
220
221#[derive(Debug,Clone, Copy)]
223pub struct UhwtSpec {
224 pub len: i32,
225
226}
227
228#[derive(Debug,Clone, Copy)]
230pub struct SrgeSpec {
231 pub len: i32,
232 pub version: i32,
233
234}
235
236#[derive(Debug,Clone, Copy)]
238pub struct SrgoSpec {
239 pub len: i32,
240 pub version: i32,
241
242}
243
244#[derive(Debug,Clone, Copy)]
246pub struct CueSpec {
247 pub len: i32,
248
249}
250
251#[derive(Debug,Clone, Copy)]
253pub struct SmplSpec {
254 pub len: i32,
255
256}
257
258#[derive(Default,Debug,Clone, Copy)]
261pub struct WavSpecSurge {
262
263 pub specx: Option<WavSpecEx>,
265
266 pub clm: Option<ClmSpec>,
268
269 pub uhwt: Option<UhwtSpec>,
271
272 pub srge: Option<SrgeSpec>,
274
275 pub srgo: Option<SrgoSpec>,
277
278 pub cue: Option<CueSpec>,
280
281 pub smpl: Option<SmplSpec>,
283}
284
285pub struct WavReader<R> {
293 surge_spec: WavSpecSurge,
295
296 bytes_per_sample: u16,
298
299 num_samples: u32,
305
306 samples_read: u32,
308
309 reader: R,
311}
312
313pub struct WavSamples<'wr, R, S>
318 where R: 'wr
319{
320 reader: &'wr mut WavReader<R>,
321 phantom_sample: marker::PhantomData<S>,
322}
323
324pub struct WavIntoSamples<R, S> {
329 reader: WavReader<R>,
330 phantom_sample: marker::PhantomData<S>,
331}
332
333pub fn read_wave_header<R: io::Read>(reader: &mut R) -> Result<u64> {
342 if b"RIFF" != &reader.read_bytes(4)?[..] {
348 return Err(Error::FormatError("no RIFF tag found"));
349 }
350
351 let file_len = reader.read_le_u32()?;
352
353 if b"WAVE" != &reader.read_bytes(4)?[..] {
355 return Err(Error::FormatError("no WAVE tag found"));
356 }
357
358 Ok(file_len as u64 + 8)
361}
362
363pub fn read_until_data<R: io::Read>(mut reader: R) -> Result<(WavSpecSurge, u32)> {
369
370 let mut surge_spec_opt: Option<WavSpecSurge> = Some(WavSpecSurge::default());
371
372 loop {
373 let header = WavReader::read_chunk_header(&mut reader)?;
374 match header.kind {
375 ChunkKind::Fmt => {
376 let specx = WavReader::read_fmt_chunk(&mut reader, header.len)?;
377 if let Some(ref mut spec) = surge_spec_opt {
378 spec.specx = Some(specx);
379 }
380 }
381 ChunkKind::Clm => {
382 let clm = WavReader::read_clm_chunk(&mut reader, header.len)?;
383 if let Some(ref mut spec) = surge_spec_opt {
384 spec.clm = Some(clm);
385 }
386 },
387 ChunkKind::Uhwt => {
388 let uhwt = WavReader::read_uhwt_chunk(&mut reader, header.len);
389 if let Some(ref mut spec) = surge_spec_opt {
390 spec.uhwt = Some(uhwt);
391 }
392 },
393 ChunkKind::Srge => {
394 let srge = WavReader::read_srge_chunk(&mut reader, header.len)?;
395 if let Some(ref mut spec) = surge_spec_opt {
396 spec.srge = Some(srge);
397 }
398 },
399 ChunkKind::Srgo => {
400 let srgo = WavReader::read_srgo_chunk(&mut reader, header.len)?;
401 if let Some(ref mut spec) = surge_spec_opt {
402 spec.srgo = Some(srgo);
403 }
404 },
405 ChunkKind::Cue => {
406 let cue = WavReader::read_cue_chunk(&mut reader, header.len)?;
407 if let Some(ref mut spec) = surge_spec_opt {
408 spec.cue = Some(cue);
409 }
410 },
411 ChunkKind::Smpl => {
412 let smpl = WavReader::read_smpl_chunk(&mut reader, header.len)?;
413 if let Some(ref mut spec) = surge_spec_opt {
414 spec.smpl = Some(smpl);
415 }
416 },
417 ChunkKind::Fact => {
418 let _samples_per_channel = reader.read_le_u32();
429 }
430 ChunkKind::Data => {
431 if let Some(spec) = surge_spec_opt {
434 return Ok((spec, header.len));
435 } else {
436 return Err(Error::FormatError("missing fmt chunk"));
437 }
438 }
439 ChunkKind::Unknown => {
440 reader.skip_bytes(header.len as usize)?;
442 }
443 }
444 }
447}
448
449impl<R> WavReader<R>
450 where R: io::Read
451{
452 fn read_chunk_header(reader: &mut R) -> Result<ChunkHeader> {
454 let mut kind_str = [0; 4];
455 reader.read_into(&mut kind_str)?;
456 let len = reader.read_le_u32()?;
457
458 let kind = match &kind_str[..] {
459 b"fmt " => ChunkKind::Fmt,
460 b"fact" => ChunkKind::Fact,
461 b"data" => ChunkKind::Data,
462 b"clm " => ChunkKind::Clm,
463 b"uhWT" => ChunkKind::Uhwt,
464 b"srge" => ChunkKind::Srge,
465 b"srgo" => ChunkKind::Srgo,
466 b"cue " => ChunkKind::Cue,
467 b"smpl" => ChunkKind::Smpl,
468 _ => ChunkKind::Unknown,
469 };
470
471 Ok(ChunkHeader { kind, len })
472 }
473
474 fn read_fmt_chunk(reader: &mut R, chunk_len: u32) -> Result<WavSpecEx> {
476 if chunk_len < 16 {
481 return Err(Error::FormatError("invalid fmt chunk size"));
482 }
483
484 let format_tag = reader.read_le_u16()?;
522 let n_channels = reader.read_le_u16()?;
523 let n_samples_per_sec = reader.read_le_u32()?;
524 let n_bytes_per_sec = reader.read_le_u32()?;
525 let block_align = reader.read_le_u16()?;
526 let bits_per_sample = reader.read_le_u16()?;
527
528 if n_channels == 0 {
529 return Err(Error::FormatError("file contains zero channels"));
530 }
531
532 if (Some(bits_per_sample) != (block_align / n_channels).checked_mul(8)) ||
535 (Some(n_bytes_per_sec) != (block_align as u32).checked_mul(n_samples_per_sec)) {
536 return Err(Error::FormatError("inconsistent fmt chunk"));
537 }
538
539 if bits_per_sample % 8 != 0 {
542 return Err(Error::FormatError("bits per sample is not a multiple of 8"));
543 }
544
545 if bits_per_sample == 0 {
546 return Err(Error::FormatError("bits per sample is 0"));
547 }
548
549 let spec = WavSpec {
550 channels: n_channels,
551 sample_rate: n_samples_per_sec,
552 bits_per_sample,
553 sample_format: SampleFormat::Int,
554 };
555
556 const PCM: u16 = 0x0001;
561 const ADPCM: u16 = 0x0002;
562 const IEEE_FLOAT: u16 = 0x0003;
563 const EXTENSIBLE: u16 = 0xfffe;
564 match format_tag {
565 PCM => WavReader::read_wave_format_pcm(reader, chunk_len, spec),
566 ADPCM => Err(Error::Unsupported),
567 IEEE_FLOAT => WavReader::read_wave_format_ieee_float(reader, chunk_len, spec),
568 EXTENSIBLE => WavReader::read_wave_format_extensible(reader, chunk_len, spec),
569 _ => Err(Error::Unsupported),
570 }
571 }
572
573 fn read_clm_chunk(reader: &mut R, chunk_len: u32) -> Result<ClmSpec> {
575
576 let _prefix = reader.read_le_u24()?;
578
579 let c1: char = reader.read_u8()?.into();
580 let c2: char = reader.read_u8()?.into();
581 let c3: char = reader.read_u8()?.into();
582 let c4: char = reader.read_u8()?.into();
583
584 reader.skip_bytes((chunk_len - 7) as usize)?;
585
586 match (c1,c2,c3,c4) {
587 ('2', '0', '4', '8') => {
588 Ok(ClmSpec {
590 len: 2048,
591 })
592 },
593 _ => {
594 Err(Error::FormatError("invalid clm prefix"))
595 },
596 }
597 }
598
599 fn read_uhwt_chunk(_reader: &mut R, _chunk_len: u32) -> UhwtSpec {
601 UhwtSpec { len: 2048 }
603 }
604
605 fn read_srge_chunk(reader: &mut R, chunk_len: u32) -> Result<SrgeSpec> {
607 let version = reader.read_le_i32()?;
608 let len = reader.read_le_i32()?;
609 reader.skip_bytes((chunk_len - 8) as usize)?;
610 Ok( SrgeSpec { len, version, })
611 }
612
613 fn read_srgo_chunk(reader: &mut R, chunk_len: u32) -> Result<SrgoSpec> {
615 let version = reader.read_le_i32()?;
616 let len = reader.read_le_i32()?;
617 reader.skip_bytes((chunk_len - 8) as usize)?;
618 Ok( SrgoSpec { len, version, })
619 }
620
621 fn read_cue_chunk(reader: &mut R, chunk_len: u32) -> Result<CueSpec> {
623
624 let mut parsed = 0;
625
626 let num_cues = reader.read_le_i32()?;
627 parsed += 4;
628
629 let mut chunk_starts = vec![];
630
631 for _cue in 0..num_cues {
632 for j in 0..6 {
633
634 let d = reader.read_le_i32()?;
635
636 parsed += 4;
637
638 if j == 5 {
639 chunk_starts.push(d);
640 }
641 }
642 }
643
644 let mut d = -1;
646 let mut regular = true;
647 for i in 1..chunk_starts.len() {
648 match d {
649 -1 => {
650 d = chunk_starts[i] - chunk_starts[i - 1];
651
652 },
653 _ => {
654 if d != chunk_starts[i] - chunk_starts[i - 1] {
655 regular = false;
656 }
657 },
658 }
659 }
660
661 reader.skip_bytes((chunk_len - parsed) as usize)?;
662
663 if regular {
664 Ok( CueSpec { len: d})
665 } else {
666 Err(Error::FormatError("invalid CUE chunk"))
667
668 }
669 }
670
671 fn read_smpl_chunk(reader: &mut R, chunk_len: u32) -> Result<SmplSpec> {
673
674 let mut parsed = 0;
675
676 let samplechunk: [u32; 9] = [
677 reader.read_le_u32()?,
678 reader.read_le_u32()?,
679 reader.read_le_u32()?,
680 reader.read_le_u32()?,
681 reader.read_le_u32()?,
682 reader.read_le_u32()?,
683 reader.read_le_u32()?,
684 reader.read_le_u32()?,
685 reader.read_le_u32()?,
686 ];
687
688 parsed += 9 * 4;
689
690 let nloops: u32 = samplechunk[7];
691 let _sdsz: u32 = samplechunk[8];
692
693 let mut smpl_len: i32 = 0;
694
695 if nloops == 0 {
696 smpl_len = 2048;
698 }
699
700 if nloops > 1 {
701 return Err(Error::FormatError("SMPL chunk, nloops > 1, not supported"));
702 }
703
704 for _i in 0..nloops {
705
706 let loopdata: [i32; 6] = [
707 reader.read_le_i32()?,
708 reader.read_le_i32()?,
709 reader.read_le_i32()?,
710 reader.read_le_i32()?,
711 reader.read_le_i32()?,
712 reader.read_le_i32()?,
713 ];
714
715 parsed += 6 * 4;
716
717 smpl_len = loopdata[3] - loopdata[2] + 1;
718
719 if smpl_len == 0 {
720 smpl_len = 2048;
721 }
722 }
723
724 reader.skip_bytes((chunk_len - parsed) as usize)?;
725
726 Ok( SmplSpec{ len: smpl_len } )
727 }
728
729 fn read_wave_format_pcm(mut reader: R, chunk_len: u32, spec: WavSpec) -> Result<WavSpecEx> {
730 let is_wave_format_ex = match chunk_len {
733 16 => false,
734 18 => true,
735 40 => true,
738 _ => return Err(Error::FormatError("unexpected fmt chunk size")),
739 };
740
741 if is_wave_format_ex {
742 let _cb_size = reader.read_le_u16()?;
747
748 match spec.bits_per_sample {
755 8 => {}
756 16 => {}
757 24 => {}
758 _ => return Err(Error::FormatError("bits per sample is not 8 or 16")),
759 }
760 }
761
762 if chunk_len == 40 {
764 reader.skip_bytes(22)?;
765 }
766
767 let spec_ex = WavSpecEx {
768 spec,
769 bytes_per_sample: spec.bits_per_sample / 8,
770 };
771 Ok(spec_ex)
772 }
773
774 fn read_wave_format_ieee_float(mut reader: R, chunk_len: u32, spec: WavSpec)
775 -> Result<WavSpecEx> {
776 let is_wave_format_ex = chunk_len == 18;
779
780 if !is_wave_format_ex && chunk_len != 16 {
781 return Err(Error::FormatError("unexpected fmt chunk size"));
782 }
783
784 if is_wave_format_ex {
785 let cb_size = reader.read_le_u16()?;
788 if cb_size != 0 {
789 return Err(Error::FormatError("unexpected WAVEFORMATEX size"));
790 }
791 }
792
793 if spec.bits_per_sample != 32 {
800 return Err(Error::FormatError("bits per sample is not 32"));
801 }
802
803 let spec_ex = WavSpecEx {
804 spec: WavSpec {
805 sample_format: SampleFormat::Float,
806 ..spec
807 },
808 bytes_per_sample: spec.bits_per_sample / 8,
809 };
810 Ok(spec_ex)
811 }
812
813 fn read_wave_format_extensible(mut reader: R, chunk_len: u32, spec: WavSpec)
814 -> Result<WavSpecEx> {
815 if chunk_len < 40 {
819 return Err(Error::FormatError("unexpected fmt chunk size"));
820 }
821
822 let cb_size = reader.read_le_u16()?;
824
825 if cb_size != 22 {
828 return Err(Error::FormatError("unexpected WAVEFORMATEXTENSIBLE size"));
829 }
830
831 let valid_bits_per_sample = reader.read_le_u16()?;
846 let _channel_mask = reader.read_le_u32()?; let mut subformat = [0u8; 16];
848 reader.read_into(&mut subformat)?;
849
850 let sample_format = match subformat {
855 super::KSDATAFORMAT_SUBTYPE_PCM => SampleFormat::Int,
856 super::KSDATAFORMAT_SUBTYPE_IEEE_FLOAT => SampleFormat::Float,
857 _ => return Err(Error::Unsupported),
858 };
859
860 let spec_ex = WavSpecEx {
861 spec: WavSpec {
862 bits_per_sample: valid_bits_per_sample,
863 sample_format,
864 ..spec
865 },
866 bytes_per_sample: spec.bits_per_sample / 8,
867 };
868 Ok(spec_ex)
869 }
870
871 pub fn new(mut reader: R) -> Result<WavReader<R>> {
876 read_wave_header(&mut reader)?;
877 let (surge_spec, data_len) = read_until_data(&mut reader)?;
878
879 let num_samples = data_len / surge_spec.specx.unwrap().bytes_per_sample as u32;
880
881 if num_samples * surge_spec.specx.unwrap().bytes_per_sample as u32 != data_len {
887 let msg = "data chunk length is not a multiple of sample size";
888 return Err(Error::FormatError(msg));
889 }
890
891 if num_samples % surge_spec.specx.unwrap().spec.channels as u32 != 0 {
895 return Err(Error::FormatError("invalid data chunk length"));
896 }
897
898 let wav_reader = WavReader {
899 surge_spec,
900 bytes_per_sample: surge_spec.specx.unwrap().bytes_per_sample,
901 num_samples,
902 samples_read: 0,
903 reader,
904 };
905
906 Ok(wav_reader)
907 }
908
909 pub fn spec(&self) -> WavSpec {
911 self.surge_spec.specx.unwrap().spec
912 }
913
914 pub fn surge_spec(&self) -> WavSpecSurge {
916 self.surge_spec
917 }
918
919 pub fn samples<S: Sample>(&mut self) -> WavSamples<'_, R, S> {
935 WavSamples {
936 reader: self,
937 phantom_sample: marker::PhantomData,
938 }
939 }
940
941 pub fn into_samples<S: Sample>(self) -> WavIntoSamples<R, S> {
945 WavIntoSamples {
946 reader: self,
947 phantom_sample: marker::PhantomData,
948 }
949 }
950
951 pub fn duration(&self) -> u32 {
958 self.num_samples / self.surge_spec.specx.unwrap().spec.channels as u32
959 }
960
961 pub fn len(&self) -> u32 {
968 self.num_samples
969 }
970
971 pub fn is_empty(&self) -> bool {
973 self.len() == 0
974 }
975
976 pub fn into_inner(self) -> R {
978 self.reader
979 }
980
981 pub fn seek(&mut self, time: u32) -> io::Result<()>
992 where R: io::Seek,
993 {
994 let bytes_per_sample = self.surge_spec.specx.unwrap().spec.bits_per_sample / 8;
995 let sample_position = time * self.surge_spec.specx.unwrap().spec.channels as u32;
996 let offset_samples = sample_position as i64 - self.samples_read as i64;
997 let offset_bytes = offset_samples * bytes_per_sample as i64;
998 self.reader.seek(io::SeekFrom::Current(offset_bytes))?;
999 self.samples_read = sample_position;
1000 Ok(())
1001 }
1002}
1003
1004impl WavReader<io::BufReader<fs::File>> {
1005 pub fn open<P: AsRef<path::Path>>(filename: P) -> Result<WavReader<io::BufReader<fs::File>>> {
1010 let file = fs::File::open(filename)?;
1011 let buf_reader = io::BufReader::new(file);
1012 WavReader::new(buf_reader)
1013 }
1014}
1015
1016fn iter_next<R, S>(reader: &mut WavReader<R>) -> Option<Result<S>>
1017 where R: io::Read,
1018 S: Sample
1019{
1020 if reader.samples_read < reader.num_samples {
1021 reader.samples_read += 1;
1022 let sample = Sample::read(&mut reader.reader,
1023 reader.surge_spec.specx.unwrap().spec.sample_format,
1024 reader.bytes_per_sample,
1025 reader.surge_spec.specx.unwrap().spec.bits_per_sample);
1026 Some(sample.map_err(Error::from))
1027 } else {
1028 None
1029 }
1030}
1031
1032fn iter_size_hint<R>(reader: &WavReader<R>) -> (usize, Option<usize>) {
1033 let samples_left = reader.num_samples - reader.samples_read;
1034 (samples_left as usize, Some(samples_left as usize))
1035}
1036
1037impl<'wr, R, S> Iterator for WavSamples<'wr, R, S>
1038 where R: io::Read,
1039 S: Sample
1040{
1041 type Item = Result<S>;
1042
1043 fn next(&mut self) -> Option<Result<S>> {
1044 iter_next(&mut self.reader)
1045 }
1046
1047 fn size_hint(&self) -> (usize, Option<usize>) {
1048 iter_size_hint(&self.reader)
1049 }
1050}
1051
1052impl<'wr, R, S> ExactSizeIterator for WavSamples<'wr, R, S>
1053 where R: io::Read,
1054 S: Sample
1055{
1056}
1057
1058impl<R, S> Iterator for WavIntoSamples<R, S>
1059 where R: io::Read,
1060 S: Sample
1061{
1062 type Item = Result<S>;
1063
1064 fn next(&mut self) -> Option<Result<S>> {
1065 iter_next(&mut self.reader)
1066 }
1067
1068 fn size_hint(&self) -> (usize, Option<usize>) {
1069 iter_size_hint(&self.reader)
1070 }
1071}
1072
1073impl<R, S> ExactSizeIterator for WavIntoSamples<R, S>
1074 where R: io::Read,
1075 S: Sample
1076{
1077}
1078
1079#[test]
1080fn duration_and_len_agree() {
1081 let files = &["testsamples/pcmwaveformat-16bit-44100Hz-mono.wav",
1082 "testsamples/waveformatex-16bit-44100Hz-stereo.wav",
1083 "testsamples/waveformatextensible-32bit-48kHz-stereo.wav"];
1084
1085 for fname in files {
1086 let reader = WavReader::open(fname).unwrap();
1087 assert_eq!(reader.spec().channels as u32 * reader.duration(),
1088 reader.len());
1089 }
1090}
1091
1092#[test]
1094fn read_wav_pcm_wave_format_pcm() {
1095 let mut wav_reader = WavReader::open("testsamples/pcmwaveformat-16bit-44100Hz-mono.wav")
1096 .unwrap();
1097
1098 assert_eq!(wav_reader.spec().channels, 1);
1099 assert_eq!(wav_reader.spec().sample_rate, 44100);
1100 assert_eq!(wav_reader.spec().bits_per_sample, 16);
1101 assert_eq!(wav_reader.spec().sample_format, SampleFormat::Int);
1102
1103 let samples: Vec<i16> = wav_reader.samples()
1104 .map(|r| r.unwrap())
1105 .collect();
1106
1107 assert_eq!(&samples[..], &[2, -3, 5, -7]);
1109}
1110
1111#[test]
1112fn read_wav_skips_unknown_chunks() {
1113 let files = ["testsamples/pcmwaveformat-16bit-44100Hz-mono-extra.wav",
1116 "testsamples/waveformatex-16bit-44100Hz-mono-extra.wav"];
1117
1118 for file in &files {
1119 let mut wav_reader = WavReader::open(file).unwrap();
1120
1121 assert_eq!(wav_reader.spec().channels, 1);
1122 assert_eq!(wav_reader.spec().sample_rate, 44100);
1123 assert_eq!(wav_reader.spec().bits_per_sample, 16);
1124 assert_eq!(wav_reader.spec().sample_format, SampleFormat::Int);
1125
1126 let sample = wav_reader.samples::<i16>().next().unwrap().unwrap();
1127 assert_eq!(sample, 2);
1128 }
1129}
1130
1131#[test]
1132fn len_and_size_hint_are_correct() {
1133 let mut wav_reader = WavReader::open("testsamples/pcmwaveformat-16bit-44100Hz-mono.wav")
1134 .unwrap();
1135
1136 assert_eq!(wav_reader.len(), 4);
1137
1138 {
1139 let mut samples = wav_reader.samples::<i16>();
1140
1141 assert_eq!(samples.size_hint(), (4, Some(4)));
1142 samples.next();
1143 assert_eq!(samples.size_hint(), (3, Some(3)));
1144 }
1145
1146 assert_eq!(wav_reader.len(), 4);
1148
1149 {
1151 let mut samples = wav_reader.samples::<i16>();
1152
1153 assert_eq!(samples.size_hint(), (3, Some(3)));
1154 samples.next();
1155 assert_eq!(samples.size_hint(), (2, Some(2)));
1156 }
1157}
1158
1159#[test]
1160fn size_hint_is_exact() {
1161 let files = &["testsamples/pcmwaveformat-16bit-44100Hz-mono.wav",
1162 "testsamples/waveformatex-16bit-44100Hz-stereo.wav",
1163 "testsamples/waveformatextensible-32bit-48kHz-stereo.wav"];
1164
1165 for fname in files {
1166 let mut reader = WavReader::open(fname).unwrap();
1167 let len = reader.len();
1168 let mut iter = reader.samples::<i32>();
1169 for i in 0..len {
1170 let remaining = (len - i) as usize;
1171 assert_eq!(iter.size_hint(), (remaining, Some(remaining)));
1172 assert!(iter.next().is_some());
1173 }
1174 assert!(iter.next().is_none());
1175 }
1176}
1177
1178#[test]
1179fn samples_equals_into_samples() {
1180 let wav_reader_val = WavReader::open("testsamples/pcmwaveformat-8bit-44100Hz-mono.wav").unwrap();
1181 let mut wav_reader_ref = WavReader::open("testsamples/pcmwaveformat-8bit-44100Hz-mono.wav").unwrap();
1182
1183 let samples_val: Vec<i16> = wav_reader_val.into_samples()
1184 .map(|r| r.unwrap())
1185 .collect();
1186
1187 let samples_ref: Vec<i16> = wav_reader_ref.samples()
1188 .map(|r| r.unwrap())
1189 .collect();
1190
1191 assert_eq!(samples_val, samples_ref);
1192}
1193
1194#[test]
1196fn read_wav_wave_format_ex_pcm() {
1197 let mut wav_reader = WavReader::open("testsamples/waveformatex-16bit-44100Hz-mono.wav")
1198 .unwrap();
1199
1200 assert_eq!(wav_reader.spec().channels, 1);
1201 assert_eq!(wav_reader.spec().sample_rate, 44100);
1202 assert_eq!(wav_reader.spec().bits_per_sample, 16);
1203 assert_eq!(wav_reader.spec().sample_format, SampleFormat::Int);
1204
1205 let samples: Vec<i16> = wav_reader.samples()
1206 .map(|r| r.unwrap())
1207 .collect();
1208
1209 assert_eq!(&samples[..], &[2, -3, 5, -7]);
1211}
1212
1213#[test]
1214fn read_wav_wave_format_ex_ieee_float() {
1215 let mut wav_reader = WavReader::open("testsamples/waveformatex-ieeefloat-44100Hz-mono.wav")
1216 .unwrap();
1217
1218 assert_eq!(wav_reader.spec().channels, 1);
1219 assert_eq!(wav_reader.spec().sample_rate, 44100);
1220 assert_eq!(wav_reader.spec().bits_per_sample, 32);
1221 assert_eq!(wav_reader.spec().sample_format, SampleFormat::Float);
1222
1223 let samples: Vec<f32> = wav_reader.samples()
1224 .map(|r| r.unwrap())
1225 .collect();
1226
1227 assert_eq!(&samples[..], &[2.0, 3.0, -16411.0, 1019.0]);
1229}
1230
1231#[test]
1232fn read_wav_stereo() {
1233 let mut wav_reader = WavReader::open("testsamples/waveformatex-16bit-44100Hz-stereo.wav")
1234 .unwrap();
1235
1236 assert_eq!(wav_reader.spec().channels, 2);
1237 assert_eq!(wav_reader.spec().sample_rate, 44100);
1238 assert_eq!(wav_reader.spec().bits_per_sample, 16);
1239 assert_eq!(wav_reader.spec().sample_format, SampleFormat::Int);
1240
1241 let samples: Vec<i16> = wav_reader.samples()
1242 .map(|r| r.unwrap())
1243 .collect();
1244
1245 assert_eq!(&samples[..], &[2, -3, 5, -7, 11, -13, 17, -19]);
1247
1248}
1249
1250#[test]
1251fn read_wav_pcm_wave_format_8bit() {
1252 let mut wav_reader = WavReader::open("testsamples/pcmwaveformat-8bit-44100Hz-mono.wav")
1253 .unwrap();
1254
1255 assert_eq!(wav_reader.spec().channels, 1);
1256 assert_eq!(wav_reader.spec().bits_per_sample, 8);
1257 assert_eq!(wav_reader.spec().sample_format, SampleFormat::Int);
1258
1259 let samples: Vec<i16> = wav_reader.samples()
1260 .map(|r| r.unwrap())
1261 .collect();
1262
1263 assert_eq!(&samples[..], &[19, -53, 89, -127]);
1265}
1266
1267#[test]
1269fn read_wav_wave_format_ex_8bit() {
1270 let mut wav_reader = WavReader::open("testsamples/waveformatex-8bit-11025Hz-mono.wav").unwrap();
1271
1272 assert_eq!(wav_reader.spec().channels, 1);
1273 assert_eq!(wav_reader.spec().bits_per_sample, 8);
1274 assert_eq!(wav_reader.spec().sample_format, SampleFormat::Int);
1275
1276 let samples: Vec<i32> = wav_reader.samples()
1277 .map(|r| r.unwrap())
1278 .collect();
1279
1280 assert_eq!(&samples[..], &[-128, -128, -128, -128]);
1283}
1284
1285#[test]
1287fn read_wav_wave_format_extensible_pcm_24bit() {
1288 let mut wav_reader = WavReader::open("testsamples/waveformatextensible-24bit-192kHz-mono.wav")
1289 .unwrap();
1290
1291 assert_eq!(wav_reader.spec().channels, 1);
1292 assert_eq!(wav_reader.spec().sample_rate, 192_000);
1293 assert_eq!(wav_reader.spec().bits_per_sample, 24);
1294 assert_eq!(wav_reader.spec().sample_format, SampleFormat::Int);
1295
1296 let samples: Vec<i32> = wav_reader.samples()
1297 .map(|r| r.unwrap())
1298 .collect();
1299
1300 assert_eq!(&samples[..], &[-17, 4_194_319, -6_291_437, 8_355_817]);
1302}
1303
1304#[test]
1305fn read_wav_32bit() {
1306 let mut wav_reader = WavReader::open("testsamples/waveformatextensible-32bit-48kHz-stereo.wav")
1307 .unwrap();
1308
1309 assert_eq!(wav_reader.spec().bits_per_sample, 32);
1310 assert_eq!(wav_reader.spec().sample_format, SampleFormat::Int);
1311
1312 let samples: Vec<i32> = wav_reader.samples()
1313 .map(|r| r.unwrap())
1314 .collect();
1315
1316 assert_eq!(&samples[..], &[19, -229_373, 33_587_161, -2_147_483_497]);
1318}
1319
1320#[test]
1321fn read_wav_wave_format_extensible_ieee_float() {
1322 let mut wav_reader =
1323 WavReader::open("testsamples/waveformatextensible-ieeefloat-44100Hz-mono.wav").unwrap();
1324
1325 assert_eq!(wav_reader.spec().channels, 1);
1326 assert_eq!(wav_reader.spec().sample_rate, 44100);
1327 assert_eq!(wav_reader.spec().bits_per_sample, 32);
1328 assert_eq!(wav_reader.spec().sample_format, SampleFormat::Float);
1329
1330 let samples: Vec<f32> = wav_reader.samples()
1331 .map(|r| r.unwrap())
1332 .collect();
1333
1334 assert_eq!(&samples[..], &[2.0, 3.0, -16411.0, 1019.0]);
1336}
1337
1338#[test]
1339fn read_wav_nonstandard_01() {
1340 let mut wav_reader = WavReader::open("testsamples/nonstandard-01.wav").unwrap();
1350
1351 assert_eq!(wav_reader.spec().bits_per_sample, 24);
1352 assert_eq!(wav_reader.spec().sample_format, SampleFormat::Int);
1353
1354 let samples: Vec<i32> = wav_reader.samples()
1355 .map(|r| r.unwrap())
1356 .collect();
1357
1358 assert_eq!(&samples[..], &[0, 0]);
1359}
1360
1361#[test]
1362fn wide_read_should_signal_error() {
1363 let mut reader24 = WavReader::open("testsamples/waveformatextensible-24bit-192kHz-mono.wav")
1364 .unwrap();
1365
1366 assert!(reader24.samples::<i8>().next().unwrap().is_err());
1370 assert!(reader24.samples::<i16>().next().unwrap().is_err());
1371 assert!(reader24.samples::<i32>().next().unwrap().is_ok());
1372
1373 let mut reader32 = WavReader::open("testsamples/waveformatextensible-32bit-48kHz-stereo.wav")
1374 .unwrap();
1375
1376 assert!(reader32.samples::<i8>().next().unwrap().is_err());
1378 assert!(reader32.samples::<i16>().next().unwrap().is_err());
1379 assert!(reader32.samples::<i32>().next().unwrap().is_ok());
1380}
1381
1382#[test]
1383fn sample_format_mismatch_should_signal_error() {
1384 let mut reader_f32 = WavReader::open("testsamples/waveformatex-ieeefloat-44100Hz-mono.wav")
1385 .unwrap();
1386
1387 assert!(reader_f32.samples::<i8>().next().unwrap().is_err());
1388 assert!(reader_f32.samples::<i16>().next().unwrap().is_err());
1389 assert!(reader_f32.samples::<i32>().next().unwrap().is_err());
1390 assert!(reader_f32.samples::<f32>().next().unwrap().is_ok());
1391
1392 let mut reader_i8 = WavReader::open("testsamples/pcmwaveformat-8bit-44100Hz-mono.wav").unwrap();
1393
1394 assert!(reader_i8.samples::<i8>().next().unwrap().is_ok());
1395 assert!(reader_i8.samples::<i16>().next().unwrap().is_ok());
1396 assert!(reader_i8.samples::<i32>().next().unwrap().is_ok());
1397 assert!(reader_i8.samples::<f32>().next().unwrap().is_err());
1398}
1399
1400#[test]
1401fn fuzz_crashes_should_be_fixed() {
1402 use std::fs;
1403 use std::ffi::OsStr;
1404
1405 let dir = fs::read_dir("testsamples/fuzz").ok()
1408 .expect("failed to enumerate fuzz test corpus");
1409 for path in dir {
1410 let path = path.ok().expect("failed to obtain path info").path();
1411 let is_file = fs::metadata(&path).unwrap().file_type().is_file();
1412 if is_file && path.extension() == Some(OsStr::new("wav")) {
1413 println!(" testing {} ...", path.to_str()
1414 .expect("unsupported filename"));
1415 let mut reader = match WavReader::open(path) {
1416 Ok(r) => r,
1417 Err(..) => continue,
1418 };
1419 match reader.spec().sample_format {
1420 SampleFormat::Int => {
1421 for sample in reader.samples::<i32>() {
1422 match sample {
1423 Ok(..) => { }
1424 Err(..) => break,
1425 }
1426 }
1427 }
1428 SampleFormat::Float => {
1429 for sample in reader.samples::<f32>() {
1430 match sample {
1431 Ok(..) => { }
1432 Err(..) => break,
1433 }
1434 }
1435 }
1436 }
1437 }
1438 }
1439}
1440
1441#[test]
1442fn seek_is_consistent() {
1443 let files = &["testsamples/pcmwaveformat-16bit-44100Hz-mono.wav",
1444 "testsamples/waveformatex-16bit-44100Hz-stereo.wav",
1445 "testsamples/waveformatextensible-32bit-48kHz-stereo.wav"];
1446 for fname in files {
1447 let mut reader = WavReader::open(fname).unwrap();
1448
1449 let count = reader.samples::<i32>().count();
1451 reader.seek(0).unwrap();
1452 assert_eq!(reader.samples_read, 0);
1453 assert_eq!(count, reader.samples::<i32>().count());
1454
1455 let last_time = reader.duration() - 1;
1457 let channels = reader.spec().channels;
1458 reader.seek(last_time).unwrap();
1459 {
1460 let mut samples = reader.samples::<i32>();
1461 for _ in 0..channels {
1462 assert!(samples.next().is_some());
1463 }
1464 assert!(samples.next().is_none());
1465 }
1466
1467 let num_samples = reader.len();
1469 reader.seek(num_samples).unwrap();
1470 assert!(reader.samples::<i32>().next().is_none());
1471 reader.seek(::std::u32::MAX / channels as u32).unwrap();
1472 assert!(reader.samples::<i32>().next().is_none());
1473 }
1474}