Audio Fix
This commit is contained in:
parent
4522367a64
commit
f8528897de
@ -31,7 +31,25 @@ impl AudioOut {
|
||||
.downcast::<gst_app::AppSrc>()
|
||||
.expect("src not an AppSrc");
|
||||
|
||||
src.set_caps(Some(&gst::Caps::builder("audio/mpeg") // mpeg‑4 AAC
|
||||
.field("mpegversion", &4i32)
|
||||
.field("stream-format", &"adts")
|
||||
.build()));
|
||||
src.set_format(gst::Format::Time);
|
||||
|
||||
{
|
||||
let bus = pipeline.bus().expect("bus");
|
||||
std::thread::spawn(move || {
|
||||
use gst::MessageView::*;
|
||||
for msg in bus.iter_timed(gst::ClockTime::NONE) {
|
||||
if let Error(e) = msg.view() {
|
||||
error!("💥 client‑audio: {} ({})",
|
||||
e.error(), e.debug().unwrap_or_default());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pipeline.set_state(gst::State::Playing)?;
|
||||
|
||||
Ok(Self { src })
|
||||
|
||||
@ -7,6 +7,7 @@ use gstreamer as gst;
|
||||
use gstreamer_app as gst_app;
|
||||
use gst::prelude::*;
|
||||
use gst::ElementFactory;
|
||||
use gst::MessageView::*;
|
||||
use lesavka_common::lesavka::AudioPacket;
|
||||
use tokio_stream::wrappers::ReceiverStream;
|
||||
use tonic::Status;
|
||||
@ -36,10 +37,10 @@ impl Drop for AudioStream {
|
||||
}
|
||||
|
||||
/*───────────────────────────────────────────────────────────────────────────*/
|
||||
/* eye_ear() – capture from ALSA (“speaker”) and push AAC AUs via gRPC */
|
||||
/* ear() – capture from ALSA (“speaker”) and push AAC AUs via gRPC */
|
||||
/*───────────────────────────────────────────────────────────────────────────*/
|
||||
|
||||
pub async fn eye_ear(alsa_dev: &str, id: u32) -> anyhow::Result<AudioStream> {
|
||||
pub async fn ear(alsa_dev: &str, id: u32) -> anyhow::Result<AudioStream> {
|
||||
// NB: one *logical* speaker → id==0. A 2nd logical stream could be
|
||||
// added later (for multi‑channel) without changing the client.
|
||||
gst::init().context("gst init")?;
|
||||
@ -65,10 +66,9 @@ pub async fn eye_ear(alsa_dev: &str, id: u32) -> anyhow::Result<AudioStream> {
|
||||
|
||||
let (tx, rx) = tokio::sync::mpsc::channel(8192);
|
||||
|
||||
let bus = pipeline.bus().expect("no bus");
|
||||
let bus = pipeline.bus().expect("bus");
|
||||
std::thread::spawn(move || {
|
||||
for msg in bus.iter_timed(gst::ClockTime::NONE) {
|
||||
use gst::MessageView::*;
|
||||
match msg.view() {
|
||||
Error(e) => error!("💥 audio pipeline: {} ({})",
|
||||
e.error(), e.debug().unwrap_or_default()),
|
||||
@ -93,7 +93,7 @@ pub async fn eye_ear(alsa_dev: &str, id: u32) -> anyhow::Result<AudioStream> {
|
||||
std::sync::atomic::AtomicU64::new(0);
|
||||
let n = CNT.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
||||
if n < 10 || n % 300 == 0 {
|
||||
debug!("🔊 eye‑ear #{n}: {} bytes", map.len());
|
||||
debug!("🎧 ear #{n}: {} bytes", map.len());
|
||||
}
|
||||
|
||||
let pts_us = buffer
|
||||
@ -111,7 +111,7 @@ pub async fn eye_ear(alsa_dev: &str, id: u32) -> anyhow::Result<AudioStream> {
|
||||
std::sync::atomic::AtomicU64::new(0);
|
||||
let d = DROPS.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
||||
if d % 300 == 0 {
|
||||
warn!("🔊💔 dropped {d} audio AUs (client too slow)");
|
||||
warn!("🎧💔 dropped {d} audio AUs (client too slow)");
|
||||
}
|
||||
}
|
||||
Ok(gst::FlowSuccess::Ok)
|
||||
@ -129,17 +129,17 @@ pub async fn eye_ear(alsa_dev: &str, id: u32) -> anyhow::Result<AudioStream> {
|
||||
}
|
||||
|
||||
fn build_pipeline_desc(dev: &str) -> anyhow::Result<String> {
|
||||
use gst::ElementFactory; // <- simpler probe
|
||||
// choose the first encoder that exists on the system
|
||||
let enc = ["voaacenc", "avenc_aac", "fdkaacenc"]
|
||||
.into_iter()
|
||||
.find(|&e| ElementFactory::find(e).is_some())
|
||||
.find(|e| ElementFactory::find(e).is_some()) // cheap run‑time probe
|
||||
.ok_or_else(|| anyhow::anyhow!("no AAC encoder plugin available"))?;
|
||||
|
||||
Ok(format!(
|
||||
// ➊ provide-clock=false lets the USB gadget be master
|
||||
// ➋ audioconvert+audioresample make sure caps match encoder
|
||||
// 48 kHz stereo, floats, gadget is master → provide‑clock=false
|
||||
"alsasrc device=\"{dev}\" provide-clock=false do-timestamp=true ! \
|
||||
audioconvert ! audioresample ! audio/x-raw,channels=2,rate=48000,format=F32LE ! \
|
||||
audioconvert ! audioresample ! \
|
||||
audio/x-raw,format=F32LE,channels=2,rate=48000 ! \
|
||||
{enc} bitrate=192000 ! aacparse ! queue ! \
|
||||
appsink name=asink emit-signals=true max-buffers=64 drop=true"
|
||||
))
|
||||
|
||||
@ -192,7 +192,7 @@ impl Relay for Handler {
|
||||
let dev = std::env::var("LESAVKA_ALSA_DEV")
|
||||
.unwrap_or_else(|_| "hw:UAC2Gadget,0".into());
|
||||
|
||||
let s = audio::eye_ear(&dev, 0)
|
||||
let s = audio::ear(&dev, 0)
|
||||
.await
|
||||
.map_err(|e| Status::internal(format!("{e:#}")))?;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user