Skip to content

Commit 57482c3

Browse files
thinking-towera1phyr
authored andcommitted
opus: Decode table of contents (TOC) byte. (#111)
1 parent 5bd7081 commit 57482c3

File tree

4 files changed

+47
-10
lines changed

4 files changed

+47
-10
lines changed

symphonia-codec-opus/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ version = "0.0.1"
44
description = "Pure Opus decoder (a part of project Symphonia)."
55
homepage = "https://github.com/pdeljanov/Symphonia"
66
repository = "https://github.com/pdeljanov/Symphonia"
7-
authors = ["Philip Deljanov <[email protected]>"]
7+
authors = ["Philip Deljanov <[email protected]>", "Darius Tan <[email protected]>"]
88
license = "MPL-2.0"
99
readme = "README.md"
1010
categories = ["multimedia", "multimedia::audio", "multimedia::encoding"]

symphonia-codec-opus/src/lib.rs

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
// Disable to better express the specification.
1717
#![allow(clippy::collapsible_else_if)]
1818

19-
use symphonia_core::audio::GenericAudioBufferRef;
19+
use symphonia_core::audio::{AsGenericAudioBufferRef, AudioBuffer, GenericAudioBufferRef};
2020
use symphonia_core::codecs::audio::well_known::CODEC_ID_OPUS;
2121
use symphonia_core::codecs::audio::{
2222
AudioCodecParameters, AudioDecoder, AudioDecoderOptions, FinalizeResult,
@@ -32,6 +32,18 @@ use symphonia_core::support_audio_codec;
3232
pub struct OpusDecoder {
3333
ident_header: IdentificationHeader,
3434
params: AudioCodecParameters,
35+
buffer: AudioBuffer<f32>,
36+
}
37+
38+
/// The operating mode for the Opus Decoder.
39+
/// See RFC 6716 Section 3.1, https://tools.ietf.org/pdf/rfc7845.pdf.
40+
enum Mode {
41+
/// SILK-only mode.
42+
Silk,
43+
/// CELT-only mode.
44+
Celt,
45+
/// SILK and CELT mode.
46+
Hybrid,
3547
}
3648

3749
impl OpusDecoder {
@@ -44,7 +56,7 @@ impl OpusDecoder {
4456
let mut reader = BufReader::new(extra_data);
4557

4658
let ident_header = read_ident_header(&mut reader)?;
47-
Ok(OpusDecoder { ident_header, params: params.clone() })
59+
Ok(OpusDecoder { ident_header, params: params.clone(), buffer: AudioBuffer::default() })
4860
}
4961
}
5062

@@ -63,7 +75,22 @@ impl AudioDecoder for OpusDecoder {
6375

6476
#[allow(unused_variables)]
6577
fn decode(&mut self, packet: &Packet) -> Result<GenericAudioBufferRef<'_>> {
66-
unimplemented!()
78+
let mut reader = packet.as_buf_reader();
79+
80+
// Configuring the decoder from the table of contents (toc) byte.
81+
// See RFC 6716 Section 3.1, https://tools.ietf.org/pdf/rfc7845.pdf.
82+
let toc = reader.read_byte()?;
83+
let config = toc >> 3;
84+
let mode = match config {
85+
0..=11 => Mode::Silk,
86+
12..=15 => Mode::Hybrid,
87+
16..=31 => Mode::Celt,
88+
_ => unreachable!(),
89+
};
90+
let stereo_flag = toc & 0b00000100;
91+
let frame_count_code = toc & 0b00000011;
92+
93+
Ok(self.buffer.as_generic_audio_buffer_ref())
6794
}
6895

6996
fn finalize(&mut self) -> FinalizeResult {
@@ -103,12 +130,11 @@ pub struct IdentificationHeader {
103130
pub channel_mapping: [u8; 8],
104131
}
105132

106-
/** Create an IdentificationHeader from \a reader.
107-
*
108-
* If the header is invalid, a DecodeError is returned.
109-
*
110-
* See RFC 7845 Section 5.1, https://tools.ietf.org/pdf/rfc7845.pdf.
111-
*/
133+
/// Create an IdentificationHeader from a reader.
134+
///
135+
/// If the header is invalid, a DecodeError is returned.
136+
///
137+
/// See RFC 7845 Section 5.1, https://tools.ietf.org/pdf/rfc7845.pdf.
112138
fn read_ident_header<B: ReadBytes>(reader: &mut B) -> Result<IdentificationHeader> {
113139
// The first 8 bytes are the magic signature ASCII bytes.
114140
const OGG_OPUS_MAGIC_SIGNATURE: &[u8] = b"OpusHead";

symphonia/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ wav = ["dep:symphonia-format-riff", "symphonia-format-riff/wav"]
3535
ape = ["symphonia-metadata/ape"]
3636
id3v1 = ["symphonia-metadata/id3v1"]
3737
id3v2 = ["symphonia-metadata/id3v2"]
38+
opus = ["dep:symphonia-codec-opus"]
3839

3940
# MPEG audio codecs.
4041
mpa = ["mp1", "mp2", "mp3"]
@@ -138,6 +139,11 @@ version = "0.5.4"
138139
path = "../symphonia-codec-vorbis"
139140
optional = true
140141

142+
[dependencies.symphonia-codec-opus]
143+
version = "0.0.1"
144+
path = "../symphonia-codec-opus"
145+
optional = true
146+
141147
[dependencies.symphonia-format-riff]
142148
version = "0.5.4"
143149
path = "../symphonia-format-riff"

symphonia/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ pub mod default {
161161
pub use symphonia_codec_adpcm::AdpcmDecoder;
162162
#[cfg(feature = "alac")]
163163
pub use symphonia_codec_alac::AlacDecoder;
164+
#[cfg(feature = "opus")]
165+
pub use symphonia_codec_opus::OpusDecoder;
164166
#[cfg(feature = "pcm")]
165167
pub use symphonia_codec_pcm::PcmDecoder;
166168
#[cfg(feature = "vorbis")]
@@ -278,6 +280,9 @@ pub mod default {
278280

279281
#[cfg(feature = "vorbis")]
280282
registry.register_audio_decoder::<codecs::VorbisDecoder>();
283+
284+
#[cfg(feature = "opus")]
285+
registry.register_audio_decoder::<codecs::OpusDecoder>();
281286
}
282287

283288
/// Registers all the formats selected by the `feature` flags in the includer's `Cargo.toml` on

0 commit comments

Comments
 (0)