Hello,
Not sure I will be able to formulate correctly my question, but Ill try.
MPD is a perfect platform as a music server. I currently connect this server to a Stm32 microcontroller through USB with Asynch feedback to change the time domain. The Stm32 then applies the DSP and generates several digital outputs (I2S or SPDIF).
Is there a "protocol" that would allow to skip the USB stage, to go over Ethernet, with a flow control by the client? Something existing for audio applications and featured in MPD, where the server would not be time reference but the "slave" of the client?
The client would be the responsible to time the thing, provide master clock, play at the right pace.
Best regards,
JMF
Not sure I will be able to formulate correctly my question, but Ill try.
MPD is a perfect platform as a music server. I currently connect this server to a Stm32 microcontroller through USB with Asynch feedback to change the time domain. The Stm32 then applies the DSP and generates several digital outputs (I2S or SPDIF).
Is there a "protocol" that would allow to skip the USB stage, to go over Ethernet, with a flow control by the client? Something existing for audio applications and featured in MPD, where the server would not be time reference but the "slave" of the client?
The client would be the responsible to time the thing, provide master clock, play at the right pace.
Best regards,
JMF
The primary clock is at the soundcard. In most setups the player is clocked by the soundcard. If not, some form of adaptive resampling must be deployed to align the two independent clock domains.
In your setup mpd is clocked by your stm32 clock generating the I2S output, propagated via USB async + linux blocking writes all the way to the thread reading the source data.
If you want an existing client-driven network protocol - jackd has a very precise (but network-consuming) protocol. Also pulseaudio implements a network protocol.
Or you can feed samples from mpd by pipes and netcat to your client. Piping is simple to do but sometimes player behave erratically - they cannot fastforward in the output buffer, cancel the playback etc. But perhaps it would not matter. Of course you must expect pretty large latency.
In your setup mpd is clocked by your stm32 clock generating the I2S output, propagated via USB async + linux blocking writes all the way to the thread reading the source data.
If you want an existing client-driven network protocol - jackd has a very precise (but network-consuming) protocol. Also pulseaudio implements a network protocol.
Or you can feed samples from mpd by pipes and netcat to your client. Piping is simple to do but sometimes player behave erratically - they cannot fastforward in the output buffer, cancel the playback etc. But perhaps it would not matter. Of course you must expect pretty large latency.
Sound like a solution based on Logitech Media Server (LMS) and a client running Squeezelite? Take a look at Daphile in combination with PiCorePlayer on a Raspberry Pi with USB-DAC or a HAT audio device. (Or if you want to use R-Pi at both ends: 2 PiCorePlayers: one acting as LMS server and one as squeezelite-player)Hello,
Not sure I will be able to formulate correctly my question, but Ill try.
MPD is a perfect platform as a music server. I currently connect this server to a Stm32 microcontroller through USB with Asynch feedback to change the time domain. The Stm32 then applies the DSP and generates several digital outputs (I2S or SPDIF).
Is there a "protocol" that would allow to skip the USB stage, to go over Ethernet, with a flow control by the client? Something existing for audio applications and featured in MPD, where the server would not be time reference but the "slave" of the client?
The client would be the responsible to time the thing, provide master clock, play at the right pace.
Best regards,
JMF
There are several solutions possible using LMS.
Last edited:
Hello,
Thanks for your feedbacks and ideas. I'm more looking to something like the proposal of phofman. A stm32 can only be a very thin client. It is not the idea to run a Linux on this , but to streamline things.
I should have a look at the jackd protocol. I would have looked for something even simpler, but I imagine that this is needed if implemented as support for jackd.
Best regards,
JMF
Thanks for your feedbacks and ideas. I'm more looking to something like the proposal of phofman. A stm32 can only be a very thin client. It is not the idea to run a Linux on this , but to streamline things.
I should have a look at the jackd protocol. I would have looked for something even simpler, but I imagine that this is needed if implemented as support for jackd.
Best regards,
JMF
IMO the easiest way is to implement the simple blocking read/write protocol as in netcat. Then you can use simple pipe from mpd. Of course a single byte loss can lead to misalignment of the samples and total sound corruption.
Another promising solution is to use HTTP server. I believe light-weight Express web
server from Node.js should be enough. On client side you can play files directly in
browser using Aurora codecs:
https://github.com/audiocogs/aurora.js/
This way you can currently play MP3, ALAC, FLAC and AAC:
Codecs — Audiocogs
server from Node.js should be enough. On client side you can play files directly in
browser using Aurora codecs:
https://github.com/audiocogs/aurora.js/
This way you can currently play MP3, ALAC, FLAC and AAC:
Codecs — Audiocogs
IIUC the client side is a small stm32 microprocessor which generally does not run linux and the client code must be programmed from scratch, likely in C.
Do you know bufhrt and playhrt?
It's small and well programmed linux utilities relying on the cpu high resolution timer (...hrt stands for high resolution timer). You can use bufhrt to send chunks of audio data over the net, and you can use playhrt to receive them and pass it over to a local soundcard. Very precisely clocked, as you can tweak the timing parameters.
I use both programs alongside an mpd pipe and they work well.
Have a look at frankl's stereo pages - Overview
The author of this software uses a minimalistic two-cpu-approach which is also worth to take a look at.
It's small and well programmed linux utilities relying on the cpu high resolution timer (...hrt stands for high resolution timer). You can use bufhrt to send chunks of audio data over the net, and you can use playhrt to receive them and pass it over to a local soundcard. Very precisely clocked, as you can tweak the timing parameters.
I use both programs alongside an mpd pipe and they work well.
Have a look at frankl's stereo pages - Overview
The author of this software uses a minimalistic two-cpu-approach which is also worth to take a look at.
I just skimmed the webpage without noticing - how does it handle the difference between client soundcard clock and the HR timer ticks in the server which is what the OP asks for? Does it adaptively adjust the HR timer ticks to zero the clock shift? I saw netcat on the client side, which has no feedback apart of blocking the reading which is IMO a bit too late if the player is timed by the HR timer instead.
Talking about bufhrt, which can also be used as a network buffer:
You have to specify the exact amount of bits/s the client needs by adapting a parameter named --extra-bytes-per-second on the server-sided bufhrt instance. Have a look at
http://frankl.luebecknet.de/frankl/stereoutils/player.html#extrabuf
There is also a possibiliby to de-couple the speeds of the server and the client completely by using the writeloop and catloop utilities from the same author:
http://frankl.luebecknet.de/frankl/stereoutils/player.html#pwritecat
... how does it handle the difference between client soundcard clock and the HR timer ticks in the server which is what the OP asks for ...?
You have to specify the exact amount of bits/s the client needs by adapting a parameter named --extra-bytes-per-second on the server-sided bufhrt instance. Have a look at
http://frankl.luebecknet.de/frankl/stereoutils/player.html#extrabuf
There is also a possibiliby to de-couple the speeds of the server and the client completely by using the writeloop and catloop utilities from the same author:
http://frankl.luebecknet.de/frankl/stereoutils/player.html#pwritecat
You have to specify the exact amount of bits/s the client needs by adapting a parameter named --extra-bytes-per-second on the server-sided bufhrt instance. Have a look at
frankl's stereo pages - Player
Well, that is not really a synchronization, but trying luck.
There is also a possibiliby to de-couple the speeds of the server and the client completely by using the writeloop and catloop utilities from the same author:
frankl's stereo pages - Player
A buffer does not decouple the speeds, just splits the chain into independent processes. If the consumer runs faster than the producer, no buffer helps. If it runs slower, the buffer eventually runs out of space. That is why JMF11 is looking for a protocol slaving the producer (software-based player) to the consumer (hardware-based soundcard). Just like any playback chain does it, only this time over network.
That looks like a very nice project. BTW the used synchro technology:
Time deviations are corrected by
* skipping parts or whole chunks
* playing silence
* playing faster/slower
Hi,
This type of time deviation management is the type of things that I wanted to avoid, as it alter the samples playing.
I wanted to see if there was a light and existing audio protocol where the master would be by design the time master, and the player would read the data at its pace, not having the data pushed to it at a predefined pace... ie read from the music server, over Ethernet, as if "reading from a file".
JMF
This type of time deviation management is the type of things that I wanted to avoid, as it alter the samples playing.
I wanted to see if there was a light and existing audio protocol where the master would be by design the time master, and the player would read the data at its pace, not having the data pushed to it at a predefined pace... ie read from the music server, over Ethernet, as if "reading from a file".
JMF
I understand, it is a crude (but very efficient 🙂 ) way of synchronization.
The netcat blocking pipe is IMO the easiest protocol. The consumer reads samples from the network incoming buffer at the pace of the soundcard. Once the buffer has free space, the protocol notifies the producer (netcat) to send more samples. Netcat sends the samples and notifies the input pipe which in turn wakes-up the writing thread of the player, just like the driver of a real soundcard does when it receives IRQ from the soundcard.
I have no experience with STM32, but the lwip implementation https://github.com/mikeferguson/stm32/tree/master/libraries/lwip looks rather comprehensive to handle this task.
The netcat blocking pipe is IMO the easiest protocol. The consumer reads samples from the network incoming buffer at the pace of the soundcard. Once the buffer has free space, the protocol notifies the producer (netcat) to send more samples. Netcat sends the samples and notifies the input pipe which in turn wakes-up the writing thread of the player, just like the driver of a real soundcard does when it receives IRQ from the soundcard.
I have no experience with STM32, but the lwip implementation https://github.com/mikeferguson/stm32/tree/master/libraries/lwip looks rather comprehensive to handle this task.
- Status
- Not open for further replies.
- Home
- Source & Line
- PC Based
- A protocol to "pull" samples from a MPD server over ethernet?