summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjakka <jakkadoujin@gmail.com>2025-06-04 20:01:07 +0300
committerjakka <jakkadoujin@gmail.com>2025-06-04 20:01:07 +0300
commit3b55294f1fc09a957ca63c3a9a718b1082b9a894 (patch)
treee9923ca12127130cc69953a8b03e6d7f04236e9e /src
parent5a39e523da7f4fe2c9c1e6c369a366162be122fa (diff)
implemented flac reencoding. started working on md5sum implementation
Diffstat (limited to 'src')
-rw-r--r--src/flac.rs149
-rw-r--r--src/main.rs4
2 files changed, 52 insertions, 101 deletions
diff --git a/src/flac.rs b/src/flac.rs
index 8b03664..1881756 100644
--- a/src/flac.rs
+++ b/src/flac.rs
@@ -1,130 +1,79 @@
use anyhow::{Result, anyhow};
use flac_bound::{FlacEncoder, WriteWrapper};
+use md5::{Digest, Md5};
+use metaflac::Tag;
use std::fs::File;
-use symphonia::core::{
- audio::SampleBuffer,
- codecs::{DecoderOptions, CODEC_TYPE_NULL},
- errors::Error::DecodeError,
- formats::{FormatOptions, Track},
- io::MediaSourceStream,
- meta::MetadataOptions,
- probe::{Hint, ProbeResult},
-};
#[derive(Debug)]
struct StreamConfig {
channels: u32,
- bits_per_sample: Bps,
+ bits_per_sample: u32,
sample_rate: u32,
total_samples_estimate: u64,
}
-#[derive(Debug)]
-enum Bps {
- _16,
- _24,
- _32
-}
-
-fn get_probe(file: &std::path::Path) -> Result<ProbeResult> {
- let src = std::fs::File::open(file)?;
- let mss = MediaSourceStream::new(Box::new(src), Default::default());
- let mut hint = Hint::new();
- hint.with_extension("flac");
- let meta_opts: MetadataOptions = Default::default();
- let fmt_opts: FormatOptions = Default::default();
- Ok(symphonia::default::get_probe().format(&hint, mss, &fmt_opts, &meta_opts)?)
-}
-
-fn read_streaminfo(track: &Track) -> Result<StreamConfig> {
- let params = &track.codec_params;
-
- Ok(StreamConfig {
- channels: params.channels.unwrap().count() as u32,
- bits_per_sample: match params.bits_per_sample.unwrap() {
- 16 => Bps::_16,
- 24 => Bps::_24,
- 32 => Bps::_32,
- _ => return Err(anyhow!("invalid Bps"))
- },
- sample_rate: params.sample_rate.unwrap(),
- total_samples_estimate: params.n_frames.unwrap(),
- })
-}
-
pub fn encode_file(file: &std::path::Path) -> Result<()> {
- let probed = get_probe(file)?;
- let mut format = probed.format;
- let dec_opts: DecoderOptions = Default::default();
- let track = format
- .tracks()
- .iter()
- .find(|t| t.codec_params.codec != CODEC_TYPE_NULL)
- .unwrap();
-
- let config = read_streaminfo(track)?;
-
- let mut outf = File::create(format!("{}.{}", file.display(), "tmp"))?;
+ let mut reader = claxon::FlacReader::open(file)?;
+ let config = StreamConfig {
+ channels: reader.streaminfo().channels,
+ bits_per_sample: reader.streaminfo().bits_per_sample,
+ sample_rate: reader.streaminfo().sample_rate,
+ total_samples_estimate: reader.streaminfo().samples.unwrap(),
+ };
+ let tempname = format!("{}.{}", file.display(), "tmp");
+ let mut outf = File::create(&tempname)?;
let mut outw = WriteWrapper(&mut outf);
let mut enc = FlacEncoder::new()
.unwrap()
.channels(config.channels)
- .bits_per_sample(match config.bits_per_sample {
- Bps::_16 => 16,
- Bps::_24 => 24,
- Bps::_32 => 32
- })
+ .bits_per_sample(config.bits_per_sample)
.sample_rate(config.sample_rate)
.total_samples_estimate(config.total_samples_estimate)
.compression_level(8)
- .verify(true)
+ .verify(false)
.init_write(&mut outw)
.unwrap();
- let mut decoder = symphonia::default::get_codecs()
- .make(&track.codec_params, &dec_opts)
- .unwrap();
- let track_id = track.id;
-
- let mut sample_buf = None;
+ let mut hasher = Md5::new();
+ let mut bytes = Vec::new();
- loop {
- let packet = format.next_packet().unwrap();
+ for samples in reader
+ .samples()
+ .map(|sample| sample.unwrap())
+ .collect::<Vec<_>>()
+ .chunks(4096)
+ {
+ enc.process_interleaved(samples, 2048).unwrap();
+ let _ = samples
+ .iter()
+ .map(|sample| {
+ for byte in sample.to_le_bytes() {
+ bytes.push(byte)
+ }
+ })
+ .collect::<Vec<_>>();
+ hasher.update(&bytes);
+ bytes.clear();
+ }
- if packet.track_id() != track_id {
- continue;
- }
+ match enc.finish() {
+ Ok(_) => {}
+ Err(enc) => return Err(anyhow!("Encoding failed:\t{:?}", enc.state())),
+ }
- match decoder.decode(&packet) {
- Ok(audio_buf) => {
- if sample_buf.is_none() {
- let spec = *audio_buf.spec();
+ /* let source_tags = Tag::read_from_path(file)?;
+ let mut target_tags = Tag::read_from_path(tempname)?;
- let duration = audio_buf.capacity() as u64;
- sample_buf = Some(SampleBuffer::<i16>::new(duration, spec));
- /* match config.bits_per_sample {
- Bps::_16 => sample_buf = Some(SampleBuffer::<i16>::new(duration, spec)),
- Bps::_24 => sample_buf = Some(SampleBuffer::<i24>::new(duration, spec)),
- Bps::_32 => sample_buf = Some(SampleBuffer::<i32>::new(duration, spec)),
- } */
- }
+ for block in source_tags.blocks() {
+ todo!()
+ } */
- if let Some(buf) = &mut sample_buf {
- buf.copy_interleaved_ref(audio_buf);
- let mut samples = Vec::new();
- _ = buf.samples().iter().map(|sample| samples.push(*sample as i32)).collect::<Vec<_>>();
- enc.process_interleaved(samples.as_slice(), samples.iter().len() as u32 / config.channels)
- .unwrap();
- }
- }
- Err(DecodeError(_)) => (),
- Err(_) => break,
- }
- }
+ let mut tags = Tag::read_from_path(tempname)?;
+ let mut streaminfo = tags.get_streaminfo().unwrap().clone();
+ streaminfo.md5 = hasher.finalize()[..].to_vec();
+ tags.set_streaminfo(streaminfo);
+ tags.save()?;
- match enc.finish() {
- Ok(_) => Ok(()),
- Err(enc) => Err(anyhow!("Encoding failed:\t{:?}", enc.state())),
- }
+ Ok(())
}
diff --git a/src/main.rs b/src/main.rs
index 6c4cb43..ba95650 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,5 +1,7 @@
mod flac;
fn main() {
- flac::encode_file(std::path::Path::new("./1.flac")).unwrap();
+ if let Err(error) = flac::encode_file(std::path::Path::new("./1.flac")) {
+ println!("{}", error)
+ };
}