qradiolink / MMDVM-SDR

MMDVM fork for usage with SDR devices (supports DMR tier III trunked radio)
https://qradiolink.org/docs/MMDVM/MMDVM.html
GNU General Public License v2.0
7 stars 2 forks source link

Sample output excessively high during DMR TX #2

Open craftxbox opened 9 months ago

craftxbox commented 9 months ago

At idle, the ZMQ socket will supply ~25,000 empty samples per second, however, when MMDVMHost pushes mmdvm-sdr into tx mode, the samples per second will jump to on average, 1.9 million samples per second. The upstream repo, however, pushes zero samples when idle and only pushes ~24,000 samples when in TX.

I'm not overly familiar with Gnuradio and ZMQ usage, but I have a thought that this may be because of the usage of ZMQ_REP instead of ZMQ_PUSH as the upstream does. Is this behaviour intentional? How can we limit the speed at which samples are obtained?

kantooon commented 9 months ago

I wrote both the ZeroMQ upstream code and this one, so I can explain the issue. In original MMDVM, the transmit timing is controlled by ADC/DAC hardware interrupts.

With those removed, the DMR TX code will run as fast as it can and output samples continuously as long as the buffer has space for them. This was also the reason why the socket type was switched from PUSH to REQ/REP.

In this version, transmit timing is driven by qradiolink and the GNU Radio source (it is desirable to let the SDR hardware drive the timing, but the GNU Radio scheduler has a behaviour where it will run the source as fast as it can while downstream buffers are not filled so an additional constraint was used, the state of the Lime FIFO and then later the value of DMR slot time to support Ettus USRP).

If you implement timing control in MMDVM-SDR you will end up having two sources of timing, leading to an inevitable two-clock problem and sample rate mismatch.

The implementation chosen here is described in more detail at this page: https://qradiolink.org/multicarrier-transceiver-DMR-YSF-M17-with-MMDVM-and-LimeSDR.html

If you intend to use MMDVM-SDR without qradiolink, you will need to supply your own timing control mechanism in the consumer of ZeroMQ samples, and you will need to request and consume exactly 720 samples every 30 msec. It does not matter whether you request too fast or too slow in one iteration as you can adjust the time in the next iteration, as long as the overall sample rate of 24k is maintained. Actual RF transmit time is precisely adjusted at the FPGA based on timestamps so you need not worry about that.

craftxbox commented 9 months ago

Thanks for the info, I am indeed trying to run this without qradiolink. My experimentation has mainly been with trying to integrate this with rpitx, so I'm not entirely certain how to control for timing in that case.

kantooon commented 9 months ago

In that case, you will need to implement your own timing mechanism either in the consumer of ZeroMQ samples (keeping the REQ/REP pattern) or in MMDVM-SDR (and switch to PUSH/PULL). You'll probably find it easier in the first case.

Anyway, I doubt you will achieve precise timeslot synchronization without a hardware source of time that applies to both the receiver and the transmitter. If you don't care about receiving both timeslots as specified by ETSI, you will only be able to receive one timeslot like r4d10n's mmdvm-sdr does but you can transmit both timeslots.

craftxbox commented 9 months ago

So far, switching to r4d10n's version w/ the PUSH/PULL has gotten me samples that decode properly in local testing (with dsd-fme), though something about my setup is wrong as after transmit & recieving with an RTL-SDR, decode is very intermittent and full of decode errors.

I'm not worried about RX as I was planning to use DSD-FME for that part anyway.

kantooon commented 9 months ago

Two things: buffer one timeslot worth of samples and send them all at once via zmq, and second, make sure you are not off-frequency by more than 100-200 Hz, the correlation algorith is sensitive to being off-frequency.