16
16
// Disable to better express the specification.
17
17
#![ allow( clippy:: collapsible_else_if) ]
18
18
19
- use symphonia_core:: audio:: GenericAudioBufferRef ;
19
+ use symphonia_core:: audio:: {
20
+ AsGenericAudioBufferRef , AudioBuffer , AudioSpec , Channels , GenericAudioBufferRef ,
21
+ } ;
20
22
use symphonia_core:: codecs:: audio:: well_known:: CODEC_ID_OPUS ;
21
23
use symphonia_core:: codecs:: audio:: {
22
24
AudioCodecParameters , AudioDecoder , AudioDecoderOptions , FinalizeResult ,
@@ -32,6 +34,18 @@ use symphonia_core::support_audio_codec;
32
34
pub struct OpusDecoder {
33
35
ident_header : IdentificationHeader ,
34
36
params : AudioCodecParameters ,
37
+ buffer : AudioBuffer < f32 > ,
38
+ }
39
+
40
+ /// The operating mode for the Opus Decoder.
41
+ /// See RFC 6716 Section 3.1, https://tools.ietf.org/pdf/rfc7845.pdf.
42
+ enum Mode {
43
+ /// SILK-only mode.
44
+ Silk ,
45
+ /// CELT-only mode.
46
+ Celt ,
47
+ /// SILK and CELT mode.
48
+ Hybrid ,
35
49
}
36
50
37
51
impl OpusDecoder {
@@ -44,7 +58,11 @@ impl OpusDecoder {
44
58
let mut reader = BufReader :: new ( extra_data) ;
45
59
46
60
let ident_header = read_ident_header ( & mut reader) ?;
47
- Ok ( OpusDecoder { ident_header, params : params. clone ( ) } )
61
+ Ok ( OpusDecoder {
62
+ ident_header,
63
+ params : params. clone ( ) ,
64
+ buffer : AudioBuffer :: new ( AudioSpec :: new ( 0 , Channels :: None ) , 0 ) ,
65
+ } )
48
66
}
49
67
}
50
68
@@ -63,7 +81,22 @@ impl AudioDecoder for OpusDecoder {
63
81
64
82
#[ allow( unused_variables) ]
65
83
fn decode ( & mut self , packet : & Packet ) -> Result < GenericAudioBufferRef < ' _ > > {
66
- unimplemented ! ( )
84
+ let mut reader = packet. as_buf_reader ( ) ;
85
+
86
+ // Configuring the decoder from the table of contents (toc) byte.
87
+ // See RFC 6716 Section 3.1, https://tools.ietf.org/pdf/rfc7845.pdf.
88
+ let toc = reader. read_byte ( ) ?;
89
+ let config = toc >> 3 ;
90
+ let mode = match config {
91
+ 0 ..=11 => Mode :: Silk ,
92
+ 12 ..=15 => Mode :: Hybrid ,
93
+ 16 ..=31 => Mode :: Celt ,
94
+ _ => unreachable ! ( ) ,
95
+ } ;
96
+ let stereo_flag = toc & 0b00000100 ;
97
+ let frame_count_code = toc & 0b00000011 ;
98
+
99
+ Ok ( self . buffer . as_generic_audio_buffer_ref ( ) )
67
100
}
68
101
69
102
fn finalize ( & mut self ) -> FinalizeResult {
@@ -103,12 +136,11 @@ pub struct IdentificationHeader {
103
136
pub channel_mapping : [ u8 ; 8 ] ,
104
137
}
105
138
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
- */
139
+ /// Create an IdentificationHeader from a reader.
140
+ ///
141
+ /// If the header is invalid, a DecodeError is returned.
142
+ ///
143
+ /// See RFC 7845 Section 5.1, https://tools.ietf.org/pdf/rfc7845.pdf.
112
144
fn read_ident_header < B : ReadBytes > ( reader : & mut B ) -> Result < IdentificationHeader > {
113
145
// The first 8 bytes are the magic signature ASCII bytes.
114
146
const OGG_OPUS_MAGIC_SIGNATURE : & [ u8 ] = b"OpusHead" ;
0 commit comments