docker: add audio passthrough for containerized FM receiver
New files for running the FM receiver in Docker with audio output: - Dockerfile.gnuradio-audio: GNU Radio image with ALSA→PulseAudio bridge - libasound2-plugins for ALSA PulseAudio plugin - /etc/asound.conf configures ALSA to route to PulseAudio - docker-compose.fm-receiver.yml: Full FM receiver setup - PulseAudio socket mount for audio - USB passthrough for RTL-SDR (requires privileged mode) - XML-RPC port 8090 exposed for tuning control - Environment vars: FREQ_MHZ, GAIN - entrypoint-fm.sh: Builds and runs flowgraph at specified frequency - run-fm-receiver.sh: Helper script with usage instructions Usage: HOST_UID=$(id -u) FREQ_MHZ=107.2 docker compose -f docker/docker-compose.fm-receiver.yml up
This commit is contained in:
parent
f6c9e465c5
commit
6c642f4a7e
35
docker/Dockerfile.gnuradio-audio
Normal file
35
docker/Dockerfile.gnuradio-audio
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
FROM librespace/gnuradio:latest
|
||||||
|
|
||||||
|
# PulseAudio client + ALSA-PulseAudio plugin for audio output
|
||||||
|
# GNU Radio uses ALSA backend, so we bridge ALSA → PulseAudio
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
pulseaudio-utils \
|
||||||
|
libpulse0 \
|
||||||
|
libasound2-plugins \
|
||||||
|
alsa-utils \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Configure ALSA to use PulseAudio as default output
|
||||||
|
# This makes any ALSA app (including GNU Radio) output to PulseAudio
|
||||||
|
RUN echo 'pcm.!default { type pulse }' > /etc/asound.conf && \
|
||||||
|
echo 'ctl.!default { type pulse }' >> /etc/asound.conf
|
||||||
|
|
||||||
|
# Create non-root user for PulseAudio (matches typical host UID)
|
||||||
|
ARG USER_ID=1000
|
||||||
|
ARG GROUP_ID=1000
|
||||||
|
RUN groupadd -g ${GROUP_ID} gnuradio || true \
|
||||||
|
&& useradd -m -u ${USER_ID} -g ${GROUP_ID} gnuradio || true
|
||||||
|
|
||||||
|
WORKDIR /flowgraphs
|
||||||
|
|
||||||
|
# PulseAudio socket location
|
||||||
|
ENV PULSE_SERVER=unix:/run/pulse/native
|
||||||
|
|
||||||
|
# XML-RPC port for runtime control
|
||||||
|
ENV XMLRPC_PORT=8090
|
||||||
|
EXPOSE 8090
|
||||||
|
|
||||||
|
USER gnuradio
|
||||||
|
|
||||||
|
# Default: run a flowgraph passed as argument
|
||||||
|
ENTRYPOINT ["python3"]
|
||||||
32
docker/docker-compose.fm-receiver.yml
Normal file
32
docker/docker-compose.fm-receiver.yml
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
services:
|
||||||
|
fm-receiver:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile.gnuradio-audio
|
||||||
|
|
||||||
|
# Root required for USB device access (RTL-SDR)
|
||||||
|
user: root
|
||||||
|
privileged: true
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
# PulseAudio socket for audio output (ALSA → PulseAudio bridge)
|
||||||
|
- /run/user/${HOST_UID:-1000}/pulse/native:/run/pulse/native
|
||||||
|
# Flowgraph source files
|
||||||
|
- ../examples:/flowgraphs:ro
|
||||||
|
- ../src:/src:ro
|
||||||
|
# Entrypoint script
|
||||||
|
- ./entrypoint-fm.sh:/entrypoint-fm.sh:ro
|
||||||
|
|
||||||
|
environment:
|
||||||
|
- PULSE_SERVER=unix:/run/pulse/native
|
||||||
|
- FREQ_MHZ=${FREQ_MHZ:-101.1}
|
||||||
|
- GAIN=${GAIN:-10}
|
||||||
|
|
||||||
|
# XML-RPC port for tuning control from host
|
||||||
|
ports:
|
||||||
|
- "8090:8090"
|
||||||
|
|
||||||
|
entrypoint: ["/bin/bash", "/entrypoint-fm.sh"]
|
||||||
|
|
||||||
|
stdin_open: true
|
||||||
|
tty: true
|
||||||
22
docker/entrypoint-fm.sh
Normal file
22
docker/entrypoint-fm.sh
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Entrypoint for containerized FM receiver
|
||||||
|
set -e
|
||||||
|
|
||||||
|
FREQ_MHZ=${FREQ_MHZ:-101.1}
|
||||||
|
GAIN=${GAIN:-10}
|
||||||
|
|
||||||
|
python3 -c "
|
||||||
|
import sys, subprocess, os
|
||||||
|
sys.path.insert(0, '/flowgraphs')
|
||||||
|
sys.path.insert(0, '/src')
|
||||||
|
from fm_scanner import build_fm_receiver
|
||||||
|
|
||||||
|
freq = float(os.environ.get('FREQ_MHZ', '101.1'))
|
||||||
|
gain = int(os.environ.get('GAIN', '10'))
|
||||||
|
|
||||||
|
print(f'Building FM receiver for {freq} MHz (gain {gain} dB)...')
|
||||||
|
py_path = build_fm_receiver(freq, gain=gain)
|
||||||
|
print(f'Launching {py_path.name} — Ctrl+C to stop')
|
||||||
|
print(f'XML-RPC control at http://localhost:8090')
|
||||||
|
subprocess.run([sys.executable, str(py_path)])
|
||||||
|
"
|
||||||
24
docker/run-fm-receiver.sh
Executable file
24
docker/run-fm-receiver.sh
Executable file
@ -0,0 +1,24 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Run containerized FM receiver with audio output to host
|
||||||
|
#
|
||||||
|
# Usage: ./run-fm-receiver.sh [FREQ_MHZ] [GAIN]
|
||||||
|
# FREQ_MHZ: FM frequency (default: 101.1)
|
||||||
|
# GAIN: RF gain in dB (default: 10)
|
||||||
|
#
|
||||||
|
# Once running, use XML-RPC from host to retune:
|
||||||
|
# python -c "import xmlrpc.client; p=xmlrpc.client.ServerProxy('http://localhost:8090'); p.set_freq(107.2e6)"
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
export HOST_UID=$(id -u)
|
||||||
|
export FREQ_MHZ=${1:-101.1}
|
||||||
|
export GAIN=${2:-10}
|
||||||
|
|
||||||
|
echo "Starting FM receiver at $FREQ_MHZ MHz (gain: $GAIN dB)"
|
||||||
|
echo "XML-RPC control available at http://localhost:8090"
|
||||||
|
echo "Press Ctrl+C to stop"
|
||||||
|
echo
|
||||||
|
|
||||||
|
docker compose -f "$SCRIPT_DIR/docker-compose.fm-receiver.yml" up --build
|
||||||
Loading…
x
Reference in New Issue
Block a user