mirror of
https://github.com/iluvcapra/bwavfile.git
synced 2025-12-31 08:50:44 +00:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8e341990fa | ||
|
|
2dfddff0b5 | ||
|
|
aa8365a38d | ||
|
|
b8a428e757 | ||
|
|
c1d2b2c836 | ||
|
|
f41b7ea575 | ||
|
|
9a62bdc375 | ||
|
|
368ef4366d | ||
|
|
bfa51a4e4c | ||
|
|
4270dc9866 | ||
|
|
92d76289e4 | ||
|
|
15f9a240c0 |
28
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
28
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: "[Bug] __Enter a title here__"
|
||||
labels: bug
|
||||
assignees: iluvcapra
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Example Code**:
|
||||
```rust
|
||||
// Give an example of code that is failing here.
|
||||
```
|
||||
|
||||
**Platform**:
|
||||
- OS
|
||||
- `rustc` version: ____ (from `rustup -V`)
|
||||
- Host: ____ (from `rustup show` e.g. x86_64-apple-darwin)
|
||||
- Rust toolchain: ____ (e.g. stable-x86_64-apple-darwin)
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
25
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
25
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: "[Feature] __Name the Feature__"
|
||||
labels: enhancement
|
||||
assignees: iluvcapra
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like:**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Code Example:**
|
||||
```rust
|
||||
// Give an example of how you would like your feature to work.
|
||||
```
|
||||
|
||||
**Describe alternatives you've considered:**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context:**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -30,7 +30,7 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bwavfile"
|
||||
version = "1.1.0"
|
||||
version = "2.0.0"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"clap",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "bwavfile"
|
||||
version = "2.0.0"
|
||||
version = "2.0.1"
|
||||
authors = ["Jamie Hardt <jamiehardt@me.com>", "Ian Hobson <ian.r.hobson@gmail.com>"]
|
||||
edition = "2018"
|
||||
license = "MIT"
|
||||
|
||||
@@ -19,12 +19,12 @@ reading and creating new wave audio files.
|
||||
* Unpacked reading and writing of Integer PCM and IEEE float audio data
|
||||
formats.
|
||||
* A unified interface for standard `WaveFormat` and extended `WaveFormatEx`
|
||||
wave data format specification.
|
||||
wave data format.
|
||||
|
||||
The library has extensive metadata support, with emphasis on film and video
|
||||
production metadata:
|
||||
* Broadcast-Wave metdata extension, including long description, originator
|
||||
information, SMPTE UMID and coding history.
|
||||
* Broadcast-Wave metadata extension, including long description, originator,
|
||||
SMPTE UMID and coding history.
|
||||
* Reading and writing of embedded iXML and axml/ADM metadata.
|
||||
* Reading and writing of timed cues and and timed cue regions.
|
||||
* Multichannel, surround, and ambisonic audio data description including
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "."
|
||||
}
|
||||
],
|
||||
"settings": {}
|
||||
}
|
||||
@@ -1,8 +1,16 @@
|
||||
/// Format tags, UUIDs and utilities
|
||||
use uuid::Uuid;
|
||||
|
||||
/// Format tag for integer LPCM
|
||||
pub const WAVE_TAG_PCM: u16 = 0x0001;
|
||||
|
||||
/// Format tag for float LPCM
|
||||
pub const WAVE_TAG_FLOAT: u16 = 0x0003;
|
||||
|
||||
/// Format tag for MPEG1
|
||||
pub const WAVE_TAG_MPEG: u16 = 0x0050;
|
||||
|
||||
/// Format tag indicating extended format
|
||||
pub const WAVE_TAG_EXTENDED: u16 = 0xFFFE;
|
||||
|
||||
/* RC 2361 §4:
|
||||
@@ -15,34 +23,38 @@ pub const WAVE_TAG_EXTENDED: u16 = 0xFFFE;
|
||||
|
||||
*/
|
||||
|
||||
/// Extended format UUID for integer PCM
|
||||
pub const WAVE_UUID_PCM: Uuid = Uuid::from_bytes([
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71,
|
||||
]);
|
||||
|
||||
/// Extended format UUID for float PCM
|
||||
pub const WAVE_UUID_FLOAT: Uuid = Uuid::from_bytes([
|
||||
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71,
|
||||
]);
|
||||
|
||||
/// Extended format UUID for MPEG1 data
|
||||
pub const WAVE_UUID_MPEG: Uuid = Uuid::from_bytes([
|
||||
0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71,
|
||||
]);
|
||||
|
||||
/// Extended format for integer Ambisonic B-Format
|
||||
pub const WAVE_UUID_BFORMAT_PCM: Uuid = Uuid::from_bytes([
|
||||
0x01, 0x00, 0x00, 0x00, 0x21, 0x07, 0xd3, 0x11, 0x86, 0x44, 0xc8, 0xc1, 0xca, 0x00, 0x00, 0x00,
|
||||
]);
|
||||
|
||||
/// Extended format for float Ambisonic B-Format
|
||||
pub const WAVE_UUID_BFORMAT_FLOAT: Uuid = Uuid::from_bytes([
|
||||
0x03, 0x00, 0x00, 0x00, 0x21, 0x07, 0xd3, 0x11, 0x86, 0x44, 0xc8, 0xc1, 0xca, 0x00, 0x00, 0x00,
|
||||
]);
|
||||
|
||||
/// Generate an extended format UUID for the given basic format tag from [WaveFmt::tag].
|
||||
fn uuid_from_basic_tag(tag: u16) -> Uuid {
|
||||
let tail: [u8; 6] = [0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71];
|
||||
Uuid::from_fields_le(tag as u32, 0x0000, 0x0010, &tail).unwrap()
|
||||
}
|
||||
|
||||
/// Sample format of the Wave file.
|
||||
///
|
||||
///
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub enum CommonFormat {
|
||||
/// Integer linear PCM
|
||||
@@ -77,7 +89,9 @@ impl CommonFormat {
|
||||
(WAVE_TAG_EXTENDED, Some(WAVE_UUID_PCM)) => Self::IntegerPCM,
|
||||
(WAVE_TAG_EXTENDED, Some(WAVE_UUID_FLOAT)) => Self::IeeeFloatPCM,
|
||||
(WAVE_TAG_EXTENDED, Some(WAVE_UUID_BFORMAT_PCM)) => Self::AmbisonicBFormatIntegerPCM,
|
||||
(WAVE_TAG_EXTENDED, Some(WAVE_UUID_BFORMAT_FLOAT)) => Self::AmbisonicBFormatIeeeFloatPCM,
|
||||
(WAVE_TAG_EXTENDED, Some(WAVE_UUID_BFORMAT_FLOAT)) => {
|
||||
Self::AmbisonicBFormatIeeeFloatPCM
|
||||
}
|
||||
(WAVE_TAG_EXTENDED, Some(x)) => CommonFormat::UnknownExtended(x),
|
||||
(x, _) => CommonFormat::UnknownBasic(x),
|
||||
}
|
||||
|
||||
23
src/fmt.rs
23
src/fmt.rs
@@ -116,7 +116,8 @@ impl ChannelMask {
|
||||
/**
|
||||
* Extended Wave Format
|
||||
*
|
||||
* https://docs.microsoft.com/en-us/windows/win32/api/mmreg/ns-mmreg-waveformatextensible
|
||||
* Resources:
|
||||
* * [WAVEFORMATEXTENSIBLE structure](https://docs.microsoft.com/en-us/windows/win32/api/mmreg/ns-mmreg-waveformatextensible)
|
||||
*/
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct WaveFmtExtended {
|
||||
@@ -151,7 +152,7 @@ pub struct WaveFmtExtended {
|
||||
/// ### Other resources
|
||||
/// - [RFC 3261][rfc3261] (June 1998) "WAVE and AVI Codec Registries"
|
||||
/// - [Sampler Metadata](http://www.piclist.com/techref/io/serial/midi/wave.html)
|
||||
/// - [Peter Kabal, McGill University](http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html)
|
||||
/// - [Audio File Format Specifications](http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html) (September 2022) Prof. Peter Kabal, MMSP Lab, ECE, McGill University
|
||||
/// - [Multimedia Programming Interface and Data Specifications 1.0](http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Docs/riffmci.pdf)
|
||||
/// (August 1991), IBM Corporation and Microsoft Corporation
|
||||
///
|
||||
@@ -162,7 +163,7 @@ pub struct WaveFmt {
|
||||
/// A tag identifying the codec in use.
|
||||
///
|
||||
/// If this is 0xFFFE, the codec will be identified by a GUID
|
||||
/// in `extended_format`
|
||||
/// in [`extended_format`](WaveFmt::extended_format).
|
||||
pub tag: u16,
|
||||
|
||||
/// Count of audio channels in each frame
|
||||
@@ -198,7 +199,7 @@ pub struct WaveFmt {
|
||||
|
||||
/// Extended format description
|
||||
///
|
||||
/// Additional format metadata if `channel_count` is greater than 2,
|
||||
/// Additional format metadata if channel_count is greater than 2,
|
||||
/// or if certain codecs are used.
|
||||
pub extended_format: Option<WaveFmtExtended>,
|
||||
}
|
||||
@@ -245,11 +246,11 @@ impl WaveFmt {
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new integer PCM format `WaveFmt` with a custom channel bitmap.
|
||||
/// Create a new integer PCM format [WaveFmt] with a custom channel bitmap.
|
||||
///
|
||||
/// The order of `channels` is not important. When reading or writing
|
||||
/// The order of [channels](WaveFmt::channels) is not important. When reading or writing
|
||||
/// audio frames you must use the standard multichannel order for Wave
|
||||
/// files, the numerical order of the cases of `ChannelMask`.
|
||||
/// files, the numerical order of the cases of [ChannelMask].
|
||||
pub fn new_pcm_multichannel(
|
||||
sample_rate: u32,
|
||||
bits_per_sample: u16,
|
||||
@@ -300,7 +301,7 @@ impl WaveFmt {
|
||||
|
||||
/// Format or codec of the file's audio data.
|
||||
///
|
||||
/// The `CommonFormat` unifies the format tag and the format extension GUID. Use this
|
||||
/// The [CommonFormat] unifies the format tag and the format extension GUID. Use this
|
||||
/// method to determine the codec.
|
||||
pub fn common_format(&self) -> CommonFormat {
|
||||
CommonFormat::make(self.tag, self.extended_format.map(|ext| ext.type_guid))
|
||||
@@ -377,7 +378,8 @@ impl WaveFmt {
|
||||
}
|
||||
}
|
||||
|
||||
trait ReadWavAudioData {
|
||||
pub trait ReadWavAudioData {
|
||||
/// Read audio data from the receiver as interleaved [i32] samples.
|
||||
fn read_i32_frames(
|
||||
&mut self,
|
||||
format: WaveFmt,
|
||||
@@ -394,6 +396,9 @@ impl<T> ReadWavAudioData for T
|
||||
where
|
||||
T: std::io::Read,
|
||||
{
|
||||
/// # Panics:
|
||||
/// * If the format's [valid bits per sample](WaveFmt::valid_bits_per_sample) is
|
||||
/// not compatible with the format's [bits per sample](WaveFmt::bits_per_sample).
|
||||
fn read_i32_frames(
|
||||
&mut self,
|
||||
format: WaveFmt,
|
||||
|
||||
22
src/lib.rs
22
src/lib.rs
@@ -3,22 +3,8 @@
|
||||
|
||||
Rust Wave File Reader/Writer with Broadcast-WAV, MBWF and RF64 Support
|
||||
|
||||
## Interfaces
|
||||
|
||||
### `WaveReader`
|
||||
|
||||
`WaveReader` can open and parse a Wave, Broadcast-Wave, or RF64/BW64 64-bit
|
||||
wave file. Metadata can be accessed and parsed in arbitrary order and audio
|
||||
samples can be accessed using the `AudioFrameReader` type, created by an
|
||||
accessor method of `WaveReader`.
|
||||
|
||||
### `WaveWriter`
|
||||
|
||||
`WaveWriter` can create a new Wave, Broadcast-Wave, or RF64/BW64 64-bit wave
|
||||
file. Metadata chunks and audio samples are added sequentially, write-only, to
|
||||
a Wave file which is automatically promoted from standard Wave to RF64 wave
|
||||
when the total WAVE form size exceeds 0xFFFFFFFF bytes.
|
||||
|
||||
Refer to the individual modules for relevant documentation. For opening
|
||||
and writing files begin with [WaveReader] and [WaveWriter] respectively.
|
||||
|
||||
## Objectives and Roadmap
|
||||
|
||||
@@ -64,7 +50,9 @@ pub use common_format::{
|
||||
};
|
||||
pub use cue::Cue;
|
||||
pub use errors::Error;
|
||||
pub use fmt::{ADMAudioID, ChannelDescriptor, ChannelMask, WaveFmt, WaveFmtExtended};
|
||||
pub use fmt::{
|
||||
ADMAudioID, ChannelDescriptor, ChannelMask, ReadWavAudioData, WaveFmt, WaveFmtExtended,
|
||||
};
|
||||
pub use sample::{Sample, I24};
|
||||
pub use wavereader::{AudioFrameReader, WaveReader};
|
||||
pub use wavewriter::{AudioFrameWriter, WaveWriter};
|
||||
|
||||
Reference in New Issue
Block a user