From 896f659226bf84c0926302176a6fc7c3037bbc31 Mon Sep 17 00:00:00 2001 From: Jamie Hardt Date: Tue, 10 Dec 2024 16:52:00 -0800 Subject: [PATCH] Added channel_bitmask to WavSpec struct Added field, implemented parsing, updated tests. --- examples/append.rs | 1 + examples/wavstdout.rs | 1 + src/lib.rs | 17 +++++++++++++++++ src/read.rs | 3 ++- src/write.rs | 6 +++++- 5 files changed, 26 insertions(+), 2 deletions(-) diff --git a/examples/append.rs b/examples/append.rs index b5fbdc4..47b7d18 100644 --- a/examples/append.rs +++ b/examples/append.rs @@ -25,6 +25,7 @@ fn main() { sample_rate: 44100, bits_per_sample: 16, sample_format: hound::SampleFormat::Int, + channel_bitmask: None, }; let path: &Path = "sine.wav".as_ref(); diff --git a/examples/wavstdout.rs b/examples/wavstdout.rs index 475a44b..74dabc1 100644 --- a/examples/wavstdout.rs +++ b/examples/wavstdout.rs @@ -11,6 +11,7 @@ fn main() { channels: 1, sample_format: hound::SampleFormat::Int, sample_rate: 16000, + channel_bitmask: None, }; let v = spec.into_header_for_infinite_file(); diff --git a/src/lib.rs b/src/lib.rs index 244d4ea..efd187a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,6 +28,7 @@ //! sample_rate: 44100, //! bits_per_sample: 16, //! sample_format: hound::SampleFormat::Int, +//! channel_bitmask: None, //! }; //! let mut writer = hound::WavWriter::create("sine.wav", spec).unwrap(); //! for t in (0 .. 44100).map(|x| x as f32 / 44100.0) { @@ -360,6 +361,9 @@ pub struct WavSpec { /// Whether the wav's samples are float or integer values. pub sample_format: SampleFormat, + + /// The channel bitmask for this wav, if present. + pub channel_bitmask: Option } /// The error type for operations on `WavReader` and `WavWriter`. @@ -504,6 +508,7 @@ impl WavSpec { /// channels: 1, /// sample_format: hound::SampleFormat::Int, /// sample_rate: 16000, + /// channel_bitmask: None, /// }; /// /// let v = spec.into_header_for_infinite_file(); @@ -553,6 +558,7 @@ fn write_read_i16_is_lossless() { sample_rate: 44100, bits_per_sample: 16, sample_format: SampleFormat::Int, + channel_bitmask: None, }; { @@ -582,6 +588,7 @@ fn write_read_i16_via_sample_writer_is_lossless() { sample_rate: 44100, bits_per_sample: 16, sample_format: SampleFormat::Int, + channel_bitmask: None, }; { @@ -625,6 +632,7 @@ fn write_read_i8_is_lossless() { sample_rate: 48000, bits_per_sample: 8, sample_format: SampleFormat::Int, + channel_bitmask: Some(65535u32), }; // Write `i8` samples. @@ -657,6 +665,7 @@ fn write_read_i24_is_lossless() { sample_rate: 96000, bits_per_sample: 24, sample_format: SampleFormat::Int, + channel_bitmask: Some(65535u32), }; // Write `i32` samples, but with at most 24 bits per sample. @@ -690,6 +699,7 @@ fn write_read_f32_is_lossless() { sample_rate: 44100, bits_per_sample: 32, sample_format: SampleFormat::Float, + channel_bitmask: Some(0b11), }; { @@ -722,6 +732,7 @@ fn no_32_bps_for_float_sample_format_panics() { sample_rate: 44100, bits_per_sample: 16, // will panic, because value must be 32 for floating point sample_format: SampleFormat::Float, + channel_bitmask: None, }; WavWriter::new(&mut buffer, write_spec).unwrap(); @@ -741,6 +752,7 @@ fn flush_should_produce_valid_file() { sample_rate: 44100, bits_per_sample: 16, sample_format: SampleFormat::Int, + channel_bitmask: None, }; let mut writer = WavWriter::new(&mut buffer, spec).unwrap(); @@ -781,6 +793,7 @@ fn new_append_should_append() { sample_rate: 44100, bits_per_sample: 16, sample_format: SampleFormat::Int, + channel_bitmask: None, }; // Write initial file. @@ -887,6 +900,7 @@ fn append_works_on_files() { sample_rate: 44100, bits_per_sample: 16, sample_format: SampleFormat::Int, + channel_bitmask: None, }; let mut writer = WavWriter::create("append.wav", spec).unwrap(); @@ -960,6 +974,7 @@ fn write_read_chunks_is_lossless() { sample_rate: 44100, bits_per_sample: 16, sample_format: SampleFormat::Int, + channel_bitmask: None, }, bytes_per_sample: 2, }; @@ -1007,6 +1022,7 @@ fn test_into_header_for_infinite_file() { channels: 1, sample_format: SampleFormat::Int, sample_rate: 16000, + channel_bitmask: None, }; let v = spec.into_header_for_infinite_file(); assert_eq!(&v[..], &b"RIFF\xFF\xFF\xFF\xFFWAVE\ @@ -1018,6 +1034,7 @@ data\xFF\xFF\xFF\xFF"[..]); channels: 10, sample_format: SampleFormat::Int, sample_rate: 16000, + channel_bitmask: None, }; let v = spec.into_header_for_infinite_file(); assert_eq!(&v[..], &b"RIFF\xFF\xFF\xFF\xFFWAVE\ diff --git a/src/read.rs b/src/read.rs index 7024947..4d8c90e 100644 --- a/src/read.rs +++ b/src/read.rs @@ -518,6 +518,7 @@ impl ChunksReader { sample_rate: n_samples_per_sec, bits_per_sample: bits_per_sample, sample_format: SampleFormat::Int, + channel_bitmask: None, }; // The different format tag definitions can be found in mmreg.h that is @@ -647,7 +648,7 @@ impl ChunksReader { // } WAVEFORMATEXTENSIBLE, *PWAVEFORMATEXTENSIBLE; // ``` let valid_bits_per_sample = try!(self.reader.read_le_u16()); - let _channel_mask = try!(self.reader.read_le_u32()); // Not used for now. + spec.channel_bitmask = Some(try!(self.reader.read_le_u32())); // Not used for now. let mut subformat = [0u8; 16]; try!(self.reader.read_into(&mut subformat)); diff --git a/src/write.rs b/src/write.rs index db04287..53dc704 100644 --- a/src/write.rs +++ b/src/write.rs @@ -990,6 +990,7 @@ fn short_write_should_signal_error() { sample_rate: 48000, bits_per_sample: 8, sample_format: SampleFormat::Int, + channel_bitmask: None, }; // Deliberately write one sample less than 17 * 5. @@ -1014,6 +1015,7 @@ fn wide_write_should_signal_error() { sample_rate: 44100, bits_per_sample: 8, sample_format: SampleFormat::Int, + channel_bitmask: None, }; { let mut writer = WavWriter::new(&mut buffer, spec8).unwrap(); @@ -1024,7 +1026,8 @@ fn wide_write_should_signal_error() { assert!(writer.write_sample(128_i32).is_err()); } - let spec16 = WavSpec { bits_per_sample: 16, ..spec8 }; + let wav_spec = WavSpec { bits_per_sample: 16, ..spec8 }; + let spec16 = wav_spec; { let mut writer = WavWriter::new(&mut buffer, spec16).unwrap(); assert!(writer.write_sample(32767_i16).is_ok()); @@ -1052,6 +1055,7 @@ fn s24_wav_write() { sample_rate: 48000, bits_per_sample: 24, sample_format: SampleFormat::Int, + channel_bitmask: None, }, bytes_per_sample: 4, };