diff options
| author | jakka <jakka@jakka.su> | 2025-07-11 11:47:25 +0300 |
|---|---|---|
| committer | jakka <jakka@jakka.su> | 2025-07-11 11:47:25 +0300 |
| commit | 93289110b103f80ecd20fe5aa8d217dc6d3cb3a0 (patch) | |
| tree | 39205c571fc6e46287e641d70fbd333d084a59f7 /src | |
| parent | 60efe6b1978c228b0ecd3e982a08dc1f6766e7d0 (diff) | |
removed hashing since its not really needed if original file is intact, now brocessing data in blocks
Diffstat (limited to 'src')
| -rw-r--r-- | src/flac.rs | 98 |
1 files changed, 46 insertions, 52 deletions
diff --git a/src/flac.rs b/src/flac.rs index eb38bc5..4d7c632 100644 --- a/src/flac.rs +++ b/src/flac.rs @@ -1,7 +1,6 @@ use anyhow::{Result, anyhow}; use claxon::{FlacReader, FlacReaderOptions}; use flac_bound::FlacEncoder; -use md5::{Digest, Md5}; use metaflac::{Block, Tag}; use std::{ path::Path, @@ -13,15 +12,14 @@ use std::{ pub const CURRENT_VENDOR: &str = "reference libFLAC 1.5.0 20250211"; -fn write_tags(filename: impl AsRef<Path>, hash: Vec<u8>) -> Result<()> { +fn write_tags(filename: impl AsRef<Path>) -> Result<()> { let tags = Tag::read_from_path(&filename)?; let temp_name = filename.as_ref().with_extension("tmp"); let mut output = Tag::read_from_path(&temp_name)?; - let mut streaminfo = tags.get_streaminfo().unwrap().clone(); - - streaminfo.md5 = hash; - output.set_streaminfo(streaminfo); + if let Some(streaminfo) = tags.get_streaminfo() { + output.set_streaminfo(streaminfo.clone()); + } for block in tags.blocks() { match block { @@ -50,7 +48,6 @@ fn encode_file(filename: impl AsRef<Path>, handler: Arc<AtomicBool>) -> Result<b let streaminfo = decoder.streaminfo(); let num_channels: usize = streaminfo.channels.try_into()?; - let bps = streaminfo.bits_per_sample; let mut encoder = if let Some(encoder) = FlacEncoder::new() { if let Ok(encoder) = encoder @@ -69,50 +66,44 @@ fn encode_file(filename: impl AsRef<Path>, handler: Arc<AtomicBool>) -> Result<b return Err(anyhow!("failed to create encoder")); }; - let mut hasher = Md5::new(); - - let mut samples_iter = decoder.samples(); - - let mut buf = Vec::with_capacity(num_channels); + let mut frame_reader = decoder.blocks(); + let mut buffer = Vec::new(); + let mut block_buffer = + Vec::with_capacity(streaminfo.max_block_size as usize * num_channels as usize); - while let Some(Ok(sample)) = samples_iter.next() { - if handler.load(Ordering::SeqCst) { - match bps { - 16 => { - hasher.update(i16::try_from(sample)?.to_le_bytes()); - } - 24 => { - hasher.update(if let Some(conv_sample) = i24::i24::try_from_i32(sample) { - conv_sample.to_le_bytes() - } else { - return Err(anyhow!("failed to hash samples")); - }); - } - 32 => { - hasher.update(sample.to_le_bytes()); + loop { + if !handler.load(Ordering::SeqCst) { + let _ = encoder.finish(); + std::fs::remove_file(temp_name)?; + return Ok(true); + } + match frame_reader.read_next_or_eof(block_buffer) { + Ok(Some(block)) => { + for sample in 0..(block.len() / block.channels()) { + for ch in 0..block.channels() { + buffer.push(block.sample(ch, sample)); + } } - _ => {} - } - buf.push(sample); - if num_channels == buf.len() { - if let Err(_) = encoder.process_interleaved(&buf, 1) { - return Err(anyhow!("failed to process samples:\t{:?}", encoder.state())); + if let Err(_) = encoder.process_interleaved(&buffer, block.len() / block.channels()) + { + return Err(anyhow!( + "Error while processing samples:\t{:?}", + encoder.state() + )); }; - buf.clear(); + buffer.clear(); + block_buffer = block.into_buffer(); } - } else { - let _ = std::fs::remove_file(temp_name); - return Ok(true); + Ok(None) => break, + Err(error) => return Err(error.into()), } } if let Err(enc) = encoder.finish() { return Err(anyhow!("Encoding failed:\t{:?}", enc.state())); } - - let hash = hasher.finalize().to_vec(); - write_tags(&filename, hash)?; + write_tags(&filename)?; std::fs::rename(temp_name, filename)?; Ok(false) } @@ -154,11 +145,12 @@ mod tests { std::fs::copy(name, tempname).unwrap(); let handler = Arc::new(AtomicBool::new(true)); encode_file(name, handler).unwrap(); - let target_md5 = FlacReader::open(tempname).unwrap().streaminfo().md5sum; - let temp_md5 = FlacReader::open(name).unwrap().streaminfo().md5sum; - + let output = std::process::Command::new("flac") + .arg("-wts") + .arg(name) + .status(); std::fs::rename(tempname, name).unwrap(); - assert_eq!(target_md5, temp_md5); + assert!(output.unwrap().success()); } #[test] @@ -168,11 +160,12 @@ mod tests { std::fs::copy(name, tempname).unwrap(); let handler = Arc::new(AtomicBool::new(true)); encode_file(name, handler).unwrap(); - let target_md5 = FlacReader::open(tempname).unwrap().streaminfo().md5sum; - let temp_md5 = FlacReader::open(name).unwrap().streaminfo().md5sum; - + let output = std::process::Command::new("flac") + .arg("-wts") + .arg(name) + .status(); std::fs::rename(tempname, name).unwrap(); - assert_eq!(target_md5, temp_md5); + assert!(output.unwrap().success()); } #[test] @@ -182,10 +175,11 @@ mod tests { std::fs::copy(name, tempname).unwrap(); let handler = Arc::new(AtomicBool::new(true)); encode_file(name, handler).unwrap(); - let target_md5 = FlacReader::open(tempname).unwrap().streaminfo().md5sum; - let temp_md5 = FlacReader::open(name).unwrap().streaminfo().md5sum; - + let output = std::process::Command::new("flac") + .arg("-wts") + .arg(name) + .status(); std::fs::rename(tempname, name).unwrap(); - assert_eq!(target_md5, temp_md5); + assert!(output.unwrap().success()); } } |
