[alsa-devel] Control the exact moment of output
For a distributed system that requires synchronized output I would like to determine the exact moment when output samples are sent, preferably within +/- 1 sample time. For example, output is sent in blocks with a system time in usec or nsec as a parameter or header, and the the first sample leaves the soundcard as closely as possible to the specified system time.
Is this possible within the ALSA API? Low latency is of course nice to have, but not the prime concern. What I need is synchronous output between systems that are physically separated and need to send audio that they receive from a central system over the network. My intention is to send blocks of audio with an accurate time of transmission in the header, and then have the systems output it exactly at that time, of course preferably managed mostly by the driver, not the application.
Are some types of soundcard more suitable than others for this purpose? And are there soundcards available where the sample clock can somehow be locked to system time or an external 10MHz/1PPS reference?
Rob
Rob Janssen wrote:
For a distributed system that requires synchronized output I would like to determine the exact moment when output samples are sent, preferably within +/- 1 sample time.
Is this possible within the ALSA API?
In theory, yes; snd_pcm_delay() should take these latencies into account.
In practice, there is no hardware where this value is accurate. Drivers with large latencies (e.g., USB) report their internal queues, but nobody bothers for the small delays (about 10 samples) in the DMA controllers and DACs.
Are some types of soundcard more suitable than others for this purpose?
PCI(e) cards have lower latencies, but if you configure two USB devices with the same parameters, the driver's queues will have the same length.
And are there soundcards available where the sample clock can somehow be locked to system time or an external 10MHz/1PPS reference?
Some cards can be locked to an S/PDIF input or to a word clock from another sound card. This does not work for physically separated outputs; you'd have to measure the clock differences and do dynamic resampling.
Regards, Clemens
Clemens Ladisch wrote:
Rob Janssen wrote:
For a distributed system that requires synchronized output I would like to determine the exact moment when output samples are sent, preferably within +/- 1 sample time.
Is this possible within the ALSA API?
In theory, yes; snd_pcm_delay() should take these latencies into account.
In practice, there is no hardware where this value is accurate. Drivers with large latencies (e.g., USB) report their internal queues, but nobody bothers for the small delays (about 10 samples) in the DMA controllers and DACs.
Ok, thanks for the reply! We will use PCI soundcards, not USB dongles, and it is not a problem when there is a fixed extra delay that is the same for all the systems. What we need to control is the synchronization between the physically separated systems, and my approach up to now is to do this by synchronizing to the very precise system time derived from GPS.
I was thinking along the line of an API feature where one can send frames with a related moment of playback, but now I realize that what I should do is calculate how far off the desired playback moment we are (using the current system time, the desired playback time, and the snd_pcm_delay) for each block, and then pad or trim some frames as required before sending the block. Is that correct?
And are there soundcards available where the sample clock can somehow be locked to system time or an external 10MHz/1PPS reference?
Some cards can be locked to an S/PDIF input or to a word clock from another sound card. This does not work for physically separated outputs; you'd have to measure the clock differences and do dynamic resampling.
We would have to generate a word clock or S/PDIF signal from the 10MHz/1PPS we have available from the GPS (which are synchronous on all the sites). That will be the next step when the first approximation does not yield us enough perfection.
Rob
On Tue, April 29, 2014 6:25 pm, Rob Janssen wrote:
Clemens Ladisch wrote:
Rob Janssen wrote:
For a distributed system that requires synchronized output I would like to determine the exact moment when output samples are sent, preferably within +/- 1 sample time.
Is this possible within the ALSA API?
In theory, yes; snd_pcm_delay() should take these latencies into account.
In practice, there is no hardware where this value is accurate. Drivers with large latencies (e.g., USB) report their internal queues, but nobody bothers for the small delays (about 10 samples) in the DMA controllers and DACs.
Ok, thanks for the reply! We will use PCI soundcards, not USB dongles, and it is not a problem when there is a fixed extra delay that is the same for all the systems. What we need to control is the synchronization between the physically separated systems, and my approach up to now is to do this by synchronizing to the very precise system time derived from GPS.
I was thinking along the line of an API feature where one can send frames with a related moment of playback, but now I realize that what I should do is calculate how far off the desired playback moment we are (using the current system time, the desired playback time, and the snd_pcm_delay) for each block, and then pad or trim some frames as required before sending the block. Is that correct?
And are there soundcards available where the sample clock can somehow be locked to system time or an external 10MHz/1PPS reference?
Some cards can be locked to an S/PDIF input or to a word clock from another sound card. This does not work for physically separated outputs; you'd have to measure the clock differences and do dynamic resampling.
We would have to generate a word clock or S/PDIF signal from the 10MHz/1PPS we have available from the GPS (which are synchronous on all the sites). That will be the next step when the first approximation does not yield us enough perfection.
Have you looked into netjack?
Several of the network timing issues have been worked through quite extensively. We have used it to distribute data across several machines in a cluster and find it to be very stable and workable with acceptable latency over gigbit lan.
You might find netjack gives you a good headstart on this project.
Adding support for JACK is a minor task compared to rewriting (and testing) netjack. You will also gain access to a host of other professional functionality and ALSA, OSS, FIrewire support too.
In addition your software will play nice with other professional software and have direct access to data on the JACK graph as a bonus.
-- Patrick Shirkey Boost Hardware Ltd
Patrick Shirkey wrote:
Have you looked into netjack?
Several of the network timing issues have been worked through quite extensively. We have used it to distribute data across several machines in a cluster and find it to be very stable and workable with acceptable latency over gigbit lan.
You might find netjack gives you a good headstart on this project.
Adding support for JACK is a minor task compared to rewriting (and testing) netjack. You will also gain access to a host of other professional functionality and ALSA, OSS, FIrewire support too.
In addition your software will play nice with other professional software and have direct access to data on the JACK graph as a bonus.
Thanks for the pointer! It indeed appears that this project is trying the same thing as we are doing.
It will require some further study. Documentation appears to be scarce, I have not been able to locate a document yet that describles what it actually achieves and what caveats there are. I saw one thing on the Wiki: it transmits data all the time. We will probably need some form of on/off control to avoid wasting bandwidth, but maybe it can be done in a CODEC.
I also saw it has fixed network latency setting, while I had already envisioned a system for automatically determining the added latency based on feedback from the remotes.
But at least it provides a lot of insight into using Alsa in timing critical applications, something I had been looking for.
(I know that writing documentation is a drag, but projects like Alsa and this one would be so much more useful and accessible when there would be more detailed documentation that goes beyond an installation HOWTO and a plain listing of available functions and parameters)
Rob
participants (3)
-
Clemens Ladisch
-
Patrick Shirkey
-
Rob Janssen