Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/ci-linux-rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ jobs:
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y pkg-config libdbus-1-dev libpulse-dev appstream just libfuse2
sudo apt-get install -y pkg-config libdbus-1-dev libpulse-dev appstream just libfuse2 \
libavutil-dev libavcodec-dev libavformat-dev libavfilter-dev libavdevice-dev libswresample-dev libswscale-dev

- name: Install AppImage tools
run: |
Expand Down
128 changes: 125 additions & 3 deletions linux-rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions linux-rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ dbus = "0.9.10"
hex = "0.4.3"
iced = { version = "0.14.0", features = ["tokio", "image"] }
libpulse-binding = "2.30.1"
libpulse-simple-binding = "2.29.0"
ksni = "0.3.1"
image = "0.25.8"
imageproc = "0.26.1"
Expand All @@ -22,6 +23,9 @@ serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
aes = "0.9.0-rc.4"
futures = "0.3.32"
# AAC-ELD decode for the hi-res microphone. System libavcodec/libavutil via
# pkg-config (no bundled build); avformat/swscale/etc. are not needed.
ffmpeg-sys-next = { version = "8.1", default-features = false, features = ["avcodec"] }

[profile.release]
opt-level = "s"
Expand Down
8 changes: 8 additions & 0 deletions linux-rust/flatpak/me.kavishdevar.librepods.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ sdk-extensions:

command: librepods

# Hi-res microphone deps (verified present in org.freedesktop.Platform 25.08):
# - libavcodec.so.61 / libavutil.so.59 (FFmpeg 7.1) for AAC-ELD decode.
# ffmpeg-sys-next auto-detects this version at build time, so no pin needed.
# - libpulse-simple.so.0 for the PCM playback stream.
# The virtual mic is created over the existing --socket=pulseaudio (module load
# + playback are protocol calls; no extra finish-args, no pactl/pw-cat needed).
# Build note: ffmpeg-sys-next runs bindgen, which needs libclang from the SDK.

finish-args:
- --socket=wayland
- --socket=fallback-x11
Expand Down
47 changes: 47 additions & 0 deletions linux-rust/src/audio/agc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//! AGC (Automatic Gain Control) for audio processing.

pub struct Agc {
envelope: f32,
gain: f32,
}

impl Agc {
const TARGET: f32 = 0.25; // ≈ -12 dBFS
const MAX_GAIN: f32 = 8.0; // +18 dB
const ATTACK: f32 = 0.02;
const RELEASE: f32 = 0.001;

pub fn new() -> Self {
Self {
envelope: 0.0,
gain: 1.0,
}
}

pub fn process(&mut self, samples: &mut [i16]) {
for s in samples {
let x = *s as f32 / 32768.0;
let level = x.abs();

if level > self.envelope {
self.envelope += (level - self.envelope) * Self::ATTACK;
} else {
self.envelope += (level - self.envelope) * Self::RELEASE;
}

// Target gain
let desired = (Self::TARGET / self.envelope.max(1e-4)).min(Self::MAX_GAIN);

// Smooth gain
self.gain += (desired - self.gain) * 0.01;

// Apply gain
let mut y = x * self.gain;

// Soft limiter
y = y.tanh();

*s = (y * 32767.0) as i16;
}
}
}
Loading