usrp-users@lists.ettus.com

Discussion and technical support related to USRP, UHD, RFNoC

View all threads

Align multi-channel captures with different rx_stremers

Z
zackkomo@utexas.edu
Tue, Feb 6, 2024 10:04 PM

Hello!

I am trying to do something very similar to the rx_samples_to_file example here. In this script, if multithreading is selected, then a different call to recv_to_file spawns for each channel, which in turn creates a different rx_streamer for each channel.

I modified the code to specify the uhd::time_spec_t that feeds to each stream_cmd.time_spec, outside the loop so that the streaming start time for each channel is identical.

I have only tried with 2 channels so far. I have a GPS L1 signal connected to each port corresponding to my 2 channels, and I am using a USRP X410. If I capture at the same rate for both channels, I show that they start at an identical time (to the nearest ns). When I change the rate of the second channel, I then have a difference of about 732ns.

The rates I choose are 9830400 Msps and 20480000 Msps. These correspond to the master clock rate of 245760000 divided by 25 and 12 respectively.

Does anyone have an idea as to how to align the captures?

Thanks!

Hello! I am trying to do something very similar to the rx_samples_to_file example [here](https://github.com/EttusResearch/uhd/blob/master/host/examples/rx_samples_to_file.cpp). In this script, if multithreading is selected, then a different call to recv_to_file spawns for each channel, which in turn creates a different rx_streamer for each channel.\ \ I modified the code to specify the uhd::time_spec_t that feeds to each stream_cmd.time_spec, outside the loop so that the streaming start time for each channel is identical. I have only tried with 2 channels so far. I have a GPS L1 signal connected to each port corresponding to my 2 channels, and I am using a USRP X410. If I capture at the same rate for both channels, I show that they start at an identical time (to the nearest ns). When I change the rate of the second channel, I then have a difference of about 732ns. The rates I choose are 9830400 Msps and 20480000 Msps. These correspond to the master clock rate of 245760000 divided by 25 and 12 respectively. Does anyone have an idea as to how to align the captures? Thanks!
MD
Marcus D. Leech
Tue, Feb 6, 2024 10:12 PM

On 06/02/2024 17:04, zackkomo@utexas.edu wrote:

Hello!

I am trying to do something very similar to the rx_samples_to_file
example here
https://github.com/EttusResearch/uhd/blob/master/host/examples/rx_samples_to_file.cpp.
In this script, if multithreading is selected, then a different call
to recv_to_file spawns for each channel, which in turn creates a
different rx_streamer for each channel.

I modified the code to specify the uhd::time_spec_t that feeds to each
stream_cmd.time_spec, outside the loop so that the streaming start
time for each channel is identical.

I have only tried with 2 channels so far. I have a GPS L1 signal
connected to each port corresponding to my 2 channels, and I am using
a USRP X410. If I capture at the same rate for both channels, I show
that they start at an identical time (to the nearest ns). When I
change the rate of the second channel, I then have a difference of
about 732ns.

The rates I choose are 9830400 Msps and 20480000 Msps. These
correspond to the master clock rate of 245760000 divided by 25 and 12
respectively.

Does anyone have an idea as to how to align the captures?

Thanks!


USRP-users mailing list --usrp-users@lists.ettus.com
To unsubscribe send an email tousrp-users-leave@lists.ettus.com

There's a timestamp associated with each sample buffer that comes back
from a _recv() call.   That is often used for alignment,
  although with differing sample rates, alignment cannot be perfect.

On 06/02/2024 17:04, zackkomo@utexas.edu wrote: > > Hello! > > I am trying to do something very similar to the rx_samples_to_file > example here > <https://github.com/EttusResearch/uhd/blob/master/host/examples/rx_samples_to_file.cpp>. > In this script, if multithreading is selected, then a different call > to recv_to_file spawns for each channel, which in turn creates a > different rx_streamer for each channel. > > I modified the code to specify the uhd::time_spec_t that feeds to each > stream_cmd.time_spec, outside the loop so that the streaming start > time for each channel is identical. > > I have only tried with 2 channels so far. I have a GPS L1 signal > connected to each port corresponding to my 2 channels, and I am using > a USRP X410. If I capture at the same rate for both channels, I show > that they start at an identical time (to the nearest ns). When I > change the rate of the second channel, I then have a difference of > about 732ns. > > The rates I choose are 9830400 Msps and 20480000 Msps. These > correspond to the master clock rate of 245760000 divided by 25 and 12 > respectively. > > Does anyone have an idea as to how to align the captures? > > Thanks! > > > _______________________________________________ > USRP-users mailing list --usrp-users@lists.ettus.com > To unsubscribe send an email tousrp-users-leave@lists.ettus.com There's a timestamp associated with each sample buffer that comes back from a _recv() call.   That is often used for alignment,   although with differing sample rates, alignment cannot be perfect.
Z
zackkomo@utexas.edu
Tue, Feb 6, 2024 10:23 PM

If I do thing concurrently (same thread, same rx_streamer) would that solve the timing issue? For example:

stream_args.channels = { 0, 1};
uhd::rx_streamer::sptr rx_stream = usrp_->get_rx_stream(stream_args);
size_t num_rx_samps =
                rx_stream->recv(buffs, samps_per_buff_, md, timeout, one_packet);

Where buffs is a collection of receive buffers.

It would become a little awkward with different sampling rates, but would this potentially solve the timing issue?

If I do thing concurrently (same thread, same rx_streamer) would that solve the timing issue? For example: ``` stream_args.channels = { 0, 1}; ``` ``` uhd::rx_streamer::sptr rx_stream = usrp_->get_rx_stream(stream_args); ``` ``` … ``` ``` size_t num_rx_samps = ``` ```                 rx_stream->recv(buffs, samps_per_buff_, md, timeout, one_packet); ``` Where buffs is a collection of receive buffers. It would become a little awkward with different sampling rates, but would this potentially solve the timing issue?
RK
Rob Kossler
Tue, Feb 6, 2024 10:44 PM

You mentioned a difference of 732ns. Is this a measured difference or is
this the difference in the timestamps contained in the metadata for the 2
streams?

On Tue, Feb 6, 2024 at 5:23 PM zackkomo@utexas.edu wrote:

If I do thing concurrently (same thread, same rx_streamer) would that
solve the timing issue? For example:

stream_args.channels = { 0, 1};

uhd::rx_streamer::sptr rx_stream = usrp_->get_rx_stream(stream_args);

size_t num_rx_samps =

             rx_stream->recv(buffs, samps_per_buff_, md, timeout, one_packet);

Where buffs is a collection of receive buffers.

It would become a little awkward with different sampling rates, but would
this potentially solve the timing issue?


USRP-users mailing list -- usrp-users@lists.ettus.com
To unsubscribe send an email to usrp-users-leave@lists.ettus.com

You mentioned a difference of 732ns. Is this a measured difference or is this the difference in the timestamps contained in the metadata for the 2 streams? On Tue, Feb 6, 2024 at 5:23 PM <zackkomo@utexas.edu> wrote: > If I do thing concurrently (same thread, same rx_streamer) would that > solve the timing issue? For example: > > stream_args.channels = { 0, 1}; > > uhd::rx_streamer::sptr rx_stream = usrp_->get_rx_stream(stream_args); > > … > > size_t num_rx_samps = > > rx_stream->recv(buffs, samps_per_buff_, md, timeout, one_packet); > > Where buffs is a collection of receive buffers. > > It would become a little awkward with different sampling rates, but would > this potentially solve the timing issue? > _______________________________________________ > USRP-users mailing list -- usrp-users@lists.ettus.com > To unsubscribe send an email to usrp-users-leave@lists.ettus.com >
Z
zackkomo@utexas.edu
Tue, Feb 6, 2024 10:50 PM

It’s an estimated difference using a GPS SDR I have access to, not the timestamps in the metadata.

I just tired choosing different sampling rates, it seems like when I use pairs of sampling rates corresponding to odd divisions of the master clock rate, it works fine. Similarly when I choose even pairs. Choosing a sampling rates corresponding to odd and even though causes a mismatch.

It’s an estimated difference using a GPS SDR I have access to, not the timestamps in the metadata.\ \ I just tired choosing different sampling rates, it seems like when I use pairs of sampling rates corresponding to odd divisions of the master clock rate, it works fine. Similarly when I choose even pairs. Choosing a sampling rates corresponding to odd and even though causes a mismatch.
MD
Marcus D. Leech
Wed, Feb 7, 2024 12:53 AM

On 06/02/2024 17:23, zackkomo@utexas.edu wrote:

If I do thing concurrently (same thread, same rx_streamer) would that
solve the timing issue? For example:

|stream_args.channels = { 0, 1};|
|uhd::rx_streamer::sptr rx_stream = usrp_->get_rx_stream(stream_args);|
|…|
|size_t num_rx_samps =|
|                rx_stream->recv(buffs, samps_per_buff_, md, timeout,
one_packet);|

Where buffs is a collection of receive buffers.

It would become a little awkward with different sampling rates, but
would this potentially solve the timing issue?

All the steams in a streamer must be at the same sample-rate from what I
recall.

One of the semantics in a streamer is that UHD will try to time-align
the samples in the channels in a streamer, based on
  the time-stamps.

On 06/02/2024 17:23, zackkomo@utexas.edu wrote: > > If I do thing concurrently (same thread, same rx_streamer) would that > solve the timing issue? For example: > > |stream_args.channels = { 0, 1};| > |uhd::rx_streamer::sptr rx_stream = usrp_->get_rx_stream(stream_args);| > |…| > |size_t num_rx_samps =| > |                rx_stream->recv(buffs, samps_per_buff_, md, timeout, > one_packet);| > > Where buffs is a collection of receive buffers. > > It would become a little awkward with different sampling rates, but > would this potentially solve the timing issue? > > All the steams in a streamer must be at the same sample-rate from what I recall. One of the semantics in a streamer is that UHD will try to time-align the samples in the channels in a streamer, based on   the time-stamps.
RK
Rob Kossler
Wed, Feb 7, 2024 3:27 PM

On Tue, Feb 6, 2024 at 5:50 PM zackkomo@utexas.edu wrote:

It’s an estimated difference using a GPS SDR I have access to, not the timestamps in the metadata.

I just tired choosing different sampling rates, it seems like when I use pairs of sampling rates corresponding to odd divisions of the master clock rate, it works fine. Similarly when I choose even pairs. Choosing a sampling rates corresponding to odd and even though causes a mismatch.

Try checking the timestamps.  Assuming that the metadata timestamps
are different by the measured amount, would that allow you to throw
away samples from one of the streamers in order to align them?

On Tue, Feb 6, 2024 at 5:50 PM <zackkomo@utexas.edu> wrote: > > It’s an estimated difference using a GPS SDR I have access to, not the timestamps in the metadata. > > I just tired choosing different sampling rates, it seems like when I use pairs of sampling rates corresponding to odd divisions of the master clock rate, it works fine. Similarly when I choose even pairs. Choosing a sampling rates corresponding to odd and even though causes a mismatch. Try checking the timestamps. Assuming that the metadata timestamps are different by the measured amount, would that allow you to throw away samples from one of the streamers in order to align them?
Z
zackkomo@utexas.edu
Wed, Feb 7, 2024 4:50 PM

I have no clue how to explain it but .. I added just getting the timestamp from the metadata on my first rx_streamer->recv call and magically now the timestamps are aligned, and my aforementioned method of checking the timestamp also agrees. This works for the rates I originally mentioned I was having issues with (9830400 Msps and 20480000 Msps). Thanks for your help and time!

I have no clue how to explain it but .. I added just getting the timestamp from the metadata on my first rx_streamer->recv call and magically now the timestamps are aligned, and my aforementioned method of checking the timestamp also agrees. This works for the rates I originally mentioned I was having issues with (9830400 Msps and 20480000 Msps). Thanks for your help and time!
Z
zackkomo@utexas.edu
Wed, Feb 7, 2024 5:31 PM

Actually I was running it wrong… The md.time_spec on each of my thread/channel’s first call to rx_streamer->recv returns the same full and fractional seconds from md.time_spec, but my method of checking against the estimated time form the GPS signal still returns about a 700ns difference.

Actually I was running it wrong… The md.time_spec on each of my thread/channel’s first call to rx_streamer->recv returns the same full and fractional seconds from md.time_spec, but my method of checking against the estimated time form the GPS signal still returns about a 700ns difference.