Reorganized source, comments

This commit is contained in:
Jamie Hardt
2020-11-23 00:23:17 -08:00
parent dea68662f8
commit 521e9d0670
7 changed files with 253 additions and 179 deletions

143
src/fmt.rs Normal file
View File

@@ -0,0 +1,143 @@
/**
* References:
* - http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Docs/multichaudP.pdf
*/
#[derive(PartialEq)]
enum FormatTags {
Integer = 0x0001,
Float = 0x0003,
Extensible = 0xFFFE
}
const PCM_SUBTYPE_UUID: [u8; 16] = [0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x10,
0x80, 0x00, 0x00, 0xaa,
0x00, 0x38, 0x9b, 0x71];
const FLOAT_SUBTYPE_UUID: [u8; 16] = [0x00, 0x00, 0x00, 0x03,
0x00, 0x00, 0x00, 0x10,
0x80, 0x00, 0x00, 0xaa,
0x00, 0x38, 0x9b, 0x71];
/*
https://docs.microsoft.com/en-us/windows-hardware/drivers/audio/subformat-guids-for-compressed-audio-formats
http://dream.cs.bath.ac.uk/researchdev/wave-ex/bformat.html
These are from http://dream.cs.bath.ac.uk/researchdev/wave-ex/mulchaud.rtf
*/
#[derive(Debug)]
pub enum WaveFmtExtendedChannelMask {
FrontLeft = 0x1,
FrontRight = 0x2,
FrontCenter = 0x4,
LowFrequency = 0x8,
BackLeft = 0x10,
BackRight = 0x20,
FrontCenterLeft = 0x40,
FrontCenterRight = 0x80,
BackCenter = 0x100,
SideLeft = 0x200,
SideRight = 0x400,
TopCenter = 0x800,
TopFrontLeft = 0x1000,
TopFrontCenter = 0x2000,
TopFrontRight = 0x4000,
TopBackLeft = 0x8000,
TopBackCenter = 0x10000,
TopBackRight = 0x20000
}
/**
* Extended Wave Format
*
* https://docs.microsoft.com/en-us/windows/win32/api/mmreg/ns-mmreg-waveformatextensible
*/
#[derive(Debug)]
pub struct WaveFmtExtended {
/// Valid bits per sample
pub valid_bits_per_sample : u16,
/// Channel mask
///
/// Identifies the speaker assignment for each channel in the file
pub channel_mask : WaveFmtExtendedChannelMask,
/// Codec GUID
///
/// Identifies the codec of the audio stream
pub type_guid : [u8; 16],
}
/**
* WAV file data format record.
*
* The `fmt` record contains essential information describing the binary
* structure of the data segment of the WAVE file, such as sample
* rate, sample binary format, channel count, etc.
*
*/
#[derive(Debug)]
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`
pub tag: u16,
/// Count of audio channels in each frame
pub channel_count: u16,
/// Sample rate of the audio data
pub sample_rate: u32,
/// Count of bytes per second
///
/// By rule, this is `block_alignment * sample_rate`
pub bytes_per_second: u32,
/// Count of bytes per audio frame
///
/// By rule, this is `channel_count * bits_per_sample / 8`
pub block_alignment: u16,
/// Count of bits stored in the file per sample
pub bits_per_sample: u16,
/// Extended format description
///
/// Additional format metadata if `channel_count` is greater than 2,
/// or if certain codecs are used.
pub extended_format: Option<WaveFmtExtended>
}
impl WaveFmt {
/// Create a new integer PCM format `WaveFmt`
pub fn new_pcm(sample_rate: u32, bits_per_sample: u16, channel_count: u16) -> Self {
let container_bits_per_sample = bits_per_sample + (bits_per_sample % 8);
let container_bytes_per_sample= container_bits_per_sample / 8;
let tag :u16 = match channel_count {
0 => panic!("Error"),
1..=2 => FormatTags::Integer as u16,
_ => FormatTags::Extensible as u16,
};
WaveFmt {
tag,
channel_count,
sample_rate,
bytes_per_second: container_bytes_per_sample as u32 * sample_rate * channel_count as u32,
block_alignment: container_bytes_per_sample * channel_count,
bits_per_sample: container_bits_per_sample,
extended_format: None
}
}
}