diff --git a/Cargo.lock b/Cargo.lock index b1912ea..5fa4022 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "ansi_term" version = "0.11.0" @@ -32,6 +34,7 @@ version = "1.1.0" dependencies = [ "byteorder", "clap", + "dasp_sample", "encoding", "serde_json", "uuid", @@ -58,6 +61,12 @@ dependencies = [ "vec_map", ] +[[package]] +name = "dasp_sample" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c87e182de0887fd5361989c677c4e8f5000cd9491d6d563161a8f3a5519fc7f" + [[package]] name = "encoding" version = "0.2.33" diff --git a/Cargo.toml b/Cargo.toml index 5ed401f..6d96a1f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ keywords = ["audio", "broadcast", "multimedia","smpte"] [dependencies] byteorder = "1.3.4" +dasp_sample = "0.11.0" encoding = "0.2.33" uuid = "0.8.1" clap = "2.33.3" diff --git a/examples/blits.rs b/examples/blits.rs index ad0e67d..fc04a52 100644 --- a/examples/blits.rs +++ b/examples/blits.rs @@ -208,7 +208,7 @@ fn create_blits_file(file_name: &str, sample_rate: u32, bits_per_sample: u16) -> let mut fw = file.audio_frame_writer()?; for frame in frames { let buf = vec![frame.0, frame.1, frame.2, frame.3, frame.4, frame.5]; - fw.write_integer_frames(&buf)?; + fw.write_frames(&buf)?; } fw.end()?; diff --git a/examples/wave-deinter.rs b/examples/wave-deinter.rs index ffa57de..a75b4ea 100644 --- a/examples/wave-deinter.rs +++ b/examples/wave-deinter.rs @@ -4,11 +4,14 @@ //! This program demonstrates splitting a multichannel file into separate monophonic files for each //! individual channel. -use std::io; +use std::io::{Read, Seek}; use std::path::Path; extern crate bwavfile; -use bwavfile::{ChannelDescriptor, ChannelMask, Error, WaveFmt, WaveReader, WaveWriter}; +use bwavfile::{ + ChannelDescriptor, ChannelMask, CommonFormat, Error, Sample, WaveFmt, WaveReader, WaveWriter, + I24, +}; #[macro_use] extern crate clap; @@ -48,17 +51,25 @@ fn name_suffix( } } -fn process_file(infile: &str, delim: &str, numeric_channel_names: bool) -> Result<(), Error> { - let mut input_file = WaveReader::open(infile)?; +fn deinterleave_file( + mut input_file: WaveReader, + input_format: WaveFmt, + settings: Settings, +) -> Result<(), Error> +where + S: Sample, + R: Read + Seek, +{ + let frames_per_read = 4096; let channel_desc = input_file.channels()?; - let input_format = input_file.format()?; + let channel_count = channel_desc.len(); if channel_desc.len() == 1 { println!("Input file in monoaural, exiting."); return Ok(()); } - let infile_path = Path::new(infile); + let infile_path = Path::new(&settings.input_path); let basename = infile_path .file_stem() .expect("Unable to extract file basename") @@ -68,41 +79,91 @@ fn process_file(infile: &str, delim: &str, numeric_channel_names: bool) -> Resul .parent() .expect("Unable to derive parent directory"); - let ouptut_format = - WaveFmt::new_pcm_mono(input_format.sample_rate, input_format.bits_per_sample); - let mut input_wave_reader = input_file.audio_frame_reader()?; - let mut output_wave_writers = channel_desc + let output_block_alignment = input_format.bits_per_sample / 8; + let output_format = WaveFmt { + channel_count: 1, + block_alignment: output_block_alignment, + bytes_per_second: output_block_alignment as u32 * input_format.sample_rate, + ..input_format + }; + let mut reader = input_file.audio_frame_reader()?; + let mut writers = channel_desc .iter() .enumerate() .map(|(n, channel)| { - let suffix = name_suffix(numeric_channel_names, delim, n + 1, channel); + let suffix = name_suffix( + settings.use_numeric_names, + &settings.delimiter, + n + 1, + channel, + ); let outfile_name = output_dir .join(format!("{}{}.wav", basename, suffix)) .into_os_string() .into_string() .unwrap(); - WaveWriter::create(&outfile_name, ouptut_format) + println!("Will create file {}", outfile_name); + + WaveWriter::create(&outfile_name, output_format) .expect("Failed to create new file") .audio_frame_writer() }) .collect::, _>>()?; - let mut buffer = input_format.create_frame_buffer(1); - while input_wave_reader.read_integer_frame(&mut buffer)? > 0 { - for (n, writer) in output_wave_writers.iter_mut().enumerate() { - writer.write_integer_frames(&buffer[n..=n])?; + let mut input_buffer = vec![S::EQUILIBRIUM; frames_per_read * channel_count]; + let mut output_buffer = vec![S::EQUILIBRIUM; frames_per_read]; + + loop { + let frames_read = reader.read_frames(&mut input_buffer)? as usize; + if frames_read == 0 { + break; + } + + output_buffer.resize(frames_read, S::EQUILIBRIUM); + + for (n, writer) in writers.iter_mut().enumerate() { + for (output, input) in output_buffer + .iter_mut() + .zip(input_buffer.iter().skip(n).step_by(channel_count)) + { + *output = *input; + } + writer.write_frames(&output_buffer)?; } } - for writer in output_wave_writers.drain(..) { + for writer in writers.drain(..) { writer.end()?; } Ok(()) } -fn main() -> io::Result<()> { +fn process_file(mut input: WaveReader, settings: Settings) -> Result<(), Error> +where + R: Read + Seek, +{ + let format = input.format()?; + + use CommonFormat::*; + match (format.common_format(), format.bits_per_sample) { + (IntegerPCM, 8) => deinterleave_file::(input, format, settings), + (IntegerPCM, 16) => deinterleave_file::(input, format, settings), + (IntegerPCM, 24) => deinterleave_file::(input, format, settings), + (IntegerPCM, 32) => deinterleave_file::(input, format, settings), + (IeeeFloatPCM, 32) => deinterleave_file::(input, format, settings), + other => panic!("Unsupported format: {:?}", other), + } +} + +struct Settings { + input_path: String, + delimiter: String, + use_numeric_names: bool, +} + +fn main() -> Result<(), Box> { let matches = App::new("wave-deinter") .version(crate_version!()) .author(crate_authors!()) @@ -129,13 +190,12 @@ fn main() -> io::Result<()> { ) .get_matches(); - let delimiter = matches.value_of("channel_delimiter").unwrap(); - let use_numeric_names = matches.is_present("numeric_names"); - let infile = matches.value_of("INPUT").unwrap(); + let settings = Settings { + input_path: matches.value_of("INPUT").unwrap().into(), + delimiter: matches.value_of("channel_delimiter").unwrap().into(), + use_numeric_names: matches.is_present("numeric_names"), + }; - match process_file(infile, delimiter, use_numeric_names) { - Err(Error::IOError(io)) => Err(io), - Err(e) => panic!("Error: {:?}", e), - Ok(()) => Ok(()), - } + process_file(WaveReader::open(&settings.input_path)?, settings)?; + Ok(()) } diff --git a/src/fmt.rs b/src/fmt.rs index be34ff6..bb6cc47 100644 --- a/src/fmt.rs +++ b/src/fmt.rs @@ -1,9 +1,11 @@ -use super::common_format::{CommonFormat, UUID_BFORMAT_PCM, UUID_PCM}; +use crate::common_format::{CommonFormat, UUID_BFORMAT_PCM, UUID_PCM}; +use crate::Sample; + use std::io::Cursor; use uuid::Uuid; use byteorder::LittleEndian; -use byteorder::{ReadBytesExt, WriteBytesExt}; +use byteorder::ReadBytesExt; // Need more test cases for ADMAudioID #[allow(dead_code)] @@ -309,8 +311,8 @@ impl WaveFmt { /// /// This is a conveneince method that creates a `Vec` with /// as many elements as there are channels in the underlying stream. - pub fn create_frame_buffer(&self, length: usize) -> Vec { - vec![0i32; self.channel_count as usize * length] + pub fn create_frame_buffer(&self, length: usize) -> Vec { + vec![S::EQUILIBRIUM; self.channel_count as usize * length] } /// Create a raw byte buffer to hold `length` blocks from a reader or @@ -319,27 +321,6 @@ impl WaveFmt { vec![0u8; self.block_alignment as usize * length] } - /// Write frames into a byte vector - pub fn pack_frames(&self, from_frames: &[i32], into_bytes: &mut [u8]) { - let mut write_cursor = Cursor::new(into_bytes); - - assert!( - from_frames.len() % self.channel_count as usize == 0, - "frames buffer does not contain a number of samples % channel_count == 0" - ); - - for frame in from_frames { - match (self.valid_bits_per_sample(), self.bits_per_sample) { - (0..=8,8) => write_cursor.write_u8((frame + 0x80) as u8 ).unwrap(), // EBU 3285 §A2.2 - (9..=16,16) => write_cursor.write_i16::(*frame as i16).unwrap(), - (10..=24,24) => write_cursor.write_i24::(*frame).unwrap(), - (25..=32,32) => write_cursor.write_i32::(*frame).unwrap(), - (b,_)=> panic!("Unrecognized integer format, bits per sample {}, channels {}, block_alignment {}", - b, self.channel_count, self.block_alignment) - } - } - } - /// Read bytes into frames pub fn unpack_frames(&self, from_bytes: &[u8], into_frames: &mut [i32]) { let mut rdr = Cursor::new(from_bytes); diff --git a/src/lib.rs b/src/lib.rs index 0c87342..8295079 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -52,6 +52,8 @@ mod chunks; mod cue; mod fmt; +mod sample; + mod wavereader; mod wavewriter; @@ -60,5 +62,6 @@ pub use common_format::CommonFormat; pub use cue::Cue; pub use errors::Error; pub use fmt::{ADMAudioID, ChannelDescriptor, ChannelMask, WaveFmt, WaveFmtExtended}; +pub use sample::{Sample, I24}; pub use wavereader::{AudioFrameReader, WaveReader}; pub use wavewriter::{AudioFrameWriter, WaveWriter}; diff --git a/src/sample.rs b/src/sample.rs new file mode 100644 index 0000000..5fed5b6 --- /dev/null +++ b/src/sample.rs @@ -0,0 +1,14 @@ +pub use dasp_sample::I24; + +use dasp_sample::Duplex; + +pub trait Sample: + dasp_sample::Sample + Duplex + Duplex + Duplex + Duplex + Duplex +{ +} + +impl Sample for u8 {} +impl Sample for i16 {} +impl Sample for I24 {} +impl Sample for i32 {} +impl Sample for f32 {} diff --git a/src/wavereader.rs b/src/wavereader.rs index 73989b2..f0e3320 100644 --- a/src/wavereader.rs +++ b/src/wavereader.rs @@ -18,11 +18,13 @@ use super::fourcc::{ IXML_SIG, JUNK_SIG, LIST_SIG, }; use super::parser::Parser; -use super::CommonFormat; +use super::{CommonFormat, Sample, I24}; use byteorder::LittleEndian; use byteorder::ReadBytesExt; +use dasp_sample::Sample as _; // Expose to_sample() + /// Read audio frames /// /// The inner reader is interpreted as a raw audio data @@ -88,78 +90,79 @@ impl AudioFrameReader { Ok((seek_result - self.start) / self.format.block_alignment as u64) } - /// Read a frame + /// Reads frames from the file into the provided buffer /// - /// A single frame is read from the audio stream and the read location - /// is advanced one frame. + /// The function will attempt to fill the buffer, but will stop without error when the end of + /// the file is reached. /// - /// Regardless of the number of bits in the audio sample, this method - /// always writes `i32` samples back to the buffer. These samples are - /// written back "right-aligned" so samples that are shorter than i32 - /// will leave the MSB bits empty. + /// The reader will convert from the file's sample type into the buffer's sample type. + /// Note that no dithering will be applied during sample type conversion, + /// if dithering is required then it will need to be applied manually. /// - /// For example: A full-code sample in 16 bit (0xFFFF) will be written - /// back to the buffer as 0x0000FFFF. - /// - /// - /// ### Panics - /// - /// The `buffer` must have a number of elements equal to the number of - /// channels and this method will panic if this is not the case. - pub fn read_integer_frame(&mut self, buffer: &mut [i32]) -> Result { + /// The return value is the number of frames read into the buffer. + pub fn read_frames(&mut self, buffer: &mut [S]) -> Result + where + S: Sample, + { + use CommonFormat::*; + + let channel_count = self.format.channel_count as usize; + let common_format = self.format.common_format(); + let bits_per_sample = self.format.bits_per_sample; + assert!( - buffer.len() as u16 == self.format.channel_count, - "read_integer_frame was called with a mis-sized buffer, expected {}, was {}", - self.format.channel_count, + buffer.len() % channel_count == 0, + "read_frames was called with a mis-sized buffer, expected a multiple of {}, was {}", + channel_count, buffer.len() ); - let framed_bits_per_sample = self.format.block_alignment * 8 / self.format.channel_count; + let position = self.inner.stream_position()? - self.start; + let frames_requested = (buffer.len() / channel_count) as u64; + let bytes_per_frame = self.format.block_alignment as u64; + let frames_remaining = (self.length - position) / bytes_per_frame; + let frames_to_read = frames_requested.min(frames_remaining); + let samples_to_read = frames_to_read as usize * channel_count; - let tell = self.inner.stream_position()?; + match (common_format, bits_per_sample) { + (IntegerPCM, 8) => read_into_buffer(samples_to_read, buffer, || { + Ok(self.inner.read_u8()?.to_sample()) + }), + (IntegerPCM, 16) => read_into_buffer(samples_to_read, buffer, || { + Ok(self.inner.read_i16::()?.to_sample()) + }), + (IntegerPCM, 24) => read_into_buffer(samples_to_read, buffer, || { + Ok(I24::from(self.inner.read_i24::()?).to_sample()) + }), + (IntegerPCM, 32) => read_into_buffer(samples_to_read, buffer, || { + Ok(self.inner.read_i32::()?.to_sample()) + }), + (IeeeFloatPCM, 32) => read_into_buffer(samples_to_read, buffer, || { + Ok(self.inner.read_f32::()?.to_sample()) + }), + (_, _) => panic!( + "Unsupported format, bits per sample {}, channels {}, sample format: {:?}", + bits_per_sample, channel_count, common_format + ), + }?; - if (tell - self.start) < self.length { - for sample in buffer.iter_mut().take(self.format.channel_count as usize) { - *sample = match (self.format.bits_per_sample, framed_bits_per_sample) { - (0..=8,8) => self.inner.read_u8()? as i32 - 0x80_i32, // EBU 3285 §A2.2 - (9..=16,16) => self.inner.read_i16::()? as i32, - (10..=24,24) => self.inner.read_i24::()?, - (25..=32,32) => self.inner.read_i32::()?, - (b,_)=> panic!("Unrecognized integer format, bits per sample {}, channels {}, block_alignment {}", - b, self.format.channel_count, self.format.block_alignment) - } - } - Ok(1) - } else { - Ok(0) - } + Ok(frames_to_read) + } +} + +fn read_into_buffer( + sample_count: usize, + buffer: &mut [S], + mut read_fn: F, +) -> Result<(), Error> +where + F: FnMut() -> Result, +{ + for output in buffer.iter_mut().take(sample_count) { + *output = read_fn()?; } - pub fn read_float_frame(&mut self, buffer: &mut [f32]) -> Result { - assert!( - buffer.len() as u16 == self.format.channel_count, - "read_float_frame was called with a mis-sized buffer, expected {}, was {}", - self.format.channel_count, - buffer.len() - ); - - let framed_bits_per_sample = self.format.block_alignment * 8 / self.format.channel_count; - - let tell = self.inner.stream_position()?; - - if (tell - self.start) < self.length { - for sample in buffer.iter_mut().take(self.format.channel_count as usize) { - *sample = match (self.format.bits_per_sample, framed_bits_per_sample) { - (25..=32,32) => self.inner.read_f32::()?, - (b,_)=> panic!("Unrecognized integer format, bits per sample {}, channels {}, block_alignment {}", - b, self.format.channel_count, self.format.block_alignment) - } - } - Ok(1) - } else { - Ok(0) - } - } + Ok(()) } /// Wave, Broadcast-WAV and RF64/BW64 parser/reader. @@ -173,9 +176,9 @@ impl AudioFrameReader { /// assert_eq!(format.channel_count, 1); /// /// let mut frame_reader = r.audio_frame_reader().unwrap(); -/// let mut buffer = format.create_frame_buffer(1); +/// let mut buffer = format.create_frame_buffer::(1); /// -/// let read = frame_reader.read_integer_frame(&mut buffer).unwrap(); +/// let read = frame_reader.read_frames(&mut buffer).unwrap(); /// /// assert_eq!(buffer, [0i32]); /// assert_eq!(read, 1); diff --git a/src/wavewriter.rs b/src/wavewriter.rs index 2e04779..c3aa0c5 100644 --- a/src/wavewriter.rs +++ b/src/wavewriter.rs @@ -2,12 +2,14 @@ use std::fs::File; use std::io::{BufWriter, Cursor, Seek, SeekFrom, Write}; use std::path::Path; +use crate::CommonFormat; + use super::fmt::WaveFmt; use super::fourcc::{ FourCC, WriteFourCC, AXML_SIG, BEXT_SIG, DATA_SIG, DS64_SIG, ELM1_SIG, FMT__SIG, IXML_SIG, JUNK_SIG, RF64_SIG, RIFF_SIG, WAVE_SIG, }; -use super::Error; +use super::{Error, Sample, I24}; //use super::common_format::CommonFormat; use super::bext::Bext; use super::chunks::WriteBWaveChunks; @@ -33,28 +35,67 @@ where AudioFrameWriter { inner } } - fn write_integer_frames_to_buffer(&self, from_frames: &[i32], to_buffer: &mut [u8]) { - assert!( - from_frames.len() % self.inner.inner.format.channel_count as usize == 0, - "frames buffer does not contain a number of samples % channel_count == 0" - ); - self.inner.inner.format.pack_frames(from_frames, to_buffer); - } - /// Write interleaved samples in `buffer` /// /// # Panics /// /// This function will panic if `buffer.len()` modulo the Wave file's channel count /// is not zero. - pub fn write_integer_frames(&mut self, buffer: &[i32]) -> Result { + pub fn write_frames(&mut self, buffer: &[S]) -> Result + where + S: Sample, + { + let format = &self.inner.inner.format; + let channel_count = format.channel_count as usize; + + assert!( + buffer.len() % channel_count == 0, + "frames buffer does not contain a number of samples % channel_count == 0" + ); + let mut write_buffer = self .inner .inner .format - .create_raw_buffer(buffer.len() / self.inner.inner.format.channel_count as usize); + .create_raw_buffer(buffer.len() / channel_count); - self.write_integer_frames_to_buffer(buffer, &mut write_buffer); + let into_bytes: &mut [u8] = &mut write_buffer; + let mut write_cursor = Cursor::new(into_bytes); + + let common_format = format.common_format(); + let bits_per_sample = format.bits_per_sample; + + match (common_format, bits_per_sample) { + (_, 8) => { + for sample in buffer { + write_cursor.write_u8(sample.to_sample())? + } + } + (_, 16) => { + for sample in buffer { + write_cursor.write_i16::(sample.to_sample())? + } + } + (_, 24) => { + for sample in buffer { + write_cursor.write_i24::(sample.to_sample::().inner())? + } + } + (CommonFormat::IntegerPCM, 32) => { + for sample in buffer { + write_cursor.write_i32::(sample.to_sample())? + } + } + (CommonFormat::IeeeFloatPCM, 32) => { + for sample in buffer { + write_cursor.write_f32::(sample.to_sample())? + } + } + (_, _) => panic!( + "Unrecognized format, bits per sample {}, channels {}, sample format {:?}", + bits_per_sample, channel_count, common_format + ), + } self.inner.write_all(&write_buffer)?; Ok(write_buffer.len() as u64 / self.inner.inner.format.channel_count as u64) @@ -194,9 +235,9 @@ where /// /// let mut frame_writer = w.audio_frame_writer().unwrap(); /// -/// frame_writer.write_integer_frames(&[0i32]).unwrap(); -/// frame_writer.write_integer_frames(&[0i32]).unwrap(); -/// frame_writer.write_integer_frames(&[0i32]).unwrap(); +/// frame_writer.write_frames(&[0i32]).unwrap(); +/// frame_writer.write_frames(&[0i32]).unwrap(); +/// frame_writer.write_frames(&[0i32]).unwrap(); /// frame_writer.end().unwrap(); /// ``` /// @@ -432,9 +473,9 @@ fn test_write_audio() { let mut frame_writer = w.audio_frame_writer().unwrap(); - frame_writer.write_integer_frames(&[0i32]).unwrap(); - frame_writer.write_integer_frames(&[0i32]).unwrap(); - frame_writer.write_integer_frames(&[0i32]).unwrap(); + frame_writer.write_frames(&[0i32]).unwrap(); + frame_writer.write_frames(&[0i32]).unwrap(); + frame_writer.write_frames(&[0i32]).unwrap(); frame_writer.end().unwrap(); @@ -500,14 +541,14 @@ fn test_write_bext() { let mut frame_writer = w.audio_frame_writer().unwrap(); - frame_writer.write_integer_frames(&[0i32]).unwrap(); - frame_writer.write_integer_frames(&[0i32]).unwrap(); - frame_writer.write_integer_frames(&[0i32]).unwrap(); + frame_writer.write_frames(&[0i32]).unwrap(); + frame_writer.write_frames(&[0i32]).unwrap(); + frame_writer.write_frames(&[0i32]).unwrap(); frame_writer.end().unwrap(); } -// NOTE! This test of RF64 writing takes several minutes to complete. +// NOTE! This test of RF64 writing takes several minutes to complete in debug builds #[test] fn test_create_rf64() { use super::fourcc::ReadFourCC; @@ -526,7 +567,7 @@ fn test_create_rf64() { let mut af = w.audio_frame_writer().unwrap(); for _ in 0..(four_and_a_half_hours_of_frames * format.channel_count as u64 / buflen) { - af.write_integer_frames(&buf).unwrap(); + af.write_frames(&buf).unwrap(); } af.end().unwrap(); diff --git a/tests/integration_test.rs b/tests/integration_test.rs index 85bd525..ae49def 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -3,6 +3,7 @@ extern crate bwavfile; use bwavfile::ChannelMask; use bwavfile::Error; use bwavfile::WaveReader; +use bwavfile::I24; #[test] fn test_open() { @@ -80,16 +81,16 @@ fn test_read() { let path = "tests/media/audacity_16bit.wav"; let mut w = WaveReader::open(path).expect("Failure opening test file"); - let mut buffer = w.format().unwrap().create_frame_buffer(1); + let mut buffer = w.format().unwrap().create_frame_buffer::(1); let mut reader = w.audio_frame_reader().unwrap(); - assert_eq!(reader.read_integer_frame(&mut buffer).unwrap(), 1); - assert_eq!(buffer[0], -2823_i32); - assert_eq!(reader.read_integer_frame(&mut buffer).unwrap(), 1); - assert_eq!(buffer[0], 2012_i32); - assert_eq!(reader.read_integer_frame(&mut buffer).unwrap(), 1); - assert_eq!(buffer[0], 4524_i32); + assert_eq!(reader.read_frames(&mut buffer).unwrap(), 1); + assert_eq!(buffer[0], -2823_i16); + assert_eq!(reader.read_frames(&mut buffer).unwrap(), 1); + assert_eq!(buffer[0], 2012_i16); + assert_eq!(reader.read_frames(&mut buffer).unwrap(), 1); + assert_eq!(buffer[0], 4524_i16); } #[test] @@ -97,21 +98,21 @@ fn test_locate_multichannel_read() { let path = "tests/media/ff_pink.wav"; let mut w = WaveReader::open(path).expect("Failure opening test file"); - let mut buffer = w.format().unwrap().create_frame_buffer(1); + let mut buffer = w.format().unwrap().create_frame_buffer::(1); let mut reader = w.audio_frame_reader().unwrap(); - assert_eq!(reader.read_integer_frame(&mut buffer).unwrap(), 1); - assert_eq!(buffer[0], 332702_i32); - assert_eq!(buffer[1], 3258791_i32); - assert_eq!(reader.read_integer_frame(&mut buffer).unwrap(), 1); - assert_eq!(buffer[0], -258742_i32); // 0x800000 = 8388608 // 8129866 - 8388608 - assert_eq!(buffer[1], 0x0D7EF9_i32); + assert_eq!(reader.read_frames(&mut buffer).unwrap(), 1); + assert_eq!(buffer[0], I24::from(332702)); + assert_eq!(buffer[1], I24::from(3258791)); + assert_eq!(reader.read_frames(&mut buffer).unwrap(), 1); + assert_eq!(buffer[0], I24::from(-258742)); // 0x800000 = 8388608 // 8129866 - 8388608 + assert_eq!(buffer[1], I24::from(0x0D7EF9)); assert_eq!(reader.locate(100).unwrap(), 100); - assert_eq!(reader.read_integer_frame(&mut buffer).unwrap(), 1); - assert_eq!(buffer[0], 0x109422_i32); - assert_eq!(buffer[1], -698901_i32); // 7689707 - 8388608 + assert_eq!(reader.read_frames(&mut buffer).unwrap(), 1); + assert_eq!(buffer[0], I24::from(0x109422)); + assert_eq!(buffer[1], I24::from(-698901)); // 7689707 - 8388608 } #[test]