Skip to content

Commit f0b1c51

Browse files
committed
Merge branch 'master' into release
2 parents 25589ea + e14bcd8 commit f0b1c51

15 files changed

+448
-338
lines changed

Cargo.lock

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

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "bwavfile"
3-
version = "0.9.1"
3+
version = "0.9.2"
44
authors = ["Jamie Hardt <[email protected]>"]
55
edition = "2018"
66
license = "MIT"

README.md

+10-3
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,19 @@ This is currently a work-in-progress! However many features presently work:
1212

1313
| Feature |Read |Write|
1414
|---------------------------------------|:---:|:-----:|
15-
| Standard .wav files | ☑️ | |
15+
| Standard .wav files | ☑️ | |
1616
| Transparent promotion to RF64/BW64 | ☑️ | ☑️ |
1717
| Unified interface for regular and extended Wave format | ☑️ | ☑️ |
1818
| Channel/speaker map metadata | ☑️ | ☑️ |
1919
| Ambisonic B-format metadata | ☑️ | ☑️ |
2020
| EBU Broadcast-WAVE metadata | ☑️ | ☑️ |
21-
| Basic iXML/ADM metadata | ☑️ | |
21+
| Basic iXML/ADM metadata | ☑️ | ☑️ |
2222
| Enhanced iXML metadata support | | |
23+
| ADM `chna` channel metadata | | |
2324
| Broadcast-WAVE Level overview `levl` metadata | | |
2425
| Cue list metadata | ☑️ | |
2526
| Sampler and instrument metadata | | |
26-
| Enhanced Wave file form validation | | |
27+
| Enhanced Wave file form validation | | |
2728

2829

2930
## Use Examples
@@ -69,3 +70,9 @@ All of the media for the integration tests is committed to the respository
6970
in zipped form. Before you can run tests, you need to `cd` into the `tests`
7071
directory and run the `create_test_media.sh` script. Note that one of the
7172
test files (the RF64 test case) is over four gigs in size.
73+
74+
Likewise, [the RF64 _writing_ test case][rf64test] writes an RF64 wave file
75+
to memory and is very time-intensive, so is commented-out in the code but
76+
can be un-commented if you want to run it on your system.
77+
78+
[rf64test]: https://github.com/iluvcapra/bwavfile/blob/1f8542a7efb481da076120bf8107032c5b48889d/src/wavewriter.rs#L399

examples/blits.rs

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn main() -> () {
2+
3+
}

examples/bwavefile_probe.rs

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn main() -> () {
2+
3+
}

src/bext.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,12 @@ pub type Decibels = f32;
1414
/// For a Wave file to be a complaint "Broadcast-WAV" file, it must contain
1515
/// a `bext` metadata record.
1616
///
17-
/// For reference on the structure and use of the BEXT record
18-
/// check out [EBU Tech 3285](https://tech.ebu.ch/docs/tech/tech3285.pdf).
17+
/// ## Resources
18+
/// - [EBU Tech 3285](https://tech.ebu.ch/docs/tech/tech3285.pdf).
19+
/// - [EBU Tech R098](https://tech.ebu.ch/docs/r/r098.pdf) (1999) "Format for the &lt;CodingHistory&gt; field in Broadcast Wave Format files, BWF"
20+
/// - [EBU Tech R099](https://tech.ebu.ch/docs/r/r099.pdf) (October 2011) "‘Unique’ Source Identifier (USID) for use in the
21+
/// &lt;OriginatorReference&gt; field of the Broadcast Wave Format"
22+
1923
#[derive(Debug)]
2024
pub struct Bext {
2125

src/cue.rs

+4
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,11 @@ impl AdtlMemberSearch for Vec<RawAdtlMember> {
190190

191191
/// A cue point recorded in the `cue` and `adtl` metadata.
192192
///
193+
/// ## Resources
194+
/// - [Cue list, label and other metadata](https://sites.google.com/site/musicgapi/technical-documents/wav-file-format#smpl)
193195
///
196+
/// ### Not Implemented
197+
/// - [EBU 3285 Supplement 2](https://tech.ebu.ch/docs/tech/tech3285s2.pdf) (July 2001): Quality chunk and cuesheet
194198
pub struct Cue {
195199

196200
/// Unique numeric identifier for this cue

src/fmt.rs

+81-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
use uuid::Uuid;
22
use super::common_format::{CommonFormat, UUID_PCM,UUID_BFORMAT_PCM};
3+
use std::io::Cursor;
34

5+
use byteorder::LittleEndian;
6+
use byteorder::WriteBytesExt;
7+
8+
// Need more test cases for ADMAudioID
49
#[allow(dead_code)]
510

611
/// ADM Audio ID record.
@@ -20,6 +25,9 @@ pub struct ADMAudioID {
2025
}
2126

2227
/// Describes a single channel in a WAV file.
28+
///
29+
/// This information is correlated from the Wave format ChannelMap field and
30+
/// the `chna` chunk, if present.
2331
pub struct ChannelDescriptor {
2432
/// Index, the offset of this channel's samples in one frame.
2533
pub index: u16,
@@ -124,14 +132,30 @@ pub struct WaveFmtExtended {
124132
pub type_guid : Uuid,
125133
}
126134

127-
/**
128-
* WAV file data format record.
129-
*
130-
* The `fmt` record contains essential information describing the binary
131-
* structure of the data segment of the WAVE file, such as sample
132-
* rate, sample binary format, channel count, etc.
133-
*
134-
*/
135+
///
136+
/// WAV file data format record.
137+
///
138+
/// The `fmt` record contains essential information describing the binary
139+
/// structure of the data segment of the WAVE file, such as sample
140+
/// rate, sample binary format, channel count, etc.
141+
///
142+
///
143+
/// ## Resources
144+
///
145+
/// ### Implementation of Wave format `fmt` chunk
146+
/// - [MSDN WAVEFORMATEX](https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/ns-mmeapi-waveformatex)
147+
/// - [MSDN WAVEFORMATEXTENSIBLE](https://docs.microsoft.com/en-us/windows/win32/api/mmreg/ns-mmreg-waveformatextensible)
148+
///
149+
/// ### Other resources
150+
/// - [RFC 3261][rfc3261] (June 1998) "WAVE and AVI Codec Registries"
151+
/// - [Sampler Metadata](http://www.piclist.com/techref/io/serial/midi/wave.html)
152+
/// - [Peter Kabal, McGill University](http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html)
153+
/// - [Multimedia Programming Interface and Data Specifications 1.0](http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Docs/riffmci.pdf)
154+
/// (August 1991), IBM Corporation and Microsoft Corporation
155+
///
156+
/// [rfc3261]: https://tools.ietf.org/html/rfc2361
157+
158+
135159
#[derive(Debug, Copy, Clone)]
136160
pub struct WaveFmt {
137161

@@ -181,7 +205,15 @@ pub struct WaveFmt {
181205

182206

183207
impl WaveFmt {
184-
208+
209+
pub fn valid_bits_per_sample(&self) -> u16 {
210+
if let Some(ext) = self.extended_format {
211+
ext.valid_bits_per_sample
212+
} else {
213+
self.bits_per_sample
214+
}
215+
}
216+
185217
/// Create a new integer PCM format for a monoaural audio stream.
186218
pub fn new_pcm_mono(sample_rate: u32, bits_per_sample: u16) -> Self {
187219
Self::new_pcm_multichannel(sample_rate, bits_per_sample, 0x4)
@@ -266,6 +298,46 @@ impl WaveFmt {
266298
vec![0i32; self.channel_count as usize]
267299
}
268300

301+
/// Calculate the size of a byte buffer needed to hold audio data of this
302+
/// format for a given number of frames
303+
pub fn buffer_length(&self, frame_count: u64) -> usize {
304+
(self.block_alignment as u64 * frame_count) as usize
305+
}
306+
307+
// Write frames into a byte vector
308+
pub fn pack_frames(&self, from_frames: &[i32], into_bytes: &mut Vec<u8>) -> () {
309+
let mut write_cursor = Cursor::new(into_bytes);
310+
311+
assert!(from_frames.len() % self.channel_count as usize == 0,
312+
"frames buffer does not contain a number of samples % channel_count == 0");
313+
314+
for n in 0..from_frames.len() {
315+
match (self.valid_bits_per_sample(), self.bits_per_sample) {
316+
(0..=8,8) => write_cursor.write_u8((from_frames[n] + 0x80) as u8 ).unwrap(), // EBU 3285 §A2.2
317+
(9..=16,16) => write_cursor.write_i16::<LittleEndian>(from_frames[n] as i16).unwrap(),
318+
(10..=24,24) => write_cursor.write_i24::<LittleEndian>(from_frames[n]).unwrap(),
319+
(25..=32,32) => write_cursor.write_i32::<LittleEndian>(from_frames[n]).unwrap(),
320+
(b,_)=> panic!("Unrecognized integer format, bits per sample {}, channels {}, block_alignment {}",
321+
b, self.channel_count, self.block_alignment)
322+
}
323+
}
324+
()
325+
}
326+
327+
/// Read bytes into frames
328+
// pub fn unpack_frames(&self, from_bytes: &[u8], into_frames: &mut Vec<i32>) -> () {
329+
// for n in 0..(from_bytes.len()) {
330+
// buffer[n] = match (self.format.bits_per_sample, framed_bits_per_sample) {
331+
// (0..=8,8) => self.inner.read_u8()? as i32 - 0x80_i32, // EBU 3285 §A2.2
332+
// (9..=16,16) => self.inner.read_i16::<LittleEndian>()? as i32,
333+
// (10..=24,24) => self.inner.read_i24::<LittleEndian>()?,
334+
// (25..=32,32) => self.inner.read_i32::<LittleEndian>()?,
335+
// (b,_)=> panic!("Unrecognized integer format, bits per sample {}, channels {}, block_alignment {}",
336+
// b, self.format.channel_count, self.format.block_alignment)
337+
// }
338+
// }
339+
// }
340+
269341

270342
/// Channel descriptors for each channel.
271343
pub fn channels(&self) -> Vec<ChannelDescriptor> {

src/fourcc.rs

+2
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ pub const FMT__SIG: FourCC = FourCC::make(b"fmt ");
103103

104104
pub const BEXT_SIG: FourCC = FourCC::make(b"bext");
105105
//pub const FACT_SIG: FourCC = FourCC::make(b"fact");
106+
pub const IXML_SIG: FourCC = FourCC::make(b"iXML");
107+
pub const AXML_SIG: FourCC = FourCC::make(b"axml");
106108

107109
pub const JUNK_SIG: FourCC = FourCC::make(b"JUNK");
108110
pub const FLLR_SIG: FourCC = FourCC::make(b"FLLR");

src/levl.rs

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/// Resources
2+
///
3+
/// [EBU 3285 Supplement 3](https://tech.ebu.ch/docs/tech/tech3285s3.pdf) (July 2001): Peak Metadata

src/lib.rs

+17-77
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,23 @@
22
# bwavfile
33
44
Rust Wave File Reader/Writer with Broadcast-WAV, MBWF and RF64 Support
5-
6-
__(Note: This crate is still in an alpha or pre-alpha stage of development. Reading of
7-
files works however the interfaces may change significantly. Stay up-to-date on the
8-
status of this project at [Github][github].)__
5+
6+
## Interfaces
7+
8+
### `WaveReader`
9+
10+
`WaveReader` can open and parse a Wave, Broadcast-Wave, or RF64/BW64 64-bit
11+
wave file. Metadata can be accessed and parsed in arbitrary order and audio
12+
samples can be accessed using the `AudioFrameReader` type, created by an
13+
accessor method of `WaveReader`.
14+
15+
### `WaveWriter`
16+
17+
`WaveWriter` can create a new Wave, Broadcast-Wave, or RF64/BW64 64-bit wave
18+
file. Metadata chunks and audio samples are added sequentially, write-only, to
19+
a Wave file which is automatically promoted from standard Wave to RF64 wave
20+
when the total WAVE form size exceeds 0xFFFFFFFF bytes.
21+
922
1023
## Objectives and Roadmap
1124
@@ -19,79 +32,6 @@ Apps we test against:
1932
- FFMpeg
2033
- Audacity
2134
22-
Wave features we want to support with maximum reliability and ease of use:
23-
24-
- Large file size, RF64 support
25-
- Multichannel audio formats
26-
- Embedded metadata
27-
28-
In addition to reading the audio, we want to support all of the different
29-
metadata planes you are liable to need to use.
30-
31-
- Broadcast-WAV metadata (including the SMPTE UMID and EBU v2 extensions)
32-
- iXML Production recorder metadata
33-
- ADM XML (with associated `chna` mappings)
34-
- Dolby metadata block
35-
36-
Things that are _not_ necessarily in the scope of this package:
37-
38-
- Broad codec support. There are a little more than one-hundred
39-
[registered wave codecs][rfc3261], but because this library is targeting
40-
professional formats being created today, we only plan on supporting
41-
two of them: tag 0x0001 (Integer Linear PCM) and tag 0x0003 (IEEE Float
42-
Linear PCM).
43-
- Music library metadata. There are several packages that can read ID3
44-
metadata and it's not particuarly common in wave files in any case. INFO
45-
metadata is more common though in professional applications it tends not
46-
to be used by many applications.
47-
48-
49-
## Resources
50-
51-
### Implementation of Broadcast Wave Files
52-
- [EBU Tech 3285][ebu3285] (May 2011), "Specification of the Broadcast Wave Format (BWF)"
53-
- [Supplement 1](https://tech.ebu.ch/docs/tech/tech3285s1.pdf) (July 1997): MPEG Audio
54-
- [EBU Rec 68](https://tech.ebu.ch/docs/r/r068.pdf): Signal modulation and format constraints
55-
56-
57-
### Implementation of 64-bit Wave Files
58-
- [ITU-R 2088][itu2088] (October 2019), "Long-form file format for the international exchange of audio programme materials with metadata"
59-
- Presently in force, adopted by the EBU in [EBU Tech 3306v2][ebu3306v2] (June 2018).
60-
- [EBU Tech 3306v1][ebu3306v1] (July 2009), "MBWF / RF64: An extended File Format for Audio"
61-
- No longer in force, however long-established.
62-
63-
64-
### Implementation of Wave format `fmt` chunk
65-
- [MSDN WAVEFORMATEX](https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/ns-mmeapi-waveformatex)
66-
- [MSDN WAVEFORMATEXTENSIBLE](https://docs.microsoft.com/en-us/windows/win32/api/mmreg/ns-mmreg-waveformatextensible)
67-
68-
69-
### Other resources
70-
- [RFC 3261][rfc3261] (June 1998) "WAVE and AVI Codec Registries"
71-
- [Sampler Metadata](http://www.piclist.com/techref/io/serial/midi/wave.html)
72-
- [Cue list, label and other metadata](https://sites.google.com/site/musicgapi/technical-documents/wav-file-format#smpl)
73-
- [Peter Kabal, McGill University](http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html)
74-
- [Multimedia Programming Interface and Data Specifications 1.0](http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Docs/riffmci.pdf)
75-
(August 1991), IBM Corporation and Microsoft Corporation
76-
77-
78-
### Formatting of Specific Metadatums
79-
- [iXML Metadata Specification](http://www.gallery.co.uk/ixml/) (April 2019)
80-
- EBU 3285 Supplements:
81-
- [Supplement 2](https://tech.ebu.ch/docs/tech/tech3285s2.pdf) (July 2001): Quality chunk and cuesheet
82-
- [Supplement 3](https://tech.ebu.ch/docs/tech/tech3285s3.pdf) (July 2001): Peak Metadata
83-
- [Supplement 4](https://tech.ebu.ch/docs/tech/tech3285s4.pdf) (April 2003): Link Metadata
84-
- [Supplement 5](https://tech.ebu.ch/docs/tech/tech3285s5.pdf) (May 2018): ADM Metadata
85-
- [Supplement 6](https://tech.ebu.ch/docs/tech/tech3285s6.pdf) (October 2009): Dolby Metadata
86-
- [EBU Tech R099](https://tech.ebu.ch/docs/r/r099.pdf) (October 2011) "‘Unique’ Source Identifier (USID) for use in the
87-
<OriginatorReference> field of the Broadcast Wave Format"
88-
- [EBU Tech R098](https://tech.ebu.ch/docs/r/r098.pdf) (1999) "Format for the &lt;CodingHistory&gt; field in Broadcast Wave Format files, BWF"
89-
90-
[ebu3285]: https://tech.ebu.ch/docs/tech/tech3285.pdf
91-
[ebu3306v1]: https://tech.ebu.ch/docs/tech/tech3306v1_1.pdf
92-
[ebu3306v2]: https://tech.ebu.ch/docs/tech/tech3306.pdf
93-
[itu2088]: https://www.itu.int/dms_pubrec/itu-r/rec/bs/R-REC-BS.2088-1-201910-I!!PDF-E.pdf
94-
[rfc3261]: https://tools.ietf.org/html/rfc2361
9535
[github]: https://github.com/iluvcapra/bwavfile
9636
*/
9737

src/sampler.rs

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/// ## Resources
2+
/// - [Sampler Metadata](http://www.piclist.com/techref/io/serial/midi/wave.html)

0 commit comments

Comments
 (0)