1use crate::error::{EncodingError, EncodingResult};
8use crate::types::{ShineGlobalConfig, ShineSideInfo, GRANULE_SIZE};
9use crate::tables::{SAMPLERATES, BITRATES};
10use crate::bitstream::BitstreamWriter;
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
48#[repr(C)]
51#[derive(Debug, Clone)]
52pub struct ShineMpeg {
53 pub mode: i32,
54 pub bitr: i32,
55 pub emph: i32,
56 pub copyright: i32,
57 pub original: i32,
58}
59
60#[repr(C)]
63#[derive(Debug, Clone)]
64pub struct ShineConfig {
65 pub wave: ShineWave,
66 pub mpeg: ShineMpeg,
67}
68
69pub fn shine_set_config_mpeg_defaults(mpeg: &mut ShineMpeg) {
72 mpeg.bitr = 128;
73 mpeg.emph = NONE;
74 mpeg.copyright = 0;
75 mpeg.original = 1;
76}
77
78pub fn shine_mpeg_version(samplerate_index: i32) -> i32 {
81 if samplerate_index < 3 {
82 MPEG_I
84 } else if samplerate_index < 6 {
85 MPEG_II
87 } else {
88 MPEG_25
90 }
91}
92
93pub fn shine_find_samplerate_index(freq: i32) -> i32 {
96 for i in 0..9 {
97 if freq == SAMPLERATES[i] {
98 return i as i32;
99 }
100 }
101 -1 }
103
104pub fn shine_find_bitrate_index(bitr: i32, mpeg_version: i32) -> i32 {
107 for i in 0..16 {
108 if bitr == BITRATES[i][mpeg_version as usize] {
109 return i as i32;
110 }
111 }
112 -1 }
114
115pub fn shine_check_config(freq: i32, bitr: i32) -> i32 {
118 let samplerate_index = shine_find_samplerate_index(freq);
119 if samplerate_index < 0 {
120 return -1;
121 }
122
123 let mpeg_version = shine_mpeg_version(samplerate_index);
124
125 let bitrate_index = shine_find_bitrate_index(bitr, mpeg_version);
126 if bitrate_index < 0 {
127 return -1;
128 }
129
130 mpeg_version
131}
132
133pub fn shine_samples_per_pass(config: &ShineGlobalConfig) -> i32 {
136 config.mpeg.granules_per_frame * GRANULE_SIZE as i32
137}
138
139pub fn shine_initialise(pub_config: &ShineConfig) -> EncodingResult<Box<ShineGlobalConfig>> {
142 if shine_check_config(pub_config.wave.samplerate, pub_config.mpeg.bitr) < 0 {
143 return Err(EncodingError::ValidationError("Invalid configuration".to_string()));
144 }
145
146 let mut config = Box::new(ShineGlobalConfig::default());
147
148 crate::subband::shine_subband_initialise(&mut config.subband);
150 crate::mdct::shine_mdct_initialise(&mut config);
151 crate::quantization::shine_loop_initialise(&mut config);
152
153 config.wave.channels = pub_config.wave.channels;
155 config.wave.samplerate = pub_config.wave.samplerate;
156 config.mpeg.mode = pub_config.mpeg.mode;
157 config.mpeg.bitr = pub_config.mpeg.bitr;
158 config.mpeg.emph = pub_config.mpeg.emph;
159 config.mpeg.copyright = pub_config.mpeg.copyright;
160 config.mpeg.original = pub_config.mpeg.original;
161
162 config.resv_max = 0;
164 config.resv_size = 0;
165 config.mpeg.layer = LAYER_III;
166 config.mpeg.crc = 0;
167 config.mpeg.ext = 0;
168 config.mpeg.mode_ext = 0;
169 config.mpeg.bits_per_slot = 8;
170
171 config.mpeg.samplerate_index = shine_find_samplerate_index(config.wave.samplerate);
172 config.mpeg.version = shine_mpeg_version(config.mpeg.samplerate_index);
173 config.mpeg.bitrate_index = shine_find_bitrate_index(config.mpeg.bitr, config.mpeg.version);
174 config.mpeg.granules_per_frame = GRANULES_PER_FRAME[config.mpeg.version as usize];
175
176 let avg_slots_per_frame = (config.mpeg.granules_per_frame as f64 * GRANULE_SIZE as f64 /
178 config.wave.samplerate as f64) *
179 (1000.0 * config.mpeg.bitr as f64 / config.mpeg.bits_per_slot as f64);
180
181 config.mpeg.whole_slots_per_frame = avg_slots_per_frame as i32;
182
183 config.mpeg.frac_slots_per_frame = avg_slots_per_frame - config.mpeg.whole_slots_per_frame as f64;
184 config.mpeg.slot_lag = -config.mpeg.frac_slots_per_frame;
185
186 if config.mpeg.frac_slots_per_frame == 0.0 {
187 config.mpeg.padding = 0;
188 }
189
190 config.bs = BitstreamWriter::new(BUFFER_SIZE);
191
192 config.side_info = ShineSideInfo::default();
194
195 if config.mpeg.granules_per_frame == 2 {
197 config.sideinfo_len = 8 * if config.wave.channels == 1 { 4 + 17 } else { 4 + 32 };
199 } else {
200 config.sideinfo_len = 8 * if config.wave.channels == 1 { 4 + 9 } else { 4 + 17 };
202 }
203
204 Ok(config)
205}
206
207fn shine_encode_buffer_internal(config: &mut ShineGlobalConfig, stride: i32) -> EncodingResult<(&[u8], usize)> {
210 #[cfg(any(debug_assertions, feature = "diagnostics"))]
211 let frame_num = crate::get_next_frame_number();
212
213 #[cfg(feature = "diagnostics")]
215 crate::diagnostics_data::start_frame_collection(frame_num);
216
217 if config.mpeg.frac_slots_per_frame != 0.0 {
219 config.mpeg.padding = if config.mpeg.slot_lag <= (config.mpeg.frac_slots_per_frame - 1.0) { 1 } else { 0 };
220 config.mpeg.slot_lag += config.mpeg.padding as f64 - config.mpeg.frac_slots_per_frame;
221 }
222
223 config.mpeg.bits_per_frame = 8 * (config.mpeg.whole_slots_per_frame + config.mpeg.padding);
224 config.mean_bits = (config.mpeg.bits_per_frame - config.sideinfo_len) / config.mpeg.granules_per_frame;
225
226 crate::mdct::shine_mdct_sub(config, stride);
228
229 crate::quantization::shine_iteration_loop(config);
231
232 crate::bitstream::format_bitstream(config)?;
234
235 let written = config.bs.data_position as usize;
237 config.bs.data_position = 0;
238
239 #[cfg(any(debug_assertions, feature = "diagnostics"))]
241 {
242 use log::debug;
243 debug!("[Frame {}] pad={}, bits={}, written={}, slot_lag={:.6}",
244 frame_num, config.mpeg.padding, config.mpeg.bits_per_frame, written, config.mpeg.slot_lag);
245 }
246
247 #[cfg(feature = "diagnostics")]
249 crate::diagnostics_data::record_bitstream_data(
250 config.mpeg.padding,
251 config.mpeg.bits_per_frame,
252 written,
253 config.mpeg.slot_lag
254 );
255
256 #[cfg(any(debug_assertions, feature = "diagnostics"))]
258 {
259 if let Ok(max_frames_str) = std::env::var("RUST_MP3_MAX_FRAMES") {
261 if let Ok(max_frames) = max_frames_str.parse::<i32>() {
262 if frame_num > max_frames {
263 #[cfg(any(debug_assertions, feature = "diagnostics"))]
264 {
265 use log::info;
266 info!("[RUST] Stopping after {} frames for comparison", max_frames);
267 }
268 return Err(EncodingError::StopAfterFrames);
270 }
271 }
272 }
273 }
274
275 Ok((&config.bs.data[..written], written))
276}
277
278pub fn shine_encode_buffer<'a>(config: &'a mut ShineGlobalConfig, data: &[*const i16]) -> EncodingResult<(&'a [u8], usize)> {
281 config.buffer[0] = data[0] as *mut i16;
282 if config.wave.channels == 2 {
283 config.buffer[1] = data[1] as *mut i16;
284 }
285
286 shine_encode_buffer_internal(config, 1)
287}
288
289pub unsafe fn shine_encode_buffer_interleaved(config: &mut ShineGlobalConfig, data: *const i16) -> EncodingResult<(&[u8], usize)> {
292 config.buffer[0] = data as *mut i16;
293 if config.wave.channels == 2 {
294 config.buffer[1] = data.offset(1) as *mut i16;
295 }
296
297 shine_encode_buffer_internal(config, config.wave.channels)
298}
299
300pub fn shine_flush(config: &mut ShineGlobalConfig) -> (&[u8], usize) {
303 let written = config.bs.data_position as usize;
307 config.bs.data_position = 0;
308
309 (&config.bs.data[..written], written)
310}
311
312pub fn shine_close(_config: Box<ShineGlobalConfig>) {
315 }