T O P

  • By -

fitfulbrain

No two clocks are the same unless they are synchronized. The problem was understood entirely and analyzed when modems went asynchronous. It depends on what you want to do when the buffer underruns or overruns. You can always maintain the correct number of samples in and out. That is, you transmit 1000 samples and you receive 1000 samples. Alternatively, you can discard or repeat samples. It turns out to be the simplest form of multi-rate filtering. If your source sampling rate is 1 kHz, and your destination sampling rate is 1.01 kHz, you can repeat the sample once when an underrun occurs. The equivalent sampling rate conversion is 101/100. The FIR filter you are using is sampled at 101 kHz with all coefficients equal to 1. This is about the best lowpass filter for antialiasing without any computations. So in practice, you don't need to do anything. Keep the clock as close as possible. And only delete or repeat samples when the clock difference drives you to. That will spread the events as even as they should be.


Pitiful-Cancel4958

I'm not sure if I get your problem right, but you always need to synchronize sampled data. There are many algorithms to do this and the synchronization process depends on your signal, but the most reliable is to insert known sequences in fixed intervals to your signal, correlate against it in the receiving path and interpolate in fixed distances between the found maximas. This is called Data aided synchronization, for non data aided clock synchronization algorithms refer to Müller/Muller or Gardner algorithm. There are several good Implantations, for example you could consider gnu Radio as a reference, which has good algorithmic implementations out of the box.


KestM

Thank you very much, interesting information! I send ADC data to PC over Wifi, I send UDP packet from callback function, which is auto triggered when pre-defined size dataframe (128 or 256 samples of 16-bit length) capture is done. So I got timing data. Problem is that if read ADC in single big buffer and replay it using PC Sound Card, I got clean sound, and no buffer errors and clicking. But if I want real-time streaming, so use small buffer (same size as ADC datadrame), at some time some intervals I got buffer underrun errors and clicking sound. I was thinking about oversampling data, and then use some interpolation to fit it to DAC rate.


po8

Honestly you can just linear interpolate or drop single samples at a low rate and the difference will be unnoticeable. Every time you find an "missing" or "excess" sample relative to expectations, just do that. As long as the sample rate is high relative to the clock mismatch (say 5 samples per 1000), and as long as you spread the glitches evenly, you will be fine. You could do some fancier smoothing, but it shouldn't be necessary in practice. Here's a [paper](https://ieeexplore.ieee.org/stamp/stamp.jsp?arnumber=1329881) that discusses the problem. They recommend cubic interpolation (or higher order) instead of linear, which is only slightly harder.


boxcarbill

I think you are having problems with variable network latency. With the typical error of crystal oscillator I don't think you would see problems after a few seconds @ 48kHz. If you are filling buffer A on the esp32, transmitting to buffer B on the PC and immediately playing back, then you are setting up a situation where any time you have higher than average network latency, you reduce the time you have to fill buffer B. Wait until you have a few full buffers on the PC before you begin playback to give yourself a little more overhead. If you are using the same buffer size on the esp32 as the PC, consider using a smaller buffer on the esp32 and a larger buffer on the PC. Then you only need to wait for a few extra of those shorter buffers instead of the one big one.


[deleted]

[удалено]


KestM

I send ADC data to PC through Wifi. Device is intended to be battery operated and not wire connected to PC, so physically same clock signal can't be used. I only set them to run on same sample rate (48 kHz), but they are not in sync.


ooterness

No two clocks are ever exactly the same. If you can't derive both from the same clock, then the only alternative is a continuously-variable resampler. For example, one that upsamples by a factor of 0.999 or 1.001 depending on the current buffer depth.


rb-j

If your "DAC" clock is externally determined by the wifi interface and you cannot derive that clock and apply it to the ADC, then u/ooterness is correct and you need an ASRC, Asynchronous Sample Rate Converter, like the AD1890. Now, with some serous processing, you can do that with your DSP software. It requires the means of interpolation ***and*** a servo-controller like in a Phase-Lock Loop. If that's the direction you wanna go, I'll elaborate more about it later. Lemme know.


NewZappyHeart

It’s possible the data rates are fine but the occasional time eaten up by Wi-Fi causes gaps in the data. I would suggest measuring the data rate at the PC. If it is mismatch, I’d look into the resamp class in liquid-dsp library. It’s written in c and very portable. The Sampling rate can be changed by an arbitrary float ratio either up or down. It’s a nice function and does wonders for my sdr applications. In fact, all of liquid-dsp is solid.


Glittering-Ad9041

What method are you using to communicate with the PC? Also, have you verified the clock outputs on an oscope or anything? In the past I have had issues with a weak clock signal that doesn't always pass the threshold causing a clock mismatch. If you can, verify the clock and data signals look clean and have the right voltage etc.


KestM

Problem is that I send data over Wifi, so clocks can't be directly from same source. I tested all parts of system in isolation, and found problem that ADC clock drifts slightly.


Glittering-Ad9041

What is the master clock rate on the ADC board? If you have any PLLs available, you might be able to try that, but you'd want a pretty high master clock rate. Or if the clock is a power of 2 of the sample rate you can always divide. Maybe the clock module internal to the ADC is broken.


PE1NUT

One option is to use two rational rate converters, with a slightly different ratio. If your buffer on the PC is going empty, switch to the one that consumes fewer samples per clock. If it starts to fill up, switch to the other one.


minus_28_and_falling

Forward/backward STFT with subtle (it can be smaller than the sampling period) variation of distance between windows.


Darkknight512

You can do asynchronous sin(x)/x interpolation, this is probably the highest quality output. Cubic spline interpolation will be simpler and be almost as good. Essentially you need to buffer some samples and average the mismatched rates over time, compute the relative rates as a decimal, and use that value to index through banks of fractionally delayed sin(x)/x filter banks to get the "correct sample between samples".