Stream1090

Ok, then i am safe here. This should then not be a problem.

dump1090’s equivalent looks for the best-scoring message out of the nearby candidates:

For deduping bitwise-identical messages, then that’s not relevant, but something like that could possibly be useful when you have candidates for the same transmitted message that demodulate slightly differently with different offsets.

1 Like

Yea that is along my lines what i have on my mind right now.

@jimMerk2 @JRG1956 i made some change to the recognition logic for ADS-B. This most likely will affect you, not so much Euro stations, i think. Let me know how it goes.

It looks good to me. But i cannot really tell yet. I will have it running a bit more on the live setup. Things are very difficult to judge here. Sunday, nice weather => plenty of GA, but no planes from the Middle East.

1 Like

I’ve run my RTL-SDR samples through the latest version and it has almost eliminated the generation of single message tracks. This is the same sample as that reported in my post # 612 above:

Stream1090

jrg@pi44:~/projects $ cat rtl_sample20260217-2.4M_30m.raw | stream1090 -s 2.4 -u 12 -q -v | socat -u - TCP4:localhost:30001
[Stream1090] build 260301
[Stream1090] Input sampling speed: 2.4 MHz
[Stream1090] Output sampling speed: 12 MHz
[Stream1090] Input to output ratio: 1:5
[Stream1090] Number of streams: 12
[Stream1090] Size of input buffer: 8196 samples 
[Stream1090] Size of sample buffer: 40980 samples 
[IQLowPass] tap count: 15 symmetric: 1
[IQLowPass] taps: (-0.00245953, -0.00200476, 0.0238445, 0.0310966, 0.0531385, 0.096997, 0.0569147, 0.484946, 0.0569147, 0.096997, 0.0531385, 0.0310966, 0.0238445, -0.00200476, -0.00245953)
[Stream1090] Sync Stdin Mode
[Stream1090] Reading from stdin
-------------------------------------------------------------
|     Type |  #Msgs |  %Total |    Dups |   Fixed |   Msg/s | 
-------------------------------------------------------------
|    ADS-B | 172601 |   52.1% |   24.6% |   28.8% |   95.93 | 
|   Comm-B |  48599 |   14.7% |      0% |         |   27.01 | 
|     ACAS |  61190 |   18.5% |      0% |         |   34.01 | 
|     Surv |   6246 |    1.9% |      0% |         |   3.472 | 
|    DF-11 |  42583 |   12.9% |   31.9% |   39.7% |   23.67 | 
-------------------------------------------------------------
|  112-bit | 224751 |   67.9% |     20% |   23.5% |   124.9 | 
|   56-bit | 106468 |   32.1% |   15.8% |   19.7% |   59.18 | 
-------------------------------------------------------------
|    Total | 331219 |    100% |   18.7% |   22.3% |   184.1 | 
-------------------------------------------------------------
(Max. msgs/s 184.1)
Messages Total 331219
DF 0 : 57639
DF 4 : 2761
DF 5 : 3485
DF 11 : 42583
DF 16 : 3551
DF 17 : 172601
DF 20 : 26909
DF 21 : 21690
1799182505 iterations @1MHz
[Stream1090] Finished. (691.925s)

Fed into dump1090-fa:

Statistics: Mon Mar  2 06:08:47 2026 AEDT - Mon Mar  2 06:23:25 2026 AEDT
Local receiver:
             0 samples processed
             0 samples dropped
             0 Mode A/C messages received
             0 Mode-S message preambles received
               0 with bad message format or invalid CRC
               0 with unrecognized ICAO address
               0 accepted with correct CRC
  ----- dBFS noise power
  ----- dBFS mean signal power
  ----- dBFS peak signal power
      0 messages with signal power above -3dBFS
Messages from network clients:
         0 Mode A/C messages received
    331219 Mode S messages received
          16 with bad message format or invalid CRC
           0 with unrecognized ICAO address
      331203 accepted with correct CRC
Decoder:
    331203 total usable messages
       57624 DF0 messages
        2761 DF4 messages
        3485 DF5 messages
       42583 DF11 messages
        3551 DF16 messages
      172601 DF17 messages
       26908 DF20 messages
       21690 DF21 messages
       420 surface position messages received
     67467 airborne position messages received
     66938 global CPR attempts with valid positions
       114 global CPR attempts with bad data
           0 global CPR attempts that failed the range check
         114 global CPR attempts that failed the speed check
       459 global CPR attempts with insufficient data
        35 local CPR attempts with valid positions
           0 aircraft-relative positions
           0 receiver-relative positions
       800 local CPR attempts that did not produce useful positions
           0 local CPR attempts that failed the range check
          62 local CPR attempts that failed the speed check
         0 CPR messages that look like transponder failures filtered
         0 non-ES altitude messages from ES-equipped aircraft ignored
        64 unique aircraft tracks
         5 aircraft tracks where only one message was seen
         5 aircraft tracks which were not marked reliable
CPU load:   0.7%
      0 ms for demodulation
      0 ms for reading from USB
   6093 ms for network input and background tasks

Single message /unreliable tracks flagged by dump1090-fa went from 80/83 to 5/5 with no obvious impact on the “real” messages counts. The other samples were similar.

I’ve been feeding stream1090 into FlightAware with these single message tracks without issue for a couple of months, but it will be nice not to have the blue band in graphs1090.

I’ve been neglecting stream1090 running on my airspy R2 - it is still running the 260222 build with my compiled custom filter. I see you have made changes to diff_evolve.py and changed the seed size to 9 - do I need to start again with filter optimisation for the latest build?

Here are results from the new software using previous sample file from post #615:

pi@raspberrypi:~/stream1090 $ sudo cat /home/pi/samples2.4_12.raw | ./build/stream1090 -s 2.4 -u 12 -q -v  > /dev/null
[Stream1090] build 260301
[Stream1090] Input sampling speed: 2.4 MHz
[Stream1090] Output sampling speed: 12 MHz
[Stream1090] Input to output ratio: 1:5
[Stream1090] Number of streams: 12
[Stream1090] Size of input buffer: 8196 samples
[Stream1090] Size of sample buffer: 40980 samples
[IQLowPass] tap count: 15 symmetric: 1
[IQLowPass] taps: (-0.00245953, -0.00200476, 0.0238445, 0.0310966, 0.0531385, 0.096997, 0.0569147, 0.484946, 0.0569147, 0.096997, 0.0531385, 0.0310966, 0.0238445, -0.00200476, -0.00245953)
[Stream1090] Sync Stdin Mode
[Stream1090] Reading from stdin
-------------------------------------------------------------
|     Type |  #Msgs |  %Total |    Dups |   Fixed |   Msg/s |
-------------------------------------------------------------
|    ADS-B | 170121 |   39.1% |   30.6% |   41.4% |     278 |
|   Comm-B |    889 |    0.2% |    0.1% |         |   1.453 |
|     ACAS | 100828 |   23.2% |    0.1% |         |   164.8 |
|     Surv |  37353 |    8.6% |      0% |         |   61.05 |
|    DF-11 | 126146 |     29% |   39.3% |     37% |   206.2 |
-------------------------------------------------------------
|  112-bit | 174129 |     40% |   30.1% |   40.7% |   284.6 |
|   56-bit | 261208 |     60% |   23.8% |   22.4% |   426.9 |
-------------------------------------------------------------
|    Total | 435337 |    100% |   26.5% |   30.1% |   711.5 |
-------------------------------------------------------------
(Max. msgs/s 711.5)
Messages Total 435337
DF 0 : 97709
DF 4 : 36768
DF 5 : 585
DF 11 : 126146
DF 16 : 3119
DF 17 : 167461
DF 18 : 2660
DF 20 : 850
DF 21 : 39
611889455 iterations @1MHz
[Stream1090] Finished. (256.355s)

Number of messages down slightly from post #615.
There are no DF-19 messages,

Edit: Note, I didn’t do a run using dump1090-fa as a decoder. I use dump1090-fa in my regular system and have been stopping it to run dump1090-fa here. Is that required – or can I run two instances of dump1090-fa at the same time?

So as a generale statement. I will move away from these forums. I have been verbaly attacked here and there, ones by some of the staff without any knowledge what i was doing do at all.

I will move on, you have the code. You will figure it out.

Edit: i was here to share code. If you do not like that. Your problem.

So as I understand it, dump1090-fa calculates those five phase offsets, takes the sign bit of the calculations and then looks for the preamble pattern in each of the five outputs, where + = 1 and - = 0. Assume the m in the phase calculations is magnitude i.e. sqrt(I^2 + Q^2) ? Is the pairing of I and Q important – that is, do you have to slip one sample and do the calculations that way also, or does that not matter?

For sure you will see the preamble pattern in just noise, but you can throw out a lot of those false detections from consideration based on magnitude level.

That’s right. m is the result of doing envelope detection by looking at the magnitude of each complex sample.

not quite. That is what happens when trying to interpret the data bits. The preamble detection is separate and doesn’t use the slice_* functions (but still looks at the levels of m): dump1090/demod_2400.c at 4f47d12a18db24238ab2d91c8637dae25937fd98 · flightaware/dump1090 · GitHub

Once a preamble is found, the demodulator tries to demodulate all the following data bits using the sign bit comparison described above, starting at different phase offsets, and picks the best result.

The I and Q values are always paired – they are a single complex value, (I + jQ). It wouldn’t really make sense to combine e.g. I[0] and Q[1], which is what I think you’re asking.

Yeah, it’s very much a tradeoff of “do you want more messages?” vs “do you want messages you can trust?”. If you lower the threshold and consider more messages, you’ll get more weak messages, but you also get more garbage coming out of the demodulator, and detecting the bad messages later down the pipeline during decoding can be tricky.

The dump1090 preamble detector has a very basic check that the peaks are sufficiently far above the “off” parts of the preamble, here: dump1090/demod_2400.c at 4f47d12a18db24238ab2d91c8637dae25937fd98 · flightaware/dump1090 · GitHub

Regarding the paring of the IQ values, I meant how do you know how they are paired? Say you get a,b,c,d,e,f … on the input IQ stream. How do you know you should do:
sqrt(a^2+b^2) , sqrt(c^2+d^2) …
or
sqrt(b^2+c^2) , sqrt(d^2+e^2) …

Edit: One additional question – the IQ data is 8-bit unsigned. I notice during a quiescent state the values are at mid-scale 0x80 or 128 decimal +/- a couple of counts. So I assume the first step is to convert that to signed by subtracting 128 decimal from all values so that you have values of -128 to +127.

Well, it’s all undocumented magic inside the 2832, so I can’t say for sure, but everything just assumes that each USB transfer starts with an I sample. it’s probably a reasonable assumption that the individual USB data packets are always even-sized and the ASIC puts the I sample at the start of the packet, but I don’t think I’ve ever explicitly tested it (it’d be hard to test)

If you did get the pairing wrong, it would probably show up as an inverted spectrum (swapping I and Q reflects around the y=x line, which reflects the spectrum around f=0) and I don’t think I’ve ever unexpectedly seen that when working in the frequency domain.

yes, -ish (we use 127.4 as the center point for reasons I don’t remember the exact details of): dump1090/dsp/impl/magnitude_uc8.c at 4f47d12a18db24238ab2d91c8637dae25937fd98 · flightaware/dump1090 · GitHub

Ok, then in a file of IQ samples, we can assume it starts with the I sample.

Thanks.