the DIY Streaming Audio Thread

Status
This old topic is closed. If you want to reopen this topic, contact a moderator using the "Report Post" button.
After messing some time with VLC and its scary learning curve, i recently stumbled with this...

Hipster music player: when MPD is just too mainstream - Bytopia.org

... and discovered how simple it is to send a stream from my turntables/cd players to any speaker in the house without overkill solutions like MPD or VLC.

sox -r 44100 -b16 -c2 -t alsa hw:0,0 -t flac - | sshpass -p 'pi' ssh pi@192.168.1.41 sox -t flac - -t alsa hw:2,1

SSH for TCP ( no data lost...) streaming in flac from a capturing RPI to another playing RPI seems to be more than enough...:p

Are both Pis using Wireless networking?

Thanks for posting the command line... I will definitely be checking out sshpass.

There seems to be several ways to successfully send audio over a network to ONE client. When you have multiple clients involved, things get a lot more complicated... I have only been successful using RTP to control playback speed (keep everything in sync) across multiple clients.
 
For the moment i have been testing both rpis wire connected. On the source side i have fixed places devices like cd player or turntables, but on the playing side it also might be convenient to use also wireless connections. Will check.

BTW, I like the idea of "wifi speakers" you seem to be after, but the way of getting proper tight sync between devices is well over my skills...:eek:

Anyway, it is nice to experiment. HTTP streaming with VLC is interesting because the stream is available all around the house ( though not in a synced way...), but i find pushing the audio to one slave renderer with SSH is also interesting for sending audio from one source to another on a network.
 
Last edited:
sox -r 44100 -b16 -c2 -t alsa hw:0,0 -t flac - | sshpass -p 'pi' ssh pi@192.168.1.41 sox -t flac - -t alsa hw:2,1

The capturing part is timed by the capturing soundcard, while the playback part by the playback card. The two clocks will eventually shift apart so much that the difference will exhaust the buffers within the chain (in soxes, in pipes, in soundcard DMA buffers) and xruns will occur. How long it will take depends on the actual clock difference, It could be hours, or even days but it will happen. It may happen in normal use the stream will never be so long for the buffer underrun to occur.
 
The capturing part is timed by the capturing soundcard, while the playback part by the playback card. The two clocks will eventually shift apart so much that the difference will exhaust the buffers within the chain (in soxes, in pipes, in soundcard DMA buffers) and xruns will occur. How long it will take depends on the actual clock difference, It could be hours, or even days but it will happen. It may happen in normal use the stream will never be so long for the buffer underrun to occur.

I wonder if this applies just to under runs? If it is the source clock that is fractionally faster might we be able to rely on flow control to handle this for us?

For under runs it seems reasonable that, as you say, buffers may not be enough. I see that sox has a configurable buffer size although I don't know what range of values it can accept. We could even put in the pipe some utility providing arbitrary sized buffering through a memory mapped file but as you say any size buffer eventually gets exhausted - even if it takes years :) I'm sure that isn't a practical solution though as for enormous buffers it would take ages to start or stop playing while the buffer fills or empties.
 
I'm sure that isn't a practical solution though as for enormous buffers it would take ages to start or stop playing while the buffer fills or empties.

Well, i have just been playing with this new toy during the week end and it seems that the default buffers i am using are storing about 10s of music and this seems to allow a few hours of uninterrupted playing.

I admit that such latency is not acceptable for guys constantly zapping tracks from a cd or a playlist, but for playing LP's i find it more than convenient enough. To play safe i even might restart the SSH session while changing the face of the LP. We analog guys have plenty of time...:p

Btw, plenty of time... except for ripping anything, nor maintaining these monstruous terabyte music libraries and the hell of the tagging, etc...!:D
 
Last edited:
This delay is fine enough, though a bit too short, considering the time i need to come from the room where i have settled my collection of turntables, back to the living room where i do the listenning.:D

Btw, i had similar delay when creating an http stream with VLC.
 
I wonder if this applies just to under runs? If it is the source clock that is fractionally faster might we be able to rely on flow control to handle this for us?

The clocks in both soundcards are running continuously, there is no room for lossless corrections. If the input clock runs faster, the chain will not keep up with reading samples from the input circular DMA buffer and the soundcard will either be halted or overwrite the yet unread samples with new ones.
 
The clocks in both soundcards are running continuously, there is no room for lossless corrections. If the input clock runs faster, the chain will not keep up with reading samples from the input circular DMA buffer and the soundcard will either be halted or overwrite the yet unread samples with new ones.

Yes, but suppose that both soundcards are clocked by their respective computer in isosynchronous/adaptative mode ( as currently my case ), won't the TCP keep the 2 machines in sync?

Btw, i have launched my current session more than 8 hours ago and everything still ok...
 
Last edited:
USB adaptive mode is clocked by the USB controller hardware clock, independent of any software.

Unless the input source is SPDIF stream, then the actual input clock is the clock of the spdif output transmitter and the adaptive input receives variable number of samples in each frame).

10 secs buffer is very large, no wonders it will take many hours (days?) to glitch. If your latency requirements are that loose, you do not have to worry about independent clocks drifting apart and you can use plain pipes just fine.
 
Yes amazing stuff...:eek: Plenty of tricks to learn in these pages, thanks!:cool:

For network streaming it is really important to keep the timing of output stream as precise as possible. But I do not see validity of the timing arguments for direct soundcard output. The output stage is always timed by the soundcard clock and from the DAC clock jitter POW it makes no difference if the batch copying samples to RAM DMA buffer is started by an interrupt thrown by a timer, or by an interrupt thrown by the actual soundcard. The DMA reading pointer is always controlled by the soundcard.

Honestly, I do not accept the non-technical voodoo claims of jplay and the likes...
 
Honestly, I do not accept the non-technical voodoo claims of jplay and the likes...

Well, i don't see why i should matter about audiophile players, nas, routers and stuff like that... I have not the technical background nor the golden ears... Definitely not the tasty picky fine *** discerning audio freak...:deer:

I simply found command lines like...

ORIGRATE=`sox --i "$1" | grep "Sample Rate" | cut -d: -f2 | sed -e "s/ //g"`
...
sox -t flac - -t raw -r ${ORIGRATE} -c 2 -e float -b 64 - | \...

... quite enlightening for a linux audio beginner as me...:cool:
 
The clocks in both soundcards are running continuously, there is no room for lossless corrections. If the input clock runs faster, the chain will not keep up with reading samples from the input circular DMA buffer and the soundcard will either be halted or overwrite the yet unread samples with new ones.

Forgive me if I'm missing something fundamental here as I'm only just getting started in computer audio, but if the problem is the two clocks have no way of coping with differences why use two clocks?

If we are sending from one pi to another, as seems to be the example quoted, instead of sending a clocked music stream why not send the file with netcat or similar to a remote invocation of aplay or whatever your preferred music file player is so there is only one clock at the target end and the stream is sent as a buffered, flow controlled, data stream?
 
...why not send the file with netcat or similar to a remote invocation of aplay or whatever your preferred music file player is so there is only one clock at the target end and the stream is sent as a buffered, flow controlled, data stream?

May be i am also missing something, but my feeling is that this is precisely what i have been doing during the last sunday...:rolleyes:

Btw, will close now that everlasting ssh session: i am paying the bill for electric supply!:D
 
If we are sending from one pi to another, as seems to be the example quoted, instead of sending a clocked music stream why not send the file with netcat or similar to a remote invocation of aplay or whatever your preferred music file player is so there is only one clock at the target end and the stream is sent as a buffered, flow controlled, data stream?

That is very true. I was referring to this sox example

sox -r 44100 -b16 -c2 -t alsa hw:0,0 -t flac - | sshpass -p 'pi' ssh pi@192.168.1.41 sox -t flac - -t alsa hw:2,1

which does not read from a file, but captures from a running soundcard (hw:0,0) on the source machine.

But again, if the buffers (thus also latency) are large enough, it is OK for non-continuous playback.
 
May be i am also missing something, but my feeling is that this is precisely what i have been doing during the last sunday...:rolleyes:

Btw, will close now that everlasting ssh session: i am paying the bill for electric supply!:D

Unless I have read it wrong I think your setup is Some_Music_File -> Some_music_App -> Alsa -> Sox -> sshpass to 2nd Pi -> sox -> Alsa. i.e. you are generating a clocked music stream at source and transferring this to the second pi with its own clock.

I was considering the alternate approach of sending the raw (unclocked) file to a music player on the second pi hence avoiding all clock difference issues. i.e. Some_Music_file -> (sshpass or netcat or other utility) to second pi -> (aplay or some other preferred mucic player). Alternatively you could put the music file on a network drive and then simply send the command to the second pi to play it thus avoiding the whole transfer control bit?

Lots of choices :)
 
Unless I have read it wrong I think your setup is Some_Music_File -> Some_music_App -> Alsa -> Sox -> sshpass to 2nd Pi -> sox -> Alsa. i.e. you are generating a clocked music stream at source and transferring this to the second pi with its own clock.

First i am not reading from a file, but recording a live music program ( LP's) from the input of a soundcard. Second, i don't think i am sending any clocked digital audio from one pi to the other, but rather packed data taken on some buffer on the recording pi which is copied or transported by TCP to another buffer on the receiving side.

I suppose, on the receiving side Sox reads the buffer expecting to find data corresponding to a flac audio stream, but i don't think that there is any timing info in these data. The data are simply stacked in chronological order and without losses in a receiving buffer and sox, if provided by the command line the right parameters will make a properly clocked audio stream.

So i guess, as commented by Phofman, the size of the buffers is what avoids failures due to the slight difference of speed of the 2 clocks. I have no idea about how TCP manages this buffering, but i guess it will do that the same way transporting audio, video, text, images, of whatever kind of data. I think TCP has no idea of the nature of the data it transports, nor this matters at all.:rolleyes:
 
Last edited:
Status
This old topic is closed. If you want to reopen this topic, contact a moderator using the "Report Post" button.