optivorbis/
vorbis.rs

1//! Container-agnostic data types for parsing and optimizing Vorbis streams.
2
3use std::{
4	error::Error,
5	fmt::{Display, Formatter}
6};
7
8pub(crate) mod optimizer;
9
10pub(crate) mod codebook;
11
12/// Helper macro that implements a custom error type for a failed [`TryFrom`] conversion
13/// from an enum representation to its variant.
14macro_rules! try_from_impl {
15	{ type Enum = $enum_type:ident($repr_type:ty) { $( $variant:ident ),+ }; type Error = $error_type:ident } => {
16		#[doc = "The error type for fallible conversions from integers to a `"]
17		#[doc = stringify!($enum_type)]
18		#[doc = "`."]
19		#[derive(Debug)]
20		#[repr(transparent)]
21		pub struct $error_type($repr_type);
22
23		impl Display for $error_type {
24			fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
25				write!(f, "{}", self.0)
26			}
27		}
28
29		impl Error for $error_type {}
30
31		impl TryFrom<$repr_type> for $enum_type {
32			type Error = $error_type;
33
34			fn try_from(value: $repr_type) -> Result<Self, Self::Error> {
35				match value {
36					$( value if Self::$variant as $repr_type == value => Ok(Self::$variant) ),+,
37					_ => Err($error_type(value))
38				}
39			}
40		}
41
42		impl $error_type {
43			/// Returns the integer whose conversion failed.
44			pub const fn integer(&self) -> $repr_type {
45				self.0
46			}
47		}
48	}
49}
50
51/// Represents a Vorbis packet type, defined in the Vorbis I specification, § 4.2.1.
52#[derive(Debug, Eq, PartialEq, Clone, Copy)]
53#[repr(u8)]
54pub enum PacketType {
55	/// An audio packet, which encodes an audio frame composed of samples.
56	Audio = 0,
57	/// The Vorbis identification header packet, that marks a stream as Vorbis and contains
58	/// some basic metadata about it.
59	IdentificationHeader = 1,
60	/// The Vorbis comment header packet, which contains a list of comment key-value pairs meant
61	/// for tagging and stream metadata that does not affect decoding.
62	CommentHeader = 3,
63	/// The Vorbis setup header packet, whose data sets up the codec setup data structures used
64	/// for decoding audio packets.
65	SetupHeader = 5
66}
67
68try_from_impl! {
69	type Enum = PacketType(u8) { Audio, IdentificationHeader, CommentHeader, SetupHeader };
70	type Error = TryPacketTypeFromInt
71}
72
73impl Display for PacketType {
74	fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
75		f.write_str(match self {
76			Self::Audio => "audio packet",
77			Self::IdentificationHeader => "identification header packet",
78			Self::CommentHeader => "comment header packet",
79			Self::SetupHeader => "setup header packet"
80		})
81	}
82}
83
84/// Represents a codebook vector quantization lookup type, defined in the Vorbis I
85/// specification, § 3.2.1.
86#[derive(Debug, Eq, PartialEq, Clone, Copy)]
87#[repr(u8)]
88enum VectorLookupType {
89	NoLookup = 0,
90	ImplicitlyPopulated = 1,
91	ExplicitlyPopulated = 2
92}
93
94try_from_impl! {
95	type Enum = VectorLookupType(u8) { NoLookup, ImplicitlyPopulated, ExplicitlyPopulated };
96	type Error = TryVectorLookupTypeFromInt
97}
98
99/// Represents a residue vector type, defined in the Vorbis I specification, § 8.
100#[derive(Debug, Eq, PartialEq, Clone, Copy)]
101#[repr(u16)]
102enum ResidueType {
103	Interleaved = 0,
104	Ordered = 1,
105	InterleavedVectors = 2
106}
107
108try_from_impl! {
109	type Enum = ResidueType(u16) { Interleaved, Ordered, InterleavedVectors };
110	type Error = TryResidueTypeFromInt
111}