flac/
flac.rs

1#![allow(dead_code)]
2#![allow(unused_imports)]
3#![allow(clippy::map_entry)]
4#![allow(clippy::type_complexity)]
5#![allow(clippy::too_many_arguments)]
6#![allow(clippy::enum_variant_names)]
7
8const SHOW_CALLBACKS: bool = false;
9
10use std::{any::Any, io::{Read, Write, Seek}};
11
12use std::io::SeekFrom;
13
14/// ## The compression level of the FLAC file
15/// A higher number means less file size. Default compression level is 5
16#[derive(Debug, Clone, Copy, PartialEq)]
17pub enum FlacCompression {
18    /// Almost no compression
19    Level0 = 0,
20    Level1 = 1,
21    Level2 = 2,
22    Level3 = 3,
23    Level4 = 4,
24    Level5 = 5,
25    Level6 = 6,
26    Level7 = 7,
27
28    /// Maximum compression
29    Level8 = 8
30}
31
32/// ## Parameters for the encoder to encode the audio.
33#[derive(Debug, Clone, Copy, PartialEq)]
34pub struct FlacEncoderParams {
35    /// * If set to true, the FLAC encoder will send the encoded data to a decoder to verify if the encoding is successful, and the encoding process will be slower.
36    pub verify_decoded: bool,
37
38    /// * The compression level of the FLAC file, a higher number means less file size.
39    pub compression: FlacCompression,
40
41    /// * Num channels of the audio file, max channels is 8.
42    pub channels: u16,
43
44    /// * The sample rate of the audio file. Every FLAC frame contains this value.
45    pub sample_rate: u32,
46
47    /// * How many bits in an `i32` are valid for a sample, for example, if this value is 16, your `i32` sample should be between -32768 to +32767.
48    ///   Because the FLAC encoder **only eats `[i32]`** , and you can't just pass `[i16]` to it.
49    ///   It seems like 8, 12, 16, 20, 24, 32 are valid values for this field.
50    pub bits_per_sample: u32,
51
52    /// * How many samples you will put into the encoder, set to zero if you don't know.
53    pub total_samples_estimate: u64,
54}
55
56impl FlacEncoderParams {
57    pub fn new() -> Self {
58        Self {
59            verify_decoded: false,
60            compression: FlacCompression::Level5,
61            channels: 2,
62            sample_rate: 44100,
63            bits_per_sample: 16,
64            total_samples_estimate: 0,
65        }
66    }
67}
68
69impl Default for FlacEncoderParams {
70    fn default() -> Self {
71        Self::new()
72    }
73}
74
75use std::{borrow::Cow, io::{self, ErrorKind}, fmt::{self, Debug, Display, Formatter}, slice, ffi::{CStr, c_void}, ptr, collections::BTreeMap};
76
77#[cfg(feature = "id3")]
78use id3::{self, TagLike};
79
80use libflac_sys::*;
81
82/// ## A trait for me to coveniently write `FlacDecoderError`, `FlacDecoderInitError`, `FlacEncoderError`, `FlacEncoderInitError`
83/// Not for you to use.
84pub trait FlacError: Any {
85    /// * This method allows the trait to be able to downcast to a specific error struct.
86    fn as_any(&self) -> &dyn Any;
87
88    /// * Get the error or status code from the error struct. The code depends on which type of the error struct.
89    fn get_code(&self) -> u32;
90
91    /// * Get the message that describes the error code, mostly useful if you don't know what exact the error type is.
92    fn get_message(&self) -> &'static str;
93
94    /// * On which function call to get the error. Also useful for addressing errors.
95    fn get_function(&self) -> &'static str;
96
97    /// * This function is implemented by the specific error struct, each struct has a different way to describe the code.
98    fn get_message_from_code(&self) -> &'static str;
99
100    /// * The common formatter for the error.
101    fn format(&self, f: &mut Formatter) -> fmt::Result {
102        let code = self.get_code();
103        let message = self.get_message();
104        let function = self.get_function();
105        write!(f, "Code: {code}, function: {function}, message: {message}")?;
106        Ok(())
107    }
108}
109
110macro_rules! impl_FlacError {
111    ($error:ty) => {
112        impl FlacError for $error {
113            fn as_any(&self) -> &dyn Any {self}
114            fn get_code(&self) -> u32 {self.code}
115            fn get_message(&self) -> &'static str {self.message}
116            fn get_function(&self) -> &'static str {self.function}
117            fn get_message_from_code(&self) -> &'static str {
118                Self::get_message_from_code(self.get_code())
119            }
120        }
121
122        impl std::error::Error for $error {}
123
124        impl Display for $error {
125            fn fmt(&self, f: &mut Formatter) -> fmt::Result {
126                <$error as FlacError>::format(self, f)
127            }
128        }
129    }
130}
131
132/// ## Error info for the encoder, most of the encoder functions return this.
133#[derive(Debug, Clone, Copy)]
134pub struct FlacEncoderError {
135    /// * This code is actually `FlacEncoderErrorCode`
136    pub code: u32,
137
138    /// * The description of the status, as a constant string from `libflac-sys`
139    pub message: &'static str,
140
141    /// * Which function generates this error
142    pub function: &'static str,
143}
144
145impl FlacEncoderError {
146    pub fn new(code: u32, function: &'static str) -> Self {
147        Self {
148            code,
149            message: Self::get_message_from_code(code),
150            function,
151        }
152    }
153
154    pub fn get_message_from_code(code: u32) -> &'static str {
155        unsafe {
156            CStr::from_ptr(*FLAC__StreamEncoderStateString.as_ptr().add(code as usize)).to_str().unwrap()
157        }
158    }
159}
160
161impl_FlacError!(FlacEncoderError);
162
163/// ## The error code for `FlacEncoderError`
164#[derive(Debug, Clone, Copy)]
165pub enum FlacEncoderErrorCode {
166    /// * The encoder is in the normal OK state and samples can be processed.
167    StreamEncoderOk = FLAC__STREAM_ENCODER_OK as isize,
168
169    /// * The encoder is in the uninitialized state; one of the FLAC__stream_encoder_init_*() functions must be called before samples can be processed.
170    StreamEncoderUninitialized = FLAC__STREAM_ENCODER_UNINITIALIZED as isize,
171
172    /// * An error occurred in the underlying Ogg layer.
173    StreamEncoderOggError = FLAC__STREAM_ENCODER_OGG_ERROR as isize,
174
175    /// * An error occurred in the underlying verify stream decoder; check FLAC__stream_encoder_get_verify_decoder_state().
176    StreamEncoderVerifyDecoderError = FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR as isize,
177
178    /// * The verify decoder detected a mismatch between the original audio signal and the decoded audio signal.
179    StreamEncoderVerifyMismatchInAudioData = FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA as isize,
180
181    /// * One of the closures returned a fatal error.
182    StreamEncoderClientError = FLAC__STREAM_ENCODER_CLIENT_ERROR as isize,
183
184    /// * An I/O error occurred while opening/reading/writing a file.
185    StreamEncoderIOError = FLAC__STREAM_ENCODER_IO_ERROR as isize,
186
187    /// * An error occurred while writing the stream; usually, the `on_write()` returned an error.
188    StreamEncoderFramingError = FLAC__STREAM_ENCODER_FRAMING_ERROR as isize,
189
190    /// * Memory allocation failed
191    StreamEncoderMemoryAllocationError = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR as isize,
192}
193
194impl Display for FlacEncoderErrorCode {
195    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
196        match self {
197            Self::StreamEncoderOk => write!(f, "The encoder is in the normal OK state and samples can be processed."),
198            Self::StreamEncoderUninitialized => write!(f, "The encoder is in the uninitialized state; one of the FLAC__stream_encoder_init_*() functions must be called before samples can be processed."),
199            Self::StreamEncoderOggError => write!(f, "An error occurred in the underlying Ogg layer."),
200            Self::StreamEncoderVerifyDecoderError => write!(f, "An error occurred in the underlying verify stream decoder; check FLAC__stream_encoder_get_verify_decoder_state()."),
201            Self::StreamEncoderVerifyMismatchInAudioData => write!(f, "The verify decoder detected a mismatch between the original audio signal and the decoded audio signal."),
202            Self::StreamEncoderClientError => write!(f, "One of the closures returned a fatal error."),
203            Self::StreamEncoderIOError => write!(f, "An I/O error occurred while opening/reading/writing a file."),
204            Self::StreamEncoderFramingError => write!(f, "An error occurred while writing the stream; usually, the `on_write()` returned an error."),
205            Self::StreamEncoderMemoryAllocationError => write!(f, "Memory allocation failed."),
206        }
207    }
208}
209
210impl From<u32> for FlacEncoderErrorCode {
211    fn from(code: u32) -> Self {
212        use FlacEncoderErrorCode::*;
213        match code {
214            FLAC__STREAM_ENCODER_OK => StreamEncoderOk,
215            FLAC__STREAM_ENCODER_UNINITIALIZED => StreamEncoderUninitialized,
216            FLAC__STREAM_ENCODER_OGG_ERROR => StreamEncoderOggError,
217            FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR => StreamEncoderVerifyDecoderError,
218            FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA => StreamEncoderVerifyMismatchInAudioData,
219            FLAC__STREAM_ENCODER_CLIENT_ERROR => StreamEncoderClientError,
220            FLAC__STREAM_ENCODER_IO_ERROR => StreamEncoderIOError,
221            FLAC__STREAM_ENCODER_FRAMING_ERROR  => StreamEncoderFramingError,
222            FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR => StreamEncoderMemoryAllocationError,
223            o => panic!("Not an encoder error code: {o}."),
224        }
225    }
226}
227
228impl std::error::Error for FlacEncoderErrorCode {}
229
230/// ## Error info for `initialize()`
231#[derive(Debug, Clone, Copy)]
232pub struct FlacEncoderInitError {
233    /// * This code is actually `FlacEncoderInitErrorCode`
234    pub code: u32,
235
236    /// * The description of the status, as a constant string from `libflac-sys`
237    pub message: &'static str,
238
239    /// * Which function generates this error
240    pub function: &'static str,
241}
242
243impl FlacEncoderInitError {
244    pub fn new(code: u32, function: &'static str) -> Self {
245        Self {
246            code,
247            message: Self::get_message_from_code(code),
248            function,
249        }
250    }
251
252    pub fn get_message_from_code(code: u32) -> &'static str {
253        unsafe {
254            CStr::from_ptr(*FLAC__StreamEncoderInitStatusString.as_ptr().add(code as usize)).to_str().unwrap()
255        }
256    }
257}
258
259impl_FlacError!(FlacEncoderInitError);
260
261/// ## The error code for `FlacEncoderInitError`
262#[derive(Debug, Clone, Copy)]
263pub enum FlacEncoderInitErrorCode {
264    /// * Initialization was successful
265    StreamEncoderInitStatusOk = FLAC__STREAM_ENCODER_INIT_STATUS_OK as isize,
266
267    /// * General failure to set up encoder; call FLAC__stream_encoder_get_state() for cause.
268    StreamEncoderInitStatusEncoderError = FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR as isize,
269
270    /// * The library was not compiled with support for the given container format.
271    StreamEncoderInitStatusUnsupportedContainer = FLAC__STREAM_ENCODER_INIT_STATUS_UNSUPPORTED_CONTAINER as isize,
272
273    /// * A required callback was not supplied.
274    StreamEncoderInitStatusInvalidCallbacks = FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_CALLBACKS as isize,
275
276    /// * The encoder has an invalid setting for number of channels.
277    StreamEncoderInitStatusInvalidNumberOfChannels = FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_NUMBER_OF_CHANNELS as isize,
278
279    /// * The encoder has an invalid setting for bits-per-sample. FLAC supports 4-32 bps.
280    StreamEncoderInitStatusInvalidBitsPerSample = FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BITS_PER_SAMPLE as isize,
281
282    /// * The encoder has an invalid setting for the input sample rate.
283    StreamEncoderInitStatusInvalidSampleRate = FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_SAMPLE_RATE as isize,
284
285    /// * The encoder has an invalid setting for the block size.
286    StreamEncoderInitStatusInvalidBlockSize = FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BLOCK_SIZE as isize,
287
288    /// * The encoder has an invalid setting for the maximum LPC order.
289    StreamEncoderInitStatusInvalidMaxLpcOrder = FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_MAX_LPC_ORDER as isize,
290
291    /// * The encoder has an invalid setting for the precision of the quantized linear predictor coefficients.
292    StreamEncoderInitStatusInvalidQlpCoeffPrecision = FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_QLP_COEFF_PRECISION as isize,
293
294    /// * The specified block size is less than the maximum LPC order.
295    StreamEncoderInitStatusBlockSizeTooSmallForLpcOrder = FLAC__STREAM_ENCODER_INIT_STATUS_BLOCK_SIZE_TOO_SMALL_FOR_LPC_ORDER as isize,
296
297    /// * The encoder is bound to the Subset but other settings violate it.
298    StreamEncoderInitStatusNotStreamable = FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE as isize,
299
300    /// * The metadata input to the encoder is invalid, in one of the following ways:
301    ///   * FLAC__stream_encoder_set_metadata() was called with a null pointer but a block count > 0
302    ///   * One of the metadata blocks contains an undefined type
303    ///   * It contains an illegal CUESHEET as checked by FLAC__format_cuesheet_is_legal()
304    ///   * It contains an illegal SEEKTABLE as checked by FLAC__format_seektable_is_legal()
305    ///   * It contains more than one SEEKTABLE block or more than one VORBIS_COMMENT block
306    ///   * FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED
307    ///   * FLAC__stream_encoder_init_*() was called when the encoder was already initialized, usually because FLAC__stream_encoder_finish() was not called.
308    StreamEncoderInitStatusInvalidMetadata = FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA as isize,
309
310    /// * FLAC__stream_encoder_init_*() was called when the encoder was already initialized, usually because FLAC__stream_encoder_finish() was not called.
311    StreamEncoderInitStatusAlreadyInitialized = FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED as isize,
312}
313
314impl Display for FlacEncoderInitErrorCode {
315    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
316        match self {
317            Self::StreamEncoderInitStatusOk => write!(f, "Initialization was successful."),
318            Self::StreamEncoderInitStatusEncoderError => write!(f, "General failure to set up encoder; call FLAC__stream_encoder_get_state() for cause."),
319            Self::StreamEncoderInitStatusUnsupportedContainer => write!(f, "The library was not compiled with support for the given container format."),
320            Self::StreamEncoderInitStatusInvalidCallbacks => write!(f, "A required callback was not supplied."),
321            Self::StreamEncoderInitStatusInvalidNumberOfChannels => write!(f, "The encoder has an invalid setting for number of channels."),
322            Self::StreamEncoderInitStatusInvalidBitsPerSample => write!(f, "The encoder has an invalid setting for bits-per-sample. FLAC supports 4-32 bps."),
323            Self::StreamEncoderInitStatusInvalidSampleRate => write!(f, "The encoder has an invalid setting for the input sample rate."),
324            Self::StreamEncoderInitStatusInvalidBlockSize => write!(f, "The encoder has an invalid setting for the block size."),
325            Self::StreamEncoderInitStatusInvalidMaxLpcOrder => write!(f, "The encoder has an invalid setting for the maximum LPC order."),
326            Self::StreamEncoderInitStatusInvalidQlpCoeffPrecision => write!(f, "The encoder has an invalid setting for the precision of the quantized linear predictor coefficients."),
327            Self::StreamEncoderInitStatusBlockSizeTooSmallForLpcOrder => write!(f, "The specified block size is less than the maximum LPC order."),
328            Self::StreamEncoderInitStatusNotStreamable => write!(f, "The encoder is bound to the Subset but other settings violate it."),
329            Self::StreamEncoderInitStatusInvalidMetadata => write!(f, "The metadata input to the encoder is invalid, in one of the following ways:\n\n* FLAC__stream_encoder_set_metadata() was called with a null pointer but a block count > 0\n* One of the metadata blocks contains an undefined type\n* It contains an illegal CUESHEET as checked by FLAC__format_cuesheet_is_legal()\n* It contains an illegal SEEKTABLE as checked by FLAC__format_seektable_is_legal()\n* It contains more than one SEEKTABLE block or more than one VORBIS_COMMENT block\n* FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED\n* FLAC__stream_encoder_init_*() was called when the encoder was already initialized, usually because FLAC__stream_encoder_finish() was not called."),
330            Self::StreamEncoderInitStatusAlreadyInitialized => write!(f, "FLAC__stream_encoder_init_*() was called when the encoder was already initialized, usually because FLAC__stream_encoder_finish() was not called."),
331        }
332    }
333}
334
335impl From<u32> for FlacEncoderInitErrorCode {
336    fn from(code: u32) -> Self {
337        use FlacEncoderInitErrorCode::*;
338        match code {
339            FLAC__STREAM_ENCODER_INIT_STATUS_OK => StreamEncoderInitStatusOk,
340            FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR => StreamEncoderInitStatusEncoderError,
341            FLAC__STREAM_ENCODER_INIT_STATUS_UNSUPPORTED_CONTAINER => StreamEncoderInitStatusUnsupportedContainer,
342            FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_CALLBACKS => StreamEncoderInitStatusInvalidCallbacks,
343            FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_NUMBER_OF_CHANNELS => StreamEncoderInitStatusInvalidNumberOfChannels,
344            FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BITS_PER_SAMPLE => StreamEncoderInitStatusInvalidBitsPerSample,
345            FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_SAMPLE_RATE => StreamEncoderInitStatusInvalidSampleRate,
346            FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BLOCK_SIZE => StreamEncoderInitStatusInvalidBlockSize,
347            FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_MAX_LPC_ORDER => StreamEncoderInitStatusInvalidMaxLpcOrder,
348            FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_QLP_COEFF_PRECISION => StreamEncoderInitStatusInvalidQlpCoeffPrecision,
349            FLAC__STREAM_ENCODER_INIT_STATUS_BLOCK_SIZE_TOO_SMALL_FOR_LPC_ORDER => StreamEncoderInitStatusBlockSizeTooSmallForLpcOrder,
350            FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE => StreamEncoderInitStatusNotStreamable,
351            FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA => StreamEncoderInitStatusInvalidMetadata,
352            FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED => StreamEncoderInitStatusAlreadyInitialized,
353            o => panic!("Not an encoder init error code: {o}."),
354        }
355    }
356}
357
358impl std::error::Error for FlacEncoderInitErrorCode {}
359
360impl From<FlacEncoderError> for FlacEncoderInitError {
361    fn from(err: FlacEncoderError) -> Self {
362        Self {
363            code: err.code,
364            message: err.message,
365            function: err.function,
366        }
367    }
368}
369
370impl From<FlacEncoderInitError> for FlacEncoderError {
371    fn from(err: FlacEncoderInitError) -> Self {
372        Self {
373            code: err.code,
374            message: err.message,
375            function: err.function,
376        }
377    }
378}
379
380/// ## Available comment keys for metadata usage.
381pub const COMMENT_KEYS: [&str; 33] = [
382    "ACTOR",
383    "ALBUM",
384    "ARTIST",
385    "ALBUMARTIST",
386    "COMMENT",
387    "COMPOSER",
388    "CONTACT",
389    "COPYRIGHT",
390    "COVERART",
391    "COVERARTMIME",
392    "DATE",
393    "DESCRIPTION",
394    "DIRECTOR",
395    "ENCODED_BY",
396    "ENCODED_USING",
397    "ENCODER",
398    "ENCODER_OPTIONS",
399    "GENRE",
400    "ISRC",
401    "LICENSE",
402    "LOCATION",
403    "ORGANIZATION",
404    "PERFORMER",
405    "PRODUCER",
406    "REPLAYGAIN_ALBUM_GAIN",
407    "REPLAYGAIN_ALBUM_PEAK",
408    "REPLAYGAIN_TRACK_GAIN",
409    "REPLAYGAIN_TRACK_PEAK",
410    "TITLE",
411    "TRACKNUMBER",
412    "TRACKTOTAL",
413    "VERSION",
414    "vendor"
415];
416
417/// ## Picture data, normally the cover of the CD
418#[derive(Clone)]
419pub struct PictureData {
420    /// * The binary picture data as a byte array
421    pub picture: Vec<u8>,
422
423    /// * The mime type of the picture data
424    pub mime_type: String,
425
426    /// * The description
427    pub description: String,
428
429    /// * The width of the picture
430    pub width: u32,
431
432    /// * The height of the picture
433    pub height: u32,
434
435    /// * The color depth of the picture
436    pub depth: u32,
437
438    /// * How many colors in the picture
439    pub colors: u32,
440}
441
442impl Debug for PictureData {
443    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
444        fmt.debug_struct("PictureData")
445            .field("picture", &format_args!("[u8; {}]", self.picture.len()))
446            .field("mime_type", &self.mime_type)
447            .field("description", &self.description)
448            .field("width", &self.width)
449            .field("height", &self.height)
450            .field("depth", &self.depth)
451            .field("colors", &self.colors)
452            .finish()
453    }
454}
455
456impl PictureData {
457    pub fn new() -> Self {
458        Self {
459            picture: Vec::<u8>::new(),
460            mime_type: "".to_owned(),
461            description: "".to_owned(),
462            width: 0,
463            height: 0,
464            depth: 0,
465            colors: 0,
466        }
467    }
468
469    pub fn is_empty(&self) -> bool {
470        self.picture.is_empty()
471    }
472}
473
474impl Default for PictureData {
475    fn default() -> Self {
476        Self::new()
477    }
478}
479
480#[derive(Debug)]
481#[repr(C)]
482struct FlacMetadata {
483    /// * See [https://xiph.org/flac/api/group__flac__metadata__object.html]
484    metadata: *mut FLAC__StreamMetadata,
485}
486
487#[derive(Debug)]
488#[repr(C)]
489struct FlacCueTrackWrap {
490    track: *mut FLAC__StreamMetadata_CueSheet_Track,
491}
492
493impl FlacCueTrackWrap {
494    pub fn new() -> Result<Self, FlacEncoderError> {
495        let ret = Self {
496            track: unsafe {FLAC__metadata_object_cuesheet_track_new()},
497        };
498        if ret.track.is_null() {
499            Err(FlacEncoderError::new(FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR, "FLAC__metadata_object_cuesheet_track_new"))
500        } else {
501            Ok(ret)
502        }
503    }
504
505    pub fn get_ref_mut(&mut self) -> &mut FLAC__StreamMetadata_CueSheet_Track {
506        unsafe {&mut *self.track}
507    }
508
509    pub fn get_ptr(&self) -> *const FLAC__StreamMetadata_CueSheet_Track{
510        self.track as *const FLAC__StreamMetadata_CueSheet_Track
511    }
512
513    pub fn get_mut_ptr(&self) -> *mut FLAC__StreamMetadata_CueSheet_Track{
514        self.track
515    }
516}
517
518impl Default for FlacCueTrackWrap {
519    fn default() -> Self {
520        Self {
521            track: ptr::null_mut(),
522        }
523    }
524}
525
526impl Drop for FlacCueTrackWrap {
527    fn drop(&mut self) {
528        if !self.track.is_null() {
529            unsafe {FLAC__metadata_object_cuesheet_track_delete(self.track)};
530            self.track = ptr::null_mut();
531        }
532    }
533}
534
535fn make_sz(s: &str) -> String {
536    let mut s = s.to_owned();
537    if !s.ends_with('\0') {s.push('\0');}
538    s
539}
540
541/// ## The track type
542#[derive(Debug, Clone, Copy)]
543pub enum FlacTrackType {
544    Audio,
545    NonAudio,
546}
547
548impl Display for FlacTrackType {
549    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
550        match self {
551            Self::Audio => write!(f, "audio"),
552            Self::NonAudio => write!(f, "non-audio"),
553        }
554    }
555}
556
557#[derive(Debug, Clone, Copy)]
558#[repr(C)]
559pub struct FlacCueSheetIndex {
560    /// * Offset in samples, relative to the track offset, of the index point.
561    pub offset: u64,
562
563    /// * The index point number
564    pub number: u8,
565}
566
567#[derive(Clone)]
568#[repr(C)]
569pub struct FlacCueTrack {
570    /// * In samples
571    pub offset: u64,
572
573    /// * Track number
574    pub track_no: u8,
575
576    /// * ISRC
577    pub isrc: [i8; 13],
578
579    /// * What type is this track, is it audio or not.
580    pub type_: FlacTrackType,
581
582    /// * Pre_emphasis
583    pub pre_emphasis: bool,
584
585    /// * Indices
586    pub indices: Vec<FlacCueSheetIndex>,
587}
588
589impl FlacCueTrack {
590    pub fn get_isrc(&self) -> String {
591        String::from_utf8_lossy(&self.isrc.iter().map(|c|{*c as u8}).collect::<Vec<u8>>()).to_string()
592    }
593}
594
595impl Debug for FlacCueTrack {
596    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
597        f.debug_struct("FlacCueTrack")
598            .field("offset", &self.offset)
599            .field("track_no", &self.track_no)
600            .field("isrc", &self.get_isrc())
601            .field("type_", &self.type_)
602            .field("pre_emphasis", &self.pre_emphasis)
603            .field("indices", &self.indices)
604            .finish()
605    }
606}
607
608impl Display for FlacCueTrack {
609    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
610        f.debug_struct("FlacCueTrack")
611            .field("offset", &self.offset)
612            .field("track_no", &self.track_no)
613            .field("isrc", &self.get_isrc())
614            .field("type_", &self.type_)
615            .field("pre_emphasis", &self.pre_emphasis)
616            .field("indices", &self.indices)
617            .finish()
618    }
619}
620
621/// ## Cue sheet for the FLAC audio
622#[derive(Clone)]
623pub struct FlacCueSheet {
624    /// * media_catalog_number
625    pub media_catalog_number: [i8; 129],
626
627    /// * In samples
628    pub lead_in: u64,
629
630    /// * Is this FLAC file from a CD or not.
631    pub is_cd: bool,
632
633    /// * The tracks
634    pub tracks: BTreeMap<u8, FlacCueTrack>,
635}
636
637impl FlacCueSheet {
638    pub fn get_media_catalog_number(&self) -> String {
639        String::from_utf8_lossy(&self.media_catalog_number.iter().map(|c|{*c as u8}).collect::<Vec<u8>>()).to_string()
640    }
641}
642
643impl Debug for FlacCueSheet {
644    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
645        f.debug_struct("FlacCueSheet")
646            .field("media_catalog_number", &self.get_media_catalog_number())
647            .field("lead_in", &self.lead_in)
648            .field("is_cd", &self.is_cd)
649            .field("tracks", &self.tracks)
650            .finish()
651    }
652}
653
654impl Display for FlacCueSheet {
655    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
656        f.debug_struct("FlacCueSheet")
657            .field("media_catalog_number", &self.get_media_catalog_number())
658            .field("lead_in", &self.lead_in)
659            .field("is_cd", &self.is_cd)
660            .field("tracks", &self.tracks)
661            .finish()
662    }
663}
664
665impl FlacMetadata {
666    pub fn new_vorbis_comment() -> Result<Self, FlacEncoderError> {
667        let ret = Self {
668            metadata: unsafe {FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT)},
669        };
670        if ret.metadata.is_null() {
671            Err(FlacEncoderError::new(FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR, "FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT)"))
672        } else {
673            Ok(ret)
674        }
675    }
676
677    pub fn new_cue_sheet() -> Result<Self, FlacEncoderError> {
678        let ret = Self {
679            metadata: unsafe {FLAC__metadata_object_new(FLAC__METADATA_TYPE_CUESHEET)},
680        };
681        if ret.metadata.is_null() {
682            Err(FlacEncoderError::new(FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR, "FLAC__metadata_object_new(FLAC__METADATA_TYPE_CUESHEET)"))
683        } else {
684            Ok(ret)
685        }
686    }
687
688    pub fn new_picture() -> Result<Self, FlacEncoderError> {
689        let ret = Self {
690            metadata: unsafe {FLAC__metadata_object_new(FLAC__METADATA_TYPE_PICTURE)},
691        };
692        if ret.metadata.is_null() {
693            Err(FlacEncoderError::new(FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR, "FLAC__metadata_object_new(FLAC__METADATA_TYPE_PICTURE)"))
694        } else {
695            Ok(ret)
696        }
697    }
698
699    pub fn insert_comments(&self, key: &'static str, value: &str) -> Result<(), FlacEncoderError> {
700        unsafe {
701            // ATTENTION:
702            // Any strings to be added to the entry must be NUL terminated.
703            // Or you can see the `FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR` due to the failure to find the NUL terminator.
704            let szkey = make_sz(key);
705            let szvalue = make_sz(value);
706            let mut entry = FLAC__StreamMetadata_VorbisComment_Entry{length: 0, entry: ptr::null_mut()};
707            if FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair (
708                &mut entry as *mut FLAC__StreamMetadata_VorbisComment_Entry,
709                szkey.as_ptr() as *mut i8,
710                szvalue.as_ptr() as *mut i8
711            ) == 0 {
712                eprintln!("On set comment {key}: {value}: {:?}", FlacEncoderError::new(FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR, "FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair"));
713            }
714            if FLAC__metadata_object_vorbiscomment_append_comment(self.metadata, entry, 0) == 0 {
715                eprintln!("On set comment {key}: {value}: {:?}", FlacEncoderError::new(FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR, "FLAC__metadata_object_vorbiscomment_append_comment"));
716            }
717        }
718        Ok(())
719    }
720
721    pub fn insert_cue_track(&mut self, track_no: u8, cue_track: &FlacCueTrack) -> Result<(), FlacEncoderError> {
722        unsafe {
723            let mut track = FlacCueTrackWrap::new()?;
724            let track_data = track.get_ref_mut();
725            track_data.offset = cue_track.offset;
726            track_data.number = track_no;
727            track_data.isrc = cue_track.isrc;
728            track_data.set_type(match cue_track.type_ {
729                FlacTrackType::Audio => 0,
730                FlacTrackType::NonAudio => 1,
731            });
732            track_data.set_pre_emphasis(match cue_track.pre_emphasis {
733                true => 1,
734                false => 0,
735            });
736            track_data.num_indices = cue_track.indices.len() as u8;
737            let mut indices: Vec<FLAC__StreamMetadata_CueSheet_Index> = cue_track.indices.iter().map(|index| -> FLAC__StreamMetadata_CueSheet_Index {
738                FLAC__StreamMetadata_CueSheet_Index {
739                    offset: index.offset,
740                    number: index.number,
741                }
742            }).collect();
743            track_data.indices = indices.as_mut_ptr();
744            if FLAC__metadata_object_cuesheet_set_track(self.metadata, track_no as u32, track.get_mut_ptr(), 1) == 0 {
745                eprintln!("Failed to create new cuesheet track for {track_no} {cue_track}:  {:?}", FlacEncoderError::new(FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR, "FLAC__metadata_object_cuesheet_set_track"));
746            }
747        }
748        Ok(())
749    }
750
751    pub fn set_picture(&mut self, picture_binary: &mut [u8], description: &mut str, mime_type: &mut str) -> Result<(), FlacEncoderError> {
752        let mut desc_sz = make_sz(description);
753        let mut mime_sz = make_sz(mime_type);
754        unsafe {
755            if FLAC__metadata_object_picture_set_data(self.metadata, picture_binary.as_mut_ptr(), picture_binary.len() as u32, 0) == 0 {
756                Err(FlacEncoderError::new(FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR, "FLAC__metadata_object_picture_set_data"))
757            } else if FLAC__metadata_object_picture_set_mime_type(self.metadata, desc_sz.as_mut_ptr() as *mut i8, 0) == 0 {
758                Err(FlacEncoderError::new(FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR, "FLAC__metadata_object_picture_set_mime_type"))
759            } else if FLAC__metadata_object_picture_set_description(self.metadata, mime_sz.as_mut_ptr(), 0) == 0 {
760                Err(FlacEncoderError::new(FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR, "FLAC__metadata_object_picture_set_description"))
761            } else {
762                Ok(())
763            }
764        }
765    }
766}
767
768impl Default for FlacMetadata {
769    fn default() -> Self {
770        Self {
771            metadata: ptr::null_mut(),
772        }
773    }
774}
775
776impl Drop for FlacMetadata {
777    fn drop(&mut self) {
778        if !self.metadata.is_null() {
779            unsafe {FLAC__metadata_object_delete(self.metadata)};
780            self.metadata = ptr::null_mut();
781        }
782    }
783}
784
785/// ## The encoder's core structure, but can't move after `initialize()` has been called.
786/// Use a `Box` to contain it, or just don't move it will be fine.
787pub struct FlacEncoderUnmovable<'a, WriteSeek>
788where
789    WriteSeek: Write + Seek + Debug {
790    /// * See: <https://xiph.org/flac/api/group__flac__stream__encoder.html>
791    encoder: *mut FLAC__StreamEncoder,
792
793    /// * This is a piece of allocated memory as the libFLAC form, for libFLAC to access the metadata that you provided to it.
794    metadata: Vec<FlacMetadata>,
795
796    /// * Is encoder initialized or not
797    encoder_initialized: bool,
798
799    /// * The parameters you provided to create the encoder.
800    params: FlacEncoderParams,
801
802    /// * The encoder uses this `writer` to write the FLAC file.
803    writer: WriteSeek,
804
805    /// * Your `on_write()` closure, to receive the encoded FLAC file pieces.
806    /// * Instead of just writing the data to the `writer`, you can do what you want to do to the data, and return a proper `Result`.
807    on_write: Box<dyn FnMut(&mut WriteSeek, &[u8]) -> Result<(), io::Error> + 'a>,
808
809    /// * Your `on_seek()` closure. Often works by calling `writer.seek()` to help your encoder to move the file pointer.
810    on_seek: Box<dyn FnMut(&mut WriteSeek, u64) -> Result<(), io::Error> + 'a>,
811
812    /// * Your `on_tell()` closure. Often works by calling `writer.stream_position()` to help your encoder to know the current write position.
813    on_tell: Box<dyn FnMut(&mut WriteSeek) -> Result<u64, io::Error> + 'a>,
814
815    /// * The metadata to be added to the FLAC file. You can only add the metadata before calling `initialize()`
816    comments: BTreeMap<&'static str, String>,
817
818    /// * The cue sheets to be added to the FLAC file. You can only add the cue sheets before calling `initialize()`
819    cue_sheets: Vec<FlacCueSheet>,
820
821    /// * The pictures to be added to the FLAC file. You can only add the pictures before calling `initialize()`
822    pictures: Vec<PictureData>,
823
824    /// * Did you called `finish()`. This variable prevents a duplicated finish.
825    finished: bool,
826}
827
828impl<'a, WriteSeek> FlacEncoderUnmovable<'a, WriteSeek>
829where
830    WriteSeek: Write + Seek + Debug {
831    pub fn new(
832        writer: WriteSeek,
833        on_write: Box<dyn FnMut(&mut WriteSeek, &[u8]) -> Result<(), io::Error> + 'a>,
834        on_seek: Box<dyn FnMut(&mut WriteSeek, u64) -> Result<(), io::Error> + 'a>,
835        on_tell: Box<dyn FnMut(&mut WriteSeek) -> Result<u64, io::Error> + 'a>,
836        params: &FlacEncoderParams
837    ) -> Result<Self, FlacEncoderError> {
838        let ret = Self {
839            encoder: unsafe {FLAC__stream_encoder_new()},
840            metadata: Vec::<FlacMetadata>::new(),
841            encoder_initialized: false,
842            params: *params,
843            writer,
844            on_write,
845            on_seek,
846            on_tell,
847            comments: BTreeMap::new(),
848            cue_sheets: Vec::new(),
849            pictures: Vec::new(),
850            finished: false,
851        };
852        if ret.encoder.is_null() {
853            Err(FlacEncoderError::new(FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR, "FLAC__stream_encoder_new"))
854        } else {
855            Ok(ret)
856        }
857    }
858
859    /// * If the status code is ok then return `Ok(())` else return `Err()`
860    pub fn get_status_as_result(&self, function: &'static str) -> Result<(), FlacEncoderError> {
861        let code = unsafe {FLAC__stream_encoder_get_state(self.encoder)};
862        if code == 0 {
863            Ok(())
864        } else {
865            Err(FlacEncoderError::new(code, function))
866        }
867    }
868
869    /// * Regardless of the status code, just return it as an `Err()`
870    pub fn get_status_as_error(&self, function: &'static str) -> Result<(), FlacEncoderError> {
871        let code = unsafe {FLAC__stream_encoder_get_state(self.encoder)};
872        Err(FlacEncoderError::new(code, function))
873    }
874
875    /// * The pointer to the struct, as `client_data` to be transferred to a field of the libFLAC encoder `private_` struct.
876    /// * All of the callback functions need the `client_data` to retrieve `self`, and libFLAC forgot to provide a function for us to change the `client_data`
877    /// * That's why our struct is `Unmovable`
878    pub fn as_ptr(&self) -> *const Self {
879        self as *const Self
880    }
881
882    /// * The pointer to the struct, as `client_data` to be transferred to a field of the libFLAC encoder `private_` struct.
883    /// * All of the callback functions need the `client_data` to retrieve `self`, and libFLAC forgot to provide a function for us to change the `client_data`
884    /// * That's why our struct is `Unmovable`
885    pub fn as_mut_ptr(&mut self) -> *mut Self {
886        self as *mut Self
887    }
888
889    /// * Insert a metadata key-value pair before calling to `initialize()`
890    pub fn insert_comments(&mut self, key: &'static str, value: &str) -> Result<(), FlacEncoderInitError> {
891        if self.encoder_initialized {
892            Err(FlacEncoderInitError::new(FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED, "FlacEncoderUnmovable::insert_comments"))
893        } else {
894            if let Some(old_value) = self.comments.insert(key, value.to_owned()) {
895                eprintln!("\"{key}\" is changed to \"{value}\" from \"{old_value}\"");
896            }
897            Ok(())
898        }
899    }
900
901    /// * Insert a cue sheet before calling to `initialize()`
902    pub fn insert_cue_sheet(&mut self, cue_sheet: &FlacCueSheet) -> Result<(), FlacEncoderInitError> {
903        if self.encoder_initialized {
904            Err(FlacEncoderInitError::new(FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED, "FlacEncoderUnmovable::insert_cue_track"))
905        } else {
906            self.cue_sheets.push(cue_sheet.clone());
907            Ok(())
908        }
909    }
910
911    /// * Add a picture before calling to `initialize()`
912    pub fn add_picture(&mut self, picture_binary: &[u8], description: &str, mime_type: &str, width: u32, height: u32, depth: u32, colors: u32) -> Result<(), FlacEncoderInitError> {
913        if self.encoder_initialized {
914            Err(FlacEncoderInitError::new(FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED, "FlacEncoderUnmovable::set_picture"))
915        } else {
916            self.pictures.push(PictureData{
917                picture: picture_binary.to_vec(),
918                description: description.to_owned(),
919                mime_type: mime_type.to_owned(),
920                width,
921                height,
922                depth,
923                colors
924            });
925            Ok(())
926        }
927    }
928
929    #[cfg(feature = "id3")]
930    pub fn inherit_metadata_from_id3(&mut self, tag: &id3::Tag) -> Result<(), FlacEncoderInitError> {
931        if let Some(artist) = tag.artist() {self.insert_comments("ARTIST", artist)?;}
932        if let Some(album) = tag.album() {self.insert_comments("ALBUM", album)?;}
933        if let Some(title) = tag.title() {self.insert_comments("TITLE", title)?;}
934        if let Some(genre) = tag.genre() {self.insert_comments("GENRE", genre)?;}
935        for picture in tag.pictures() {
936            self.add_picture(&picture.data, &picture.description, &picture.mime_type, 0, 0, 0, 0)?;
937        }
938        let comm_str = tag.comments().enumerate().map(|(i, comment)| -> String {
939            let lang = &comment.lang;
940            let desc = &comment.description;
941            let text = &comment.text;
942            format!("Comment {i}:\n\tlang: {lang}\n\tdesc: {desc}\n\ttext: {text}")
943        }).collect::<Vec<String>>().join("\n");
944        if !comm_str.is_empty() {self.insert_comments("COMMENT", &comm_str)?;}
945        Ok(())
946    }
947
948    /// * The `initialize()` function. Sets up all of the callback functions, transfers all of the metadata to the encoder, and then sets `client_data` to the address of the `self` struct.
949    pub fn initialize(&mut self) -> Result<(), FlacEncoderError> {
950        if self.encoder_initialized {
951            return Err(FlacEncoderInitError::new(FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED, "FlacEncoderUnmovable::init").into())
952        }
953        unsafe {
954            if FLAC__stream_encoder_set_verify(self.encoder, if self.params.verify_decoded {1} else {0}) == 0 {
955                return self.get_status_as_error("FLAC__stream_encoder_set_verify");
956            }
957            if FLAC__stream_encoder_set_compression_level(self.encoder, self.params.compression as u32) == 0 {
958                return self.get_status_as_error("FLAC__stream_encoder_set_compression_level");
959            }
960            if FLAC__stream_encoder_set_channels(self.encoder, self.params.channels as u32) == 0 {
961                return self.get_status_as_error("FLAC__stream_encoder_set_channels");
962            }
963            if FLAC__stream_encoder_set_bits_per_sample(self.encoder, self.params.bits_per_sample) == 0 {
964                return self.get_status_as_error("FLAC__stream_encoder_set_bits_per_sample");
965            }
966            if FLAC__stream_encoder_set_sample_rate(self.encoder, self.params.sample_rate) == 0 {
967                return self.get_status_as_error("FLAC__stream_encoder_set_sample_rate");
968            }
969            if self.params.total_samples_estimate > 0 && FLAC__stream_encoder_set_total_samples_estimate(self.encoder, self.params.total_samples_estimate) == 0 {
970                return self.get_status_as_error("FLAC__stream_encoder_set_total_samples_estimate");
971            }
972
973            let set_metadata: Result<(), FlacEncoderError> = {
974                if !self.comments.is_empty() {
975                    let metadata = FlacMetadata::new_vorbis_comment()?;
976                    for (key, value) in self.comments.iter() {
977                        metadata.insert_comments(key, value)?;
978                    }
979                    self.metadata.push(metadata);
980                }
981                for cue_sheet in self.cue_sheets.iter() {
982                    let mut metadata = FlacMetadata::new_cue_sheet()?;
983                    for (track_no, cue_track) in cue_sheet.tracks.iter() {
984                        metadata.insert_cue_track(*track_no, cue_track)?;
985                    }
986                    self.metadata.push(metadata);
987                }
988                for picture in self.pictures.iter_mut() {
989                    let mut metadata = FlacMetadata::new_picture()?;
990                    metadata.set_picture(&mut picture.picture, &mut picture.description, &mut picture.mime_type)?;
991                    self.metadata.push(metadata);
992                }
993                if !self.metadata.is_empty() {
994                    if FLAC__stream_encoder_set_metadata(self.encoder, self.metadata.as_mut_ptr() as *mut *mut FLAC__StreamMetadata, self.metadata.len() as u32) == 0 {
995                        Err(FlacEncoderError::new(FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED, "FLAC__stream_encoder_set_metadata"))
996                    } else {
997                        Ok(())
998                    }
999                } else {
1000                    Ok(())
1001                }
1002            };
1003            if let Err(e) = set_metadata {
1004                eprintln!("When setting the metadata: {:?}", e);
1005            }
1006            let ret = FLAC__stream_encoder_init_stream(self.encoder,
1007                Some(Self::write_callback),
1008                Some(Self::seek_callback),
1009                Some(Self::tell_callback),
1010                Some(Self::metadata_callback),
1011                self.as_mut_ptr() as *mut c_void,
1012            );
1013            if ret != 0 {
1014                return Err(FlacEncoderInitError::new(ret, "FLAC__stream_encoder_init_stream").into());
1015            } else {
1016                self.encoder_initialized = true;
1017            }
1018        }
1019        self.finished = false;
1020        self.get_status_as_result("FlacEncoderUnmovable::Init()")
1021    }
1022
1023    /// * Retrieve the params from the encoder where you provided it for the creation of the encoder.
1024    pub fn get_params(&self) -> FlacEncoderParams {
1025        self.params
1026    }
1027
1028    unsafe extern "C" fn write_callback(_encoder: *const FLAC__StreamEncoder, buffer: *const u8, bytes: usize, _samples: u32, _current_frame: u32, client_data: *mut c_void) -> u32 {
1029        #[cfg(debug_assertions)]
1030        if SHOW_CALLBACKS {println!("write_callback([u8; {bytes}])");}
1031        let this = unsafe {&mut *(client_data as *mut Self)};
1032        match (this.on_write)(&mut this.writer, unsafe {slice::from_raw_parts(buffer, bytes)}) {
1033            Ok(_) => FLAC__STREAM_ENCODER_WRITE_STATUS_OK,
1034            Err(e) => {
1035                eprintln!("On `write_callback()`: {:?}", e);
1036                FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR
1037            },
1038        }
1039    }
1040
1041    unsafe extern "C" fn seek_callback(_encoder: *const FLAC__StreamEncoder, absolute_byte_offset: u64, client_data: *mut c_void) -> u32 {
1042        #[cfg(debug_assertions)]
1043        if SHOW_CALLBACKS {println!("seek_callback({absolute_byte_offset})");}
1044        let this = unsafe {&mut *(client_data as *mut Self)};
1045        match (this.on_seek)(&mut this.writer, absolute_byte_offset) {
1046            Ok(_) => FLAC__STREAM_ENCODER_SEEK_STATUS_OK,
1047            Err(e) => {
1048                match e.kind() {
1049                    ErrorKind::NotSeekable => FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED,
1050                    _ => FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR,
1051                }
1052            },
1053        }
1054    }
1055
1056    unsafe extern "C" fn tell_callback(_encoder: *const FLAC__StreamEncoder, absolute_byte_offset: *mut u64, client_data: *mut c_void) -> u32 {
1057        let this = unsafe {&mut *(client_data as *mut Self)};
1058        match (this.on_tell)(&mut this.writer) {
1059            Ok(offset) => {
1060                #[cfg(debug_assertions)]
1061                if SHOW_CALLBACKS {println!("tell_callback() == {offset}");}
1062                unsafe {*absolute_byte_offset = offset};
1063                FLAC__STREAM_ENCODER_TELL_STATUS_OK
1064            },
1065            Err(e) => {
1066                match e.kind() {
1067                    ErrorKind::NotSeekable => FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED,
1068                    _ => FLAC__STREAM_ENCODER_TELL_STATUS_ERROR,
1069                }
1070            },
1071        }
1072    }
1073
1074    unsafe extern "C" fn metadata_callback(_encoder: *const FLAC__StreamEncoder, metadata: *const FLAC__StreamMetadata, client_data: *mut c_void) {
1075        let _this = unsafe {&mut *(client_data as *mut Self)};
1076        let _meta = unsafe {*metadata};
1077        #[cfg(debug_assertions)]
1078        if SHOW_CALLBACKS {println!("{:?}", WrappedStreamMetadata(_meta))}
1079    }
1080
1081    /// * Calls your `on_tell()` closure to get the current writing position.
1082    pub fn tell(&mut self) -> Result<u64, io::Error> {
1083        (self.on_tell)(&mut self.writer)
1084    }
1085
1086    /// * Encode the interleaved samples (interleaved by channels)
1087    /// * See `FlacEncoderParams` for the information on how to provide your samples in the `[i32]` array.
1088    pub fn write_interleaved_samples(&mut self, samples: &[i32]) -> Result<(), FlacEncoderError> {
1089        #[cfg(debug_assertions)]
1090        if SHOW_CALLBACKS {println!("write_interleaved_samples([i32; {}])", samples.len());}
1091        if samples.is_empty() {return Ok(())}
1092        if samples.len() % self.params.channels as usize != 0 {
1093            Err(FlacEncoderError::new(FLAC__STREAM_ENCODER_FRAMING_ERROR, "FlacEncoderUnmovable::write_interleaved_samples"))
1094        } else {
1095            unsafe {
1096                if FLAC__stream_encoder_process_interleaved(self.encoder, samples.as_ptr(), samples.len() as u32 / self.params.channels as u32) == 0 {
1097                    return self.get_status_as_error("FLAC__stream_encoder_process_interleaved");
1098                }
1099            }
1100            Ok(())
1101        }
1102    }
1103
1104    /// * Encode mono audio. Regardless of the channel setting of the FLAC encoder, the sample will be duplicated to the number of channels to accomplish the encoding
1105    /// * See `FlacEncoderParams` for the information on how to provide your samples in the `[i32]` array.
1106    pub fn write_mono_channel(&mut self, monos: &[i32]) -> Result<(), FlacEncoderError> {
1107        #[cfg(debug_assertions)]
1108        if SHOW_CALLBACKS {println!("write_mono_channel([i32; {}])", monos.len());}
1109        if monos.is_empty() {return Ok(())}
1110        match self.params.channels {
1111            1 => unsafe {
1112                if FLAC__stream_encoder_process_interleaved(self.encoder, monos.as_ptr(), monos.len() as u32) == 0 {
1113                    return self.get_status_as_error("FLAC__stream_encoder_process_interleaved");
1114                }
1115                Ok(())
1116            },
1117            2 => self.write_stereos(&monos.iter().map(|mono| -> (i32, i32){(*mono, *mono)}).collect::<Vec<(i32, i32)>>()),
1118            o => self.write_frames(&monos.iter().map(|mono| -> Vec<i32> {(0..o).map(|_|{*mono}).collect()}).collect::<Vec<Vec<i32>>>()),
1119        }
1120    }
1121
1122    /// * Encode stereo audio, if the channels of the encoder are mono, the stereo samples will be turned to mono samples to encode.
1123    /// * If the channels of the encoder are stereo, then the samples will be encoded as it is.
1124    /// * If the encoder is multi-channel other than mono and stereo, an error is returned.
1125    /// * See `FlacEncoderParams` for the information on how to provide your samples in the `i32` way.
1126    pub fn write_stereos(&mut self, stereos: &[(i32, i32)]) -> Result<(), FlacEncoderError> {
1127        #[cfg(debug_assertions)]
1128        if SHOW_CALLBACKS {println!("write_stereos([(i32, i32); {}])", stereos.len());}
1129        if stereos.is_empty() {return Ok(())}
1130        match self.params.channels {
1131            1 => self.write_mono_channel(&stereos.iter().map(|(l, r): &(i32, i32)| -> i32 {((*l as i64 + *r as i64) / 2) as i32}).collect::<Vec<i32>>()),
1132            2 => unsafe {
1133                let samples: Vec<i32> = stereos.iter().flat_map(|(l, r): &(i32, i32)| -> [i32; 2] {[*l, *r]}).collect();
1134                if FLAC__stream_encoder_process_interleaved(self.encoder, samples.as_ptr(), stereos.len() as u32) == 0 {
1135                    return self.get_status_as_error("FLAC__stream_encoder_process_interleaved");
1136                }
1137                Ok(())
1138            },
1139            o => panic!("Can't turn stereo audio into {o} channels audio."),
1140        }
1141    }
1142
1143    /// * Encode multiple mono channels into the multi-channel encoder.
1144    /// * See `FlacEncoderParams` for the information on how to provide your samples in the `i32` way.
1145    pub fn write_monos(&mut self, monos: &[Vec<i32>]) -> Result<(), FlacEncoderError> {
1146        #[cfg(debug_assertions)]
1147        if SHOW_CALLBACKS {println!("write_monos([Vec<i32>; {}])", monos.len());}
1148        if monos.len() != self.params.channels as usize {
1149            Err(FlacEncoderError::new(FLAC__STREAM_ENCODER_FRAMING_ERROR, "FlacEncoderUnmovable::write_monos"))
1150        } else {
1151            unsafe {
1152                let len = monos[0].len();
1153                for mono in monos.iter() {
1154                    if mono.len() != len {
1155                        return Err(FlacEncoderError::new(FLAC__STREAM_ENCODER_FRAMING_ERROR, "FlacEncoderUnmovable::write_monos"));
1156                    }
1157                }
1158                let ptr_arr: Vec<*const i32> = monos.iter().map(|v|{v.as_ptr()}).collect();
1159                if FLAC__stream_encoder_process(self.encoder, ptr_arr.as_ptr(), len as u32) == 0 {
1160                    self.get_status_as_error("FLAC__stream_encoder_process")
1161                } else {
1162                    Ok(())
1163                }
1164            }
1165        }
1166    }
1167
1168    /// * Encode samples by the audio frame array. Each audio frame contains one sample for every channel.
1169    /// * See `FlacEncoderParams` for the information on how to provide your samples in the `i32` way.
1170    pub fn write_frames(&mut self, frames: &[Vec<i32>]) -> Result<(), FlacEncoderError> {
1171        #[cfg(debug_assertions)]
1172        if SHOW_CALLBACKS {println!("write_frames([Vec<i32>; {}])", frames.len());}
1173        if frames.is_empty() {return Ok(())}
1174        let samples: Vec<i32> = frames.iter().flat_map(|frame: &Vec<i32>| -> Vec<i32> {
1175            if frame.len() != self.params.channels as usize {
1176                panic!("On FlacEncoderUnmovable::write_frames(): a frame size {} does not match the encoder channels.", frame.len())
1177            } else {frame.to_vec()}
1178        }).collect();
1179        unsafe {
1180            if FLAC__stream_encoder_process_interleaved(self.encoder, samples.as_ptr(), frames.len() as u32) == 0 {
1181                return self.get_status_as_error("FLAC__stream_encoder_process_interleaved");
1182            }
1183        }
1184        Ok(())
1185    }
1186
1187    /// * After sending all of the samples to encode, must call `finish()` to complete encoding.
1188    pub fn finish(&mut self) -> Result<(), FlacEncoderError> {
1189        if self.finished {
1190            return Ok(())
1191        }
1192        #[cfg(debug_assertions)]
1193        if SHOW_CALLBACKS {println!("finish()");}
1194        unsafe {
1195            if FLAC__stream_encoder_finish(self.encoder) != 0 {
1196                match self.writer.seek(SeekFrom::End(0)) {
1197                    Ok(_) => {self.finished = true; Ok(())},
1198                    Err(_) => Err(FlacEncoderError::new(FLAC__STREAM_ENCODER_IO_ERROR, "self.writer.seek(SeekFrom::End(0))")),
1199                }
1200            } else {
1201                self.get_status_as_error("FLAC__stream_encoder_finish")
1202            }
1203        }
1204    }
1205
1206    fn on_drop(&mut self) {
1207        unsafe {
1208            if let Err(e) = self.finish() {
1209                eprintln!("On FlacEncoderUnmovable::finish(): {:?}", e);
1210            }
1211
1212            self.metadata.clear();
1213            FLAC__stream_encoder_delete(self.encoder);
1214        };
1215    }
1216
1217    /// * Call this function if you don't want the encoder anymore.
1218    pub fn finalize(self) {}
1219}
1220
1221impl<'a, WriteSeek> Debug for FlacEncoderUnmovable<'_, WriteSeek>
1222where
1223    WriteSeek: Write + Seek + Debug {
1224    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
1225        fmt.debug_struct("FlacEncoderUnmovable")
1226            .field("encoder", &self.encoder)
1227            .field("params", &self.params)
1228            .field("writer", &self.writer)
1229            .field("on_write", &"{{closure}}")
1230            .field("on_seek", &"{{closure}}")
1231            .field("on_tell", &"{{closure}}")
1232            .field("comments", &self.comments)
1233            .field("cue_sheets", &self.cue_sheets)
1234            .field("pictures", &format_args!("..."))
1235            .field("finished", &self.finished)
1236            .finish()
1237    }
1238}
1239
1240impl<'a, WriteSeek> Drop for FlacEncoderUnmovable<'_, WriteSeek>
1241where
1242    WriteSeek: Write + Seek + Debug {
1243    fn drop(&mut self) {
1244        self.on_drop();
1245    }
1246}
1247
1248/// ## A wrapper for `FlacEncoderUnmovable`, which provides a Box to make `FlacEncoderUnmovable` never move.
1249/// This is the struct that should be mainly used by you.
1250pub struct FlacEncoder<'a, WriteSeek>
1251where
1252    WriteSeek: Write + Seek + Debug {
1253    encoder: Box<FlacEncoderUnmovable<'a, WriteSeek>>,
1254}
1255
1256impl<'a, WriteSeek> FlacEncoder<'a, WriteSeek>
1257where
1258    WriteSeek: Write + Seek + Debug {
1259    pub fn new(
1260        writer: WriteSeek,
1261        on_write: Box<dyn FnMut(&mut WriteSeek, &[u8]) -> Result<(), io::Error> + 'a>,
1262        on_seek: Box<dyn FnMut(&mut WriteSeek, u64) -> Result<(), io::Error> + 'a>,
1263        on_tell: Box<dyn FnMut(&mut WriteSeek) -> Result<u64, io::Error> + 'a>,
1264        params: &FlacEncoderParams
1265    ) -> Result<Self, FlacEncoderError> {
1266        Ok(Self {
1267            encoder: Box::new(FlacEncoderUnmovable::new(writer, on_write, on_seek, on_tell, params)?)
1268        })
1269    }
1270
1271    /// * Insert a metadata key-value pair before calling to `initialize()`
1272    pub fn insert_comments(&mut self, key: &'static str, value: &str) -> Result<(), FlacEncoderInitError> {
1273        self.encoder.insert_comments(key, value)
1274    }
1275
1276    /// * Insert a cue sheet before calling to `initialize()`
1277    pub fn insert_cue_sheet(&mut self, cue_sheet: &FlacCueSheet) -> Result<(), FlacEncoderInitError> {
1278        self.encoder.insert_cue_sheet(cue_sheet)
1279    }
1280
1281    /// * Add a picture before calling to `initialize()`
1282    pub fn add_picture(&mut self, picture_binary: &[u8], description: &str, mime_type: &str, width: u32, height: u32, depth: u32, colors: u32) -> Result<(), FlacEncoderInitError> {
1283        self.encoder.add_picture(picture_binary, description, mime_type, width, height, depth, colors)
1284    }
1285
1286    #[cfg(feature = "id3")]
1287    pub fn inherit_metadata_from_id3(&mut self, tag: &id3::Tag) -> Result<(), FlacEncoderInitError> {
1288        self.encoder.inherit_metadata_from_id3(tag)
1289    }
1290
1291    /// * Retrieve the params from the encoder where you provided it for the creation of the encoder.
1292    pub fn get_params(&self) -> FlacEncoderParams {
1293        self.encoder.get_params()
1294    }
1295
1296    /// * Calls your `on_tell()` closure to get the current writing position.
1297    pub fn tell(&mut self) -> Result<u64, io::Error> {
1298        self.encoder.tell()
1299    }
1300
1301    /// * The `initialize()` function. Sets up all of the callback functions, transfers all of the metadata to the encoder.
1302    pub fn initialize(&mut self) -> Result<(), FlacEncoderInitError> {
1303        if !self.encoder.encoder_initialized {
1304            self.encoder.initialize()?
1305        }
1306        Ok(())
1307    }
1308
1309    /// * Encode the interleaved samples (interleaved by channels)
1310    /// * See `FlacEncoderParams` for the information on how to provide your samples in the `[i32]` array.
1311    pub fn write_interleaved_samples(&mut self, samples: &[i32]) -> Result<(), FlacEncoderError> {
1312        self.encoder.write_interleaved_samples(samples)
1313    }
1314
1315    /// * Encode mono audio. Regardless of the channel setting of the FLAC encoder, the sample will be duplicated to the number of channels to accomplish the encoding
1316    /// * See `FlacEncoderParams` for the information on how to provide your samples in the `[i32]` array.
1317    pub fn write_mono_channel(&mut self, monos: &[i32]) -> Result<(), FlacEncoderError> {
1318        self.encoder.write_mono_channel(monos)
1319    }
1320
1321    /// * Encode stereo audio, if the channels of the encoder are mono, the stereo samples will be turned to mono samples to encode.
1322    /// * If the channels of the encoder are stereo, then the samples will be encoded as it is.
1323    /// * If the encoder is multi-channel other than mono and stereo, an error is returned.
1324    /// * See `FlacEncoderParams` for the information on how to provide your samples in the `i32` way.
1325    pub fn write_stereos(&mut self, stereos: &[(i32, i32)]) -> Result<(), FlacEncoderError> {
1326        self.encoder.write_stereos(stereos)
1327    }
1328
1329    /// * Encode multiple mono channels into the multi-channel encoder.
1330    /// * See `FlacEncoderParams` for the information on how to provide your samples in the `i32` way.
1331    pub fn write_monos(&mut self, monos: &[Vec<i32>]) -> Result<(), FlacEncoderError> {
1332        self.encoder.write_monos(monos)
1333    }
1334
1335    /// * Encode samples by the audio frame array. Each audio frame contains one sample for every channel.
1336    /// * See `FlacEncoderParams` for the information on how to provide your samples in the `i32` way.
1337    pub fn write_frames(&mut self, frames: &[Vec<i32>]) -> Result<(), FlacEncoderError> {
1338        self.encoder.write_frames(frames)
1339    }
1340
1341    /// * After sending all of the samples to encode, must call `finish()` to complete encoding.
1342    pub fn finish(&mut self) -> Result<(), FlacEncoderError> {
1343        self.encoder.finish()
1344    }
1345
1346    /// * Call this function if you don't want the encoder anymore.
1347    pub fn finalize(self) {}
1348}
1349
1350impl<'a, WriteSeek> Debug for FlacEncoder<'_, WriteSeek>
1351where
1352    WriteSeek: Write + Seek + Debug {
1353    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
1354        fmt.debug_struct("FlacEncoder")
1355            .field("encoder", &self.encoder)
1356            .finish()
1357    }
1358}
1359
1360#[derive(Debug, Clone, Copy)]
1361pub struct FlacDecoderError {
1362    /// * This code is actually `FlacDecoderErrorCode`
1363    pub code: u32,
1364
1365    /// * The description of the status, as a constant string from `libflac-sys`
1366    pub message: &'static str,
1367
1368    /// * Which function generates this error
1369    pub function: &'static str,
1370}
1371
1372impl FlacDecoderError {
1373    pub fn new(code: u32, function: &'static str) -> Self {
1374        Self {
1375            code,
1376            message: Self::get_message_from_code(code),
1377            function,
1378        }
1379    }
1380
1381    pub fn get_message_from_code(code: u32) -> &'static str {
1382        unsafe {
1383            CStr::from_ptr(*FLAC__StreamDecoderStateString.as_ptr().add(code as usize)).to_str().unwrap()
1384        }
1385    }
1386}
1387
1388impl_FlacError!(FlacDecoderError);
1389
1390#[derive(Debug, Clone, Copy)]
1391pub enum FlacDecoderErrorCode {
1392    /// * The decoder is ready to search for metadata.
1393    StreamDecoderSearchForMetadata = FLAC__STREAM_DECODER_SEARCH_FOR_METADATA as isize,
1394
1395    /// * The decoder is ready to or is in the process of reading metadata.
1396    StreamDecoderReadMetadata = FLAC__STREAM_DECODER_READ_METADATA as isize,
1397
1398    /// * The decoder is ready to or is in the process of searching for the frame sync code.
1399    StreamDecoderSearchForFrameSync = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC as isize,
1400
1401    /// * The decoder is ready to or is in the process of reading a frame.
1402    StreamDecoderReadFrame = FLAC__STREAM_DECODER_READ_FRAME as isize,
1403
1404    /// * The decoder has reached the end of the stream.
1405    StreamDecoderEndOfStream = FLAC__STREAM_DECODER_END_OF_STREAM as isize,
1406
1407    /// * An error occurred in the underlying Ogg layer.
1408    StreamDecoderOggError = FLAC__STREAM_DECODER_OGG_ERROR as isize,
1409
1410    /// * An error occurred while seeking. The decoder must be flushed with FLAC__stream_decoder_flush() or reset with FLAC__stream_decoder_reset() before decoding can continue.
1411    StreamDecoderSeekError = FLAC__STREAM_DECODER_SEEK_ERROR as isize,
1412
1413    /// * The decoder was aborted by the read or write callback.
1414    StreamDecoderAborted = FLAC__STREAM_DECODER_ABORTED as isize,
1415
1416    /// * An error occurred allocating memory. The decoder is in an invalid state and can no longer be used.
1417    StreamDecoderMemoryAllocationError = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR as isize,
1418
1419    /// * The decoder is in the uninitialized state; one of the FLAC__stream_decoder_init_*() functions must be called before samples can be processed.
1420    StreamDecoderUninitialized = FLAC__STREAM_DECODER_UNINITIALIZED as isize,
1421}
1422
1423impl Display for FlacDecoderErrorCode {
1424    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
1425        match self {
1426            Self::StreamDecoderSearchForMetadata => write!(f, "The decoder is ready to search for metadata."),
1427            Self::StreamDecoderReadMetadata => write!(f, "The decoder is ready to or is in the process of reading metadata."),
1428            Self::StreamDecoderSearchForFrameSync => write!(f, "The decoder is ready to or is in the process of searching for the frame sync code."),
1429            Self::StreamDecoderReadFrame => write!(f, "The decoder is ready to or is in the process of reading a frame."),
1430            Self::StreamDecoderEndOfStream => write!(f, "The decoder has reached the end of the stream."),
1431            Self::StreamDecoderOggError => write!(f, "An error occurred in the underlying Ogg layer."),
1432            Self::StreamDecoderSeekError => write!(f, "An error occurred while seeking. The decoder must be flushed with FLAC__stream_decoder_flush() or reset with FLAC__stream_decoder_reset() before decoding can continue."),
1433            Self::StreamDecoderAborted => write!(f, "The decoder was aborted by the read or write callback."),
1434            Self::StreamDecoderMemoryAllocationError => write!(f, "An error occurred allocating memory. The decoder is in an invalid state and can no longer be used."),
1435            Self::StreamDecoderUninitialized => write!(f, "The decoder is in the uninitialized state; one of the FLAC__stream_decoder_init_*() functions must be called before samples can be processed."),
1436        }
1437    }
1438}
1439
1440impl From<u32> for FlacDecoderErrorCode {
1441    fn from(code: u32) -> Self {
1442        use FlacDecoderErrorCode::*;
1443        match code {
1444            FLAC__STREAM_DECODER_SEARCH_FOR_METADATA => StreamDecoderSearchForMetadata,
1445            FLAC__STREAM_DECODER_READ_METADATA => StreamDecoderReadMetadata,
1446            FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC => StreamDecoderSearchForFrameSync,
1447            FLAC__STREAM_DECODER_READ_FRAME => StreamDecoderReadFrame,
1448            FLAC__STREAM_DECODER_END_OF_STREAM => StreamDecoderEndOfStream,
1449            FLAC__STREAM_DECODER_OGG_ERROR => StreamDecoderOggError,
1450            FLAC__STREAM_DECODER_SEEK_ERROR => StreamDecoderSeekError,
1451            FLAC__STREAM_DECODER_ABORTED => StreamDecoderAborted,
1452            FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR => StreamDecoderMemoryAllocationError,
1453            FLAC__STREAM_DECODER_UNINITIALIZED => StreamDecoderUninitialized,
1454            o => panic!("Not an decoder error code: {o}."),
1455        }
1456    }
1457}
1458
1459impl std::error::Error for FlacDecoderErrorCode {}
1460
1461#[derive(Debug, Clone, Copy)]
1462pub struct FlacDecoderInitError {
1463    /// * This code is actually `FlacDecoderInitErrorCode`
1464    pub code: u32,
1465
1466    /// * The description of the status, as a constant string from `libflac-sys`
1467    pub message: &'static str,
1468
1469    /// * Which function generates this error
1470    pub function: &'static str,
1471}
1472
1473impl FlacDecoderInitError {
1474    pub fn new(code: u32, function: &'static str) -> Self {
1475        Self {
1476            code,
1477            message: Self::get_message_from_code(code),
1478            function,
1479        }
1480    }
1481
1482    pub fn get_message_from_code(code: u32) -> &'static str {
1483        unsafe {
1484            CStr::from_ptr(*FLAC__StreamDecoderInitStatusString.as_ptr().add(code as usize)).to_str().unwrap()
1485        }
1486    }
1487}
1488
1489impl_FlacError!(FlacDecoderInitError);
1490
1491#[derive(Debug, Clone, Copy)]
1492pub enum FlacDecoderInitErrorCode {
1493    StreamDecoderInitStatusOk = FLAC__STREAM_DECODER_INIT_STATUS_OK as isize,
1494    StreamDecoderInitStatusUnsupportedContainer = FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER as isize,
1495    StreamDecoderInitStatusInvalidCallbacks = FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS as isize,
1496    StreamDecoderInitStatusMemoryAllocationError = FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR as isize,
1497    StreamDecoderInitStatusErrorOpeningFile = FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE as isize,
1498    StreamDecoderInitStatusAlreadyInitialized = FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED as isize,
1499}
1500
1501impl Display for FlacDecoderInitErrorCode {
1502    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
1503        match self {
1504            Self::StreamDecoderInitStatusOk => write!(f, "Initialization was successful."),
1505            Self::StreamDecoderInitStatusUnsupportedContainer => write!(f, "The library was not compiled with support for the given container format."),
1506            Self::StreamDecoderInitStatusInvalidCallbacks => write!(f, "A required callback was not supplied."),
1507            Self::StreamDecoderInitStatusMemoryAllocationError => write!(f, "An error occurred allocating memory."),
1508            Self::StreamDecoderInitStatusErrorOpeningFile => write!(f, "fopen() failed in FLAC__stream_decoder_init_file() or FLAC__stream_decoder_init_ogg_file()."),
1509            Self::StreamDecoderInitStatusAlreadyInitialized => write!(f, "FLAC__stream_decoder_init_*() was called when the decoder was already initialized, usually because FLAC__stream_decoder_finish() was not called."),
1510        }
1511    }
1512}
1513
1514impl From<u32> for FlacDecoderInitErrorCode {
1515    fn from(code: u32) -> Self {
1516        use FlacDecoderInitErrorCode::*;
1517        match code {
1518            FLAC__STREAM_DECODER_INIT_STATUS_OK => StreamDecoderInitStatusOk,
1519            FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER => StreamDecoderInitStatusUnsupportedContainer,
1520            FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS => StreamDecoderInitStatusInvalidCallbacks,
1521            FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR => StreamDecoderInitStatusMemoryAllocationError,
1522            FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE => StreamDecoderInitStatusErrorOpeningFile,
1523            FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED => StreamDecoderInitStatusAlreadyInitialized,
1524            o => panic!("Not an decoder init error code: {o}."),
1525        }
1526    }
1527}
1528
1529impl std::error::Error for FlacDecoderInitErrorCode {}
1530
1531impl From<FlacDecoderError> for FlacDecoderInitError {
1532    fn from(err: FlacDecoderError) -> Self {
1533        Self {
1534            code: err.code,
1535            message: err.message,
1536            function: err.function,
1537        }
1538    }
1539}
1540
1541impl From<FlacDecoderInitError> for FlacDecoderError {
1542    fn from(err: FlacDecoderInitError) -> Self {
1543        Self {
1544            code: err.code,
1545            message: err.message,
1546            function: err.function,
1547        }
1548    }
1549}
1550
1551/// ## The result value for your `on_read()` closure to return
1552#[derive(Debug, Clone, Copy)]
1553pub enum FlacReadStatus {
1554    /// * Let the FLAC codec continue to process
1555    GoOn,
1556
1557    /// * Hit the end of the file
1558    Eof,
1559
1560    /// * Error occurred, let the FLAC codec abort the process
1561    Abort,
1562}
1563
1564impl Display for FlacReadStatus {
1565    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
1566        match self {
1567            Self::GoOn => write!(f, "go_on"),
1568            Self::Eof => write!(f, "eof"),
1569            Self::Abort => write!(f, "abort"),
1570        }
1571    }
1572}
1573
1574/// ## The FLAC decoder internal error value for your `on_error()` closure to report.
1575#[derive(Debug, Clone, Copy)]
1576pub enum FlacInternalDecoderError {
1577    /// * An error in the stream caused the decoder to lose synchronization.
1578    LostSync,
1579
1580    /// * The decoder encountered a corrupted frame header.
1581    BadHeader,
1582
1583    /// * The frame's data did not match the CRC in the footer.
1584    FrameCrcMismatch,
1585
1586    /// * The decoder encountered reserved fields in use in the stream.
1587    UnparseableStream,
1588
1589    /// * The decoder encountered a corrupted metadata block.
1590    BadMetadata,
1591
1592    /// * The decoder encountered a otherwise valid frame in which the decoded samples exceeded the range offered by the stated bit depth.
1593    OutOfBounds,
1594}
1595
1596impl Display for FlacInternalDecoderError {
1597    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
1598        match self {
1599            Self::LostSync => write!(f, "An error in the stream caused the decoder to lose synchronization."),
1600            Self::BadHeader => write!(f, "The decoder encountered a corrupted frame header."),
1601            Self::FrameCrcMismatch => write!(f, "The frame's data did not match the CRC in the footer."),
1602            Self::UnparseableStream => write!(f, "The decoder encountered reserved fields in use in the stream."),
1603            Self::BadMetadata => write!(f, "The decoder encountered a corrupted metadata block."),
1604            Self::OutOfBounds => write!(f, "The decoder encountered a otherwise valid frame in which the decoded samples exceeded the range offered by the stated bit depth."),
1605        }
1606    }
1607}
1608
1609impl std::error::Error for FlacInternalDecoderError {}
1610
1611/// ## The form of audio samples
1612#[derive(Debug, Clone, Copy)]
1613pub enum FlacAudioForm {
1614    /// * For the frame array, each audio frame is one sample per channel.
1615    /// * For example, a stereo frame has two samples, one for left, and one for right.
1616    FrameArray,
1617
1618    /// * For channel array, each element of the array is one channel of the audio.
1619    /// * For example, if the audio is mono, the array only contains one element, that element is the only channel for the mono audio.
1620    ChannelArray,
1621}
1622
1623#[derive(Debug, Clone, Copy)]
1624pub struct SamplesInfo {
1625    /// * Number of samples per channel decoded from the FLAC frame
1626    pub samples: u32,
1627
1628    /// * Number of channels in the FLAC frame
1629    pub channels: u32,
1630
1631    /// * The sample rate of the FLAC frame.
1632    pub sample_rate: u32,
1633
1634    /// * How many bits in an `i32` are valid for a sample. The decoder only excretes `[i32]` for you.
1635    /// * For example, the value is 16, but you got a `[i32]`, which means each `i32` is in the range of -32768 to 32767, you can then just cast the `i32` to `i16` for your convenience.
1636    pub bits_per_sample: u32,
1637
1638    /// * How are the audio data forms, audio frame array, or channel array.
1639    pub audio_form: FlacAudioForm,
1640}
1641
1642fn entry_to_str(entry: &FLAC__StreamMetadata_VorbisComment_Entry) -> Cow<'_, str> {
1643    unsafe{String::from_utf8_lossy(slice::from_raw_parts(entry.entry, entry.length as usize))}
1644}
1645
1646fn entry_to_string(entry: &FLAC__StreamMetadata_VorbisComment_Entry) -> String {
1647    entry_to_str(entry).to_string()
1648}
1649
1650/// ## The decoder's core structure, but can't move after `initialize()` has been called.
1651/// Use a `Box` to contain it, or just don't move it will be fine.
1652pub struct FlacDecoderUnmovable<'a, ReadSeek>
1653where
1654    ReadSeek: Read + Seek + Debug {
1655    /// * See <https://xiph.org/flac/api/group__flac__stream__decoder.html>
1656    decoder: *mut FLAC__StreamDecoder,
1657
1658    /// * The reader to read the FLAC file
1659    reader: ReadSeek,
1660
1661    /// * Your `on_read()` closure, read from the `reader` and return how many bytes you read, and what is the current read status.
1662    on_read: Box<dyn FnMut(&mut ReadSeek, &mut [u8]) -> (usize, FlacReadStatus) + 'a>,
1663
1664    /// * Your `on_seek()` closure, helps the decoder to set the file pointer.
1665    on_seek: Box<dyn FnMut(&mut ReadSeek, u64) -> Result<(), io::Error> + 'a>,
1666
1667    /// * Your `on_tell()` closure, returns the current read position.
1668    on_tell: Box<dyn FnMut(&mut ReadSeek) -> Result<u64, io::Error> + 'a>,
1669
1670    /// * Your `on_length()` closure. You only need to return the file length through this closure.
1671    on_length: Box<dyn FnMut(&mut ReadSeek) -> Result<u64, io::Error> + 'a>,
1672
1673    /// * Your `on_eof()` closure, if the `reader` hits the end of the file, the closure returns true. Otherwise returns false indicates that there's still data to be read by the decoder.
1674    on_eof: Box<dyn FnMut(&mut ReadSeek) -> bool + 'a>,
1675
1676    /// * Your `on_write()` closure, it's not for you to "write", but it's the decoder returns the decoded samples for you to use.
1677    on_write: Box<dyn FnMut(&[Vec<i32>], &SamplesInfo) -> Result<(), io::Error> + 'a>,
1678
1679    /// * Your `on_error()` closure. Normally it won't be called.
1680    on_error: Box<dyn FnMut(FlacInternalDecoderError) + 'a>,
1681
1682    /// * Set to true to let the decoder check the MD5 sum of the decoded samples.
1683    md5_checking: bool,
1684
1685    /// * Is this decoder finished decoding?
1686    finished: bool,
1687
1688    /// * Scale to `i32` range or not, if set to true, the sample will be scaled to the whole range of `i32` [-2147483648, +2147483647] if bits per sample is not 32.
1689    pub scale_to_i32_range: bool,
1690
1691    /// * The desired form of audio you want to receive.
1692    pub desired_audio_form: FlacAudioForm,
1693
1694    /// * The vendor string read from the FLAC file.
1695    pub vendor_string: Option<String>,
1696
1697    /// * The comments, or metadata read from the FLAC file.
1698    pub comments: BTreeMap<String, String>,
1699
1700    /// * The pictures, or CD cover read from the FLAC file.
1701    pub pictures: Vec<PictureData>,
1702
1703    /// * The cue sheets read from the FLAC file.
1704    pub cue_sheets: Vec<FlacCueSheet>,
1705}
1706
1707impl<'a, ReadSeek> FlacDecoderUnmovable<'a, ReadSeek>
1708where
1709    ReadSeek: Read + Seek + Debug {
1710    pub fn new(
1711        reader: ReadSeek,
1712        on_read: Box<dyn FnMut(&mut ReadSeek, &mut [u8]) -> (usize, FlacReadStatus) + 'a>,
1713        on_seek: Box<dyn FnMut(&mut ReadSeek, u64) -> Result<(), io::Error> + 'a>,
1714        on_tell: Box<dyn FnMut(&mut ReadSeek) -> Result<u64, io::Error> + 'a>,
1715        on_length: Box<dyn FnMut(&mut ReadSeek) -> Result<u64, io::Error> + 'a>,
1716        on_eof: Box<dyn FnMut(&mut ReadSeek) -> bool + 'a>,
1717        on_write: Box<dyn FnMut(&[Vec<i32>], &SamplesInfo) -> Result<(), io::Error> + 'a>,
1718        on_error: Box<dyn FnMut(FlacInternalDecoderError) + 'a>,
1719        md5_checking: bool,
1720        scale_to_i32_range: bool,
1721        desired_audio_form: FlacAudioForm,
1722    ) -> Result<Self, FlacDecoderError> {
1723        let ret = Self {
1724            decoder: unsafe {FLAC__stream_decoder_new()},
1725            reader,
1726            on_read,
1727            on_seek,
1728            on_tell,
1729            on_length,
1730            on_eof,
1731            on_write,
1732            on_error,
1733            md5_checking,
1734            finished: false,
1735            scale_to_i32_range,
1736            desired_audio_form,
1737            vendor_string: None,
1738            comments: BTreeMap::new(),
1739            pictures: Vec::<PictureData>::new(),
1740            cue_sheets: Vec::<FlacCueSheet>::new(),
1741        };
1742        if ret.decoder.is_null() {
1743            Err(FlacDecoderError::new(FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR, "FLAC__stream_decoder_new"))
1744        } else {
1745            Ok(ret)
1746        }
1747    }
1748
1749    fn get_status_as_result(&self, function: &'static str) -> Result<(), FlacDecoderError> {
1750        let code = unsafe {FLAC__stream_decoder_get_state(self.decoder)};
1751        if code == 0 {
1752            Ok(())
1753        } else {
1754            Err(FlacDecoderError::new(code, function))
1755        }
1756    }
1757
1758    fn get_status_as_error(&self, function: &'static str) -> Result<(), FlacDecoderError> {
1759        let code = unsafe {FLAC__stream_decoder_get_state(self.decoder)};
1760        Err(FlacDecoderError::new(code, function))
1761    }
1762
1763    fn as_ptr(&self) -> *const Self {
1764        self as *const Self
1765    }
1766
1767    fn as_mut_ptr(&mut self) -> *mut Self {
1768        self as *mut Self
1769    }
1770
1771    unsafe extern "C" fn read_callback(_decoder: *const FLAC__StreamDecoder, buffer: *mut u8, bytes: *mut usize, client_data: *mut c_void) -> u32 {
1772        let this = unsafe {&mut *(client_data as *mut Self)};
1773        if unsafe {*bytes} == 0 {
1774            FLAC__STREAM_DECODER_READ_STATUS_ABORT
1775        } else {
1776            let buf = unsafe {slice::from_raw_parts_mut(buffer, *bytes)};
1777            let (bytes_read, status) = (this.on_read)(&mut this.reader, buf);
1778            let ret = match status{
1779                FlacReadStatus::GoOn => FLAC__STREAM_DECODER_READ_STATUS_CONTINUE,
1780                FlacReadStatus::Eof => FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM,
1781                FlacReadStatus::Abort => FLAC__STREAM_DECODER_READ_STATUS_ABORT,
1782            };
1783
1784            unsafe {*bytes = bytes_read};
1785            ret
1786        }
1787    }
1788
1789    unsafe extern "C" fn seek_callback(_decoder: *const FLAC__StreamDecoder, absolute_byte_offset: u64, client_data: *mut c_void) -> u32 {
1790        let this = unsafe {&mut *(client_data as *mut Self)};
1791        match (this.on_seek)(&mut this.reader, absolute_byte_offset) {
1792            Ok(_) => FLAC__STREAM_DECODER_SEEK_STATUS_OK,
1793            Err(e) => {
1794                match e.kind() {
1795                    ErrorKind::NotSeekable => FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED,
1796                    _ => FLAC__STREAM_DECODER_SEEK_STATUS_ERROR,
1797                }
1798            },
1799        }
1800    }
1801
1802    unsafe extern "C" fn tell_callback(_decoder: *const FLAC__StreamDecoder, absolute_byte_offset: *mut u64, client_data: *mut c_void) -> u32 {
1803        let this = unsafe {&mut *(client_data as *mut Self)};
1804        match (this.on_tell)(&mut this.reader) {
1805            Ok(offset) => {
1806                unsafe {*absolute_byte_offset = offset};
1807                FLAC__STREAM_DECODER_TELL_STATUS_OK
1808            },
1809            Err(e) => {
1810                match e.kind() {
1811                    ErrorKind::NotSeekable => FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED,
1812                    _ => FLAC__STREAM_DECODER_TELL_STATUS_ERROR,
1813                }
1814            },
1815        }
1816    }
1817
1818    unsafe extern "C" fn length_callback(_decoder: *const FLAC__StreamDecoder, stream_length: *mut u64, client_data: *mut c_void) -> u32 {
1819        let this = unsafe {&mut *(client_data as *mut Self)};
1820        match (this.on_length)(&mut this.reader) {
1821            Ok(length) => {
1822                unsafe {*stream_length = length};
1823                FLAC__STREAM_DECODER_LENGTH_STATUS_OK
1824            },
1825            Err(e) => {
1826                match e.kind() {
1827                    ErrorKind::NotSeekable => FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED,
1828                    _ => FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR,
1829                }
1830            },
1831        }
1832    }
1833
1834    unsafe extern "C" fn eof_callback(_decoder: *const FLAC__StreamDecoder, client_data: *mut c_void) -> i32 {
1835        let this = unsafe {&mut *(client_data as *mut Self)};
1836        if (this.on_eof)(&mut this.reader) {1} else {0}
1837    }
1838
1839    unsafe extern "C" fn write_callback(_decoder: *const FLAC__StreamDecoder, frame: *const FLAC__Frame, buffer: *const *const i32, client_data: *mut c_void) -> u32 {
1840        // Scales signed PCM samples to full i32 dynamic range.
1841        // - `bits`: Valid bits in `sample` (1-32).
1842        // - Example: 8-bit samples [-128, 127] → [i32::MIN, i32::MAX]
1843        fn scale_to_i32(sample: i32, bits: u32) -> i32 {
1844            assert!(bits <= 32);
1845            if bits == 32 {
1846                sample
1847            } else {
1848                fn scale_to_unsigned(sample: i32, bits: u32) -> u32 {
1849                    let mask = (1u32 << bits) - 1;
1850                    let mid_number = 1u32 << (bits - 1);
1851                    ((sample as u32).wrapping_add(mid_number) & mask) << (32 - bits)
1852                }
1853                let mut lower_fill = scale_to_unsigned(sample, bits);
1854                let mut result = (sample as u32) << (32 - bits);
1855                while lower_fill > 0 {
1856                    lower_fill >>= bits;
1857                    result |= lower_fill;
1858                }
1859                result as i32
1860            }
1861        }
1862
1863        let this = unsafe {&mut *(client_data as *mut Self)};
1864        let frame = unsafe {*frame};
1865        let samples = frame.header.blocksize;
1866        let channels = frame.header.channels;
1867        let sample_rate = frame.header.sample_rate;
1868        let bits_per_sample = frame.header.bits_per_sample;
1869
1870        let mut samples_info = SamplesInfo {
1871            samples,
1872            channels,
1873            sample_rate,
1874            bits_per_sample,
1875            audio_form: this.desired_audio_form,
1876        };
1877
1878        let mut ret: Vec<Vec<i32>>;
1879        match this.desired_audio_form {
1880            FlacAudioForm::FrameArray => {
1881                // Each `frame` contains one sample for each channel
1882                ret = vec![Vec::<i32>::new(); samples as usize];
1883                for s in 0..samples {
1884                    for c in 0..channels {
1885                        let channel = unsafe {*buffer.add(c as usize)};
1886                        ret[s as usize].push(unsafe {*channel.add(s as usize)});
1887                    }
1888                }
1889            },
1890            FlacAudioForm::ChannelArray => {
1891                // Each `channel` contains all samples for the channel
1892                ret = vec![Vec::<i32>::new(); channels as usize];
1893                for c in 0..channels {
1894                    ret[c as usize] = unsafe {slice::from_raw_parts(*buffer.add(c as usize), samples as usize)}.to_vec();
1895                }
1896            }
1897        }
1898
1899        // Whatever it was, now it's just a two-dimensional array
1900        if this.scale_to_i32_range {
1901            for x in ret.iter_mut() {
1902                for y in x.iter_mut() {
1903                    *y = scale_to_i32(*y, bits_per_sample);
1904                }
1905            }
1906            samples_info.bits_per_sample = 32;
1907        }
1908
1909        match (this.on_write)(&ret, &samples_info) {
1910            Ok(_) => FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE,
1911            Err(e) => {
1912                eprintln!("On `write_callback()`: {:?}", e);
1913                FLAC__STREAM_DECODER_WRITE_STATUS_ABORT
1914            },
1915        }
1916    }
1917
1918    unsafe extern "C" fn metadata_callback(_decoder: *const FLAC__StreamDecoder, metadata: *const FLAC__StreamMetadata, client_data: *mut c_void) {
1919        let this = unsafe {&mut *(client_data as *mut Self)};
1920        let metadata = unsafe {*metadata};
1921        match metadata.type_ {
1922            FLAC__METADATA_TYPE_VORBIS_COMMENT => unsafe {
1923                let comments = metadata.data.vorbis_comment;
1924
1925                // First retrieve the vendor string
1926                this.vendor_string = Some(entry_to_string(&comments.vendor_string));
1927
1928                // Then to get all of the key pairs, the key pairs should be all uppercase, but some of them are not.
1929                // Read both the uppercase keys and the lowercase keys and store them, if it won't overwrite then we convert
1930                // the key to uppercase and store it again.
1931                let mut uppercase_keypairs = Vec::<(String, String)>::new();
1932                for i in 0..comments.num_comments {
1933                    let comment = entry_to_string(&*comments.comments.add(i as usize));
1934
1935                    // The key pair is split by the equal notation
1936                    let mut iter = comment.split("=");
1937                    if let Some(key) = iter.next() {
1938                        let key = key.to_owned();
1939
1940                        // Ignore the later equal notations.
1941                        let val = iter.map(|s: &str|{s.to_string()}).collect::<Vec<String>>().join("=");
1942                        let key_upper = key.to_uppercase();
1943                        if key != key_upper {
1944                            uppercase_keypairs.push((key_upper, val.clone()));
1945                        }
1946
1947                        // Duplication check
1948                        let if_dup = format!("Duplicated comments: new comment is {key}: {val}, the previous is {key}: ");
1949                        if let Some(old) = this.comments.insert(key, val) {
1950                            eprintln!("{if_dup}{old}");
1951                        }
1952                    } else {
1953                        // No equal notation here
1954                        eprintln!("Invalid comment: {comment}");
1955                    }
1956                }
1957
1958                // If it lacks the uppercase key pairs, we add it to the map.
1959                for (key_upper, val) in uppercase_keypairs {
1960                    if this.comments.contains_key(&key_upper) {
1961                        continue;
1962                    } else {
1963                        this.comments.insert(key_upper, val);
1964                    }
1965                }
1966            },
1967            FLAC__METADATA_TYPE_PICTURE => unsafe {
1968                let picture = metadata.data.picture;
1969                this.pictures.push(PictureData{
1970                    picture: slice::from_raw_parts(picture.data, picture.data_length as usize).to_vec(),
1971                    description: CStr::from_ptr(picture.description as *const i8).to_string_lossy().to_string(),
1972                    mime_type: CStr::from_ptr(picture.mime_type).to_string_lossy().to_string(),
1973                    width: picture.width,
1974                    height: picture.height,
1975                    depth: picture.depth,
1976                    colors: picture.colors,
1977                });
1978            },
1979            FLAC__METADATA_TYPE_CUESHEET => unsafe {
1980                let cue_sheet = metadata.data.cue_sheet;
1981                this.cue_sheets.push(FlacCueSheet{
1982                    media_catalog_number: cue_sheet.media_catalog_number,
1983                    lead_in: cue_sheet.lead_in,
1984                    is_cd: cue_sheet.is_cd != 0,
1985                    tracks: (0..cue_sheet.num_tracks).map(|i| -> (u8, FlacCueTrack) {
1986                        let track = *cue_sheet.tracks.add(i as usize);
1987                        (track.number, FlacCueTrack {
1988                            offset: track.offset,
1989                            track_no: track.number,
1990                            isrc: track.isrc,
1991                            type_: match track.type_() {
1992                                0 => FlacTrackType::Audio,
1993                                _ => FlacTrackType::NonAudio,
1994                            },
1995                            pre_emphasis: track.pre_emphasis() != 0,
1996                            indices: (0..track.num_indices).map(|i| -> FlacCueSheetIndex {
1997                                let index = *track.indices.add(i as usize);
1998                                FlacCueSheetIndex {
1999                                    offset: index.offset,
2000                                    number: index.number,
2001                                }
2002                            }).collect()
2003                        })
2004                    }).collect(),
2005                });
2006            },
2007            _ => {
2008                #[cfg(debug_assertions)]
2009                if SHOW_CALLBACKS {println!("On `metadata_callback()`: {:?}", WrappedStreamMetadata(metadata));}
2010            },
2011        }
2012    }
2013
2014    unsafe extern "C" fn error_callback(_decoder: *const FLAC__StreamDecoder, status: u32, client_data: *mut c_void) {
2015        let this = unsafe {&mut *(client_data as *mut Self)};
2016        (this.on_error)(match status {
2017            FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC => FlacInternalDecoderError::LostSync,
2018            FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER => FlacInternalDecoderError::BadHeader,
2019            FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH => FlacInternalDecoderError::FrameCrcMismatch,
2020            FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM => FlacInternalDecoderError::UnparseableStream,
2021            FLAC__STREAM_DECODER_ERROR_STATUS_BAD_METADATA => FlacInternalDecoderError::BadMetadata,
2022            o => panic!("Unknown value of `FLAC__StreamDecodeErrorStatus`: {o}"),
2023        });
2024    }
2025
2026    /// * The `initialize()` function. Sets up all of the callback functions, sets `client_data` to the address of the `self` struct.
2027    pub fn initialize(&mut self) -> Result<(), FlacDecoderError> {
2028        unsafe {
2029            if FLAC__stream_decoder_set_md5_checking(self.decoder, self.md5_checking as i32) == 0 {
2030                return self.get_status_as_error("FLAC__stream_decoder_set_md5_checking");
2031            }
2032            if FLAC__stream_decoder_set_metadata_respond_all(self.decoder) == 0 {
2033                return self.get_status_as_error("FLAC__stream_decoder_set_metadata_respond_all");
2034            }
2035            let ret = FLAC__stream_decoder_init_stream(
2036                self.decoder,
2037                Some(Self::read_callback),
2038                Some(Self::seek_callback),
2039                Some(Self::tell_callback),
2040                Some(Self::length_callback),
2041                Some(Self::eof_callback),
2042                Some(Self::write_callback),
2043                Some(Self::metadata_callback),
2044                Some(Self::error_callback),
2045                self.as_mut_ptr() as *mut c_void,
2046            );
2047            if ret != 0 {
2048                return Err(FlacDecoderError {
2049                    code: ret,
2050                    message: FlacDecoderInitError::get_message_from_code(ret),
2051                    function: "FLAC__stream_decoder_init_stream",
2052                });
2053            }
2054        }
2055        self.finished = false;
2056        self.get_status_as_result("FlacDecoderUnmovable::Init()")
2057    }
2058
2059    /// * Seek to the specific sample position, may fail.
2060    pub fn seek(&mut self, frame_index: u64) -> Result<(), FlacDecoderError> {
2061        for _retry in 0..3 {
2062            unsafe {
2063                if FLAC__stream_decoder_seek_absolute(self.decoder, frame_index) == 0 {
2064                    match FLAC__stream_decoder_get_state(self.decoder) {
2065                        FLAC__STREAM_DECODER_SEEK_STATUS_OK => panic!("`FLAC__stream_decoder_seek_absolute()` returned false, but the status of the decoder is `OK`"),
2066                        FLAC__STREAM_DECODER_SEEK_ERROR => {
2067                            if FLAC__stream_decoder_reset(self.decoder) == 0 {
2068                                return self.get_status_as_error("FLAC__stream_decoder_reset");
2069                            } else {
2070                                continue;
2071                            }
2072                        },
2073                        o => return Err(FlacDecoderError::new(o, "FLAC__stream_decoder_seek_absolute")),
2074                    }
2075                } else {
2076                    return Ok(())
2077                }
2078            }
2079        }
2080        Err(FlacDecoderError::new(FLAC__STREAM_DECODER_SEEK_ERROR, "FLAC__stream_decoder_seek_absolute"))
2081    }
2082
2083    /// * Calls your `on_tell()` closure to get the read position
2084    pub fn tell(&mut self) -> Result<u64, io::Error> {
2085        (self.on_tell)(&mut self.reader)
2086    }
2087
2088    /// * Calls your `on_length()` closure to get the length of the file
2089    pub fn length(&mut self) -> Result<u64, io::Error> {
2090        (self.on_length)(&mut self.reader)
2091    }
2092
2093    /// * Calls your `on_eof()` closure to check if `reader` hits the end of the file.
2094    pub fn eof(&mut self) -> bool {
2095        (self.on_eof)(&mut self.reader)
2096    }
2097
2098    /// * Get the vendor string.
2099    pub fn get_vendor_string(&self) -> &Option<String> {
2100        &self.vendor_string
2101    }
2102
2103    /// * Get all of the comments or metadata.
2104    pub fn get_comments(&self) -> &BTreeMap<String, String> {
2105        &self.comments
2106    }
2107
2108    /// * Get all of the pictures
2109    pub fn get_pictures(&self) -> &Vec<PictureData> {
2110        &self.pictures
2111    }
2112
2113    /// * Get all of the cue sheets
2114    pub fn get_cue_sheets(&self) -> &Vec<FlacCueSheet> {
2115        &self.cue_sheets
2116    }
2117
2118    /// * Decode one FLAC frame, may get an audio frame or a metadata frame.
2119    /// * Your closures will be called by the decoder when you call this method.
2120    pub fn decode(&mut self) -> Result<bool, FlacDecoderError> {
2121        if unsafe {FLAC__stream_decoder_process_single(self.decoder) != 0} {
2122            Ok(true)
2123        } else {
2124            match self.get_status_as_result("FLAC__stream_decoder_process_single") {
2125                Ok(_) => Ok(false),
2126                Err(e) => Err(e),
2127            }
2128        }
2129    }
2130
2131    /// * Decode all of the FLAC frames, get all of the samples and metadata and pictures and cue sheets, etc.
2132    pub fn decode_all(&mut self) -> Result<bool, FlacDecoderError> {
2133        if unsafe {FLAC__stream_decoder_process_until_end_of_stream(self.decoder) != 0} {
2134            Ok(true)
2135        } else {
2136            match self.get_status_as_result("FLAC__stream_decoder_process_until_end_of_stream") {
2137                Ok(_) => Ok(false),
2138                Err(e) => Err(e),
2139            }
2140        }
2141    }
2142
2143    /// * Finish decoding the FLAC file, the remaining samples will be returned to you via your `on_write()` closure.
2144    pub fn finish(&mut self) -> Result<(), FlacDecoderError> {
2145        if !self.finished {
2146            if unsafe {FLAC__stream_decoder_finish(self.decoder) != 0} {
2147                self.finished = true;
2148                Ok(())
2149            } else {
2150                self.get_status_as_result("FLAC__stream_decoder_finish")
2151            }
2152        } else {
2153            Ok(())
2154        }
2155    }
2156
2157    fn on_drop(&mut self) {
2158        unsafe {
2159            if let Err(e) =  self.finish() {
2160                eprintln!("On FlacDecoderUnmovable::finish(): {:?}", e);
2161            }
2162
2163            // Must delete `self.decoder` even `self.finish()` fails.
2164            FLAC__stream_decoder_delete(self.decoder);
2165        };
2166    }
2167
2168    /// * Call this function if you don't want the decoder anymore.
2169    pub fn finalize(self) {}
2170}
2171
2172impl<'a, ReadSeek> Debug for FlacDecoderUnmovable<'_, ReadSeek>
2173where
2174    ReadSeek: Read + Seek + Debug {
2175    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
2176        fmt.debug_struct("FlacDecoderUnmovable")
2177            .field("decoder", &self.decoder)
2178            .field("reader", &self.reader)
2179            .field("on_read", &"{{closure}}")
2180            .field("on_seek", &"{{closure}}")
2181            .field("on_tell", &"{{closure}}")
2182            .field("on_length", &"{{closure}}")
2183            .field("on_eof", &"{{closure}}")
2184            .field("on_write", &"{{closure}}")
2185            .field("on_error", &"{{closure}}")
2186            .field("md5_checking", &self.md5_checking)
2187            .field("finished", &self.finished)
2188            .field("scale_to_i32_range", &self.scale_to_i32_range)
2189            .field("desired_audio_form", &self.desired_audio_form)
2190            .field("vendor_string", &self.vendor_string)
2191            .field("comments", &self.comments)
2192            .field("pictures", &self.pictures)
2193            .field("cue_sheets", &self.cue_sheets)
2194            .finish()
2195    }
2196}
2197
2198impl<'a, ReadSeek> Drop for FlacDecoderUnmovable<'_, ReadSeek>
2199where
2200    ReadSeek: Read + Seek + Debug {
2201    fn drop(&mut self) {
2202        self.on_drop();
2203    }
2204}
2205
2206/// ## A wrapper for `FlacDecoderUnmovable`, which provides a Box to make `FlacDecoderUnmovable` never move.
2207/// This is the struct that should be mainly used by you.
2208pub struct FlacDecoder<'a, ReadSeek>
2209where
2210    ReadSeek: Read + Seek + Debug {
2211    decoder: Box<FlacDecoderUnmovable<'a, ReadSeek>>,
2212}
2213
2214impl<'a, ReadSeek> FlacDecoder<'a, ReadSeek>
2215where
2216    ReadSeek: Read + Seek + Debug {
2217    pub fn new(
2218        reader: ReadSeek,
2219        on_read: Box<dyn FnMut(&mut ReadSeek, &mut [u8]) -> (usize, FlacReadStatus) + 'a>,
2220        on_seek: Box<dyn FnMut(&mut ReadSeek, u64) -> Result<(), io::Error> + 'a>,
2221        on_tell: Box<dyn FnMut(&mut ReadSeek) -> Result<u64, io::Error> + 'a>,
2222        on_length: Box<dyn FnMut(&mut ReadSeek) -> Result<u64, io::Error> + 'a>,
2223        on_eof: Box<dyn FnMut(&mut ReadSeek) -> bool + 'a>,
2224        on_write: Box<dyn FnMut(&[Vec<i32>], &SamplesInfo) -> Result<(), io::Error> + 'a>,
2225        on_error: Box<dyn FnMut(FlacInternalDecoderError) + 'a>,
2226        md5_checking: bool,
2227        scale_to_i32_range: bool,
2228        desired_audio_form: FlacAudioForm,
2229    ) -> Result<Self, FlacDecoderError> {
2230        let mut ret = Self {
2231            decoder: Box::new(FlacDecoderUnmovable::<'a>::new(
2232                reader,
2233                on_read,
2234                on_seek,
2235                on_tell,
2236                on_length,
2237                on_eof,
2238                on_write,
2239                on_error,
2240                md5_checking,
2241                scale_to_i32_range,
2242                desired_audio_form,
2243            )?),
2244        };
2245        ret.decoder.initialize()?;
2246        Ok(ret)
2247    }
2248
2249    /// * Seek to the specific sample position, may fail.
2250    pub fn seek(&mut self, frame_index: u64) -> Result<(), FlacDecoderError> {
2251        self.decoder.seek(frame_index)
2252    }
2253
2254    /// * Calls your `on_tell()` closure to get the read position
2255    pub fn tell(&mut self) -> Result<u64, io::Error> {
2256        self.decoder.tell()
2257    }
2258
2259    /// * Calls your `on_length()` closure to get the length of the file
2260    pub fn length(&mut self) -> Result<u64, io::Error> {
2261        self.decoder.length()
2262    }
2263
2264    /// * Calls your `on_eof()` closure to check if `reader` hits the end of the file.
2265    pub fn eof(&mut self) -> bool {
2266        self.decoder.eof()
2267    }
2268
2269    /// * Get the vendor string.
2270    pub fn get_vendor_string(&self) -> &Option<String> {
2271        &self.decoder.vendor_string
2272    }
2273
2274    /// * Get all of the comments or metadata.
2275    pub fn get_comments(&self) -> &BTreeMap<String, String> {
2276        &self.decoder.comments
2277    }
2278
2279    /// * Get all of the pictures
2280    pub fn get_pictures(&self) -> &Vec<PictureData> {
2281        &self.decoder.pictures
2282    }
2283
2284    /// * Decode one FLAC frame, may get an audio frame or a metadata frame.
2285    /// * Your closures will be called by the decoder when you call this method.
2286    pub fn decode(&mut self) -> Result<bool, FlacDecoderError> {
2287        self.decoder.decode()
2288    }
2289
2290    /// * Decode all of the FLAC frames, get all of the samples and metadata and pictures and cue sheets, etc.
2291    pub fn decode_all(&mut self) -> Result<bool, FlacDecoderError> {
2292        self.decoder.decode_all()
2293    }
2294
2295    /// * Finish decoding the FLAC file, the remaining samples will be returned to you via your `on_write()` closure.
2296    pub fn finish(&mut self) -> Result<(), FlacDecoderError> {
2297        self.decoder.finish()
2298    }
2299
2300    /// * Call this function if you don't want the decoder anymore.
2301    pub fn finalize(self) {}
2302}
2303
2304impl<'a, ReadSeek> Debug for FlacDecoder<'_, ReadSeek>
2305where
2306    ReadSeek: Read + Seek + Debug {
2307    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
2308        fmt.debug_struct("FlacDecoder")
2309            .field("decoder", &self.decoder)
2310            .finish()
2311    }
2312}
2313
2314#[derive(Clone, Copy)]
2315struct WrappedStreamInfo(FLAC__StreamMetadata_StreamInfo);
2316
2317impl Debug for WrappedStreamInfo {
2318    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
2319        fmt.debug_struct("FLAC__StreamMetadata_StreamInfo")
2320            .field("min_blocksize", &self.0.min_blocksize)
2321            .field("max_blocksize", &self.0.max_blocksize)
2322            .field("min_framesize", &self.0.min_framesize)
2323            .field("max_framesize", &self.0.max_framesize)
2324            .field("sample_rate", &self.0.sample_rate)
2325            .field("channels", &self.0.channels)
2326            .field("bits_per_sample", &self.0.bits_per_sample)
2327            .field("total_samples", &self.0.total_samples)
2328            .field("md5sum", &format_args!("{}", self.0.md5sum.iter().map(|x|{format!("{:02x}", x)}).collect::<Vec<String>>().join("")))
2329            .finish()
2330    }
2331}
2332
2333#[derive(Clone, Copy)]
2334struct WrappedPadding(FLAC__StreamMetadata_Padding);
2335impl Debug for WrappedPadding {
2336    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
2337        fmt.debug_struct("FLAC__StreamMetadata_Padding")
2338            .field("dummy", &self.0.dummy)
2339            .finish()
2340    }
2341}
2342
2343#[derive(Clone, Copy)]
2344struct WrappedApplication(FLAC__StreamMetadata_Application, u32);
2345impl WrappedApplication {
2346    pub fn get_header(&self) -> String {
2347        String::from_utf8_lossy(&self.0.id).to_string()
2348    }
2349    pub fn get_data(&self) -> Vec<u8> {
2350        let n = self.1 - 4;
2351        unsafe {slice::from_raw_parts(self.0.data, n as usize)}.to_vec()
2352    }
2353}
2354
2355impl Debug for WrappedApplication {
2356    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
2357        fmt.debug_struct("FLAC__StreamMetadata_Application")
2358            .field("id", &self.get_header())
2359            .field("data", &String::from_utf8_lossy(&self.get_data()))
2360            .finish()
2361    }
2362}
2363
2364#[derive(Clone, Copy)]
2365struct WrappedSeekPoint(FLAC__StreamMetadata_SeekPoint);
2366impl Debug for WrappedSeekPoint {
2367    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
2368        fmt.debug_struct("FLAC__StreamMetadata_SeekPoint")
2369            .field("sample_number", &self.0.sample_number)
2370            .field("stream_offset", &self.0.stream_offset)
2371            .field("frame_samples", &self.0.frame_samples)
2372            .finish()
2373    }
2374}
2375
2376#[derive(Clone, Copy)]
2377struct WrappedSeekTable(FLAC__StreamMetadata_SeekTable);
2378impl Debug for WrappedSeekTable {
2379    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
2380        let points: Vec<WrappedSeekPoint> = unsafe {slice::from_raw_parts(self.0.points, self.0.num_points as usize).iter().map(|p|{WrappedSeekPoint(*p)}).collect()};
2381        fmt.debug_struct("FLAC__StreamMetadata_SeekTable")
2382            .field("num_points", &self.0.num_points)
2383            .field("points", &format_args!("{:?}", points))
2384            .finish()
2385    }
2386}
2387
2388#[derive(Clone, Copy)]
2389struct WrappedVorbisComment(FLAC__StreamMetadata_VorbisComment);
2390impl Debug for WrappedVorbisComment {
2391    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
2392        fmt.debug_struct("FLAC__StreamMetadata_VorbisComment")
2393            .field("vendor_string", &entry_to_string(&self.0.vendor_string))
2394            .field("num_comments", &self.0.num_comments)
2395            .field("comments", &format_args!("[{}]", (0..self.0.num_comments).map(|i|unsafe{entry_to_string(&*self.0.comments.add(i as usize))}).collect::<Vec<String>>().join(", ")))
2396            .finish()
2397    }
2398}
2399
2400#[derive(Clone, Copy)]
2401struct WrappedCueSheet(FLAC__StreamMetadata_CueSheet);
2402impl Debug for WrappedCueSheet {
2403    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
2404        fmt.debug_struct("FLAC__StreamMetadata_CueSheet")
2405            .field("media_catalog_number", &String::from_utf8_lossy(&self.0.media_catalog_number.into_iter().map(|c|{c as u8}).collect::<Vec<u8>>()))
2406            .field("lead_in", &self.0.lead_in)
2407            .field("is_cd", &self.0.is_cd)
2408            .field("num_tracks", &self.0.num_tracks)
2409            .field("tracks", &format_args!("[{}]", (0..self.0.num_tracks).map(|i|format!("{:?}", unsafe{*self.0.tracks.add(i as usize)})).collect::<Vec<String>>().join(", ")))
2410            .finish()
2411    }
2412}
2413
2414#[derive(Clone, Copy)]
2415struct WrappedCueSheetTrack(FLAC__StreamMetadata_CueSheet_Track);
2416impl Debug for WrappedCueSheetTrack {
2417    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
2418        fmt.debug_struct("FLAC__StreamMetadata_CueSheet_Track")
2419            .field("offset", &self.0.offset)
2420            .field("number", &self.0.number)
2421            .field("isrc", &self.0.isrc)
2422            .field("type", &self.0.type_())
2423            .field("pre_emphasis", &self.0.pre_emphasis())
2424            .field("num_indices", &self.0.num_indices)
2425            .field("indices", &format_args!("[{}]", (0..self.0.num_indices).map(|i|format!("{:?}", unsafe{*self.0.indices.add(i as usize)})).collect::<Vec<String>>().join(", ")))
2426            .finish()
2427    }
2428}
2429
2430#[derive(Clone, Copy)]
2431struct WrappedCueSheetIndex(FLAC__StreamMetadata_CueSheet_Index);
2432impl Debug for WrappedCueSheetIndex {
2433    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
2434        fmt.debug_struct("FLAC__StreamMetadata_CueSheet_Index")
2435            .field("offset", &self.0.offset)
2436            .field("number", &self.0.number)
2437            .finish()
2438    }
2439}
2440
2441fn picture_type_to_str(pictype: u32) -> &'static str {
2442    match pictype {
2443        FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON_STANDARD => "32x32 pixels 'file icon' (PNG only)",
2444        FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON => "Other file icon",
2445        FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER => "Cover (front)",
2446        FLAC__STREAM_METADATA_PICTURE_TYPE_BACK_COVER => "Cover (back)",
2447        FLAC__STREAM_METADATA_PICTURE_TYPE_LEAFLET_PAGE => "Leaflet page",
2448        FLAC__STREAM_METADATA_PICTURE_TYPE_MEDIA => "Media (e.g. label side of CD)",
2449        FLAC__STREAM_METADATA_PICTURE_TYPE_LEAD_ARTIST => "Lead artist/lead performer/soloist",
2450        FLAC__STREAM_METADATA_PICTURE_TYPE_ARTIST => "Artist/performer",
2451        FLAC__STREAM_METADATA_PICTURE_TYPE_CONDUCTOR => "Conductor",
2452        FLAC__STREAM_METADATA_PICTURE_TYPE_BAND => "Band/Orchestra",
2453        FLAC__STREAM_METADATA_PICTURE_TYPE_COMPOSER => "Composer",
2454        FLAC__STREAM_METADATA_PICTURE_TYPE_LYRICIST => "Lyricist/text writer",
2455        FLAC__STREAM_METADATA_PICTURE_TYPE_RECORDING_LOCATION => "Recording Location",
2456        FLAC__STREAM_METADATA_PICTURE_TYPE_DURING_RECORDING => "During recording",
2457        FLAC__STREAM_METADATA_PICTURE_TYPE_DURING_PERFORMANCE => "During performance",
2458        FLAC__STREAM_METADATA_PICTURE_TYPE_VIDEO_SCREEN_CAPTURE => "Movie/video screen capture",
2459        FLAC__STREAM_METADATA_PICTURE_TYPE_FISH => "A bright coloured fish",
2460        FLAC__STREAM_METADATA_PICTURE_TYPE_ILLUSTRATION => "Illustration",
2461        FLAC__STREAM_METADATA_PICTURE_TYPE_BAND_LOGOTYPE => "Band/artist logotype",
2462        FLAC__STREAM_METADATA_PICTURE_TYPE_PUBLISHER_LOGOTYPE => "Publisher/Studio logotype",
2463        _ => "Other",
2464    }
2465}
2466
2467#[derive(Clone, Copy)]
2468struct WrappedPicture(FLAC__StreamMetadata_Picture);
2469impl Debug for WrappedPicture {
2470    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
2471        fmt.debug_struct("FLAC__StreamMetadata_Picture")
2472            .field("type_", &picture_type_to_str(self.0.type_))
2473            .field("mime_type", &unsafe{CStr::from_ptr(self.0.mime_type).to_str()})
2474            .field("description", &unsafe{CStr::from_ptr(self.0.description as *const i8).to_str()})
2475            .field("width", &self.0.width)
2476            .field("height", &self.0.height)
2477            .field("depth", &self.0.depth)
2478            .field("colors", &self.0.colors)
2479            .field("data_length", &self.0.data_length)
2480            .field("data", &format_args!("[u8; {}]", self.0.data_length))
2481            .finish()
2482    }
2483}
2484
2485#[derive(Clone, Copy)]
2486struct WrappedUnknown(FLAC__StreamMetadata_Unknown);
2487impl Debug for WrappedUnknown {
2488    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
2489        fmt.debug_struct("FLAC__StreamMetadata_Unknown")
2490            .finish_non_exhaustive()
2491    }
2492}
2493
2494#[derive(Clone, Copy)]
2495struct WrappedStreamMetadata(FLAC__StreamMetadata);
2496
2497impl Debug for WrappedStreamMetadata {
2498    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
2499        fmt.debug_struct("FLAC__StreamMetadata")
2500            .field("type_", &self.0.type_)
2501            .field("is_last", &self.0.is_last)
2502            .field("length", &self.0.length)
2503            .field("data", &match self.0.type_ {
2504                FLAC__METADATA_TYPE_STREAMINFO => format!("{:?}", unsafe{WrappedStreamInfo(self.0.data.stream_info)}),
2505                FLAC__METADATA_TYPE_PADDING => format!("{:?}", unsafe{WrappedPadding(self.0.data.padding)}),
2506                FLAC__METADATA_TYPE_APPLICATION => format!("{:?}", unsafe{WrappedApplication(self.0.data.application, self.0.length)}),
2507                FLAC__METADATA_TYPE_SEEKTABLE => format!("{:?}", unsafe{WrappedSeekTable(self.0.data.seek_table)}),
2508                FLAC__METADATA_TYPE_VORBIS_COMMENT => format!("{:?}", unsafe{WrappedVorbisComment(self.0.data.vorbis_comment)}),
2509                FLAC__METADATA_TYPE_CUESHEET => format!("{:?}", unsafe{WrappedCueSheet(self.0.data.cue_sheet)}),
2510                FLAC__METADATA_TYPE_PICTURE => format!("{:?}", unsafe{WrappedPicture(self.0.data.picture)}),
2511                FLAC__METADATA_TYPE_UNDEFINED => format!("{:?}", unsafe{WrappedUnknown(self.0.data.unknown)}),
2512                o => format!("Unknown metadata type {o}"),
2513            })
2514            .finish()
2515    }
2516}