Skip to content

Commit da2e6f6

Browse files
committed
Merge branch 'master' of https://github.com/iluvcapra/bwavfile
2 parents 72d3c4a + eff4fe1 commit da2e6f6

16 files changed

+450
-362
lines changed

Cargo.lock

+9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "bwavfile"
3-
version = "1.1.0"
4-
authors = ["Jamie Hardt <[email protected]>"]
3+
version = "2.0.0"
4+
authors = ["Jamie Hardt <[email protected]>", "Ian Hobson <[email protected]>"]
55
edition = "2018"
66
license = "MIT"
77
description = "Rust Wave File Reader/Writer with Broadcast-WAV, MBWF and RF64 Support"
@@ -15,6 +15,7 @@ keywords = ["audio", "broadcast", "multimedia","smpte"]
1515

1616
[dependencies]
1717
byteorder = "1.3.4"
18+
dasp_sample = "0.11.0"
1819
encoding = "0.2.33"
1920
uuid = "0.8.1"
2021
clap = "2.33.3"

examples/blits.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ fn create_blits_file(file_name: &str, sample_rate: u32, bits_per_sample: u16) ->
208208
let mut fw = file.audio_frame_writer()?;
209209
for frame in frames {
210210
let buf = vec![frame.0, frame.1, frame.2, frame.3, frame.4, frame.5];
211-
fw.write_integer_frames(&buf)?;
211+
fw.write_frames(&buf)?;
212212
}
213213
fw.end()?;
214214

examples/wave-deinter.rs

+103-40
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
1-
//! wave-inter.rs
1+
//! wave-deinter.rs
22
//! (c) 2021 Jamie Hardt. All rights reserved.
33
//!
4-
//! This program demonstrats combining several wave files into a single
5-
//! polyphonic wave file.
4+
//! This program demonstrates splitting a multichannel file into separate monophonic files for each
5+
//! individual channel.
66
7-
use std::io;
7+
use std::io::{Read, Seek};
88
use std::path::Path;
99

1010
extern crate bwavfile;
11-
use bwavfile::{ChannelDescriptor, ChannelMask, Error, WaveFmt, WaveReader, WaveWriter};
11+
use bwavfile::{
12+
ChannelDescriptor, ChannelMask, CommonFormat, Error, Sample, WaveFmt, WaveReader, WaveWriter,
13+
I24,
14+
};
1215

1316
#[macro_use]
1417
extern crate clap;
@@ -48,17 +51,25 @@ fn name_suffix(
4851
}
4952
}
5053

51-
fn process_file(infile: &str, delim: &str, numeric_channel_names: bool) -> Result<(), Error> {
52-
let mut input_file = WaveReader::open(infile)?;
54+
fn deinterleave_file<S, R>(
55+
mut input_file: WaveReader<R>,
56+
input_format: WaveFmt,
57+
settings: Settings,
58+
) -> Result<(), Error>
59+
where
60+
S: Sample,
61+
R: Read + Seek,
62+
{
63+
let frames_per_read = 4096;
5364
let channel_desc = input_file.channels()?;
54-
let input_format = input_file.format()?;
65+
let channel_count = channel_desc.len();
5566

5667
if channel_desc.len() == 1 {
5768
println!("Input file in monoaural, exiting.");
5869
return Ok(());
5970
}
6071

61-
let infile_path = Path::new(infile);
72+
let infile_path = Path::new(&settings.input_path);
6273
let basename = infile_path
6374
.file_stem()
6475
.expect("Unable to extract file basename")
@@ -68,38 +79,91 @@ fn process_file(infile: &str, delim: &str, numeric_channel_names: bool) -> Resul
6879
.parent()
6980
.expect("Unable to derive parent directory");
7081

71-
let ouptut_format =
72-
WaveFmt::new_pcm_mono(input_format.sample_rate, input_format.bits_per_sample);
73-
let mut input_wave_reader = input_file.audio_frame_reader()?;
74-
75-
for (n, channel) in channel_desc.iter().enumerate() {
76-
let suffix = name_suffix(numeric_channel_names, delim, n + 1, channel);
77-
let outfile_name = output_dir
78-
.join(format!("{}{}.wav", basename, suffix))
79-
.into_os_string()
80-
.into_string()
81-
.unwrap();
82-
83-
println!("Will create file {}", outfile_name);
84-
85-
let output_file =
86-
WaveWriter::create(&outfile_name, ouptut_format).expect("Failed to create new file");
82+
let output_block_alignment = input_format.bits_per_sample / 8;
83+
let output_format = WaveFmt {
84+
channel_count: 1,
85+
block_alignment: output_block_alignment,
86+
bytes_per_second: output_block_alignment as u32 * input_format.sample_rate,
87+
..input_format
88+
};
89+
let mut reader = input_file.audio_frame_reader()?;
90+
let mut writers = channel_desc
91+
.iter()
92+
.enumerate()
93+
.map(|(n, channel)| {
94+
let suffix = name_suffix(
95+
settings.use_numeric_names,
96+
&settings.delimiter,
97+
n + 1,
98+
channel,
99+
);
100+
let outfile_name = output_dir
101+
.join(format!("{}{}.wav", basename, suffix))
102+
.into_os_string()
103+
.into_string()
104+
.unwrap();
105+
106+
println!("Will create file {}", outfile_name);
107+
108+
WaveWriter::create(&outfile_name, output_format)
109+
.expect("Failed to create new file")
110+
.audio_frame_writer()
111+
})
112+
.collect::<Result<Vec<_>, _>>()?;
113+
114+
let mut input_buffer = vec![S::EQUILIBRIUM; frames_per_read * channel_count];
115+
let mut output_buffer = vec![S::EQUILIBRIUM; frames_per_read];
116+
117+
loop {
118+
let frames_read = reader.read_frames(&mut input_buffer)? as usize;
119+
if frames_read == 0 {
120+
break;
121+
}
87122

88-
let mut output_wave_writer = output_file.audio_frame_writer()?;
89-
let mut buffer = input_format.create_frame_buffer(1);
123+
output_buffer.resize(frames_read, S::EQUILIBRIUM);
90124

91-
while input_wave_reader.read_integer_frame(&mut buffer)? > 0 {
92-
output_wave_writer.write_integer_frames(&buffer[n..=n])?;
125+
for (n, writer) in writers.iter_mut().enumerate() {
126+
for (output, input) in output_buffer
127+
.iter_mut()
128+
.zip(input_buffer.iter().skip(n).step_by(channel_count))
129+
{
130+
*output = *input;
131+
}
132+
writer.write_frames(&output_buffer)?;
93133
}
134+
}
94135

95-
output_wave_writer.end()?;
96-
input_wave_reader.locate(0)?;
136+
for writer in writers.drain(..) {
137+
writer.end()?;
97138
}
98139

99140
Ok(())
100141
}
101142

102-
fn main() -> io::Result<()> {
143+
fn process_file<R>(mut input: WaveReader<R>, settings: Settings) -> Result<(), Error>
144+
where
145+
R: Read + Seek,
146+
{
147+
let format = input.format()?;
148+
149+
use CommonFormat::*;
150+
match (format.common_format(), format.bits_per_sample) {
151+
(IntegerPCM, 8) => deinterleave_file::<u8, R>(input, format, settings),
152+
(IntegerPCM, 16) => deinterleave_file::<i16, R>(input, format, settings),
153+
(IntegerPCM, 24) => deinterleave_file::<I24, R>(input, format, settings),
154+
(IntegerPCM, 32) => deinterleave_file::<i32, R>(input, format, settings),
155+
(IeeeFloatPCM, 32) => deinterleave_file::<f32, R>(input, format, settings),
156+
other => panic!("Unsupported format: {:?}", other),
157+
}
158+
}
159+
160+
struct Settings {
161+
input_path: String,
162+
delimiter: String,
163+
use_numeric_names: bool,
164+
}
165+
166+
fn main() -> Result<(), Box<dyn std::error::Error>> {
103167
let matches = App::new("wave-deinter")
104168
.version(crate_version!())
105169
.author(crate_authors!())
@@ -126,13 +190,12 @@ fn main() -> io::Result<()> {
126190
)
127191
.get_matches();
128192

129-
let delimiter = matches.value_of("channel_delimiter").unwrap();
130-
let use_numeric_names = matches.is_present("numeric_names");
131-
let infile = matches.value_of("INPUT").unwrap();
193+
let settings = Settings {
194+
input_path: matches.value_of("INPUT").unwrap().into(),
195+
delimiter: matches.value_of("channel_delimiter").unwrap().into(),
196+
use_numeric_names: matches.is_present("numeric_names"),
197+
};
132198

133-
match process_file(infile, delimiter, use_numeric_names) {
134-
Err(Error::IOError(io)) => Err(io),
135-
Err(e) => panic!("Error: {:?}", e),
136-
Ok(()) => Ok(()),
137-
}
199+
process_file(WaveReader::open(&settings.input_path)?, settings)?;
200+
Ok(())
138201
}

src/bext.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
pub type LU = f32;
2+
#[allow(clippy::upper_case_acronyms)]
23
pub type LUFS = f32;
34
pub type Decibels = f32;
45

src/chunks.rs

+8-20
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,7 @@ pub trait ReadBWaveChunks: Read {
2121

2222
pub trait WriteBWaveChunks: Write {
2323
fn write_wave_fmt(&mut self, format: &WaveFmt) -> Result<(), ParserError>;
24-
fn write_bext_string_field(
25-
&mut self,
26-
string: &String,
27-
length: usize,
28-
) -> Result<(), ParserError>;
24+
fn write_bext_string_field(&mut self, string: &str, length: usize) -> Result<(), ParserError>;
2925
fn write_bext(&mut self, bext: &Bext) -> Result<(), ParserError>;
3026
}
3127

@@ -34,7 +30,7 @@ where
3430
T: Write,
3531
{
3632
fn write_wave_fmt(&mut self, format: &WaveFmt) -> Result<(), ParserError> {
37-
self.write_u16::<LittleEndian>(format.tag as u16)?;
33+
self.write_u16::<LittleEndian>(format.tag)?;
3834
self.write_u16::<LittleEndian>(format.channel_count)?;
3935
self.write_u32::<LittleEndian>(format.sample_rate)?;
4036
self.write_u32::<LittleEndian>(format.bytes_per_second)?;
@@ -46,18 +42,14 @@ where
4642
self.write_u16::<LittleEndian>(ext.valid_bits_per_sample)?;
4743
self.write_u32::<LittleEndian>(ext.channel_mask)?;
4844
let uuid = ext.type_guid.as_bytes();
49-
self.write(uuid)?;
45+
self.write_all(uuid)?;
5046
}
5147
Ok(())
5248
}
5349

54-
fn write_bext_string_field(
55-
&mut self,
56-
string: &String,
57-
length: usize,
58-
) -> Result<(), ParserError> {
50+
fn write_bext_string_field(&mut self, string: &str, length: usize) -> Result<(), ParserError> {
5951
let mut buf = ASCII
60-
.encode(&string, EncoderTrap::Ignore)
52+
.encode(string, EncoderTrap::Ignore)
6153
.expect("Error encoding text");
6254
buf.truncate(length);
6355
let filler_length = length - buf.len();
@@ -142,12 +134,8 @@ where
142134

143135
fn read_bext_string_field(&mut self, length: usize) -> Result<String, ParserError> {
144136
let mut buffer: Vec<u8> = vec![0; length];
145-
self.read(&mut buffer)?;
146-
let trimmed: Vec<u8> = buffer
147-
.iter()
148-
.take_while(|c| **c != 0 as u8)
149-
.cloned()
150-
.collect();
137+
self.read_exact(&mut buffer)?;
138+
let trimmed: Vec<u8> = buffer.iter().take_while(|c| **c != 0_u8).cloned().collect();
151139
Ok(ASCII
152140
.decode(&trimmed, DecoderTrap::Ignore)
153141
.expect("Error decoding text"))
@@ -168,7 +156,7 @@ where
168156
},
169157
umid: {
170158
let mut buf = [0u8; 64];
171-
self.read(&mut buf)?;
159+
self.read_exact(&mut buf)?;
172160
if version > 0 {
173161
Some(buf)
174162
} else {

0 commit comments

Comments
 (0)