Open cdlenfert opened 5 years ago
I think shairport-sync has the option "run_this_before_play_begins" which could perhaps serve you in this matter. You should then set pipe_autostart to false, and then instead achieve autostart by having shairport-sync start forked-daapd playback via the option. Something like this:
run_this_before_play_begins="mpc add file:/home/share/shairportpipe && mpc play"
I'm not that strong with mpc commands, so the above might not be spot on. I expect you will need to experiment a bit. Also haven't ever actually tried this shairport-sync option, I don't know if compounding the commands with && will work.
This solution would require manual start of the Bluetooth pipe via e.g. Remote app (so like your option 1), and a better solution would be to have that autostart as well. I imagine that would require a service that listens on the aux input all the time, and when the volume reaches a certain level it kicks of "arecord > pipe". Don't really know how to do that exactly, maybe google does :-)
If you find a solution please post it here, might help other people.
This may also be helpful:
https://github.com/b-fitzpatrick/cpiped
I used to use it w/ snapcast before switching to forked-daapd + shairport-sync
Considering using it again for mic and bluetooth input
thanks @xiubert. CPiped seems like exactly the solution I'm looking for. I don't have much experience installing packages from a git source. I'm running forked-daapd on an low powered ARMv6 device running Debian Stretch (9). Here's what I did, but not sure what the next steps should be:
git clone "https://github.com/b-fitzpatrick/cpiped.git"
cd cpiped/
make cpiped
When I try to run cpiped it wants more arguments (I think) and I'm not sure what to set for each and what format that should be in.
./cpiped
Usage:
./cpiped [-d arg] [-b arg] [-s arg] [-e arg] [-t arg] [-D] FIFO
-d : ALSA capture device ['default']
-b : target buffer in seconds [.5]
-s : command to run when sound detected
-e : command to run when silence detected
-t : silence threshold (1 - 32767, [100])
-D : daemonize
FIFO : path to a named pipe
Stopping due to error.
Here is some info about my sound card.
aplay -l
card 1: Device [USB Audio Device], device 0: USB Audio [USB Audio]
Subdevices: 0/1
Subdevice #0: subdevice #0
In my original post I'm able to capture from the following device
device=plughw:CARD=Device,DEV=0
also via command 'amixer'
Simple mixer control 'Mic',0
Capabilities: pvolume pvolume-joined cvolume cvolume-joined pswitch pswitch-joined cswitch cswitch-joined
Playback channels: Mono
Capture channels: Mono
Limits: Playback 0 - 31 Capture 0 - 35
Mono: Playback 16 [52%] [-7.00dB] [off] Capture 20 [57%] [8.00dB] [on]
You're well on your way. In case you're still at it:
the minimal input you need for cpiped is likely the named FIFO pipe (which forked-daapd will be using), but would recommend setting the capture device w/ -d and daemonizing w/ -D
list capture devices w/: arecord -l
from my notes, my command looked something like this:
cpiped -d default:CARD=Device -D /tmp/cpipefifo
I imagine you'll want to use the -s and -e flags to run scripts that call forked-daapd commands via json-api (https://github.com/ejurgensen/forked-daapd#command-line) (this is, after all, why you want cpiped in the first place)
I haven't tried any of this yet, but I imagine you'll want:
for -s: script that sets your pipe at 0 in queue and starts play for -e: script that sets another pipe like the one for shairport-sync at 0 in queue
side note: it seems the cpiped author wrote it expressly for this purpose ( ;
Decided to take a whack at this myself. Here's my approach:
physical setup: bluetooth receiver w/ split output to stereo receiver and mic line in on server
function: stereo receiver plays local bluetooth audio at only bluetooth delay, mic input takes bluetooth audio and sends it to synced airplay speakers via cpiped and forked-daapd
create named fifo pipe that will be scraped by forked-daapd library scan: mkfifo /var/media/bluetoothOutputPipe
create named fifo pipe that will take cpiped output and will be used for detection mkfifo /home/user/detectionPipe
prepare scripts to run on sound detection and absence: soundDetect.sh:
cat /home/user/detectionPipe > /var/media/bluetoothOutputPipe & echo $! > /tmp/catPipe.pid
soundAbsence.sh:
kill $(< /tmp/catPipe.pid) echo " " > /tmp/catPipe.pid
chmod +x soundDetect.sh soundAbsence.sh
Run cpiped w/ something like this: cpiped -d "hw:0,0" -s /home/user/soundDetect.sh -e /home/user/soundAbsence.sh -D /home/user/detectionPipe
forked-daapd should already be configured to auto start pipe and that is what you want in this scenario
extra: could also create a systemd unit for cpiped so that it auto starts at boot after say sound.target
@xiubert Awesome! I did the same and it's working great. Pics up the line-in when audio is playing and feeds the pipe, and when audio stops clears it so other (airplay) pipes can be played. Very very cool. I'd love to create a systemd "unit" for cpiped. That's also a bit beyond my skill set :)
I use something like below on Arch. I assume if your distro uses systemd it should work for you. Edit accordingly. systemctl start cpiped.service, systemctl status cpiped.service, if all good: systemctl enable cpiped.service
cat /etc/systemd/system/cpiped.service: [Unit] Description=cpiped After=sound.target
[Service] Type=forking KillMode=none User=forkedDAAPDusr ExecStart=/usr/local/bin/cpiped -d "hw:0,0" -s /home/forkedDAAPDusr/soundDetect.sh -e /home/forkedDAAPDusr/soundAbsence.sh -D /home/forkedDAAPDusr/detectionPipe ExecStop=/usr/bin/killall -9 cpiped WorkingDirectory=/home/forkedDAAPDusr
[Install] WantedBy=multi-user.target
@xiubert Worked great and came back up on its own upon reboot. Thank you!
It would be great if you would add a wiki page on this @xiubert!
Just wanted to add (for anyone else reading this), my Raspberry Pi Zero would work well the first time it detected sound, but would then jitter any subsequent times after. My setup is slightly different however as I have a record player plugged into the USB input of my Pi.
I'm not sure what was causing the jitter, but I think the second pipe was still receiving data somehow, but way out of my scope of knowledge. Restarting the Pi would fix it.
My fix was by creating a hard link between the detection pipe and the forked-daapd pipe on sound detection, and deleting that hard link on sound absence.
cpiped.service [Unit] Description=cpiped After=sound.target
[Service] Type=forking KillMode=none User=pi ExecStart=/usr/local/bin/cpiped -d "hw:1,0" -b 1 -s /home/pi/soundDetect.sh -e /home/pi/soundAbsence.sh -D /home/pi/detectionPipe ExecStop=/usr/bin/killall -9 cpiped WorkingDirectory=/home/pi
[Install] WantedBy=multi-user.target
soundDetect.sh
sudo ln /home/pi/detectionPipe /var/media/recordPlayer
soundAbsence.sh
sudo rm -rf /var/media/recordPlayer
I just need to work out now how to handle the rejection of the AppleTV turning off (it has a little bit of a freakout), and to reconnect on input (currently selects the first AirPlay device being my HomePod)
@sebkacz > My fix was by creating a hard link between the detection pipe and the forked-daapd pipe on sound detection, and deleting that hard link on sound absence.
Does it have to be a hard link? Would a symbolic work (and be friendlier in general)?
It would be great if you would add a wiki page on this @xiubert!
Since I did this setup from scratch and took notes, I made the how to page on the Wiki.
Very good instructions - thanks!
Those are slick @ayman ! Thanks for doing that. I'll likely be referring to them instead of my scattered notes when I get to it again.
@ayman nice writeup indeed! This setup has been working well for me. I'm now trying to do something similar on a shairport-sync endpoint device. The idea is a bit different in that I have an Echo Flex (or any analog output device really) that should always be sending Mic input out through the soundcard's output. This way I can ask the Echo questions, playback music by voice, etc, but then when I want to airplay to it, that works too. I've got it working but for some reason my arecord process just stops after a certain amount of time. I'll keep working on it, but I definitely like the idea of my source AND endpoints being able to use AUX input.
Thanks everyone. This thread was the only place that really revealed the solution; glad you liked the wiki writeup!
some reason my arecord process just stops after a certain amount of time
So arecord -d 0 ...
should just record forever; I actually had it die/timeout when my HiFiBerry DAC+ADC wasn't configured to clock slave mode for whatever reason. Maybe check the dt-overlay
settings of your ADC device if on a RPi which also needed an rpi-update
(roadblocked me for a week on that one which is why I dropped it at the bottom of the wiki).
First of all, thanks for the great writeup! I want my record player to play music on my HomePod and this seems to be the perfect solution. I managed to play the example mp3 file over forked-daapd to the HomePod and "arecord" worked as well (tested with music from my iPad over the audio cable to the raspi). Now with cpiped it kind of works but it is very pitched up... Does someone know what might be the problem here?
First of all, thanks for the great writeup! I want my record player to play music on my HomePod and this seems to be the perfect solution. I managed to play the example mp3 file over forked-daapd to the HomePod and "arecord" worked as well (tested with music from my iPad over the audio cable to the raspi). Now with cpiped it kind of works but it is very pitched up... Does someone know what might be the problem here?
likely a sample rate issue
edit: could be due to .asoundrc or some other existing alsa configuration
yes, but how/where could I fix it?
Thank you so much for that awesome writeup @ayman . Got it working perfectly even though it was my first ever rpi/linux project! I don't know if I did something wrong, but I had to create the /home/pi/.audioDetectPipe
pipe before it would work (in case that step simply has been forgotten in the wiki?).
On top of this I added quite a lot of extra stuff to handle my quirky usb-equipped vinyl player:
Please let me know if you want me to contribute to the wiki entry, I have everything noted down already as well as (really crappy I guess) code examples.
Please let me know if you want me to contribute to the wiki entry, I have everything noted down already as well as (really crappy I guess) code examples.
Please contribute! It's a wiki. I can't recall if i made that /home/pi/.audioDetectPipe
before or not (or if my dir had the right permissions to just let cpiped
make it already). I'm about to hook it up to my turntable, so please add notes and fixes. Thanks @Aeroform-se!
Hi all, I got everything to work from the wiki instructions but for some reason im not able to play the aux file in forked-daapd. It worked before configuring cpiped. after configuring cpiped the file is there but when I press play nothing happens even though my turntable is putting out audio. what can I do to troubleshoot?
I have a question about how you get the fifo to go in a reasonable place in the sorting list? My fifo winds up in 'Unknown artist,' Which means every time I want to play the truntable, I need to scroll all the way down, and then tap into Unknown and then find my fifo. Can anyone tell me how I can make it an album or an artisit so it will sort up at the top?
In answer to my last comment, I see it is a matter of adding these config options to the conf file:
CFG_STR("name_unknown_artist", "Unknown artist", CFGF_NONE), CFG_STR("name_unknown_album", "Unknown album", CFGF_NONE),
like
name_unknown_artist = "Analog Turntable"
or something. Still trying to understand how it all works
Yes, it isn't really documented, but you should be able to change the name by adding name_unknown_artist = "Analog Turntable"
to the library section of the config file. After you have done that and restarted the server, you will probably also have to trigger a rescan of the fifo which you can do with the command touch /path/to/pipe
. If that doesn't work then try a rescan (web interface > Update library > Rescan metadata for unmodified files).
Any particular reason you aren't using autostart of the pipe?
@mixographer I'd also highly recommend autostarting the pipe. In the case of using cpiped it's important to stop remove the pipe when it's not receiving audio, but that's all covered in the wiki I belive.
This is great, works wonders! I do have one issue if anyone would possibly know a solution. The audio seems to jump around at times, it will skip ahead a couple second every 35 second or so. Another issue is that the audio seems to be pitched down a bit. Any help would be appreciated, thanks!
I'm attempting to do something similar to 1liminal1 in this closed issue. I have a cheap bluetooth receiver with auxiliary output (most likely analog). It would be cool to add bluetooth connectivity as an option to my forked-daapd server, and right now I can stream to the BT receiver, which is connected to my USB DAC's mic input, capture that audio and pipe it into my forked-daapd library. FD picks up the pipe, but only once I manually enter a command to capture the audio and send it to the pipe.
arecord --device=plughw:CARD=Device,DEV=0 -f cd -t wav > /home/share/blueplay
My goal, since this is installed in our office, is to make it friendlier for non-iPhone users, or in times when our network gets jacked up, let bluetooth be a fallback option. Currently I'm using Shairport-sync as the airplay receiver that pipes to forked-daapd.
Here's what I'm wondering:
Some thoughts on the conf file:
this points me to the _ignore options, but the ignore options look like they'll exclude the pipe from showing in my library