Welcome to the new FlexRadio Community! Please review the new Community Rules and other important new Community information on the Message Board.
Need the latest SmartSDR, Power Genius, Tuner Genius and Antenna Genius Software?
SmartSDR v3.8.19 and the SmartSDR v3.8.19 Release Notes | SmartSDR v2.12.1 and the SmartSDR v2.12.1 Release Notes
SmartSDR v1.12.1 and the SmartSDR v1.12.1 Release Notes
Power Genius XL Utility v3.8.8 and the Power Genius XL Release Notes v3.8.8
Tuner Genius XL Utility v1.2.11 and the Tuner Genius XL Release Notes v1.2.11
Antenna Genius Utility v4.1.8
SmartSDR v3.8.19 and the SmartSDR v3.8.19 Release Notes | SmartSDR v2.12.1 and the SmartSDR v2.12.1 Release Notes
SmartSDR v1.12.1 and the SmartSDR v1.12.1 Release Notes
Power Genius XL Utility v3.8.8 and the Power Genius XL Release Notes v3.8.8
Tuner Genius XL Utility v1.2.11 and the Tuner Genius XL Release Notes v1.2.11
Antenna Genius Utility v4.1.8
If you are having a problem, please refer to the product documentation or check the Help Center for known solutions.
Need technical support from FlexRadio? It's as simple as Creating a HelpDesk ticket.
Need technical support from FlexRadio? It's as simple as Creating a HelpDesk ticket.
Android App
Comments
-
I will look into adding the features you requested. At some point I plan to add remote audio directly to the App. But that will not be soon. I have much more learning to do, before I can tackle that.
2 -
William it's looking awesome! I'm wondering if you will be the first person to display panadapter data from a FLEX-6000 outside of FlexRadio ;-) Let me so if I can help with the data dump that you provided earlier, referenced here again:
10.0.0.4: [954728508, 1073741824, 7213, 1397522435, 0, 0, 0, 0, 100, 2, 89416, 786444, 786444, 786444, 786445, 786444, 786444, 851980, 786444, 786444, 851980, 786444, 851981, 786445, 851981, 786445, 851981, 720906, 786445, 851981, 786445, 851981, 786444, 851980, 851981, 851981, 851981, 851981, 786445, 851981, 851981, 851981, 851979, 851981, 851981, 851981, 786445, 851981, 851981, 786445, 851981, 851981, 851980, 851981, 851981, 786445, 786445, 786445, 851981, 851979, 786445, 1429851, 1566525, 1299560, 1365096, 1429801, 1566472, 0, 0, ...
We really need to look at the hexadecimal interpretation of some of this data so here is the hex conversion for the first several words:01- 0x38E8003C
If you refer to the VITA-49 standard, the first word here is the VTIA-49 header. The header decoder ring is on about page 44 of the standard (depends on if you have the draft or the full standard). The first byte (3) indicates that this is "Extension Data packet with Stream Identifier". Extension data means that is is not in standard format -- this is because there is not an FFT format in VITA-49, but they recommend an extension packet.
02- 0x40000000
03- 0x00001C2D
04- 0x534C8003
05- 0x00000000
06- 0x00000000
07- 0x00000000
08- 0x00000000
09- 0x00000064
10- 0x00000002
11- 0x00015D48
12- 0x000C000C
13- 0x000C000C
14- 0x000C000C
15- 0x000C000D
16- 0x000C000C
17- 0x000C000C
18- 0x000D000C
Here's the format of an extension packet:
The next byte (8) has the top bit set when there will be a class identifier field (true for this packet) and the next bit is on if there will be a packet trailer (false for this packet). The other two bits are throw away.
The next nibble (E) describes the time-stamp data indicating that we will have real-time picosecond timestamps in the data. Really for the FFT we should have eliminated this, but it is here and the data is zeros as you will see later.
The next nibble (8) is the packet count. This number rolls through all four bits and starts again. so it goes 0...1...2...3 .......... E...F...0...1...2 etc. It happens to be 8 here. This will help you reassemble packets in the correct order should they get unordered in transport.
Finally, the 0x003C final 16-bits is the length of the packet in 32-bit words. In this case, 0x3C = 60 decimal = 240 bytes. The packet length you get should be this long.
Since the header said there was a stream identifier, this comes next (word #2) and it is 0x40000000. You should recognize this as the panadapter steam returned to you when you created the panadapter/panafall.
Next is the class identifier since that bit was set in the header (word #3 & 4). It is the next two words. When strung together, you get: 0x00001C2D 534C8003. The first word is the organizational unique identifier (OUI) of the company creating the packet. OUIs are used in Ethernet MAC addresses and other places on the Internet. If you do a web search for "oui 001c2d" you will see FlexRadio Systems is the owner of this OUI. Now the class ID. For all data generated by the SmartSDR codebase, we use the first 16-bits as 0x534C. This is ASCII "SL", a reference to the codename of SmartSDR before it was named and released: SMOOTHLAKE. Finally, the 0x8003 can be found in the document I linked to earlier which indicates that this data is FFT data (image below from the Information Class Document):
Next, words #5, 6, & 7 are all skipped as they would be the timestamp we said was in the data, but that is actually blank at this time.
Referring back to the Information Class document, the FFT Data Packet Class says:
So if we look at the first four words of the payload, we get:
start_bin = 0 (word #8)
num_bins = 200 (word #9)
bin_size = 2 (word #10)
frame_index = 89416 (word #11)
FFT frames can be larger than the size of permissible Ethernet packets (we are not doing jumbo frames because some hardware doesn't support it) so multiple packets may be used to send a complete FFT frame. So in this case, you can fit the whole frame into a packet and so the start_bin is 0 and there are 200 bins in the packet. Each bin is 2 bytes. The frame index can help you reassemble frames in some circumstances.
OK! We know what we have now right? Just have to decode the real data now!
Of course when you created the panadapter, you told SmartSDR how large your window for display is in pixels. SmartSDR uses this to size the display and perform all the calculations for you. Each 16-bit data element is a position in the Y-axis where the point of the FFT should be plotted. So a "0" means at the bottom and if your Y-height provided in the creation of the FFT display was, say 20, the maximum value for each pixel will be 19. Looking at the hex data for words #12-16, you can see that there are data points that read like C,C,C,C,C,C,C,D,C,C,C,C,D,C ... and so on. Translating to decimal, these are 12, 12, 12, 12, 12, 12, 12, 13, 12, 12, 12, 12, 13, 12 so this is a very averaged panadapter with the noise floor about 12 pixels from the bottom of the window. I didn't bother decoding past this point.
Let me know if any of this is confusing, etc.1 -
Steve,
That is extremely helpful. Its 5am, so I need some coffee before I can fully digest this. Can you explain the waterfall data format also? when you have time.
From what I'm finding is. Currently it does not appear that Flex is using timestamps or trailers. So this makes easy work to sift and parse the packets. I have successfully been able to capture and buffer each of the class codes I wanted. I was just really unsure of the data.
What you posted above for the FFT data, makes perfect since, And I already have some ideas to experiment with.
Now if you could point me in the right direction of the waterfall data
William
0 -
Wow, William. Great work. Using a Nexus 7 like others and same great result. Nicely done!0
-
Steve, I realize you are working through this with William and I don't want to hijack the conversation. I was kind of hoping I could get William to take the payload and process it into a series of tiles. It looks like there is one tile created per packet. Each tile has a byte array and it was my understanding that byte array is one line of pixels starting at 0,0 (top left of the window). I am not processing the waterfall data yet but when I get to that point I was assuming, and this is largely from looking at the test method in Waterfall, one would scroll the window, display the image (0,0 -> 0,max y). I am inferring from what you are saying that isn't correct. By proceeding with that ordering, there would always be a valid line of pixels at the top of the window.0
-
One thing that perplexes me is, as you and I discussed months ago, when scrolling a Windows window, one scrolls the window, invalidates the top row of pixels, which fires a paint event where the next row of pixels is drawn. Nothing appears to handle it that way now and it seems one has to animate the window to autoscroll say at every ms. I noticed in the header for the tile there is a duration value. Is that how .NET handles it?
0 -
will this be ok on lenovo A10 or cheap allwinner 31s tablet?
I need to update my ancient advent vega.
cheers
Paul0 -
Now we are getting somewhere. I successfully graphed live FFT data. Albeit I'm limiting the pan size to a single packet, so not much resolution.
https://www.youtube.com/watch?v=nGFuYaNVw-o
2 -
That looks like it should be a spectrum display, correct? If so, try doing that as a multi-line, in other words, connect the points as opposed to drawing each from the base to the point.
0 -
Ok, now one thing I don't get yet. So the panadapter data is not linked to center frequency. Changing center frequency does not shift the panadapter data. It stays static. How do I get the data to shift with center frequency?
0 -
Walt, yest its spectrum. Since Steve gave me the info for spectrum, I thought I would start with that.
0 -
That looks like it should be a spectrum display, correct? If so, try doing that as a multi-line, in other words, connect the points as opposed to drawing each from the base to the point. That is pretty cool though William. Is it upside down? In other words, should those dips be peaks and the peaks be noise floor?
0 -
When you said earlier it was 5am I thought you had pulled an all-nighter. Steve's comment was 5am. I was surprised to see you up. It's addictive, huh?
0 -
OK let me answerWalt's questions about the waterfall. First, let me talk a little about the architectural differences in the panadapter and waterfall. The panadapter is considered a wasting display -- if you don't see it shortly after it is produced, it is worthless and should be thrown away. We could argue about this statement, but it is the statement we designed against.
Waterfall, on the other hand, can be used long after it is produced. A couple of the things I really hated about waterfalls I'd seen to date are 1) if you tune the radio, the waterfall gets disjointed from the panadapter and 2) if you decide to alter the color scheme for the waterfall, it only works from that point forward. So we had two additional design goals to fix these "problems."
We also looked at the data that is calculated in the radio and what we can do with it. You have to understand some more about how the radio works, but the other important fact is that we almost always have extra bins calculated for the waterfall than what are requested for the display. We discussed what to do with this data. The two options were 1) throw it away, 2) save the data in case the operator wants to see it later. We decided 2 was the best option, but it does take more bandwidth to do so. We may alter this some for the WAN case, but for now it is what we do.
So the data presented is NOT the upper left of the waterfall window. It actually starts to the left of the display (hidden) in almost every case. This is why you can tune to either side and see new data as a general rule. It's because we calculated and saved that data. So the waterfall data contains the actual starting location of the data. The header of the packet is just like the FFT, but with a different information class. Here's the structure for the payload of the packet:
Here, we tell you the first frequency represented in the upper left bin of the tile. This is a VITA-49 frequency representation which is a 64-bit integer. If you want this in integer Hz, just perform the equivalent of >>20 or if you want as a float in Hz divide by 1048576. You will then have to align this to the display that you have drawn and throw out any bins that you don't want to display --or-- store them for later use.
The next element is the width on a pixel -- again you have to be able to figure out how you are going to line this up with your panadapter.
Next is the width and height of the tile sent. Generally today we will send a height of one, but we reserve the right to send different heights. We have discussed processing more data and providing fill data as we have it at a higher resolution. The width will be the number of bins of width pixel_bandwidth.
Next is the timecode which increments by one to help you determine if you've lost data. Finally is a computed auto-black level which you can use in your algorithm if the user selects auto black. You have to calculate the colors and the black yourself. There are two reasons for this: 1) by having the client interpret the data, you can then re-interpret it as the user changes the colors, etc. You have to have done the interpretation or we would have to resend the whole display each time. 2) It allows us to send a fraction of the data, preserving network bandwidth. Since the data point to color is a hash algorithm that is expanding (data in is 16-bit and data out is 24-bit or more, we save the data transfer).
Then the data is just 16-bit bin values that must be interpreted as color. Make sense?
0 -
Looks good William. I assume you have inverted the Y-Axis (0,0 is at the lower left, not upper left for the panadapter) and that you also have weighted average on based on the behavior that I see.0
-
Maybe the best, short, answer is no. FFT is just some vague term I recall from my Fortran days. I did try to look it up to refresh/acclimate myself to the terms. It isn't clear what a bin is beyond a fragment of information. The scenario I've been using, while something I vaguely remember doing 30 years ago had to do with scrolling a multi-line text box or a listbox where the data is finite and is moved a pixel height at a time behind the viewport. When the panadapter is created the center frequency is specifed so for the pane it is in the value of x / 2 is where the center freq is and the low freq is pixel-bandwidth * x/2 below the center freq. Pixel-bandwidth * x is the display's bandwidth. I did not make that connection to autoblack or the user colorizing the pixel. In my case I was going to take that byte array, turn it into a ByteArrayStream and create an Image object, basically a one (or more) pixel height by y width bitmap image that I would draw, starting at 0,0. the next row would start at 0,1 etc until y > window max y, in which case I'd scroll the window up and always be drawing starting at 0, max y. Thank you for explaining why Eric multipled the width by 1.2. So, for the case of the waterfall the viewport would need to be offset some into the actual image. Correct? It is still unclear how to handle the scrolling after I get to y==y(max). I really want the arrival rate of the waterfall packets to control the scrolling, not an internal timer. With SSDR I've only ever gone back in time once and I can't foresee a need to do it again so I think I won't try to maintain more than the viewport will hold.0
-
Steve,
The panadapter data is actually coming in like that. For some reason the data I'm getting shows a signal above the noise from as a lower value. Something like this:
20,20,20,20,20,13,12,15,17,20,20,20,20,20
Not sure why this is. of how to account for it. Since I'm plotting the values as they come in, I have no idea how to make a 12 higher than a 20 LOL.
Maybe someone has an algorithm that will do this.
But what I would like to know most is, How do I shift the panadapter? Since the panadapter is a snapshot of data, and not linked to center frequency. How can I manually shift the panadapter with center frequency?
William
0 -
Here is a snippet, after converting byte to int
0, 155, 0, 156, 0, 155, 0, 153, 0, 153, 0, 152, 0, 129, 0, 110, 0, 107, 0, 120, 0, 128, 0, 114, 0, 104, 0, 125, 0, 127, 0, 144, 0, 155, 0, 155, 0, 156
the lower values representing singals. Maybe I have something strange with my conversion from byte to int?
William
1 -
12 is higher than 20....remember the geometry is 0,0 is top left. in a window 20x50, a height of 20 is on the bottom so a bunch of 20's followed by a couple of 12's will have the 12 be 8 pixels higher than the 20. How are you generating the display? To invert them subtract the y dimension of the window and take the absolute value of that such that you'd get: 0,0,0,0,7,8,3,0,0,0. I am pretty sure Android does the same FU geometry as Windows. 0,0 is top left as opposed to bottom left.
0 -
William, how did you get that second set of numbers? they look like coordinate addresses (0,155), (0,156) etc. but that isn't 20's and 12's wit a 13 thrown in for good luck.
0 -
so 20 is 20 down from the top, 12 is 12 down from the top so abs(ymax-value) would be 0,0,0,8, etc. In my experience, that should work fine. so something in the way you are drawing them is converting it to the other coordinate system.
0 -
I know....Android uses OpenGL and OpenGL uses Cartesian coordinates which is bottom left is 0,0 so do that conversion I mentioned absolute(ymax-value). The x value is fine as it still goes from left to right.0
-
Here is what I have so far. Much better me thinks
Sorry my nose was stuck in the code, not ignoring you1 -
Is that being drawn in the same thread that received the UDP packet? If so, try this.
Create a BlockingQueue and another thread that just blocks on the top of the queue. In the steady state, that thread will be blocked. In your callback thread that receives the UDP packet, simply push it into the queue and let it go back to listening for the next UDP packet. As soon as you've pushed the VitaPacket into the BlockingQueue, that worker thread waiting on it will unblock. In that thread, pull off the head of the queue and process and draw it, then notify the UI thread. I think you'll find it is much faster.
But yes, that is quite nice. You may well be done this week.
0 -
You could also undo the weighted average, that too will make it more active, well, unless you prefer it that way. Once you put that on the tablet it will automatically be drawn by the GPU. The implementation you'd likely want is LinkedBlockingQueue.0
-
Maybe the best, short, answer is no. FFT is just some vague term I recall from my Fortran days. I did try to look it up to refresh/acclimate myself to the terms. It isn't clear what a bin is beyond a fragment of information.
A Fourier transform takes time-domain data and converts it into frequency-domain data. For our purposes, it is essentially a large number of receivers with very narrow bandwidth. Each of the receivers puts it's resultant signal in a bin. The magnitude of the bin indicates how much signal in that frequency range is present in the source time-domain signal. An FFT is a fast Fourier transform, just an algorithmically optimized version of the Fourier transform.
The scenario I've been using, while something I vaguely remember doing 30 years ago had to do with scrolling a multi-line text box or a listbox where the data is finite and is moved a pixel height at a time behind the viewport. When the panadapter is created the center frequency is specifed so for the pane it is in the value of x / 2 is where the center freq is and the low freq is pixel-bandwidth * x/2 below the center freq. Pixel-bandwidth * x is the display's bandwidth.
The size of the display and the data we provide are not the same as I mentioned. You will be disappointed if you make this assumption...
I did not make that connection to autoblack or the user colorizing the pixel. In my case I was going to take that byte array, turn it into a ByteArrayStream and create an Image object, basically a one (or more) pixel height by y width bitmap image that I would draw, starting at 0,0. the next row would start at 0,1 etc until y > window max y, in which case I'd scroll the window up and always be drawing starting at 0, max y. Thank you for explaining why Eric multipled the width by 1.2. So, for the case of the waterfall the viewport would need to be offset some into the actual image. Correct?
Yes.
It is still unclear how to handle the scrolling after I get to y==y(max). I really want the arrival rate of the waterfall packets to control the scrolling, not an internal timer.
This is how I would do it -- use the data to cause the scrolling. BUT if you miss a packet you have to decide how to handle it. We show a blank line where the data should be. If you see this in our application, it means that you lost data somehow. Generally the top two answers are 1) bad network connection or 2) slow PC can't draw fast enough.
With SSDR I've only ever gone back in time once and I can't foresee a need to do it again so I think I won't try to maintain more than the viewport will hold.
Fine -- this is certainly your choice as an application designer!0 -
Remember the data is uint16s so two bytes per pixel.0
-
Remember the data is uint16s so two bytes per pixel.0
-
Walt,
I am running the UDP in a separate thread. I am also running weighted average on the radio, but no additional averaging in my graphing.
I was making a big mistake. First the data is coming in a 16bit shorts vs 8bit . So I needed to first tell the radio to only send x=700. 700 sample points takes 1400 bytes. Also when converting to int, I have to throw away the extra zeros in the int array (every other byte).
I can not get a decent panadapter view in a single packet. 700 samples is plenty for a small screen.
Currently I'm using java.awt to draw the graph, This will completely change in android, as it does not support awt. But this was just a test.
Also since I have no plan in android to have offscreen data, just re-centering the panadapter as you tune works great. For now I just drew a line dead center, and use that as a tune aid.
William
1 -
Yep Steve figured that out the hard way, instead of actually reading what you wrote the first time
0
Leave a Comment
Categories
- All Categories
- 290 Community Topics
- 2.1K New Ideas
- 536 The Flea Market
- 7.5K Software
- 6K SmartSDR for Windows
- 146 SmartSDR for Maestro and M models
- 360 SmartSDR for Mac
- 250 SmartSDR for iOS
- 231 SmartSDR CAT
- 172 DAX
- 353 SmartSDR API
- 8.8K Radios and Accessories
- 7K FLEX-6000 Signature Series
- 32 FLEX-8000 Signature Series
- 851 Maestro
- 44 FlexControl
- 847 FLEX Series (Legacy) Radios
- 799 Genius Products
- 417 Power Genius XL Amplifier
- 279 Tuner Genius XL
- 103 Antenna Genius
- 243 Shack Infrastructure
- 166 Networking
- 404 Remote Operation (SmartLink)
- 130 Contesting
- 633 Peripherals & Station Integration
- 125 Amateur Radio Interests
- 873 Third-Party Software