1use crate::bitstream::BitstreamWriter;
8use crate::error::{EncodingError, EncodingResult};
9use crate::tables::{BITRATES, SAMPLERATES};
10use crate::types::{ShineGlobalConfig, ShineSideInfo, GRANULE_SIZE};
11
12const BUFFER_SIZE: i32 = 4096;
15
16pub const MPEG_I: i32 = 3;
19pub const MPEG_II: i32 = 2;
20pub const MPEG_25: i32 = 0;
21
22pub const LAYER_III: i32 = 1;
25
26pub const NONE: i32 = 0;
29
30static GRANULES_PER_FRAME: [i32; 4] = [
33 1, -1, 1, 2, ];
38
39#[repr(C)]
42#[derive(Debug, Clone)]
43pub struct ShineWave {
44 pub channels: i32,
45 pub samplerate: i32,
46}
47
48impl Default for ShineWave {
49 fn default() -> Self {
50 Self {
51 channels: 2,
52 samplerate: 44100,
53 }
54 }
55}
56
57#[repr(C)]
60#[derive(Debug, Clone)]
61pub struct ShineMpeg {
62 pub mode: i32,
63 pub bitr: i32,
64 pub emph: i32,
65 pub copyright: i32,
66 pub original: i32,
67}
68
69impl Default for ShineMpeg {
70 fn default() -> Self {
71 let mut mpeg = Self {
72 mode: 0,
73 bitr: 128,
74 emph: NONE,
75 copyright: 0,
76 original: 1,
77 };
78 shine_set_config_mpeg_defaults(&mut mpeg);
79 mpeg
80 }
81}
82
83#[repr(C)]
86#[derive(Debug, Clone, Default)]
87pub struct ShineConfig {
88 pub wave: ShineWave,
89 pub mpeg: ShineMpeg,
90}
91
92pub fn shine_set_config_mpeg_defaults(mpeg: &mut ShineMpeg) {
95 mpeg.bitr = 128;
96 mpeg.emph = NONE;
97 mpeg.copyright = 0;
98 mpeg.original = 1;
99}
100
101pub fn shine_mpeg_version(samplerate_index: i32) -> i32 {
104 if samplerate_index < 3 {
105 MPEG_I
107 } else if samplerate_index < 6 {
108 MPEG_II
110 } else {
111 MPEG_25
113 }
114}
115
116pub fn shine_find_samplerate_index(freq: i32) -> i32 {
119 SAMPLERATES
120 .iter()
121 .position(|&rate| rate == freq)
122 .map(|i| i as i32)
123 .unwrap_or(-1)
124}
125
126pub fn shine_find_bitrate_index(bitr: i32, mpeg_version: i32) -> i32 {
129 BITRATES
130 .iter()
131 .position(|&rates| rates[mpeg_version as usize] == bitr)
132 .map(|i| i as i32)
133 .unwrap_or(-1)
134}
135
136pub fn shine_check_config(freq: i32, bitr: i32) -> i32 {
139 let samplerate_index = shine_find_samplerate_index(freq);
140 if samplerate_index < 0 {
141 return -1;
142 }
143
144 let mpeg_version = shine_mpeg_version(samplerate_index);
145
146 let bitrate_index = shine_find_bitrate_index(bitr, mpeg_version);
147 if bitrate_index < 0 {
148 return -1;
149 }
150
151 mpeg_version
152}
153
154pub fn shine_samples_per_pass(config: &ShineGlobalConfig) -> i32 {
157 config.mpeg.granules_per_frame * GRANULE_SIZE as i32
158}
159
160pub fn shine_initialise(pub_config: &ShineConfig) -> EncodingResult<Box<ShineGlobalConfig>> {
163 if shine_check_config(pub_config.wave.samplerate, pub_config.mpeg.bitr) < 0 {
164 return Err(EncodingError::ValidationError(
165 "Invalid configuration".to_string(),
166 ));
167 }
168
169 let mut config = Box::new(ShineGlobalConfig::default());
170
171 crate::subband::shine_subband_initialise(&mut config.subband);
173 crate::mdct::shine_mdct_initialise(&mut config);
174 crate::quantization::shine_loop_initialise(&mut config);
175
176 config.wave.channels = pub_config.wave.channels;
178 config.wave.samplerate = pub_config.wave.samplerate;
179 config.mpeg.mode = pub_config.mpeg.mode;
180 config.mpeg.bitr = pub_config.mpeg.bitr;
181 config.mpeg.emph = pub_config.mpeg.emph;
182 config.mpeg.copyright = pub_config.mpeg.copyright;
183 config.mpeg.original = pub_config.mpeg.original;
184
185 config.resv_max = 0;
187 config.resv_size = 0;
188 config.mpeg.layer = LAYER_III;
189 config.mpeg.crc = 0;
190 config.mpeg.ext = 0;
191 config.mpeg.mode_ext = 0;
192 config.mpeg.bits_per_slot = 8;
193
194 config.mpeg.samplerate_index = shine_find_samplerate_index(config.wave.samplerate);
195 config.mpeg.version = shine_mpeg_version(config.mpeg.samplerate_index);
196 config.mpeg.bitrate_index = shine_find_bitrate_index(config.mpeg.bitr, config.mpeg.version);
197 config.mpeg.granules_per_frame = GRANULES_PER_FRAME[config.mpeg.version as usize];
198
199 let avg_slots_per_frame = (config.mpeg.granules_per_frame as f64 * GRANULE_SIZE as f64
201 / config.wave.samplerate as f64)
202 * (1000.0 * config.mpeg.bitr as f64 / config.mpeg.bits_per_slot as f64);
203
204 config.mpeg.whole_slots_per_frame = avg_slots_per_frame as i32;
205
206 config.mpeg.frac_slots_per_frame =
207 avg_slots_per_frame - config.mpeg.whole_slots_per_frame as f64;
208 config.mpeg.slot_lag = -config.mpeg.frac_slots_per_frame;
209
210 if config.mpeg.frac_slots_per_frame == 0.0 {
211 config.mpeg.padding = 0;
212 }
213
214 config.bs = BitstreamWriter::new(BUFFER_SIZE);
215
216 config.side_info = ShineSideInfo::default();
218
219 if config.mpeg.granules_per_frame == 2 {
221 config.sideinfo_len = 8 * if config.wave.channels == 1 {
223 4 + 17
224 } else {
225 4 + 32
226 };
227 } else {
228 config.sideinfo_len = 8 * if config.wave.channels == 1 {
230 4 + 9
231 } else {
232 4 + 17
233 };
234 }
235
236 Ok(config)
237}
238
239fn shine_encode_buffer_internal(
242 config: &mut ShineGlobalConfig,
243 stride: i32,
244) -> EncodingResult<(&[u8], usize)> {
245 #[cfg(feature = "diagnostics")]
246 let frame_num = crate::get_next_frame_number();
247
248 #[cfg(feature = "diagnostics")]
250 crate::diagnostics::start_frame_collection(frame_num);
251
252 if config.mpeg.frac_slots_per_frame != 0.0 {
254 config.mpeg.padding = if config.mpeg.slot_lag <= (config.mpeg.frac_slots_per_frame - 1.0) {
255 1
256 } else {
257 0
258 };
259 config.mpeg.slot_lag += config.mpeg.padding as f64 - config.mpeg.frac_slots_per_frame;
260 }
261
262 config.mpeg.bits_per_frame = 8 * (config.mpeg.whole_slots_per_frame + config.mpeg.padding);
263 config.mean_bits =
264 (config.mpeg.bits_per_frame - config.sideinfo_len) / config.mpeg.granules_per_frame;
265
266 crate::mdct::shine_mdct_sub(config, stride);
268
269 crate::quantization::shine_iteration_loop(config);
271
272 crate::bitstream::format_bitstream(config)?;
274
275 let written = config.bs.data_position as usize;
277 config.bs.data_position = 0;
278
279 #[cfg(feature = "diagnostics")]
281 {
282 }
284
285 #[cfg(feature = "diagnostics")]
287 crate::diagnostics::record_bitstream_data(
288 config.mpeg.padding,
289 config.mpeg.bits_per_frame,
290 written,
291 config.mpeg.slot_lag,
292 );
293
294 Ok((&config.bs.data[..written], written))
295}
296
297pub fn shine_encode_buffer<'a>(
300 config: &'a mut ShineGlobalConfig,
301 data: &[*const i16],
302) -> EncodingResult<(&'a [u8], usize)> {
303 config.buffer[0] = data[0] as *mut i16;
304 if config.wave.channels == 2 {
305 config.buffer[1] = data[1] as *mut i16;
306 }
307
308 shine_encode_buffer_internal(config, 1)
309}
310
311pub unsafe fn shine_encode_buffer_interleaved(
323 config: &mut ShineGlobalConfig,
324 data: *const i16,
325) -> EncodingResult<(&[u8], usize)> {
326 config.buffer[0] = data as *mut i16;
327 if config.wave.channels == 2 {
328 config.buffer[1] = data.offset(1) as *mut i16;
329 }
330
331 shine_encode_buffer_internal(config, config.wave.channels)
332}
333
334pub fn shine_flush(config: &mut ShineGlobalConfig) -> (&[u8], usize) {
337 let written = config.bs.data_position as usize;
341 config.bs.data_position = 0;
342
343 (&config.bs.data[..written], written)
344}
345
346pub fn shine_close(_config: Box<ShineGlobalConfig>) {
349 }