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#[derive(Debug, Clone, Copy, PartialEq)]
17pub enum FlacCompression {
18 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 Level8 = 8
30}
31
32#[derive(Debug, Clone, Copy, PartialEq)]
34pub struct FlacEncoderParams {
35 pub verify_decoded: bool,
37
38 pub compression: FlacCompression,
40
41 pub channels: u16,
43
44 pub sample_rate: u32,
46
47 pub bits_per_sample: u32,
51
52 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
82pub trait FlacError: Any {
85 fn as_any(&self) -> &dyn Any;
87
88 fn get_code(&self) -> u32;
90
91 fn get_message(&self) -> &'static str;
93
94 fn get_function(&self) -> &'static str;
96
97 fn get_message_from_code(&self) -> &'static str;
99
100 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#[derive(Debug, Clone, Copy)]
134pub struct FlacEncoderError {
135 pub code: u32,
137
138 pub message: &'static str,
140
141 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#[derive(Debug, Clone, Copy)]
165pub enum FlacEncoderErrorCode {
166 StreamEncoderOk = FLAC__STREAM_ENCODER_OK as isize,
168
169 StreamEncoderUninitialized = FLAC__STREAM_ENCODER_UNINITIALIZED as isize,
171
172 StreamEncoderOggError = FLAC__STREAM_ENCODER_OGG_ERROR as isize,
174
175 StreamEncoderVerifyDecoderError = FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR as isize,
177
178 StreamEncoderVerifyMismatchInAudioData = FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA as isize,
180
181 StreamEncoderClientError = FLAC__STREAM_ENCODER_CLIENT_ERROR as isize,
183
184 StreamEncoderIOError = FLAC__STREAM_ENCODER_IO_ERROR as isize,
186
187 StreamEncoderFramingError = FLAC__STREAM_ENCODER_FRAMING_ERROR as isize,
189
190 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#[derive(Debug, Clone, Copy)]
232pub struct FlacEncoderInitError {
233 pub code: u32,
235
236 pub message: &'static str,
238
239 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#[derive(Debug, Clone, Copy)]
263pub enum FlacEncoderInitErrorCode {
264 StreamEncoderInitStatusOk = FLAC__STREAM_ENCODER_INIT_STATUS_OK as isize,
266
267 StreamEncoderInitStatusEncoderError = FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR as isize,
269
270 StreamEncoderInitStatusUnsupportedContainer = FLAC__STREAM_ENCODER_INIT_STATUS_UNSUPPORTED_CONTAINER as isize,
272
273 StreamEncoderInitStatusInvalidCallbacks = FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_CALLBACKS as isize,
275
276 StreamEncoderInitStatusInvalidNumberOfChannels = FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_NUMBER_OF_CHANNELS as isize,
278
279 StreamEncoderInitStatusInvalidBitsPerSample = FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BITS_PER_SAMPLE as isize,
281
282 StreamEncoderInitStatusInvalidSampleRate = FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_SAMPLE_RATE as isize,
284
285 StreamEncoderInitStatusInvalidBlockSize = FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BLOCK_SIZE as isize,
287
288 StreamEncoderInitStatusInvalidMaxLpcOrder = FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_MAX_LPC_ORDER as isize,
290
291 StreamEncoderInitStatusInvalidQlpCoeffPrecision = FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_QLP_COEFF_PRECISION as isize,
293
294 StreamEncoderInitStatusBlockSizeTooSmallForLpcOrder = FLAC__STREAM_ENCODER_INIT_STATUS_BLOCK_SIZE_TOO_SMALL_FOR_LPC_ORDER as isize,
296
297 StreamEncoderInitStatusNotStreamable = FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE as isize,
299
300 StreamEncoderInitStatusInvalidMetadata = FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA as isize,
309
310 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
380pub 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#[derive(Clone)]
419pub struct PictureData {
420 pub picture: Vec<u8>,
422
423 pub mime_type: String,
425
426 pub description: String,
428
429 pub width: u32,
431
432 pub height: u32,
434
435 pub depth: u32,
437
438 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 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#[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 pub offset: u64,
562
563 pub number: u8,
565}
566
567#[derive(Clone)]
568#[repr(C)]
569pub struct FlacCueTrack {
570 pub offset: u64,
572
573 pub track_no: u8,
575
576 pub isrc: [i8; 13],
578
579 pub type_: FlacTrackType,
581
582 pub pre_emphasis: bool,
584
585 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#[derive(Clone)]
623pub struct FlacCueSheet {
624 pub media_catalog_number: [i8; 129],
626
627 pub lead_in: u64,
629
630 pub is_cd: bool,
632
633 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 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
785pub struct FlacEncoderUnmovable<'a, WriteSeek>
788where
789 WriteSeek: Write + Seek + Debug {
790 encoder: *mut FLAC__StreamEncoder,
792
793 metadata: Vec<FlacMetadata>,
795
796 encoder_initialized: bool,
798
799 params: FlacEncoderParams,
801
802 writer: WriteSeek,
804
805 on_write: Box<dyn FnMut(&mut WriteSeek, &[u8]) -> Result<(), io::Error> + 'a>,
808
809 on_seek: Box<dyn FnMut(&mut WriteSeek, u64) -> Result<(), io::Error> + 'a>,
811
812 on_tell: Box<dyn FnMut(&mut WriteSeek) -> Result<u64, io::Error> + 'a>,
814
815 comments: BTreeMap<&'static str, String>,
817
818 cue_sheets: Vec<FlacCueSheet>,
820
821 pictures: Vec<PictureData>,
823
824 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 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 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 pub fn as_ptr(&self) -> *const Self {
879 self as *const Self
880 }
881
882 pub fn as_mut_ptr(&mut self) -> *mut Self {
886 self as *mut Self
887 }
888
889 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 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 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 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 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 pub fn tell(&mut self) -> Result<u64, io::Error> {
1083 (self.on_tell)(&mut self.writer)
1084 }
1085
1086 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 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 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 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 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 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 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
1248pub 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 pub fn insert_comments(&mut self, key: &'static str, value: &str) -> Result<(), FlacEncoderInitError> {
1273 self.encoder.insert_comments(key, value)
1274 }
1275
1276 pub fn insert_cue_sheet(&mut self, cue_sheet: &FlacCueSheet) -> Result<(), FlacEncoderInitError> {
1278 self.encoder.insert_cue_sheet(cue_sheet)
1279 }
1280
1281 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 pub fn get_params(&self) -> FlacEncoderParams {
1293 self.encoder.get_params()
1294 }
1295
1296 pub fn tell(&mut self) -> Result<u64, io::Error> {
1298 self.encoder.tell()
1299 }
1300
1301 pub fn initialize(&mut self) -> Result<(), FlacEncoderInitError> {
1303 if !self.encoder.encoder_initialized {
1304 self.encoder.initialize()?
1305 }
1306 Ok(())
1307 }
1308
1309 pub fn write_interleaved_samples(&mut self, samples: &[i32]) -> Result<(), FlacEncoderError> {
1312 self.encoder.write_interleaved_samples(samples)
1313 }
1314
1315 pub fn write_mono_channel(&mut self, monos: &[i32]) -> Result<(), FlacEncoderError> {
1318 self.encoder.write_mono_channel(monos)
1319 }
1320
1321 pub fn write_stereos(&mut self, stereos: &[(i32, i32)]) -> Result<(), FlacEncoderError> {
1326 self.encoder.write_stereos(stereos)
1327 }
1328
1329 pub fn write_monos(&mut self, monos: &[Vec<i32>]) -> Result<(), FlacEncoderError> {
1332 self.encoder.write_monos(monos)
1333 }
1334
1335 pub fn write_frames(&mut self, frames: &[Vec<i32>]) -> Result<(), FlacEncoderError> {
1338 self.encoder.write_frames(frames)
1339 }
1340
1341 pub fn finish(&mut self) -> Result<(), FlacEncoderError> {
1343 self.encoder.finish()
1344 }
1345
1346 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 pub code: u32,
1364
1365 pub message: &'static str,
1367
1368 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 StreamDecoderSearchForMetadata = FLAC__STREAM_DECODER_SEARCH_FOR_METADATA as isize,
1394
1395 StreamDecoderReadMetadata = FLAC__STREAM_DECODER_READ_METADATA as isize,
1397
1398 StreamDecoderSearchForFrameSync = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC as isize,
1400
1401 StreamDecoderReadFrame = FLAC__STREAM_DECODER_READ_FRAME as isize,
1403
1404 StreamDecoderEndOfStream = FLAC__STREAM_DECODER_END_OF_STREAM as isize,
1406
1407 StreamDecoderOggError = FLAC__STREAM_DECODER_OGG_ERROR as isize,
1409
1410 StreamDecoderSeekError = FLAC__STREAM_DECODER_SEEK_ERROR as isize,
1412
1413 StreamDecoderAborted = FLAC__STREAM_DECODER_ABORTED as isize,
1415
1416 StreamDecoderMemoryAllocationError = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR as isize,
1418
1419 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 pub code: u32,
1465
1466 pub message: &'static str,
1468
1469 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#[derive(Debug, Clone, Copy)]
1553pub enum FlacReadStatus {
1554 GoOn,
1556
1557 Eof,
1559
1560 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#[derive(Debug, Clone, Copy)]
1576pub enum FlacInternalDecoderError {
1577 LostSync,
1579
1580 BadHeader,
1582
1583 FrameCrcMismatch,
1585
1586 UnparseableStream,
1588
1589 BadMetadata,
1591
1592 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#[derive(Debug, Clone, Copy)]
1613pub enum FlacAudioForm {
1614 FrameArray,
1617
1618 ChannelArray,
1621}
1622
1623#[derive(Debug, Clone, Copy)]
1624pub struct SamplesInfo {
1625 pub samples: u32,
1627
1628 pub channels: u32,
1630
1631 pub sample_rate: u32,
1633
1634 pub bits_per_sample: u32,
1637
1638 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
1650pub struct FlacDecoderUnmovable<'a, ReadSeek>
1653where
1654 ReadSeek: Read + Seek + Debug {
1655 decoder: *mut FLAC__StreamDecoder,
1657
1658 reader: ReadSeek,
1660
1661 on_read: Box<dyn FnMut(&mut ReadSeek, &mut [u8]) -> (usize, FlacReadStatus) + 'a>,
1663
1664 on_seek: Box<dyn FnMut(&mut ReadSeek, u64) -> Result<(), io::Error> + 'a>,
1666
1667 on_tell: Box<dyn FnMut(&mut ReadSeek) -> Result<u64, io::Error> + 'a>,
1669
1670 on_length: Box<dyn FnMut(&mut ReadSeek) -> Result<u64, io::Error> + 'a>,
1672
1673 on_eof: Box<dyn FnMut(&mut ReadSeek) -> bool + 'a>,
1675
1676 on_write: Box<dyn FnMut(&[Vec<i32>], &SamplesInfo) -> Result<(), io::Error> + 'a>,
1678
1679 on_error: Box<dyn FnMut(FlacInternalDecoderError) + 'a>,
1681
1682 md5_checking: bool,
1684
1685 finished: bool,
1687
1688 pub scale_to_i32_range: bool,
1690
1691 pub desired_audio_form: FlacAudioForm,
1693
1694 pub vendor_string: Option<String>,
1696
1697 pub comments: BTreeMap<String, String>,
1699
1700 pub pictures: Vec<PictureData>,
1702
1703 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 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 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 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 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 this.vendor_string = Some(entry_to_string(&comments.vendor_string));
1927
1928 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 let mut iter = comment.split("=");
1937 if let Some(key) = iter.next() {
1938 let key = key.to_owned();
1939
1940 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 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 eprintln!("Invalid comment: {comment}");
1955 }
1956 }
1957
1958 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 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 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 pub fn tell(&mut self) -> Result<u64, io::Error> {
2085 (self.on_tell)(&mut self.reader)
2086 }
2087
2088 pub fn length(&mut self) -> Result<u64, io::Error> {
2090 (self.on_length)(&mut self.reader)
2091 }
2092
2093 pub fn eof(&mut self) -> bool {
2095 (self.on_eof)(&mut self.reader)
2096 }
2097
2098 pub fn get_vendor_string(&self) -> &Option<String> {
2100 &self.vendor_string
2101 }
2102
2103 pub fn get_comments(&self) -> &BTreeMap<String, String> {
2105 &self.comments
2106 }
2107
2108 pub fn get_pictures(&self) -> &Vec<PictureData> {
2110 &self.pictures
2111 }
2112
2113 pub fn get_cue_sheets(&self) -> &Vec<FlacCueSheet> {
2115 &self.cue_sheets
2116 }
2117
2118 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 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 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 FLAC__stream_decoder_delete(self.decoder);
2165 };
2166 }
2167
2168 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
2206pub 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 pub fn seek(&mut self, frame_index: u64) -> Result<(), FlacDecoderError> {
2251 self.decoder.seek(frame_index)
2252 }
2253
2254 pub fn tell(&mut self) -> Result<u64, io::Error> {
2256 self.decoder.tell()
2257 }
2258
2259 pub fn length(&mut self) -> Result<u64, io::Error> {
2261 self.decoder.length()
2262 }
2263
2264 pub fn eof(&mut self) -> bool {
2266 self.decoder.eof()
2267 }
2268
2269 pub fn get_vendor_string(&self) -> &Option<String> {
2271 &self.decoder.vendor_string
2272 }
2273
2274 pub fn get_comments(&self) -> &BTreeMap<String, String> {
2276 &self.decoder.comments
2277 }
2278
2279 pub fn get_pictures(&self) -> &Vec<PictureData> {
2281 &self.decoder.pictures
2282 }
2283
2284 pub fn decode(&mut self) -> Result<bool, FlacDecoderError> {
2287 self.decoder.decode()
2288 }
2289
2290 pub fn decode_all(&mut self) -> Result<bool, FlacDecoderError> {
2292 self.decoder.decode_all()
2293 }
2294
2295 pub fn finish(&mut self) -> Result<(), FlacDecoderError> {
2297 self.decoder.finish()
2298 }
2299
2300 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}