badaix / snapcast

Synchronous multiroom audio player
GNU General Public License v3.0
6.15k stars 456 forks source link

Using soundcard line-in snapcast as source #153

Closed pbros closed 7 years ago

pbros commented 7 years ago

Hello,

I was wondering if anybody has used snapcast to take the sound from an external sound source (e.g. a turntable) using a soundcard line-in? Can this be done using ALSA or maybe something else?

Thanks

unimatrix27 commented 7 years ago

I have not tried it but this should work with pulseaudio and the pipe module.

axelsimon commented 7 years ago

Whole house live FLAC-encoded vinyl playback! 😃

aHelding commented 7 years ago

I was looking into this as well. Any luck?

axelsimon commented 7 years ago

Well with a bit of PulseAudio magic it shouldn't be too hard. You can pipe a sink into another sink using a recording sink's monitor. ie: use alsa line-in sink monitor as source of another pulse sink, in our case the file sink. (My Pulse terminology might not be spot on, but that's the idea)

rccoe commented 7 years ago

Anyone figure this out?

rccoe commented 7 years ago

I ended up using https://github.com/b-fitzpatrick/cpiped for this, easier than worrying about PA

aHelding commented 7 years ago

cpiped works like a charm. Thanks a bunch!

badaix commented 7 years ago

I've added this to the Readme

atze09 commented 7 years ago

How can i install cpiped? I did "git clone" and the "make" but "make install" did not work for me. Can anyone help me?

xiubert commented 7 years ago

for those not privy to compiling, it seems build-essential is required as is libasound2 just: git clone [rep], then cd cpiped, then make you can: sudo cp /path/to/compiled/binary /usr/local/bin/. then 'which cpiped' you should then be able to call it w/ just cpiped. This will inform you of the available settings.

I haven't tried the provided init script (I have it on an arch install and don't know how to relate init to units)

I have a bluetooth receiver plugged into a cheap usb audio input and call cpiped w/:

cpiped -d default:CARD=Device -D /tmp/cpipefifo

I'm not sure what best to use in snapserver settings. At first I had 48000:16:2, but 44100 seems to be a bit more fluid. This is what I use:

pipe:///tmp/cpipefifo?name=Bluetooth&sampleformat=44100:16:2&codec=flac

but it's still a bit laggy at times. Any hints to improve?

I used to manually pipe audio capture with arecord to pipe in a gnu screen session and actually had more fluid playback:

arecord --device=plughw:1,0 --format S16_LE --rate 44100 -c2 /tmp/snapfifo but this is harder to daemonize / consistent on resources

EDIT: actually this way (arecord) seems to be behaving worse atm

EDIT2: increasing streamBuffer seems to help tremendously: pipe:///tmp/cpipefifo?name=Bluetooth&streamBuffer=100&sampleformat=44100:16:2&codec=flac

art049 commented 5 years ago

I confirm that using arecord gives far better results than cpiped. I had audio dropouts but with arecord and a bigger streamBuffer everything is smooth. Thanks @xiubert !

Also, storing the snapfifo in a ramfile helped on OrangePi Zero.

fuchsmich commented 5 years ago

I'm using sox on an openwrt router for my turntable.

sox -q -r 48k -b 16 -c 2 -t alsa default -t raw -L -r 48k -b 16 -c 2 - silence 1 0.2 0.05% -1 0.2 0.05% > /tmp/vinyl

I'm also piping the stream over network to my raspberry, which is the snapserver.

pro: when the turntable isn't in use there is no stream (filtering silence) contra: every now and then the stream is scrambled. I can't find out why. I guess sox is already reading a scrambled stream from the soundcard.

Maybe I should give arecord a try.

xiubert commented 5 years ago

Always ran into issues when trying to fifo pipe over the network. Curious, what approach did you take?

Admittedly switched to forked-daapd + shairport-sync as it ended up being more user friendly for regular folk in the house. CPiped works well with bluetooth to trigger scripts that activate pipes on sound input ( https://github.com/ejurgensen/forked-daapd/issues/632#issuecomment-454637959 )

fuchsmich commented 5 years ago

Basically it's a systemd-service which runs on the snapserver (raspberry pi).

$ cat /etc/systemd/system/vinyl.service

[Unit]
Description=Vinyl2FIFO
After=network-online.target snapserver.service
Requires=network-online.target snapserver.service
ConditionPathExists=/tmp/vinyl

[Service]
User=snapserver
Group=snapserver
ExecStartPre=-/usr/bin/sh -c '/bin/ssh -C vinyl@openwrt killall -q sox'
ExecStart=/usr/bin/sh -c '/bin/ssh -C vinyl@openwrt sox -q -r 48k -b 16 -c 2 -t alsa default  -t raw -L -r 48k -b 16 -c 2 - silence 1 0.2 0.05% -1 0.2 0.05% > /tmp/vinyl'
Restart=always

[Install]
WantedBy=multi-user.target

The systemd-service is started by systemd-path-unit, which reacts on the creation of the FIFO by snapserver:

$ cat /etc/systemd/system/vinyl.path

[Path]
PathExists=/tmp/vinyl

[Install]
WantedBy=multi-user.target

I don't know if all the parameters in the sox command are necessary, I tried to work around the scrambled audio signal which comes every now and then. If the signal is scrambled I just got to restart the vinyl.service. If it's not scrambled, everything is very stable. So I'm quite sure the failure is somewhere between sox and the soundcard.

If you need more details, feel free to ask.

vKnmnn commented 4 years ago

i have done what's described above with pulseaudio only.

i have snapserver A and snapclients B C and D. The LP Player has it's "Zone 2" output hooked to an input on snapclient D.

Snapclient D has the pulseaudio tunnel module running, wich tunnels the audio to pulseaudio on Snapserver A. Pulse on Snapserver A is configured to play all incoming sound from to it's pipesink and from there via Snapserver to the clients.

The config was something like this: Snapclient D (vinyl source)

# create a sink on which we can play our vinyl
load-module module-tunnel-sink-new server=[192.168.10.111] sink=Snapcast format=s16le channels=2 rate=48000 sink_name=snapcast
# make our input from vinyl loop back to the tunnel-sink
load-module module-loopback source=alsa_input.usb-Burr-Brown_from_TI_USB_Audio_CODEC-00.analog-stereo  format=s16le channels=2 sink=snapcast latency_msec=20
# give the input a pretty name and an icon for pavucontrol
update-source-proplist alsa_input.usb-Burr-Brown_from_TI_USB:_Audio_CODEC-00.analog-stereo device.description=USBSound_IN device.icon_name=audio-input-microphone

for this to work, module-native-protocol-tcp has to be loaded on pulseaudio on snapserver A:

# allow clients in local lan to connect to this pulse server
load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1;192.168.10.0/24 auth-anonymous=1
# create the Snap FIFO
load-module module-pipe-sink file=/tmp/snapfifo sink_name=Snapcast rate=48000
# give the sink a pretty name and an icon for pavucontrol
update-sink-proplist Snapcast device.description=Snapcast device.icon_name=audio-speakers

I suppose you could even put cpiped in the loop to load the tunnel module only when you need it, but i didn't bother at the time.

fuchsmich commented 4 years ago

Looks nice!

I also tried this lately, but the loopback from audio device to tunnel sink didn't work. But I guess the latency would have probably solved the problem.

Syco54645 commented 2 years ago

I have written instructions to use ALSA directly and submitted a PR to the project. They were written in regards to an rpi using a HiFiBerry DAC but should work for any hardware easily enough.

https://github.com/badaix/snapcast/pull/1002