1#![warn(missing_docs)]
57
58use std::error;
59use std::fmt;
60use std::io;
61use std::result;
62use read::ReadExt;
63use write::WriteExt;
64
65mod read;
66mod write;
67
68pub use read::{WavReader, WavIntoSamples, WavSamples, read_wave_header};
69pub use write::{SampleWriter16, WavWriter};
70
71pub trait Sample: Sized {
80 fn write<W: io::Write>(self, writer: &mut W, bits: u16) -> Result<()>;
82
83 fn write_padded<W: io::Write>(self, writer: &mut W, bits: u16, byte_width: u16) -> Result<()>;
86
87 fn read<R: io::Read>(reader: &mut R, SampleFormat, bytes: u16, bits: u16) -> Result<Self>;
89
90 fn as_i16(self) -> i16;
96}
97
98fn signed_from_u8(x: u8) -> i8 {
106 (x as i16 - 128) as i8
107}
108
109fn u8_from_signed(x: i8) -> u8 {
111 (x as i16 + 128) as u8
112}
113
114#[test]
115fn u8_sign_conversion_is_bijective() {
116 for x in 0..255 {
117 assert_eq!(x, u8_from_signed(signed_from_u8(x)));
118 }
119 for x in -128..127 {
120 assert_eq!(x, signed_from_u8(u8_from_signed(x)));
121 }
122}
123
124#[inline(always)]
126fn narrow_to_i8(x: i32) -> Result<i8> {
127 use std::i8;
128 if x < i8::MIN as i32 || x > i8::MAX as i32 {
129 Err(Error::TooWide)
130 } else {
131 Ok(x as i8)
132 }
133}
134
135#[test]
136fn verify_narrow_to_i8() {
137 assert!(narrow_to_i8(127).is_ok());
138 assert!(narrow_to_i8(128).is_err());
139 assert!(narrow_to_i8(-128).is_ok());
140 assert!(narrow_to_i8(-129).is_err());
141}
142
143#[inline(always)]
145fn narrow_to_i16(x: i32) -> Result<i16> {
146 use std::i16;
147 if x < i16::MIN as i32 || x > i16::MAX as i32 {
148 Err(Error::TooWide)
149 } else {
150 Ok(x as i16)
151 }
152}
153
154#[test]
155fn verify_narrow_to_i16() {
156 assert!(narrow_to_i16(32767).is_ok());
157 assert!(narrow_to_i16(32768).is_err());
158 assert!(narrow_to_i16(-32768).is_ok());
159 assert!(narrow_to_i16(-32769).is_err());
160}
161
162#[inline(always)]
164fn narrow_to_i24(x: i32) -> Result<i32> {
165 if x < -(1 << 23) || x > (1 << 23) - 1 {
166 Err(Error::TooWide)
167 } else {
168 Ok(x)
169 }
170}
171
172#[test]
173fn verify_narrow_to_i24() {
174 assert!(narrow_to_i24(8_388_607).is_ok());
175 assert!(narrow_to_i24(8_388_608).is_err());
176 assert!(narrow_to_i24(-8_388_608).is_ok());
177 assert!(narrow_to_i24(-8_388_609).is_err());
178}
179
180impl Sample for i8 {
181 fn write<W: io::Write>(self, writer: &mut W, bits: u16) -> Result<()> {
182 self.write_padded(writer, bits, bits / 8)
183 }
184
185 fn write_padded<W: io::Write>(self, writer: &mut W, bits: u16, byte_width: u16) -> Result<()> {
186 match (bits, byte_width) {
187 (8, 1) => Ok(try!(writer.write_u8(u8_from_signed(self)))),
188 (16, 2) => Ok(try!(writer.write_le_i16(self as i16))),
189 (24, 3) => Ok(try!(writer.write_le_i24(self as i32))),
190 (24, 4) => Ok(try!(writer.write_le_i24_4(self as i32))),
191 (32, 4) => Ok(try!(writer.write_le_i32(self as i32))),
192 _ => Err(Error::Unsupported),
193 }
194 }
195
196 #[inline(always)]
197 fn as_i16(self) -> i16 {
198 self as i16
199 }
200
201 fn read<R: io::Read>(reader: &mut R, fmt: SampleFormat, bytes: u16, bits: u16) -> Result<i8> {
202 if fmt != SampleFormat::Int {
203 return Err(Error::InvalidSampleFormat);
204 }
205 match (bytes, bits) {
206 (1, 8) => Ok(try!(reader.read_u8().map(signed_from_u8))),
207 (n, _) if n > 1 => Err(Error::TooWide),
208 _ => Err(Error::Unsupported),
210 }
211 }
212}
213
214impl Sample for i16 {
215 fn write<W: io::Write>(self, writer: &mut W, bits: u16) -> Result<()> {
216 self.write_padded(writer, bits, bits / 8)
217 }
218
219 fn write_padded<W: io::Write>(self, writer: &mut W, bits: u16, byte_width: u16) -> Result<()> {
220 match (bits, byte_width) {
221 (8, 1) => Ok(try!(
222 writer.write_u8(u8_from_signed(try!(narrow_to_i8(self as i32))))
223 )),
224 (16, 2) => Ok(try!(writer.write_le_i16(self))),
225 (24, 3) => Ok(try!(writer.write_le_i24(self as i32))),
226 (24, 4) => Ok(try!(writer.write_le_i24_4(self as i32))),
227 (32, 4) => Ok(try!(writer.write_le_i32(self as i32))),
228 _ => Err(Error::Unsupported),
229 }
230 }
231
232 #[inline(always)]
233 fn as_i16(self) -> i16 {
234 self
235 }
236
237 fn read<R: io::Read>(reader: &mut R, fmt: SampleFormat, bytes: u16, bits: u16) -> Result<i16> {
238 if fmt != SampleFormat::Int {
239 return Err(Error::InvalidSampleFormat);
240 }
241 match (bytes, bits) {
242 (1, 8) => Ok(try!(reader.read_u8().map(signed_from_u8).map(|x| x as i16))),
243 (2, 16) => Ok(try!(reader.read_le_i16())),
244 (n, _) if n > 2 => Err(Error::TooWide),
245 _ => Err(Error::Unsupported),
247 }
248 }
249}
250
251impl Sample for i32 {
252 fn write<W: io::Write>(self, writer: &mut W, bits: u16) -> Result<()> {
253 self.write_padded(writer, bits, bits / 8)
254 }
255
256 fn write_padded<W: io::Write>(self, writer: &mut W, bits: u16, byte_width: u16) -> Result<()> {
257 match (bits, byte_width) {
258 (8, 1) => Ok(try!(
259 writer.write_u8(u8_from_signed(try!(narrow_to_i8(self))))
260 )),
261 (16, 2) => Ok(try!(writer.write_le_i16(try!(narrow_to_i16(self))))),
262 (24, 3) => Ok(try!(writer.write_le_i24(try!(narrow_to_i24(self))))),
263 (24, 4) => Ok(try!(writer.write_le_i24_4(try!(narrow_to_i24(self))))),
264 (32, 4) => Ok(try!(writer.write_le_i32(self))),
265 _ => Err(Error::Unsupported),
266 }
267 }
268
269 #[inline(always)]
270 fn as_i16(self) -> i16 {
271 self as i16
272 }
273
274 fn read<R: io::Read>(reader: &mut R, fmt: SampleFormat, bytes: u16, bits: u16) -> Result<i32> {
275 if fmt != SampleFormat::Int {
276 return Err(Error::InvalidSampleFormat);
277 }
278 match (bytes, bits) {
279 (1, 8) => Ok(try!(reader.read_u8().map(signed_from_u8).map(|x| x as i32))),
280 (2, 16) => Ok(try!(reader.read_le_i16().map(|x| x as i32))),
281 (3, 24) => Ok(try!(reader.read_le_i24())),
282 (4, 24) => Ok(try!(reader.read_le_i24_4())),
283 (4, 32) => Ok(try!(reader.read_le_i32())),
284 (n, _) if n > 4 => Err(Error::TooWide),
285 _ => Err(Error::Unsupported),
287 }
288 }
289}
290
291impl Sample for f32 {
292 fn write<W: io::Write>(self, writer: &mut W, bits: u16) -> Result<()> {
293 self.write_padded(writer, bits, bits / 8)
294 }
295
296 fn write_padded<W: io::Write>(self, writer: &mut W, bits: u16, byte_width: u16) -> Result<()> {
297 match (bits, byte_width) {
298 (32, 4) => Ok(try!(writer.write_le_f32(self))),
299 _ => Err(Error::Unsupported),
300 }
301 }
302
303 fn as_i16(self) -> i16 {
304 panic!("Calling as_i16 with an f32 is invalid.");
305 }
306
307 fn read<R: io::Read>(reader: &mut R, fmt: SampleFormat, bytes: u16, bits: u16) -> Result<Self> {
308 if fmt != SampleFormat::Float {
309 return Err(Error::InvalidSampleFormat);
310 }
311 match (bytes, bits) {
312 (4, 32) => Ok(try!(reader.read_le_f32())),
313 (n, _) if n > 4 => Err(Error::TooWide),
314 _ => Err(Error::Unsupported),
315 }
316 }
317}
318
319#[derive(Clone, Copy, Debug, PartialEq, Eq)]
321pub enum SampleFormat {
322 Float,
327 Int,
329}
330
331#[derive(Clone, Copy, Debug, PartialEq, Eq)]
333pub struct WavSpec {
334 pub channels: u16,
336
337 pub sample_rate: u32,
341
342 pub bits_per_sample: u16,
346
347 pub sample_format: SampleFormat,
349}
350
351#[derive(Clone, Copy)]
353pub struct WavSpecEx {
354 pub spec: WavSpec,
359
360 pub bytes_per_sample: u16,
362}
363
364#[derive(Debug)]
366pub enum Error {
367 IoError(io::Error),
369 FormatError(&'static str),
371 TooWide,
378 UnfinishedSample,
380 Unsupported,
382 InvalidSampleFormat,
392}
393
394impl fmt::Display for Error {
395 fn fmt(&self, formatter: &mut fmt::Formatter) -> result::Result<(), fmt::Error> {
396 match *self {
397 Error::IoError(ref err) => err.fmt(formatter),
398 Error::FormatError(reason) => {
399 try!(formatter.write_str("Ill-formed WAVE file: "));
400 formatter.write_str(reason)
401 }
402 Error::TooWide => {
403 formatter.write_str("The sample has more bits than the destination type.")
404 }
405 Error::UnfinishedSample => {
406 formatter.write_str(
407 "The number of samples written is not a multiple of the number of channels.")
408 }
409 Error::Unsupported => {
410 formatter.write_str("The wave format of the file is not supported.")
411 }
412 Error::InvalidSampleFormat => {
413 formatter.write_str("The sample format differs from the destination format.")
414 }
415 }
416 }
417}
418
419impl error::Error for Error {
420 fn description(&self) -> &str {
421 match *self {
422 Error::IoError(ref err) => err.description(),
423 Error::FormatError(reason) => reason,
424 Error::TooWide => "the sample has more bits than the destination type",
425 Error::UnfinishedSample => "the number of samples written is not a multiple of the number of channels",
426 Error::Unsupported => "the wave format of the file is not supported",
427 Error::InvalidSampleFormat => "the sample format differs from the destination format",
428 }
429 }
430
431 fn cause(&self) -> Option<&error::Error> {
432 match *self {
433 Error::IoError(ref err) => Some(err),
434 Error::FormatError(_) => None,
435 Error::TooWide => None,
436 Error::UnfinishedSample => None,
437 Error::Unsupported => None,
438 Error::InvalidSampleFormat => None,
439 }
440 }
441}
442
443impl From<io::Error> for Error {
444 fn from(err: io::Error) -> Error {
445 Error::IoError(err)
446 }
447}
448
449pub type Result<T> = result::Result<T, Error>;
451
452const KSDATAFORMAT_SUBTYPE_PCM: [u8; 16] = [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80,
463 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71];
464
465const KSDATAFORMAT_SUBTYPE_IEEE_FLOAT: [u8; 16] = [0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
467 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71];
468
469
470impl WavSpec {
471 pub fn into_header_for_infinite_file(self) -> Vec<u8> {
507 let mut c = std::io::Cursor::new(Vec::with_capacity(0x44));
508 {
509 let w = WavWriter::new(&mut c, self);
510 drop(w);
511 }
512 let mut v = c.into_inner();
513
514 v[4] = 0xFF; v[5] = 0xFF; v[6] = 0xFF; v[7] = 0xFF;
516
517 if v[16] == 0x10 {
519 v[0x28] = 0xFF; v[0x29] = 0xFF; v[0x2A] = 0xFF; v[0x2B] = 0xFF;
521 } else if v[16] == 0x28 {
522 v[0x40] = 0xFF; v[0x41] = 0xFF; v[0x42] = 0xFF; v[0x43] = 0xFF;
524 } else {
525 unreachable!()
526 }
527
528 v
529 }
530}
531
532#[test]
533fn write_read_i16_is_lossless() {
534 let mut buffer = io::Cursor::new(Vec::new());
535 let write_spec = WavSpec {
536 channels: 2,
537 sample_rate: 44100,
538 bits_per_sample: 16,
539 sample_format: SampleFormat::Int,
540 };
541
542 {
543 let mut writer = WavWriter::new(&mut buffer, write_spec).unwrap();
544 for s in -1024_i16..1024 {
545 writer.write_sample(s).unwrap();
546 }
547 writer.finalize().unwrap();
548 }
549
550 {
551 buffer.set_position(0);
552 let mut reader = WavReader::new(&mut buffer).unwrap();
553 assert_eq!(write_spec, reader.spec());
554 assert_eq!(reader.len(), 2048);
555 for (expected, read) in (-1024_i16..1024).zip(reader.samples()) {
556 assert_eq!(expected, read.unwrap());
557 }
558 }
559}
560
561#[test]
562fn write_read_i16_via_sample_writer_is_lossless() {
563 let mut buffer = io::Cursor::new(Vec::new());
564 let write_spec = WavSpec {
565 channels: 2,
566 sample_rate: 44100,
567 bits_per_sample: 16,
568 sample_format: SampleFormat::Int,
569 };
570
571 {
572 let mut writer = WavWriter::new(&mut buffer, write_spec).unwrap();
573 {
574 {
575 let mut sample_writer = writer.get_i16_writer(1024);
576 for s in -1024_i16..0 {
577 sample_writer.write_sample(s);
578 }
579 sample_writer.flush().unwrap();
580 }
581
582 {
583 let mut sample_writer = writer.get_i16_writer(1024);
584 for s in 0i16..1024 {
585 unsafe { sample_writer.write_sample_unchecked(s); }
586 }
587 sample_writer.flush().unwrap();
588 }
589 }
590 writer.finalize().unwrap();
591 }
592
593 {
594 buffer.set_position(0);
595 let mut reader = WavReader::new(&mut buffer).unwrap();
596 assert_eq!(write_spec, reader.spec());
597 assert_eq!(reader.len(), 2048);
598 for (expected, read) in (-1024_i16..1024).zip(reader.samples()) {
599 assert_eq!(expected, read.unwrap());
600 }
601 }
602}
603
604#[test]
605fn write_read_i8_is_lossless() {
606 let mut buffer = io::Cursor::new(Vec::new());
607 let write_spec = WavSpec {
608 channels: 16,
609 sample_rate: 48000,
610 bits_per_sample: 8,
611 sample_format: SampleFormat::Int,
612 };
613
614 {
616 let mut writer = WavWriter::new(&mut buffer, write_spec).unwrap();
617 for s in -128_i16..127 + 1 {
619 writer.write_sample(s as i8).unwrap();
620 }
621 writer.finalize().unwrap();
622 }
623
624 {
626 buffer.set_position(0);
627 let mut reader = WavReader::new(&mut buffer).unwrap();
628 assert_eq!(write_spec, reader.spec());
629 assert_eq!(reader.len(), 256);
630 for (expected, read) in (-128_i16..127 + 1).zip(reader.samples()) {
631 assert_eq!(expected, read.unwrap());
632 }
633 }
634}
635
636#[test]
637fn write_read_i24_is_lossless() {
638 let mut buffer = io::Cursor::new(Vec::new());
639 let write_spec = WavSpec {
640 channels: 16,
641 sample_rate: 96000,
642 bits_per_sample: 24,
643 sample_format: SampleFormat::Int,
644 };
645
646 {
648 let mut writer = WavWriter::new(&mut buffer, write_spec).unwrap();
649 for s in -128_i32..127 + 1 {
650 writer.write_sample(s * 256 * 256).unwrap();
651 }
652 writer.finalize().unwrap();
653 }
654
655 {
658 buffer.set_position(0);
659 let mut reader = WavReader::new(&mut buffer).unwrap();
660 assert_eq!(write_spec, reader.spec());
661 assert_eq!(reader.len(), 256);
662 for (expected, read) in (-128_i32..127 + 1)
663 .map(|x| x * 256 * 256)
664 .zip(reader.samples()) {
665 assert_eq!(expected, read.unwrap());
666 }
667 }
668}
669#[test]
670fn write_read_f32_is_lossless() {
671 let mut buffer = io::Cursor::new(Vec::new());
672 let write_spec = WavSpec {
673 channels: 2,
674 sample_rate: 44100,
675 bits_per_sample: 32,
676 sample_format: SampleFormat::Float,
677 };
678
679 {
680 let mut writer = WavWriter::new(&mut buffer, write_spec).unwrap();
681 for s in 1_u32..257 {
682 writer.write_sample(1.0f32 / s as f32).unwrap();
683 }
684 writer.finalize().unwrap();
685 }
686
687 {
688 buffer.set_position(0);
689 let mut reader = WavReader::new(&mut buffer).unwrap();
690 assert_eq!(write_spec, reader.spec());
691 assert_eq!(reader.len(), 256);
692 for (expected, read) in (1..257)
693 .map(|x| 1.0_f32 / x as f32)
694 .zip(reader.samples()) {
695 assert_eq!(expected, read.unwrap());
696 }
697 }
698}
699
700#[test]
701#[should_panic]
702fn no_32_bps_for_float_sample_format_panics() {
703 let mut buffer = io::Cursor::new(Vec::new());
704 let write_spec = WavSpec {
705 channels: 2,
706 sample_rate: 44100,
707 bits_per_sample: 16, sample_format: SampleFormat::Float,
709 };
710
711 WavWriter::new(&mut buffer, write_spec).unwrap();
712}
713
714#[test]
715fn flush_should_produce_valid_file() {
716 use std::mem;
717 use std::io::Seek;
718
719 let mut buffer = io::Cursor::new(Vec::new());
720 let samples = &[2, 4, 5, 7, 11, 13];
721
722 {
723 let spec = WavSpec {
724 channels: 2,
725 sample_rate: 44100,
726 bits_per_sample: 16,
727 sample_format: SampleFormat::Int,
728 };
729 let mut writer = WavWriter::new(&mut buffer, spec).unwrap();
730
731 for &x in samples {
732 writer.write_sample(x).unwrap();
733 }
734
735 writer.flush().unwrap();
737
738 writer.write_sample(17).unwrap();
741 writer.write_sample(19).unwrap();
742
743 mem::forget(writer);
744 }
745
746 buffer.seek(io::SeekFrom::Start(0)).unwrap();
747
748 let mut reader = WavReader::new(&mut buffer).unwrap();
749 let read_samples: Vec<i16> = reader.samples()
750 .map(|r| r.unwrap())
751 .collect();
752
753 assert_eq!(&read_samples[..], &samples[..]);
755}
756
757#[test]
758fn new_append_should_append() {
759 use std::io::Seek;
760
761 let mut buffer = io::Cursor::new(Vec::new());
762 let samples = &[2, 5, 7, 11];
763 let spec = WavSpec {
764 channels: 2,
765 sample_rate: 44100,
766 bits_per_sample: 16,
767 sample_format: SampleFormat::Int,
768 };
769
770 {
772 let mut writer = WavWriter::new(&mut buffer, spec).unwrap();
773 for s in samples { writer.write_sample(*s).unwrap(); }
774 }
775
776 buffer.seek(io::SeekFrom::Start(0)).unwrap();
777
778 {
780 let mut writer = WavWriter::new_append(&mut buffer).unwrap();
781 assert_eq!(writer.spec(), spec);
782 for s in samples { writer.write_sample(*s).unwrap(); }
783 }
784
785 buffer.seek(io::SeekFrom::Start(0)).unwrap();
786
787 let mut reader = WavReader::new(&mut buffer).unwrap();
788 let read_samples: Vec<i16> = reader.samples()
789 .map(|r| r.unwrap())
790 .collect();
791
792 assert_eq!(&read_samples[..], &[2, 5, 7, 11, 2, 5, 7, 11]);
794}
795
796#[test]
797fn new_append_does_not_corrupt_files() {
798 use std::io::Read;
799 use std::fs;
800
801 let sample_files = [
802 "testsamples/pcmwaveformat-16bit-44100Hz-mono-extra.wav",
803 "testsamples/pcmwaveformat-16bit-44100Hz-mono.wav",
804 "testsamples/pcmwaveformat-8bit-44100Hz-mono.wav",
805 "testsamples/pop.wav",
806 "testsamples/waveformatex-16bit-44100Hz-mono-extra.wav",
807 "testsamples/waveformatex-16bit-44100Hz-mono.wav",
808 "testsamples/waveformatex-16bit-44100Hz-stereo.wav",
809 "testsamples/waveformatextensible-24bit-192kHz-mono.wav",
810 "testsamples/waveformatextensible-32bit-48kHz-stereo.wav",
811 "testsamples/nonstandard-01.wav",
812 "testsamples/nonstandard-02.wav",
813 "testsamples/waveformatex-8bit-11025Hz-mono.wav",
814 ];
815
816 for fname in &sample_files {
817 print!("testing {} ... ", fname);
818
819 let mut buffer = Vec::new();
820 let mut f = fs::File::open(fname).unwrap();
821 f.read_to_end(&mut buffer).unwrap();
822
823 let samples_orig: Vec<i32>;
824 let samples_after: Vec<i32>;
825
826 let mut cursor = io::Cursor::new(buffer);
828 {
829 let mut reader = WavReader::new(&mut cursor).unwrap();
830 samples_orig = reader.samples().map(|r| r.unwrap()).collect();
831 }
832 buffer = cursor.into_inner();
833
834 let mut cursor = io::Cursor::new(buffer);
836 {
837 let mut writer = WavWriter::new_append(&mut cursor).unwrap();
838 writer.write_sample(41_i8).unwrap();
839 writer.write_sample(43_i8).unwrap();
840 }
841 buffer = cursor.into_inner();
842
843 {
844 let cursor = io::Cursor::new(buffer);
845 let mut reader = WavReader::new(cursor)
846 .expect("Reading wav failed after append.");
847 samples_after = reader.samples().map(|r| r.unwrap()).collect();
848 }
849
850 assert_eq!(&samples_orig[..], &samples_after[..samples_orig.len()]);
851 assert_eq!(samples_after[samples_after.len() - 2], 41_i32);
852 assert_eq!(samples_after[samples_after.len() - 1], 43_i32);
853
854 println!("ok");
855 }
856}
857
858#[cfg(test)]
859fn assert_contents(fname: &str, expected: &[i16]) {
860 let mut reader = WavReader::open(fname).unwrap();
861 let samples: Vec<i16> = reader.samples().map(|s| s.unwrap()).collect();
862 assert_eq!(&samples[..], expected);
863}
864
865#[test]
866fn append_works_on_files() {
867 use std::fs;
868
869 let spec = WavSpec {
870 channels: 1,
871 sample_rate: 44100,
872 bits_per_sample: 16,
873 sample_format: SampleFormat::Int,
874 };
875
876 let mut writer = WavWriter::create("append.wav", spec).unwrap();
877 writer.write_sample(11_i16).unwrap();
878 writer.write_sample(13_i16).unwrap();
879 writer.write_sample(17_i16).unwrap();
880 writer.finalize().unwrap();
881
882 assert_contents("append.wav", &[11, 13, 17]);
883
884 let len = fs::metadata("append.wav").unwrap().len();
885
886 let mut appender = WavWriter::append("append.wav").unwrap();
887
888 appender.write_sample(19_i16).unwrap();
889 appender.write_sample(23_i16).unwrap();
890 appender.finalize().unwrap();
891
892 assert_eq!(fs::metadata("append.wav").unwrap().len(), len + 4);
895
896 assert_contents("append.wav", &[11, 13, 17, 19, 23]);
897}
898
899#[cfg(test)]
900#[test]
901fn test_into_header_for_infinite_file() {
902 let spec = WavSpec {
903 bits_per_sample: 16,
904 channels: 1,
905 sample_format: SampleFormat::Int,
906 sample_rate: 16000,
907 };
908 let v = spec.into_header_for_infinite_file();
909 assert_eq!(&v[..], &b"RIFF\xFF\xFF\xFF\xFFWAVE\
910fmt \x10\x00\x00\x00\x01\x00\x01\x00\x80\x3e\x00\x00\x00\x7d\x00\x00\x02\x00\x10\x00\
911data\xFF\xFF\xFF\xFF"[..]);
912
913 let spec = WavSpec {
914 bits_per_sample: 16,
915 channels: 10,
916 sample_format: SampleFormat::Int,
917 sample_rate: 16000,
918 };
919 let v = spec.into_header_for_infinite_file();
920 assert_eq!(&v[..], &b"RIFF\xFF\xFF\xFF\xFFWAVE\
921fmt \x28\x00\x00\x00\xfe\xff\x0a\x00\x80\x3e\x00\x00\x00\xe2\x04\x00\
922\x14\x00\x10\x00\x16\x00\x10\x00\xff\x03\x00\x00\x01\x00\x00\x00\
923\x00\x00\x10\x00\x80\x00\x00\xaa\x00\x38\x9b\x71\
924data\xFF\xFF\xFF\xFF"[..]);
925}