diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/flac.rs (renamed from src/flac/mod.rs) | 84 | ||||
| -rw-r--r-- | src/flac/decoder.rs | 139 |
2 files changed, 27 insertions, 196 deletions
diff --git a/src/flac/mod.rs b/src/flac.rs index 7a79e44..05d915f 100644 --- a/src/flac/mod.rs +++ b/src/flac.rs @@ -1,25 +1,31 @@ -mod decoder; - use anyhow::{Result, anyhow}; use flac_bound::{FlacEncoder, WriteWrapper}; -/* use md5::Digest; */ -use metaflac::Tag; -use std::{fs::File, path::Path}; - -use crate::flac::decoder::FlacDecoder; +use md5::{Digest, Md5}; +use metaflac::{Block, Tag}; +use std::{ + fs::File, + path::{Path, PathBuf}, +}; +use symphonia::core::{ + audio::{Audio, GenericAudioBufferRef}, + codecs::audio::AudioDecoder, + formats::{FormatOptions, FormatReader, TrackType, probe::Hint}, + io::MediaSourceStream, + meta::MetadataOptions, +}; pub const CURRENT_VENDOR: &str = "reference libFLAC 1.5.0 20250211"; -/* type BoxedFormatReader = Box<dyn FormatReader>; -type BoxedAudioDecoder = Box<dyn AudioDecoder + 'static>; */ +type BoxedFormatReader = Box<dyn FormatReader>; +type BoxedAudioDecoder = Box<dyn AudioDecoder + 'static>; -/* pub struct StreamConfig { +struct StreamConfig { channels: u32, bits_per_sample: Bps, sample_rate: u32, } -pub enum Bps { +enum Bps { _16, _24, _32, @@ -42,9 +48,9 @@ impl Bps { Bps::_32 => 32, } } -} */ +} -/* struct FileEncoder { +struct FileEncoder { filename: PathBuf, streamdata: StreamConfig, format: BoxedFormatReader, @@ -85,16 +91,8 @@ impl FileEncoder { if let GenericAudioBufferRef::S32(buf) = self.decoder.decode(&packet)? { for sample in buf.iter_interleaved() { - let mut real_sample = sample; - if offset != 32 { - real_sample = sample >> (32 - offset) - } - match offset { - 16 => hasher.update(i16::try_from(real_sample)?.to_le_bytes()), - 24 => hasher - .update(i24::i24::try_from_i32(real_sample).unwrap().to_le_bytes()), - _ => hasher.update(real_sample.to_le_bytes()), - } + let real_sample = sample >> (32 - offset); + hasher.update(real_sample.to_le_bytes()); buffer.push(real_sample); } encoder @@ -174,10 +172,10 @@ fn init_decoder( }; Ok((format, decoder, config)) -} */ +} pub fn encode_file(filename: impl AsRef<Path>) -> Result<()> { - /* let mut filencoder = FileEncoder::new(filename)?; + let mut filencoder = FileEncoder::new(filename)?; let temp_name = filencoder.temp_name(); if temp_name.exists() { @@ -199,32 +197,7 @@ pub fn encode_file(filename: impl AsRef<Path>) -> Result<()> { let hash = filencoder.encode(enc)?; filencoder.write_tags(hash)?; std::fs::rename(filencoder.temp_name(), filencoder.filename)?; - Ok(()) */ - - let decoder = FlacDecoder::new(); - let mut buffer: Vec<i32> = Vec::new(); - decoder.init_decode_from_file(&filename, &mut buffer)?; - - let temp_name = filename.as_ref().with_extension("tmp"); - let mut outf = File::create(temp_name)?; - let mut outw = WriteWrapper(&mut outf); - let mut enc = FlacEncoder::new() - .unwrap() - .channels(decoder.get_channels()) - .bits_per_sample(decoder.get_bps()) - .sample_rate(decoder.get_samplerate()) - .compression_level(8) - .verify(false) - .init_write(&mut outw) - .unwrap(); - - while decoder.decode_frame().is_ok() { - enc.process_interleaved(&buffer, buffer.iter().len() as u32 / decoder.get_channels()) - .unwrap(); - buffer.clear(); - } - - todo!() + Ok(()) } pub fn get_vendor(file: impl AsRef<Path>) -> Result<String> { @@ -258,8 +231,7 @@ mod tests { .unwrap() .md5 .clone(); - std::fs::remove_file(name).unwrap(); - std::fs::rename(tempname, name).unwrap(); + std::fs::remove_file(tempname).unwrap(); assert_eq!(target_md5, encoded_md5); } @@ -281,8 +253,7 @@ mod tests { .unwrap() .md5 .clone(); - std::fs::remove_file(name).unwrap(); - std::fs::rename(tempname, name).unwrap(); + std::fs::remove_file(tempname).unwrap(); assert_eq!(target_md5, encoded_md5); } @@ -304,8 +275,7 @@ mod tests { .unwrap() .md5 .clone(); - std::fs::remove_file(name).unwrap(); - std::fs::rename(tempname, name).unwrap(); + std::fs::remove_file(tempname).unwrap(); assert_eq!(target_md5, encoded_md5); } } diff --git a/src/flac/decoder.rs b/src/flac/decoder.rs deleted file mode 100644 index 99ac36e..0000000 --- a/src/flac/decoder.rs +++ /dev/null @@ -1,139 +0,0 @@ -use std::{ - error::Error, - ffi::{CString, c_void}, - fmt::Display, - path::Path, -}; - -use libflac_sys::{ - FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED, - FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE, - FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS, - FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR, FLAC__STREAM_DECODER_INIT_STATUS_OK, - FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER, FLAC__StreamDecoder, - FLAC__StreamDecoderInitStatus, FLAC__bool, FLAC__stream_decoder_finish, - FLAC__stream_decoder_get_bits_per_sample, FLAC__stream_decoder_get_channels, - FLAC__stream_decoder_get_sample_rate, FLAC__stream_decoder_init_file, FLAC__stream_decoder_new, - FLAC__stream_decoder_process_single, FLAC__stream_decoder_set_md5_checking, -}; - -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[repr(u32)] -pub enum FlacDecoderInitError { - AlreadyInitialized = FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED, - - ErrorOpeningFile = FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE, - - InvalidCallbacks = FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS, - - MemoryAllocationError = FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR, - - UnsupportedContainer = FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER, -} - -impl Error for FlacDecoderInitError {} - -impl Display for FlacDecoderInitError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{self:?}") - } -} - -impl From<FlacDecoderInitError> for FLAC__StreamDecoderInitStatus { - fn from(val: FlacDecoderInitError) -> Self { - val as FLAC__StreamDecoderInitStatus - } -} - -impl TryFrom<FLAC__StreamDecoderInitStatus> for FlacDecoderInitError { - type Error = (); - - #[allow(non_upper_case_globals)] - fn try_from(raw: FLAC__StreamDecoderInitStatus) -> Result<FlacDecoderInitError, ()> { - Ok(match raw { - FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED => { - FlacDecoderInitError::AlreadyInitialized - } - FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE => { - FlacDecoderInitError::ErrorOpeningFile - } - FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS => { - FlacDecoderInitError::InvalidCallbacks - } - FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR => { - FlacDecoderInitError::MemoryAllocationError - } - FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER => { - FlacDecoderInitError::UnsupportedContainer - } - _ => return Err(()), - }) - } -} - -fn convert_path(path: &Path) -> CString { - CString::new(path.to_str().expect("non-UTF-8 filename")).expect("filename has internal NULs") -} - -pub(crate) struct FlacDecoder(pub *mut FLAC__StreamDecoder); - -impl FlacDecoder { - pub(crate) fn new() -> Self { - FlacDecoder(unsafe { FLAC__stream_decoder_new() }) - } - - pub(crate) fn init_decode_from_file<P: AsRef<Path>>( - &self, - file: &P, - buf: &mut Vec<i32>, - ) -> Result<(), FlacDecoderInitError> { - unsafe { - FLAC__stream_decoder_set_md5_checking(self.0, true as FLAC__bool); - } - - let filename = convert_path(file.as_ref()); - unsafe { - let result: FLAC__StreamDecoderInitStatus = FLAC__stream_decoder_init_file( - self.0, - filename.as_ptr(), - None, - None, - None, - buf.as_mut_ptr() as *mut c_void, - ); - if result != FLAC__STREAM_DECODER_INIT_STATUS_OK { - return Err(FlacDecoderInitError::try_from(result).unwrap()); - } - } - - Ok(()) - } - - pub(crate) fn decode_frame(&self) -> Result<(), ()> { - if unsafe { FLAC__stream_decoder_process_single(self.0) } != 0 { - Ok(()) - } else { - Err(()) - } - } - - pub(crate) fn get_channels(&self) -> u32 { - unsafe { FLAC__stream_decoder_get_channels(self.0) } - } - - pub(crate) fn get_bps(&self) -> u32 { - unsafe { FLAC__stream_decoder_get_bits_per_sample(self.0) } - } - - pub(crate) fn get_samplerate(&self) -> u32 { - unsafe { FLAC__stream_decoder_get_sample_rate(self.0) } - } -} - -impl Drop for FlacDecoder { - fn drop(&mut self) { - if !(self.0.is_null()) { - unsafe { FLAC__stream_decoder_finish(self.0) }; - } - } -} |
