[Ground-station] responses to more comments on ka9q-radio

Phil Karn karn at ka9q.net
Mon Apr 23 23:26:28 PDT 2018


On 4/23/18 17:41, Michelle Thompson wrote:
> The parameter update issue is a general-case design issue. It is
> important. Please think about it some more.

I think there's been some misunderstanding. **EVERY** filter parameter
can **ALREADY** be updated as frequently as once per FFT block, which is
typically 20 ms. That includes the frequency response and window shape
factor.

The only thing that can't (yet) is the length of the FFT block itself.
That requires so much reinitialization, and I had so little need for the
feature, that I just restart the program when I have to do it. Which is
about never.

Frequency mixing is in the time domain, so it can change on a per-sample
basis. Which it does when Doppler steering is in effect.

Remember, it's all just RTP streams. If the program restarts fast
enough, you may not even notice the interruption (though the RTP stream
ID will change unless you make it the same). One easy way to implement
this is to simply have the program exec() a new copy of itself with the
new parameters. I'll probably hook this onto a command to load a state
file (which normally happens only at startup).

I'm writing this package mainly as a proof-of-concept for RTP and
multicast in distributed SDR implementations. If my actual code is
useful to somebody, so much the better.

It was the same with my TCP/IP software in the mid-late 1980s; I wrote
it as a proof-of-concept for those protocols over ham packet radio, and
it turned out that the software had other uses. Until it was replaced by
Linux, which is what should have happened.

> RTP/multicast and Opus features are things I want to fold in to our GNU
> Radio implementation. 

Since this invokes interoperability issues, this is where we need to
nail things down.

The RTP AVP (Audio-Video Profile) already defines static payload types
for 48 kHz 16-bit PCM, one for mono and one for stereo. The samples are
sent in big-endian order (like all IETF standards) despite big-endian
CPUs being nearly extinct. I flip the bytes on both ends just to be sure
I'm compatible.

Opus is a more of a problem. After assigning a whole bunch of static
payload types to now-obsolete codecs, the powers-that-be decided to stop
assigning payload types altogether and require that they be dynamically
established with the Session Description Protocol (SDP). (As the saying
goes, every problem in computer science can be solved with yet another
layer of indirection).

Unfortunately, this happened before Opus was standardized, so even
though the IETF wants to promote Opus as *the* standard audio codec,
they've made it harder to use than the old fashioned codecs it's
supposed to replace.

So to force VLC on my iPad to play it, I have to write a short SDP text
file, serve it up on some local web server, and  point VLC at it. Then
it will join the multicast stream and decode Opus. All that extra work
and points of failure just to set one number that shouldn't need to be set.

My 'monitor' program doesn't need SDP because I use the fixed value of
111 on both ends. It *seems* be some sort of unofficial convention, so I
chose it.

Lastly, there's I/Q data. I know about VITA-42 (?) but I took one look
and the horrible CCITT/ISO/OSI flashbacks to the 1980s began. (Bob knows
of what I speak.)

This is totally nonstandard so obviously there won't be a static payload
type for it. But that's actually less of a problem because we're not
trying to interoperate with anybody; we control both ends and consenting
Internet hosts can do whatever they want. My RTP format looks like this:

RTP Header (standard), PT = 97 (arbitrary, in dynamic space)
custom SDR status header
16-bit I sample
16-bit Q sample
16-bit I sample
.......

The samples are in little endian format because, again, they don't have
to be big-endian. The custom SDR header looks like this:

struct status {
long long timestamp;
double frequency;
uint32_t samprate;
uint8_t lna_gain;
uint8_t mixer_gain;
uint8_t if_gain;
uint8_t pad;
};

Essentially the same format is used in unicast UDP packets back to the
I/Q sender to control the device (though some fields can't be changed.)

The timestamp is a little-endian integer count of nanoseconds since the
GPS epoch of January 6, 1980 at 00:00:00 UTC. This will wrap in 584
years from 1980. This timestamp comes from the original source, so you
can play back an I/Q recording and see the original time in the 'radio'
display. That's its main use; internal SDR timekeeping is all done by
counting samples, so it is only as accurate as the FCD A/D clock.

I feel *very* strongly that UTC should not be used for internal
timestamps. Nor can UTC be correctly represented as a single number, as
UNIX traditionally tries to do. That's fundamentally broken.

After I did this, I discovered that NTP has its own internal time format
consisting of two 32-bit integers counting full and fractional seconds
since Jan 1, 1900 UTC, which is almost 60 years before UTC even existed,
and long before atomic clocks that could nail down such an early epoch.
It will roll over in 2036. And NTP follows UTC, so it jumps every time
there's a leap second. In other words, I think Dave Mills made a major
mistake here, and I even told him at the time. But he actually enjoyed
watching the transient response of hundreds of NTP hosts to an abrupt
jump in time.

Because my timestamps are in GPS time, you can get it from a local GPS
receiver, which indicates the UTC-GPS offset, or from UNIX system time
(via NTP) and a leap second table -- which I've already done. I prefer
the first approach. GPS receivers are now cheap commodity devices.

The frequency is a double precision float giving the center frequency of
the I/Q stream, i.e., the local oscillator frequency in a zero-IF
receiver front end.

The sample rate is the *nominal* A/D sample rate, uncorrected for any
oscillator error (which the sender doesn't know anyway; that's corrected
by the I/Q consumer, e.g, 'radio').

lna_gain, mixer_gain and if_gain are specific to the FCD, though I
believe a bunch of zero-IF SDR front ends are using the same tuner chip.
The first two take the values '1' or '0' to indicate whether the
corresponding amplifier is on or off.

if_gain is an integer between 0 and 59 giving the gain of the baseband
amplifiers in dB between the quadrature mixers and the A/D converters.
The FCD already has so much front end gain that I always leave this at
zero, as recommended.

These values can change at any time, which is why they're included in
every packet. In fact, 'radio' won't even start up until it gets the
first I/Q RTP packet because it doesn't yet know the A/D sample rate,
and virtually every initialization needs that.

The FCD has a wide dynamic range so 'radio' doesn't even have a way to
set them right now, though the protocol allows for it. The 'funcube'
program that talks directly to the FCD will change the LNA and IF gain
settings as a strictly defensive measure when an overload is detected.
This happens in two steps: first IF gain is reduced, then if more
reduction is still needed, LNA is turned off. If either is off when the
level falls below a lower threshold, they're turned back on in reverse
order. I only see this happen on local TV and radio stations.

I strongly resisted putting hardware-specific fields in here. I really
wanted the header to convey the actual conversion gain in dB (i.e., the
output level in dBFS for an input level in dBm) but that turned out to
be impossible. I measured the gain of the FCD and it varies enormously
over its coverage range. The mixer amplifier is always 19 dB, and the IF
gain steps do seem accurate, but the LNA can range from hardly more than
1 dB up to over 20, and the big bank of switchable preselectors didn't
help matters.

Phil
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0xF14E4354ED463446.asc
Type: application/pgp-keys
Size: 3301 bytes
Desc: not available
URL: <http://lists.openresearch.institute/pipermail/ground-station-openresearch.institute/attachments/20180423/f1f1e1b6/attachment.key>


More information about the Ground-Station mailing list