symphonia/lib.rs
1// Symphonia
2// Copyright (c) 2019-2022 The Project Symphonia Developers.
3//
4// This Source Code Form is subject to the terms of the Mozilla Public
5// License, v. 2.0. If a copy of the MPL was not distributed with this
6// file, You can obtain one at https://mozilla.org/MPL/2.0/.
7
8#![warn(rust_2018_idioms)]
9#![forbid(unsafe_code)]
10
11//! # Project Symphonia
12//!
13//! Symphonia is a 100% pure Rust audio decoding and multimedia format demuxing framework.
14//!
15//! # Support
16//!
17//! Supported formats, codecs, and metadata tags are listed below. By default Symphonia only enables
18//! royalty-free open standard media formats and codecs. Other formats and codecs must be enabled
19//! using feature flags.
20//!
21//! **Tip:** All formats and codecs can be enabled with the `all` feature flag.
22//!
23//! ## Formats
24//!
25//! The following container formats are supported.
26//!
27//! | Format | Feature Flag | Gapless* | Default |
28//! |----------|--------------|----------|---------|
29//! | AIFF | `aiff` | Yes | No |
30//! | CAF | `caf` | No | No |
31//! | ISO/MP4 | `isomp4` | No | No |
32//! | MKV/WebM | `mkv` | No | Yes |
33//! | OGG | `ogg` | Yes | Yes |
34//! | Wave | `wav` | Yes | Yes |
35//!
36//! \* Gapless playback requires support from both the demuxer and decoder.
37//!
38//! **Tip:** All formats can be enabled with the `all-codecs` feature flag.
39//!
40//! ## Codecs
41//!
42//! The following codecs are supported.
43//!
44//! | Codec | Feature Flag | Gapless | Default |
45//! |----------|--------------|---------|---------|
46//! | AAC-LC | `aac` | No | No |
47//! | ADPCM | `adpcm` | Yes | Yes |
48//! | ALAC | `alac` | Yes | No |
49//! | FLAC | `flac` | Yes | Yes |
50//! | MP1 | `mp1`, `mpa` | No | No |
51//! | MP2 | `mp2`, `mpa` | No | No |
52//! | MP3 | `mp3`, `mpa` | Yes | No |
53//! | PCM | `pcm` | Yes | Yes |
54//! | Vorbis | `vorbis` | Yes | Yes |
55//!
56//! **Tip:** All codecs can be enabled with the `all-codecs` feature flag. Similarly, all MPEG
57//! audio codecs can be enabled with the `mpa` feature flag.
58//!
59//! ## Metadata
60//!
61//! The following metadata tagging formats are supported. These are always enabled.
62//!
63//! * ID3v1
64//! * ID3v2
65//! * ISO/MP4
66//! * RIFF
67//! * Vorbis Comment (in OGG & FLAC)
68//!
69//! ## Optimizations
70//!
71//! SIMD optimizations are **not** enabled by default. They may be enabled on a per-instruction
72//! set basis using the following feature flags. Enabling any SIMD support feature flags will pull
73//! in the `rustfft` dependency.
74//!
75//! | Instruction Set | Feature Flag | Default |
76//! |-----------------|-----------------|---------|
77//! | SSE | `opt-simd-sse` | No |
78//! | AVX | `opt-simd-avx` | No |
79//! | Neon | `opt-simd-neon` | No |
80//!
81//! **Tip:** All SIMD optimizations can be enabled with the `opt-simd` feature flag.
82//!
83//! # Usage
84//!
85//! The following steps describe a basic usage of Symphonia:
86//!
87//! 1. Instantiate a [`CodecRegistry`][core::codecs::CodecRegistry] and register all the codecs
88//! that are of interest. Alternatively, you may use [`default::get_codecs`] to get the default
89//! registry with all the enabled codecs pre-registered. The registry will be used to
90//! instantiate a [`Decoder`][core::codecs::Decoder] later.
91//! 2. Instantiate a [`Probe`][core::probe::Probe] and register all the formats that are of
92//! interest. Alternatively, you may use [`default::get_probe`] to get a default format probe
93//! with all the enabled formats pre-registered. The probe will be used to automatically detect
94//! the media format and instantiate a compatible [`FormatReader`][core::formats::FormatReader].
95//! 3. Make sure the [`MediaSource`][core::io::MediaSource] trait is implemented for whatever
96//! source you are using. This trait is already implemented for `std::fs::File` and
97//! `std::io::Cursor`.
98//! 4. Instantiate a [`MediaSourceStream`][core::io::MediaSourceStream] with the `MediaSource`
99//! above.
100//! 5. Using the `Probe`, call [`format`][core::probe::Probe::format] and pass it the
101//! `MediaSourceStream`.
102//! 6. If the probe successfully detects a compatible format, a `FormatReader` will be returned.
103//! This is an instance of a demuxer that can read and demux the provided source into
104//! [`Packet`][core::formats::Packet]s.
105//! 7. At this point it is possible to interrogate the `FormatReader` for general information about
106//! the media and metadata. Examine the [`Track`][core::formats::Track] listing using
107//! [`tracks`][core::formats::FormatReader::tracks] and select one or more tracks of interest to
108//! decode.
109//! 8. To instantiate a `Decoder` for a selected `Track`, call the `CodecRegistry`'s
110//! [`make`][core::codecs::CodecRegistry::make] function and pass it
111//! the [`CodecParameters`][core::codecs::CodecParameters] for that track. This step is repeated
112//! once per selected track.
113//! 9. To decode a track, obtain a packet from the `FormatReader` by
114//! calling [`next_packet`][`core::formats::FormatReader::next_packet`] and then pass the
115//! `Packet` to the `Decoder` for that track. The [`decode`][core::codecs::Decoder::decode]
116//! function will read a packet and return an [`AudioBufferRef`][core::audio::AudioBufferRef]
117//! (an "any-type" [`AudioBuffer`][core::audio::AudioBuffer]).
118//! 10. The `AudioBufferRef` may be used to access the decoded audio samples directly, or it can be
119//! copied into a [`SampleBuffer`][core::audio::SampleBuffer] or
120//! [`RawSampleBuffer`][core::audio::RawSampleBuffer] to export the audio out of Symphonia.
121//! 11. Repeat step 9 and 10 until the end-of-stream error is returned.
122//!
123//! An example implementation of a simple audio player (symphonia-play) can be found in the
124//! Project Symphonia git repository.
125//!
126//! # Gapless Playback
127//!
128//! Gapless playback is disabled by default. To enable gapless playback, set
129//! [`FormatOptions::enable_gapless`][core::formats::FormatOptions::enable_gapless] to `true`.
130//!
131//! # Adding new formats and codecs
132//!
133//! Simply implement the [`Decoder`][core::codecs::Decoder] trait for a decoder or the
134//! [`FormatReader`][core::formats::FormatReader] trait for a demuxer trait and register with
135//! the appropriate registry or probe!
136
137pub mod default {
138 //! The `default` module provides convenience functions and registries to get an implementer
139 //! up-and-running as quickly as possible, and to reduce boiler-plate. Using the `default`
140 //! module is completely optional and incurs no overhead unless actually used.
141
142 pub mod codecs {
143 //! The `codecs` module re-exports all enabled Symphonia decoders.
144
145 #[cfg(feature = "flac")]
146 pub use symphonia_bundle_flac::FlacDecoder;
147 #[cfg(any(feature = "mp1", feature = "mp2", feature = "mp3"))]
148 pub use symphonia_bundle_mp3::MpaDecoder;
149 #[cfg(feature = "aac")]
150 pub use symphonia_codec_aac::AacDecoder;
151 #[cfg(feature = "adpcm")]
152 pub use symphonia_codec_adpcm::AdpcmDecoder;
153 #[cfg(feature = "alac")]
154 pub use symphonia_codec_alac::AlacDecoder;
155 #[cfg(feature = "pcm")]
156 pub use symphonia_codec_pcm::PcmDecoder;
157 #[cfg(feature = "vorbis")]
158 pub use symphonia_codec_vorbis::VorbisDecoder;
159
160 #[deprecated = "use `default::codecs::MpaDecoder` instead"]
161 #[cfg(any(feature = "mp1", feature = "mp2", feature = "mp3"))]
162 pub type Mp3Decoder = MpaDecoder;
163 }
164
165 pub mod formats {
166 //! The `formats` module re-exports all enabled Symphonia format readers.
167
168 #[cfg(feature = "flac")]
169 pub use symphonia_bundle_flac::FlacReader;
170 #[cfg(any(feature = "mp1", feature = "mp2", feature = "mp3"))]
171 pub use symphonia_bundle_mp3::MpaReader;
172 #[cfg(feature = "aac")]
173 pub use symphonia_codec_aac::AdtsReader;
174 #[cfg(feature = "caf")]
175 pub use symphonia_format_caf::CafReader;
176 #[cfg(feature = "isomp4")]
177 pub use symphonia_format_isomp4::IsoMp4Reader;
178 #[cfg(feature = "mkv")]
179 pub use symphonia_format_mkv::MkvReader;
180 #[cfg(feature = "ogg")]
181 pub use symphonia_format_ogg::OggReader;
182 #[cfg(feature = "aiff")]
183 pub use symphonia_format_riff::AiffReader;
184 #[cfg(feature = "wav")]
185 pub use symphonia_format_riff::WavReader;
186
187 #[deprecated = "use `default::formats::MpaReader` instead"]
188 #[cfg(any(feature = "mp1", feature = "mp2", feature = "mp3"))]
189 pub type Mp3Reader = MpaReader;
190 }
191
192 use lazy_static::lazy_static;
193
194 use symphonia_core::codecs::CodecRegistry;
195 use symphonia_core::probe::Probe;
196
197 lazy_static! {
198 static ref CODEC_REGISTRY: CodecRegistry = {
199 let mut registry = CodecRegistry::new();
200 register_enabled_codecs(&mut registry);
201 registry
202 };
203 }
204
205 lazy_static! {
206 static ref PROBE: Probe = {
207 let mut probe: Probe = Default::default();
208 register_enabled_formats(&mut probe);
209 probe
210 };
211 }
212
213 /// Gets the default `CodecRegistry`. This registry pre-registers all the codecs selected by the
214 /// `feature` flags in the includer's `Cargo.toml`. If `features` is not set, the default set of
215 /// Symphonia codecs is registered.
216 ///
217 /// This function is lazy and does not instantiate the `CodecRegistry` until the first call to
218 /// this function.
219 pub fn get_codecs() -> &'static CodecRegistry {
220 &CODEC_REGISTRY
221 }
222
223 /// Gets the default `Probe`. This registry pre-registers all the formats selected by the
224 /// `feature` flags in the includer's `Cargo.toml`. If `features` is not set, the default set of
225 /// Symphonia formats is registered.
226 ///
227 /// This function is lazy and does not instantiate the `Probe` until the first call to this
228 /// function.
229 pub fn get_probe() -> &'static Probe {
230 &PROBE
231 }
232
233 /// Registers all the codecs selected by the `feature` flags in the includer's `Cargo.toml` on
234 /// the provided `CodecRegistry`. If `features` is not set, the default set of Symphonia codecs
235 /// is registered.
236 ///
237 /// Use this function to easily populate a custom registry with all enabled codecs.
238 pub fn register_enabled_codecs(registry: &mut CodecRegistry) {
239 #[cfg(feature = "aac")]
240 registry.register_all::<codecs::AacDecoder>();
241
242 #[cfg(feature = "adpcm")]
243 registry.register_all::<codecs::AdpcmDecoder>();
244
245 #[cfg(feature = "alac")]
246 registry.register_all::<codecs::AlacDecoder>();
247
248 #[cfg(feature = "flac")]
249 registry.register_all::<codecs::FlacDecoder>();
250
251 #[cfg(any(feature = "mp1", feature = "mp2", feature = "mp3"))]
252 registry.register_all::<codecs::MpaDecoder>();
253
254 #[cfg(feature = "pcm")]
255 registry.register_all::<codecs::PcmDecoder>();
256
257 #[cfg(feature = "vorbis")]
258 registry.register_all::<codecs::VorbisDecoder>();
259 }
260
261 /// Registers all the formats selected by the `feature` flags in the includer's `Cargo.toml` on
262 /// the provided `Probe`. If `features` is not set, the default set of Symphonia formats is
263 /// registered.
264 ///
265 /// Use this function to easily populate a custom probe with all enabled formats.
266 pub fn register_enabled_formats(probe: &mut Probe) {
267 use symphonia_metadata::id3v2::Id3v2Reader;
268
269 // Formats
270 #[cfg(feature = "aac")]
271 probe.register_all::<formats::AdtsReader>();
272
273 #[cfg(feature = "caf")]
274 probe.register_all::<formats::CafReader>();
275
276 #[cfg(feature = "flac")]
277 probe.register_all::<formats::FlacReader>();
278
279 #[cfg(feature = "isomp4")]
280 probe.register_all::<formats::IsoMp4Reader>();
281
282 #[cfg(any(feature = "mp1", feature = "mp2", feature = "mp3"))]
283 probe.register_all::<formats::MpaReader>();
284
285 #[cfg(feature = "aiff")]
286 probe.register_all::<formats::AiffReader>();
287
288 #[cfg(feature = "wav")]
289 probe.register_all::<formats::WavReader>();
290
291 #[cfg(feature = "ogg")]
292 probe.register_all::<formats::OggReader>();
293
294 #[cfg(feature = "mkv")]
295 probe.register_all::<formats::MkvReader>();
296
297 // Metadata
298 probe.register_all::<Id3v2Reader>();
299 }
300}
301
302pub use symphonia_core as core;