diff options
| author | jakka <jakka@jakka.su> | 2025-07-11 10:11:34 +0300 |
|---|---|---|
| committer | jakka <jakka@jakka.su> | 2025-07-11 10:11:34 +0300 |
| commit | 60efe6b1978c228b0ecd3e982a08dc1f6766e7d0 (patch) | |
| tree | 02d4efac41322d93b6fe3abd1c50b8f15246023f /src/flac.rs | |
| parent | 8dc19ef43dc60a8eac1f526bfd47d66e958229cb (diff) | |
optimized sample handling and error reporting
Diffstat (limited to 'src/flac.rs')
| -rw-r--r-- | src/flac.rs | 38 |
1 files changed, 24 insertions, 14 deletions
diff --git a/src/flac.rs b/src/flac.rs index bbb2b9d..eb38bc5 100644 --- a/src/flac.rs +++ b/src/flac.rs @@ -49,6 +49,9 @@ fn encode_file(filename: impl AsRef<Path>, handler: Arc<AtomicBool>) -> Result<b let mut decoder = FlacReader::open(&filename)?; 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 .channels(streaminfo.channels) @@ -68,29 +71,36 @@ fn encode_file(filename: impl AsRef<Path>, handler: Arc<AtomicBool>) -> Result<b let mut hasher = Md5::new(); - for samples in decoder - .samples() - .map(|res| { - let sample = res.unwrap(); - match streaminfo.bits_per_sample { + let mut samples_iter = decoder.samples(); + + let mut buf = Vec::with_capacity(num_channels); + + while let Some(Ok(sample)) = samples_iter.next() { + if handler.load(Ordering::SeqCst) { + match bps { 16 => { - hasher.update(i16::try_from(sample).unwrap().to_le_bytes()); + hasher.update(i16::try_from(sample)?.to_le_bytes()); } 24 => { - hasher.update(i24::i24::try_from_i32(sample).unwrap().to_le_bytes()); + 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()); } _ => {} } - sample - }) - .collect::<Vec<i32>>() - .chunks(streaminfo.channels as usize) - { - if handler.load(Ordering::SeqCst) { - let _ = encoder.process_interleaved(samples, 1); + 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())); + }; + buf.clear(); + } } else { let _ = std::fs::remove_file(temp_name); return Ok(true); |
