diff --git a/brro-compressor/src/main.rs b/brro-compressor/src/main.rs index 93e6d8b..cf676d4 100644 --- a/brro-compressor/src/main.rs +++ b/brro-compressor/src/main.rs @@ -1,57 +1,92 @@ use std::path::Path; use clap::{Parser, command, arg}; use log::debug; - -use brro_compressor::compressor; +use brro_compressor::compressor::Compressor; use brro_compressor::optimizer; use brro_compressor::utils::reader; use brro_compressor::utils::writer; use brro_compressor::data::CompressedStream; +use brro_compressor::types::metric_tag::MetricTag; -/// Process a chunk of WAV content and compresses it -/// If a stream is provided it adds a chunk to that stream, otherwise creates a new one -fn compress_file(stream: Option, wav_content: Vec) -> CompressedStream { - let mut cs = match stream { - Some(cs) => cs, - None => CompressedStream::new() - }; - cs.compress_chunk(&wav_content); - cs -} - +/// Processes the given input based on the provided arguments. +/// If `arguments.directory` is true, it processes all files in the directory. +/// Otherwise, it processes the individual file. fn process_args(input_path: &str, arguments: &Args) { let path = Path::new(input_path); + // If the input path points to a directory + if arguments.directory { + process_directory(path, arguments); + } + // If the input path points to a single file + else { + process_single_file(path, arguments); + } +} + +/// Processes all files in a given directory. +fn process_directory(path: &Path, arguments: &Args) { let new_name = format!("{}-compressed", path.file_name().unwrap().to_string_lossy()); let base_dir = path.with_file_name(new_name); writer::initialize_directory(&base_dir).expect("Failed to initialize directory"); + let files = reader::stream_reader(path).expect("Failed to read files from directory"); - if arguments.directory { - let files = reader::stream_reader(path).expect("TODO: panic message"); - for (index, data) in files.contents.iter().enumerate() { - let (vec_data, tag) = data; - let optimizer_results = optimizer::process_data(vec_data, tag); - let optimizer_results_f: Vec = optimizer_results.iter().map(|&x| x as f64).collect(); + for (index, data) in files.contents.iter().enumerate() { + let (vec_data, tag) = data; + let compressed_data = compress_data(vec_data, tag, arguments); - let mut compressed: Vec = Vec::new(); - if arguments.noop { - compressed = compressor::noop::noop(&optimizer_results_f); - } else if arguments.constant { - compressed = compressor::constant::constant(&optimizer_results_f); - } + let file_name = writer::replace_extension(&files.names[index], "bin"); + let new_path = base_dir.join(&file_name); + write_compressed_data_to_path(&compressed_data, &new_path); + } +} + +/// Processes a single file. +fn process_single_file(path: &Path, arguments: &Args) { + if let Some((vec, tag)) = reader::read_file(path).expect("Failed to read file") { + let compressed_data = compress_data(&vec, &tag, arguments); - let file_name = writer::replace_extension(&files.names[index], "bin"); - let new_path = base_dir.join(&file_name); - let mut file = writer::create_streaming_writer(&new_path).expect("TODO: panic message"); - writer::write_data_to_stream(&mut file, &compressed).expect("Failed to write compressed data"); + if let Some(filename_osstr) = path.file_name() { + if let Some(filename_str) = filename_osstr.to_str() { + let new_filename_string = writer::replace_extension(&filename_str.to_string(),"bin"); + let new_path = path.parent().unwrap().join(new_filename_string); + write_compressed_data_to_path(&compressed_data, &new_path); + } } + } +} + +/// Compresses the data based on the provided tag and arguments. +fn compress_data(vec: &Vec, tag: &MetricTag, arguments: &Args) -> Vec { + let optimizer_results = optimizer::process_data(vec, tag); + let optimizer_results_f: Vec = optimizer_results.iter().map(|&x| x as f64).collect(); + + let cs = CompressedStream::new(); + if arguments.constant { + compress_file(Compressor::Constant, cs, optimizer_results_f) } else { - // TODO: Make this do something... - let cs = compress_file(None, Vec::new()); - cs.to_bytes(); + compress_file(Compressor::Noop, cs, optimizer_results_f) } } +fn compress_file(compressor: Compressor, mut stream: CompressedStream, wav_content: Vec) -> Vec { + return match compressor { + Compressor::Constant =>{ + stream.compress_chunk_with(&wav_content, Compressor::Constant); + stream.to_bytes() + } + _ =>{ + stream.compress_chunk_with(&wav_content, Compressor::Noop); + stream.to_bytes() + } + } +} +/// Writes the compressed data to the specified path. +fn write_compressed_data_to_path(compressed: &Vec, path: &Path) { + let mut file = writer::create_streaming_writer(path).expect("Failed to create a streaming writer"); + writer::write_data_to_stream(&mut file, compressed).expect("Failed to write compressed data"); +} + #[derive(Parser, Default, Debug)] #[command(author, version, about, long_about = None)] @@ -69,9 +104,7 @@ struct Args { /// Forces Constant compressor #[arg(long, action)] constant: bool, - } - fn main() { env_logger::init(); let arguments = Args::parse(); diff --git a/brro-compressor/src/utils/reader.rs b/brro-compressor/src/utils/reader.rs index 276f6e3..9797c55 100644 --- a/brro-compressor/src/utils/reader.rs +++ b/brro-compressor/src/utils/reader.rs @@ -1,6 +1,6 @@ // Implement a streaming reader here use std::fs; -use std::io::{self, Read}; +use std::io::{self, Error, Read}; use std::path::Path; use log::debug; use regex::Regex; @@ -20,7 +20,7 @@ fn is_wav_file(file_path: &Path) -> io::Result { } // Function to process a WAV file -fn process_wav_file(file_path: &Path) -> io::Result<(Vec, MetricTag)> { +pub fn process_wav_file(file_path: &Path) -> io::Result<(Vec, MetricTag)> { let full_path_str = file_path.to_str().unwrap_or(""); debug!("File: {} ,", full_path_str); let wav_data = read_metrics_from_wav(full_path_str); @@ -42,7 +42,7 @@ pub struct Files { } /// Read a file by chunks and processes the chunks -pub fn process_by_chunk(file_path: &Path) -> Result<(), std::io::Error> { +pub fn process_by_chunk(file_path: &Path) -> Result<(Vec>), std::io::Error> { let mut file = match std::fs::File::open(file_path) { Ok(f) => f, Err(e) => panic!("{}", e) @@ -59,7 +59,7 @@ pub fn process_by_chunk(file_path: &Path) -> Result<(), std::io::Error> { list_of_chunks.push(chunk); if n < chunk_size { break; } } - Ok(()) + Ok(list_of_chunks) } // Function to read and process files in a directory @@ -85,18 +85,26 @@ pub fn stream_reader(directory_path: &Path) -> io::Result { } // Check if the file is a WAV file - if is_wav_file(&file_path)? { - // If it's a WAV file, process it using the process_wav_file function - let wav_result = process_wav_file(&file_path)?; - contents.push(wav_result); - } else { - // If it's not a WAV file, process it as a RAW file using the process_raw_file function - process_raw_file(&file_path)?; + let res= read_file(&file_path)?; + match res { + Some((vec, tag)) => contents.push((vec, tag)), + _ => (), } } Ok(Files {contents, names}) } +pub fn read_file(file_path: &Path) -> Result, MetricTag)>, Error> { + if is_wav_file(&file_path)? { + // If it's a WAV file, process it using the process_wav_file function + let wav_result = process_wav_file(&file_path)?; + return Ok(Option::from(wav_result)); + } else { + // If it's not a WAV file, process it as a RAW file using the process_raw_file function + process_raw_file(&file_path)?; + } + Ok(None) +} /* Reads a WAV file, checks the channels and the information contained there. From that information takes a decision on the best channel, block size and bitrate for the BRRO