diff options
| -rw-r--r-- | Cargo.lock | 94 | ||||
| -rw-r--r-- | Cargo.toml | 2 | ||||
| -rw-r--r-- | src/flac.rs | 98 |
3 files changed, 46 insertions, 148 deletions
@@ -59,39 +59,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" [[package]] -name = "autocfg" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" - -[[package]] name = "bitflags" version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" [[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] name = "bumpalo" version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] -name = "bytemuck" -version = "1.23.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c76a5792e44e4abe34d3abf15636779261d45a7450612059293d1d2cfc63422" - -[[package]] name = "byteorder" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -226,16 +205,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] name = "ctrlc" version = "3.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -246,16 +215,6 @@ dependencies = [ ] [[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "crypto-common", -] - -[[package]] name = "directories" version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -321,9 +280,7 @@ dependencies = [ "ctrlc", "directories", "flac-bound", - "i24", "indicatif", - "md-5", "metaflac", "rayon", "rusqlite", @@ -337,16 +294,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] name = "getrandom" version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -382,16 +329,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] -name = "i24" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe4e9f59fce450959a3bfe4a762ebba4afe2327ab3795ba11c489233c5d29733" -dependencies = [ - "bytemuck", - "num-traits", -] - -[[package]] name = "indicatif" version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -465,16 +402,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] -name = "md-5" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" -dependencies = [ - "cfg-if", - "digest", -] - -[[package]] name = "metaflac" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -497,15 +424,6 @@ dependencies = [ ] [[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] name = "once_cell" version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -657,12 +575,6 @@ dependencies = [ ] [[package]] -name = "typenum" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" - -[[package]] name = "unicode-ident" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -699,12 +611,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] name = "walkdir" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -15,9 +15,7 @@ clap = { version = "4.5.40", features = ["cargo", "help", "std"] } clap_complete = "4.5.54" directories = "6.0.0" flac-bound = { version = "0.5.0", default-features = false } -i24 = { version = "2.1.0", features = ["std"] } indicatif = { version = "0.18.0", features = ["improved_unicode"] } -md-5 = "0.10.6" walkdir = "2.5.0" console = { version = "0.15.11", features = ["windows-console-colors"] } claxon = { git = "https://github.com/justjakka/claxon.git" } 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()); } } |
