Page 3 of 3

Re: My es2gears went black

Posted: Sat Mar 02, 2019 2:39 am
by ab1jx
Well, I'm still playing with framebuffer graphics. I have 4 threads (so far) for getting data from the RTL2832 dongle over USB, putting it through FFTWF, plotting the spectrum (top part) and another for scrolling the waterfall. I can actually see real-world signals out there but I'm still trying to make sense of what they are. I haven't dug out a signal generator yet, just guessing at over the air stuff I can think of.
ss1551490125_hs.jpg (79.33 KiB) Viewed 227 times
These (image scaled down for this board) are National Weather Service transmitters. They operate on a nationally-allocated set of frequencies every 25 KHz from 162.400 MHz up so they make good test signals. Putting timestamps in the waterfall is an idea I borrowed from Hdsdr (every 15 seconds here). I'm using librtlsdr and there's a function to set the "center" frequency. That probably means the local oscillator frequency but it's a little weird. This is running under X, but it also works from a console. The CPU load, clock, Bitcoin price come through because they update. But now I'm in a quandary because mouse clicks anywhere get picked up by X and bring the underlying windows to the foreground. I think I can figure a way around that using Xlib to capture mouse events. Console mode is worse, I need to use curses to capture keypresses and mouse clicks, so that means GPM, with this rectangular block cursor. It's still the same problem of wanting framebuffer graphics to be housebroken, maybe I can use GLFW, I haven't looked. The text method I borrowed from an old Giflib, it makes 8x8 pixel characters.

Performance, well, I'm doing a full 1920x1080 screen. I draw the spectrum at top using XOR to write into memory, then I draw the same thing again on the next pass to erase it before the new one. I'm writing uint32_ts directly to the screen, which is handy, 1 per pixel, it's 32 BPP ARGB. For the waterfall I draw a line of colors where the color shows signal intensity, then I use memcpy to copy the whole waterfall down 1 pixel row. My decimation is broken (stuck at 8 max), but I count screen update cycles and I hit 45 updates/second at times. 77% CPU above, but Firefox is also running. I could live with about 1/3 that update frequency. I haven't done any profiling yet but noise in the spectrum causes the Bresenham line drawing to do a lot more work. I'm also using an FFT size of 4096, in the spectrum pixels get scaled into the screen resolution, in the waterfall there's the same scaling with some averaging going on. Spectrum pixels can overwrite each other, but not in the waterfall. I can see there's modulation there but I haven't tried any demodulation yet. The automated voice reads a weather forecast over and over.

Re: My es2gears went black

Posted: Sat Mar 02, 2019 3:23 pm
by ab1jx
Let me try to explain the decimation problem. It's common in SDR to throw out data points in the incoming stream before the FFT because well, an RTL2832 dongle cranks out 2 million samples/second or so and you don't need to keep them all. The sample rate affects the overall bandwidth, the frequency range covered, so you don't cut that down, you drop points. But it has to be in a regular fashion, you can't keep N points from the beginning and drop the rest. The FFT has to be able by looking at what's there (in the time domain) to determine what frequencies are present. So I have this buffer as it comes from USB containing all the points. Then I do

Code: Select all

for (i=0; i<(MAXIMUM_BUF_LENGTH-halfdec); i++) {  // decimation/load
    if ((i % DECIMATE ) == 0) {
      fftin[ftqtail][j][0] = (rfbufs[lochead][i] * hanncurve[j]);
I only use the points where modulo the decimation factor gives 0
exported4_100dpi.jpg (55.7 KiB) Viewed 212 times
But when DECIMATE is 16, 32, or 64 all my signals go away and it looks almost like a test FFT of a sine wave where there's only a single frequency present. Only the lower left has DECIMATION set to 8, the rest are 2, 4, or 8 times that.

One other thing I'm not sure is right: There are interleaved I and Q signals coming out of the dongle. They're at 90 degrees difference in the RF stream coming in. But if you're throwing out 7/8 of the data it doesn't seem like you're going to have those magic 90 degree points anymore. So I invented this concept of halfdec, which is
int halfdec = (DECIMATE/2) + 1; // IQ difference for 90 degrees
I'm trying to get not the next point but the 2nd point after I skip a bunch. This concept may be bogus.

OK, maybe I see it. I #define FFTSIZE 4096, which sets sizes of arrays, etc. If DECIMATE is > 8 there are less than 4096 points left.

Re: My es2gears went black

Posted: Fri Apr 19, 2019 10:28 pm
by ab1jx
I just stumbled across this in a program I wrote 20 years ago or so, still works.

Instead of using ** I did
char *files[500];

It makes an array of (null) pointers, then you malloc space to assign to one when you want to use it. I had just switched from FreeBSD to OpenBSD and I managed to get Open to mimic FreeBSD's StringList. But it's a list you can qsort() so I was using it for filenames from a readdir().

Well OK, not that it has anything to do with es2gears, this is my add_string()

Code: Select all

int add_string(char* newstring, char* aray[], int pos) {
  int ok = 0;  // zero is OK here
  aray[pos] = (char*)malloc(strlen(newstring) + 1);
  if (aray[pos] != NULL) {
    strncpy(aray[pos], newstring,strlen(newstring)+1);
  } else {
    ok = 1;
  return ok;
You need to maintain the count of strings in the list separately (I suppose you could add that), and loop through the list to free them when you're done.