From 0a043e10f197468a028843f20f88d8ec6e411e42 Mon Sep 17 00:00:00 2001 From: Nikolai Rodionov Date: Mon, 22 Dec 2025 09:45:40 +0100 Subject: [PATCH] Nothig --- src/main.rs | 97 ++++++++++++++++++++++++----------------------------- 1 file changed, 44 insertions(+), 53 deletions(-) diff --git a/src/main.rs b/src/main.rs index 6b26a11..d71bf20 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ use std::{fs::File, path::PathBuf}; use clap::{Parser, Subcommand, ValueEnum}; -use symphonia::core::{audio::SampleBuffer, codecs::DecoderOptions, formats::FormatOptions, io::MediaSourceStream, meta::MetadataOptions, probe::Hint}; +use symphonia::core::{audio::{AudioBufferRef, SampleBuffer}, codecs::DecoderOptions, formats::FormatOptions, io::MediaSourceStream, meta::MetadataOptions, probe::Hint}; #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)] enum Backend { @@ -9,6 +9,7 @@ enum Backend { Alsa, Pulseaudio, Coreaudio, + Cpal, } #[derive(Parser)] #[command(version, about, long_about = None)] @@ -25,94 +26,84 @@ fn main() { let cli = Cli::parse(); // You can check the value provided by positional arguments, or option arguments // Read the track from the tracks into the buffer + let mut data: Vec; if let Some(files) = cli.track { for file in files { - read_audio_file(file); + data = read_audio_file(file); } } if let Some(backend) = cli.backend { match backend { - Backend::Jack => println!("jack"), + Backend::Jack => play_with_jack(), Backend::Alsa => println!("alsa"), Backend::Pulseaudio => println!("pulse"), Backend::Coreaudio => println!("coreaudio"), + Backend::Cpal => println!("cpal"), } } } -fn read_audio_file(file: String) { - let file = Box::new(File::open(file).unwrap()); - let mss = MediaSourceStream::new(file, Default::default()); +#[cfg(feature = "jack")] +fn play_with_jack(data: Vec) { + unimplemented!() +} + +#[cfg(not(feature = "jack"))] +fn play_with_jack(_: Vec) { + unimplemented!() +} + +fn read_audio_file(path: String) -> Vec{ + // Open file + let file = File::open(path).expect("Failed to open file"); + let mss = MediaSourceStream::new(Box::new(file), Default::default()); + + // Hint format by extension let mut hint = Hint::new(); - hint.with_extension("mp3"); - let format_opts: FormatOptions = Default::default(); - let metadata_opts: MetadataOptions = Default::default(); - let decoder_opts: DecoderOptions = Default::default(); - let probed = - symphonia::default::get_probe().format(&hint, mss, &format_opts, &metadata_opts).unwrap(); - // Get the format reader yielded by the probe operation. + // Probe the file + let probed = symphonia::default::get_probe() + .format(&hint, mss, &FormatOptions::default(), &MetadataOptions::default()) + .expect("Unsupported format"); + let mut format = probed.format; + let track = format.default_track().expect("No default track"); - // Get the default track. - let track = format.default_track().unwrap(); + let mut decoder = symphonia::default::get_codecs() + .make(&track.codec_params, &DecoderOptions::default()) + .expect("Failed to create decoder"); - // Create a decoder for the track. - let mut decoder = - symphonia::default::get_codecs().make(&track.codec_params, &decoder_opts).unwrap(); + let mut samples = Vec::new(); - // Store the track identifier, we'll use it to filter packets. - let track_id = track.id; - - let mut sample_count = 0; + // Temporary sample buffer for decoding let mut sample_buf = None; - loop { - // Get the next packet from the format reader. - let packet = format.next_packet().unwrap(); - - // If the packet does not belong to the selected track, skip it. - if packet.track_id() != track_id { + while let Ok(packet) = format.next_packet() { + if packet.track_id() != track.id { continue; } - // Decode the packet into audio samples, ignoring any decode errors. + // Decode packet match decoder.decode(&packet) { Ok(audio_buf) => { - // The decoded audio samples may now be accessed via the audio buffer if per-channel - // slices of samples in their native decoded format is desired. Use-cases where - // the samples need to be accessed in an interleaved order or converted into - // another sample format, or a byte buffer is required, are covered by copying the - // audio buffer into a sample buffer or raw sample buffer, respectively. In the - // example below, we will copy the audio buffer into a sample buffer in an - // interleaved order while also converting to a f32 sample format. - - // If this is the *first* decoded packet, create a sample buffer matching the - // decoded audio buffer format. + // Create a f32 sample buffer if not already if sample_buf.is_none() { - // Get the audio buffer specification. let spec = *audio_buf.spec(); - - // Get the capacity of the decoded buffer. Note: This is capacity, not length! - let duration = audio_buf.capacity() as u64; - - // Create the f32 sample buffer. - sample_buf = Some(SampleBuffer::::new(duration, spec)); + let capacity = audio_buf.capacity() as u64; + sample_buf = Some(SampleBuffer::::new(capacity, spec)); } - // Copy the decoded audio buffer into the sample buffer in an interleaved format. + // Copy decoded data to f32 buffer if let Some(buf) = &mut sample_buf { buf.copy_interleaved_ref(audio_buf); - - // The samples may now be access via the `samples()` function. - sample_count += buf.samples().len(); - print!("\rDecoded {} samples", sample_count); + samples.extend(buf.samples()); } } - Err(symphonia::core::errors::Error::DecodeError(_)) => (), - Err(_) => break, + Err(_) => continue, } } + + samples } pub struct DecodedAudio {