Update plugins
Some checks failed
ci/woodpecker/push/code_tests Pipeline failed
ci/woodpecker/push/pre_commit_test Pipeline was successful

This commit is contained in:
2025-12-23 19:26:36 +01:00
parent 0a043e10f1
commit 29181f9c76
3 changed files with 87 additions and 66 deletions

33
Cargo.lock generated
View File

@@ -242,6 +242,12 @@ dependencies = [
"windows",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
[[package]]
name = "dasp_sample"
version = "0.11.0"
@@ -694,6 +700,21 @@ version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
[[package]]
name = "portable-atomic"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f59e70c4aef1e55797c2e8fd94a4f2a973fc972cfde0e0b05f683667b0cd39dd"
[[package]]
name = "portable-atomic-util"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507"
dependencies = [
"portable-atomic",
]
[[package]]
name = "proc-macro-crate"
version = "3.4.0"
@@ -737,6 +758,17 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "ringbuf"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe47b720588c8702e34b5979cb3271a8b1842c7cb6f57408efa70c779363488c"
dependencies = [
"crossbeam-utils",
"portable-atomic",
"portable-atomic-util",
]
[[package]]
name = "rustversion"
version = "1.0.22"
@@ -951,6 +983,7 @@ dependencies = [
"cpal",
"jack",
"pulseaudio",
"ringbuf",
"symphonia",
]

View File

@@ -5,15 +5,15 @@ edition = "2024"
[dependencies]
clap = { version = "4.5.53", features = ["derive"] }
jack = { version = "0.13.3", optional = true}
jack = { version = "0.13.3" }
pulseaudio = { version = "0.3.1", optional = true}
alsa = { version = "0.10.0", optional = true}
symphonia = { version = "0.5.5", features = ["mp3"] }
coreaudio-rs = { version = "0.13.0", optional = true }
cpal = { version = "0.16.0", optional = true }
ringbuf = "0.4.8"
[features]
jack = ["dep:jack"]
pulseaudio = ["dep:pulseaudio"]
alsa = ["dep:alsa"]
coreaudio = ["dep:coreaudio-rs"]

View File

@@ -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!()
}
#[cfg(not(feature = "jack"))]
fn play_with_jack(_: Vec<f32>) {
unimplemented!()
}
fn read_audio_file(path: String) -> Vec<f32>{
// Open file
let file = File::open(path).expect("Failed to open file");
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());
// Hint format by extension
let mut hint = Hint::new();
hint.with_extension("mp3");
// Probe the file
let probed = symphonia::default::get_probe()
.format(&hint, mss, &FormatOptions::default(), &MetadataOptions::default())
.expect("Unsupported format");
.format(
&hint,
mss,
&FormatOptions::default(),
&MetadataOptions::default(),
)
.expect("format probe failed");
let mut format = probed.format;
let track = format.default_track().expect("No 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");
.unwrap();
let mut samples = Vec::new();
let mut sample_buf: Option<SampleBuffer<f32>> = None;
// Temporary sample buffer for decoding
let mut sample_buf = None;
loop {
let packet = match format.next_packet() {
Ok(p) => p,
Err(_) => break,
};
while let Ok(packet) = format.next_packet() {
if packet.track_id() != track.id {
continue;
}
let decoded = decoder.decode(&packet).unwrap();
// 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));
}
let buf = sample_buf.get_or_insert_with(|| {
SampleBuffer::new(decoded.capacity() as u64, *decoded.spec())
});
// Copy decoded data to f32 buffer
if let Some(buf) = &mut sample_buf {
buf.copy_interleaved_ref(audio_buf);
samples.extend(buf.samples());
}
}
Err(_) => continue,
}
}
buf.copy_interleaved_ref(decoded);
samples
// Assume stereo
for frame in buf.samples().chunks(2) {
let _ = prod_l.push(frame[0]);
let _ = prod_r.push(frame[1]);
}
pub struct DecodedAudio {
pub samples: Vec<i16>, // interleaved
pub sample_rate: u32,
pub channels: u16,
}
});
}