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:: { AsGenericAudioBufferRef , AudioBuffer , GenericAudioBufferRef } ;
20
20
use symphonia_core:: codecs:: audio:: well_known:: CODEC_ID_OPUS ;
21
21
use symphonia_core:: codecs:: audio:: {
22
22
AudioCodecParameters , AudioDecoder , AudioDecoderOptions , FinalizeResult ,
@@ -32,6 +32,18 @@ use symphonia_core::support_audio_codec;
32
32
pub struct OpusDecoder {
33
33
ident_header : IdentificationHeader ,
34
34
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 ,
35
47
}
36
48
37
49
impl OpusDecoder {
@@ -44,7 +56,7 @@ impl OpusDecoder {
44
56
let mut reader = BufReader :: new ( extra_data) ;
45
57
46
58
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 ( ) } )
48
60
}
49
61
}
50
62
@@ -63,7 +75,22 @@ impl AudioDecoder for OpusDecoder {
63
75
64
76
#[ allow( unused_variables) ]
65
77
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 ( ) )
67
94
}
68
95
69
96
fn finalize ( & mut self ) -> FinalizeResult {
@@ -103,12 +130,11 @@ pub struct IdentificationHeader {
103
130
pub channel_mapping : [ u8 ; 8 ] ,
104
131
}
105
132
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.
112
138
fn read_ident_header < B : ReadBytes > ( reader : & mut B ) -> Result < IdentificationHeader > {
113
139
// The first 8 bytes are the magic signature ASCII bytes.
114
140
const OGG_OPUS_MAGIC_SIGNATURE : & [ u8 ] = b"OpusHead" ;
0 commit comments