Update plugins
This commit is contained in:
116
src/main.rs
116
src/main.rs
@@ -1,7 +1,9 @@
|
||||
use std::{fs::File, path::PathBuf};
|
||||
|
||||
use clap::{Parser, Subcommand, ValueEnum};
|
||||
use jack::{AudioOut, Client, ClientOptions};
|
||||
use symphonia::core::{audio::{AudioBufferRef, SampleBuffer}, codecs::DecoderOptions, formats::FormatOptions, io::MediaSourceStream, meta::MetadataOptions, probe::Hint};
|
||||
use ringbuf::RingBuffer;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)]
|
||||
enum Backend {
|
||||
@@ -24,90 +26,76 @@ struct Cli {
|
||||
|
||||
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<f32>;
|
||||
if let Some(files) = cli.track {
|
||||
for file in files {
|
||||
data = read_audio_file(file);
|
||||
}
|
||||
}
|
||||
let (client, _status) = Client::new("rust_jack_simple", ClientOptions::default()).unwrap();
|
||||
let out_l = client.register_port("out_l", AudioOut::default()).unwrap();
|
||||
let out_r = client.register_port("out_r", AudioOut::default()).unwrap();
|
||||
let ring_l = RingBuffer::<f32>::new(48000 * 2);
|
||||
let ring_r = RingBuffer::<f32>::new(48000 * 2);
|
||||
let (prod_l, cons_l) = ring_l.split();
|
||||
let (prod_r, cons_r) = ring_r.split();
|
||||
|
||||
|
||||
if let Some(backend) = cli.backend {
|
||||
match backend {
|
||||
Backend::Jack => play_with_jack(),
|
||||
Backend::Jack => println!("jack"),
|
||||
Backend::Alsa => println!("alsa"),
|
||||
Backend::Pulseaudio => println!("pulse"),
|
||||
Backend::Coreaudio => println!("coreaudio"),
|
||||
Backend::Cpal => println!("cpal"),
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[cfg(feature = "jack")]
|
||||
fn play_with_jack(data: Vec<f32>) {
|
||||
unimplemented!()
|
||||
}
|
||||
fn spawn_mp3_decoder(
|
||||
path: String,
|
||||
mut prod_l: ringbuf::Producer<f32>,
|
||||
mut prod_r: ringbuf::Producer<f32>,
|
||||
) {
|
||||
thread::spawn(move || {
|
||||
let file = File::open(path).expect("failed to open mp3");
|
||||
let mss = MediaSourceStream::new(Box::new(file), Default::default());
|
||||
|
||||
#[cfg(not(feature = "jack"))]
|
||||
fn play_with_jack(_: Vec<f32>) {
|
||||
unimplemented!()
|
||||
}
|
||||
let mut hint = Hint::new();
|
||||
hint.with_extension("mp3");
|
||||
|
||||
fn read_audio_file(path: String) -> Vec<f32>{
|
||||
// Open file
|
||||
let file = File::open(path).expect("Failed to open file");
|
||||
let mss = MediaSourceStream::new(Box::new(file), Default::default());
|
||||
let probed = symphonia::default::get_probe()
|
||||
.format(
|
||||
&hint,
|
||||
mss,
|
||||
&FormatOptions::default(),
|
||||
&MetadataOptions::default(),
|
||||
)
|
||||
.expect("format probe failed");
|
||||
|
||||
// Hint format by extension
|
||||
let mut hint = Hint::new();
|
||||
let mut format = probed.format;
|
||||
let track = format.default_track().unwrap();
|
||||
|
||||
// Probe the file
|
||||
let probed = symphonia::default::get_probe()
|
||||
.format(&hint, mss, &FormatOptions::default(), &MetadataOptions::default())
|
||||
.expect("Unsupported format");
|
||||
let mut decoder = symphonia::default::get_codecs()
|
||||
.make(&track.codec_params, &DecoderOptions::default())
|
||||
.unwrap();
|
||||
|
||||
let mut format = probed.format;
|
||||
let track = format.default_track().expect("No default track");
|
||||
let mut sample_buf: Option<SampleBuffer<f32>> = None;
|
||||
|
||||
let mut decoder = symphonia::default::get_codecs()
|
||||
.make(&track.codec_params, &DecoderOptions::default())
|
||||
.expect("Failed to create decoder");
|
||||
loop {
|
||||
let packet = match format.next_packet() {
|
||||
Ok(p) => p,
|
||||
Err(_) => break,
|
||||
};
|
||||
|
||||
let mut samples = Vec::new();
|
||||
let decoded = decoder.decode(&packet).unwrap();
|
||||
|
||||
// Temporary sample buffer for decoding
|
||||
let mut sample_buf = None;
|
||||
let buf = sample_buf.get_or_insert_with(|| {
|
||||
SampleBuffer::new(decoded.capacity() as u64, *decoded.spec())
|
||||
});
|
||||
|
||||
while let Ok(packet) = format.next_packet() {
|
||||
if packet.track_id() != track.id {
|
||||
continue;
|
||||
}
|
||||
buf.copy_interleaved_ref(decoded);
|
||||
|
||||
// Decode packet
|
||||
match decoder.decode(&packet) {
|
||||
Ok(audio_buf) => {
|
||||
// Create a f32 sample buffer if not already
|
||||
if sample_buf.is_none() {
|
||||
let spec = *audio_buf.spec();
|
||||
let capacity = audio_buf.capacity() as u64;
|
||||
sample_buf = Some(SampleBuffer::<f32>::new(capacity, spec));
|
||||
}
|
||||
|
||||
// Copy decoded data to f32 buffer
|
||||
if let Some(buf) = &mut sample_buf {
|
||||
buf.copy_interleaved_ref(audio_buf);
|
||||
samples.extend(buf.samples());
|
||||
}
|
||||
// Assume stereo
|
||||
for frame in buf.samples().chunks(2) {
|
||||
let _ = prod_l.push(frame[0]);
|
||||
let _ = prod_r.push(frame[1]);
|
||||
}
|
||||
Err(_) => continue,
|
||||
}
|
||||
}
|
||||
|
||||
samples
|
||||
}
|
||||
|
||||
pub struct DecodedAudio {
|
||||
pub samples: Vec<i16>, // interleaved
|
||||
pub sample_rate: u32,
|
||||
pub channels: u16,
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user