 My name is Tim O'Shea. I'm one of the Guinea Radio developers. I currently work at Virginia Tech, and I have O'Shea Research LLC in case any of you have Guinea Radio needs. All right, so I'm going to go through. This talk is two parts. The first is going to be more brief. This is just kind of talking through kind of about Guinea Radio as an intro, but I'm going to try to make it higher level because it really looks like people kind of are familiar with Guinea Radio a little bit more than I was expecting here today. And then yesterday. And then part two is looking at some hands on exercises with Guinea Radio, and I'm going to try to add some kind of make it more interesting than ones people have may have seen in the past and try to show off some of the newer things that are in Guinea Radio that people may or may not be using yet, which are some kind of cool features. All right, so a quick plug. Virginia Tech is hiring, so anyone who wants to play with usurps and SDR all day as their job, definitely look at our postings or come talk to me. Yes, we're also looking for grad students if you would like to study. All right, anyway, that's enough. All right, so intro to Guinea Radio. So a brief history. So basically Guinea Radio was started by a grant from John Gilmore to Eric Blossom to, at that time, the problem was Congress was proposing to put a bit in broadcast television called the no-copy bit, which literally tells your receiver equipment, you can't record this show because a bit is set. And kind of as a point to show Congress how silly that was, this project was born to say, well, here's an open source TV receiver. Do what you want with this bit. If it's open source, it's pretty easy to flip a bit. So that was kind of initial motivation. It was kind of born out of this program at MIT called P-Spectra, which was kind of a predecessor that did kind of stream processing software radio a while ago. And then Eric Blossom basically threw that all away and did a fresh rewrite. And so Eric was a big piece of this, or a huge piece of Guinea Radio. And he was very, he kind of instilled a strong sense of software engineering and code cloning and tendliness in Guinea Radio, which I think has been a headache at times, but has been worth it every time. And I think we've done a reasonable job of keeping things clean, even though it's hard, just because it's such an unwieldy, large project. So there's always still shortcomings. And then the last note, so Matt Addis also was very involved from the beginning in contributing to Guinea Radio as he built and sold the user on the side. So that was kind of, they kind of grew up together. And then a few years ago, Tom Rondo took over the project from Eric Blossom and John Corgan is the head maintainer of the Git repo. And then there's a handful of kind of core developers that work on feature groups and maintenance sorts of issues. All right, so we have kind of moved to GitHub for development. So if you ever want to submit changes to Guinea Radio, pull requests on GitHub are a great way to do it. They will get looked at and commented and merged if Corgan is happy and they passed the makes. There's a long testing regression process that gets run before merging things so that we don't break our code repeatedly. And that kind of thoroughness has been very helpful to Guinea Radio even though it's sometimes painful. All right, so working groups. There's I think six working groups. We have, these are kind of technically focused working groups. They're typically just a handful of people who are working on kind of advancing features in their area and helping to compile work going on amongst people who have a strong interest in that technical area. So these are embedded. There's a lot of work putting Guinea Radio on ARM processors and Android phones and Android platforms recently. There's a co-processor working group who's really interested in can I put graphics processing units or DSP PCI cards or some sort of co-processor in my Intel box or whatever and use it as an offload inside your Guinea Radio graph. And so coming up with better ways to do that. There's Volk which is basically looking at SIMD, instruction level optimization inside your SDR kernels which has technically now split off into its own project but is still very much in the Guinea Radio ecosystem. There's GRC so a couple guys who are really focused on improving the graphical tools and kind of the usability of Guinea Radio. There's community so this is Martin Braun kind of looking at working with people in the user community to understand what people's needs are with Guinea Radio and software radio and where stumbling blocks are as people try to learn it to try to improve our documentation and our examples and I think that's been a great effort to try to improve the learning curve for Guinea Radio since it is kind of a lot of disciplines jammed into one package. And then there's FOS which I lead which is the functional architectures for your signal processing systems group and this is really looking at how do you do signal processing in Guinea Radio? So we've had a stream processing system in Guinea Radio for a long time where you tie together streams with the circular buffers and you pass these continuous streams of information around and then more recently we put in the message passing system which instead passes these discrete messages around by pointer and then we're also looking at events so how do you kind of tie this to an event system and how do you go back and forth between streams and messages and events quickly in kind of a uniform way that doesn't get in people's way and actually helps people save time in their development. All right, so lastly, there's a Guinea Radio conference. Our first one was in 2011 in Philly but this year it is August, yes, this month I think in Washington. So if anyone is interested, I would definitely encourage you all to attend. It's like a tutorial day, three developer conference days which are focused on applications and systems within Guinea Radio and then a hackfest day on Friday. So that will be a great time. All right, so what does Guinea Radio provide? So Guinea Radio is kind of two things. It's this core of core modules to enable software radio and then it's this whole ecosystem of out-of-tree modules surrounding it maintained by other people as other projects and so the entry portion which you get when you like install Guinea Radio through app get or through the source build is basically these constructs of blocks with ports that form flow graphs and then a scheduler which ties them together and allocates these circular buffers between them so that they can stream samples and items around between the blocks and between the different algorithms. You get Volk which provides you all these SIMD kernels which are used down inside many different algorithms and then you get a number of performance monitoring tools to do measurements of how well these things are running. On the graphical side, you've got GRC which is kind of the Guinea Radio companion which helps you build rapidly build and prototype waveforms. You've got QT plotters, WX plotters. I don't know why this isn't graphical but file tools. And then we have kind of the core blocks, filters, resamplers, IO blocks, test and debug blocks, some basic modulation tools and channel simulation tools and also the forward error correction tools. And then the runtime, there's kind of three ways to use it even though it's really only two. You're running from Python or you can actually import and use Guinea Radio blocks from C++ applications although it's less commonly done because Python is quick and easy. And when you do use Python, all of the actual low level signal processing is going on in C, it's just swig wrapped. So it's a convenience for orchestration and you're not really hurting your performance in most cases using Python. Although Python blocks are the caveat there. I'll throw that out. All right. And then GRC just generates Python but lets you do it from a nice graphical display. All right, so out of tree, the out of tree module community, there's tons of stuff out there. There's Wi-Fi modems, ZigBee modems, DVB modems, probably a hundred different things. And so it's kind of hard to keep track of them all. And so this is the initial reason that PyBombs was created was just kind of to have a big repository of recipes which each kind of point to and briefly describe how to build out of tree modules for Guinea Radio. So you could say, go get me a Wi-Fi modem and it would come back and do it. And SeaGran was then a webpage which was reborn to basically show off all of those modules in a graphical way and show you basically who maintains them, where does it maintain, what's out there. So it's a quick way to get a handle on like what's in the software radio community that I can go play with right now. And it's helped that a bit. So these out of tree modules, Guinea Radio provides basically a template, this mod tool which helps you build an out of tree module very quickly by running this tool. And then it sets up basically a CMake build process for you and a collection of C modules, Python modules, Swig wrappers for your C modules, and then the GRC XML file which makes things show up in the graphical companion tool. And so that's kind of what makes an out of tree module. So running it, there's lots of ways to do it. Everyone has their favorite and different environments kind of are better for different things. If you're just starting and you want to play with it, the live boot environments are definitely the best way to get up and running in like two minutes. And so either the Guinea Radio live DVD or the Pentu come loaded with Guinea Radio and you can just boot it and start running it. I know that the live DVD has Python set up so that you can boot up and then if you want some of those out of tree modules, you can just install them through that quickly. And then we have, so Maitland is our Debian maintainer and so stuff gets merged into Ubuntu quite quickly now I think if you want to apt-get install Guinea Radio or you can always build the whole thing if you want and hopefully have a good reason to. So benchmarking, there's a webpage we have stats.gainradio.org where we basically just run all of the volt kernels on a bunch of, we keep track of there's, I don't know, a couple hundred kernels maybe or maybe a hundred and you can run it on many different processors everywhere from little arms to bigger arms to Intel to Atoms to PPCs or whatever you have. And so this keeps track of what throughput do those kernels get on each architecture because the thing about Volk is it's intended to take advantage of the SIMD instructions that your architecture has. So if you're on an i7, it's gonna try to use SSE 4.1 or FMA or some of the newer ISA features that Intel has had for performance. And if you're on ARM, it's gonna try to use neon kernels. So for each of these kind of operations, you might have a half a dozen different implementations for different levels or different architectures underneath. But the idea is when you write your signal processing algorithm block, you're just gonna call the functional name of the algorithm and you're not gonna worry about hard coding it for neon or for Intel because then you get into this non-portable nightmare. All right, so this is a quick way to see what kind of throughput you can expect on different platforms for these algorithms. There's also this kind of cool performance monitor tool. So if you build a waveform with a bunch of blocks chained together and you start running it off of your radio or off of a file or off of test data, this is gonna basically connect into the running graph and then show you the amount of processor time being used by each block's work function and the buffer fullness of the circular buffer between each block. And so you get this really, this cool kind of view here which has a node for each block and then a line and the darkness of the line indicates kind of the buffer fullness. So you can kind of see which algorithms are backing up your buffer, which ones are taking compute time. And so when you wanna start massaging an application to make it run faster somehow, this is a great way to quickly intuit what's going on and what's slowing down your waveform. And I guess Tom Rondeau just posted this on his blog a week ago or two. He's got this running on Android now. So if you wanna do performance profiling on Android, I think he has an APK or something out there. All right, so that's it for my overview. Now I'm going to, I'm actually on time, which is good. Although we may have lost the screen. What are you adjusting? All right, I've got lots of pixels here. All right, so the first example I was gonna look at and this is kind of the quintessential hello world of Gini Radio, but I'm gonna change it a little bit from its traditional form, is to basically just make a dial tone sound. So this is like your simple first streaming flow graph in Gini Radio. And you can see kind of how quick it is to throw things together in GRC and run them. I wish I had screen mirroring, but I don't. All right, so if you throw down, so also I should mention once you kind of know which blocks you're looking for, you can just search over on this panel here for the block that you want. And it's really fast once you kind of, yes. So most people tend to find things this way once they've worked with it a little bit. So we're gonna put down two signal sources. Each of this will generate a sine wave. I think it's 440 Hertz and 330 maybe. We can add them together. So these are gonna basically output sine wave streams. And so the color here indicates the type of data. So blue is a complex float where there is one real and one imaginary sample for each item. So if you can use just the arrow keys to change the data type. And you'll know of course that this fine color is float. So this is single float version. So we've changed it from complex to a single float. So if we then put down a audio sync, we've basically created it. All right, so if we just make sure this is all disabled, our reference design. All right, so if we run this, I think we've picked the wrong frequencies but you get the point. Yeah, reduce your amplitudes. Yes, they may be clipping. So when we sum, right. So they were lovely harmonics being generated. All right, so there we have it out there. All right, so if we want to do something a little more interesting, we know that a busy signal is 480 and 620. So let's put that in. All right, and it's also, so it's on and off for half a second at a time. So what we can do is just multiply this thing by a square wave, which is going to have a frequency of one hertz. Amplitude of one, oh wait. Yeah, so we need a multiply block. Again, we changed the types. All right, and if all goes well, we have a nice busy signal. All right, so that's like your simple version multiplying or adding and multiplying three signal generators together and spitting the resulting stream out the sound card. All right, so let's do something a little more interesting. So this is really intended for radio. So I'm just gonna show basically an example of how you can kind of start throwing together some tools to start browsing around kind of the radio spectrum and looking at things. So I was gonna use an RTL, but I've decided to be lazy and use the USRP. But the same thing applies to all of this. They work the same. I just have more bandwidth. All right, so we basically just put down a USRP source. There's also an RTL source, which operates exactly the same way. And you can use either one here interchangeably. There is actually the OsmoCom source, which tries to figure out what radio you have on your machine and then uses that one. So that if you put this in your waveform, it should work kind of depending on whichever device you plug in as long as OsmoCom supports it. So it's a little kind of an API for your radio, I guess. But I won't use that for now. All right, so the first thing to do is really just to look at the data. And so the QT plotters, if you go under QE widgets, you have QT and WX. You've thoroughly seen the WX ones yesterday from Balance Talk. So we'll use the QT ones, except that I can really only find things by searching. All right, now there are these nice widgets that let you input values from the GUI. I think Ballant was also using these the other day. So I'm going to name this one FC as the center frequency. And this will just be a variable that you can move around. And so let's say we want to go from 500 megs to two, three gigs. And let's just point it at the Wi-Fi band, which I can never remember exactly where it is. Let's go 4, 4, 5. All right, yes, let's do that. All right, we'll do the same for gain, which will go, start at 40 and go from zero to 100. I think the max is really like 70, but it depends on the user and their series you're using. And I think that's all we need. So the sample rate, let's put this up to 32 mega samples. And then you can just put the variables in here, except that not there. FC gain. All right, let's disable all this stuff. All right, so if you put FC here, also it displays the right frequency bands for you. All right, so running that, it will not work, of course. Why are you not happy? This is a terrible video cable. So this is a good time to show you the UHD tools. So if you install with PiBombs, one of the things that is typically done is installing into a prefix so that you can have multiple working copies of all of your modules, thus the sourcing. All right, so I apparently need to do this real quick, but I'll let it go and focus on another demo first. So we will come back to spectrum browsing momentarily, and I'll work on the message example for now. All right, so stream ports have been in radio since the beginning, and I believe maybe two years ago, we added messages, and the idea is to be able to pass around these discrete sized items. So the idea being like one packet or one burst or one kind of PDU of some variety. And it's going. So PDUs, or sorry, messages are built on top of a data structure in Guinea radio called the PMT, which is the polymorphic type, and this is kind of modeled after kind of a functional language, kind of a loosely typed data type, and there's Python mappings for all of it. So if we look at a message, what is strobe? So a message strobe is a block that is just gonna send out a message or a PMT data type at some periodicity. So here we're sending out the string test pushed into a PMT every 1000 milliseconds or one every second. So if you put down now a message debug block and run this, you're basically just gonna see every second, it's gonna print out the message it received, which is the string test. So you've basically built a very simple message passing system here. And this is like the hello world of messages, right? So, but this is just, all this is is a string, right? We want more interesting data structures. Typically we're passing around some kind of a PDU, whether it's an Ethernet frame or an IP packet or a big chunk of sample data. And so we have this other construct, which is called a PDU, which is basically just a PMT type with the right structure. So it's a tuple where the first element is a vector of data, typically samples or bits. And the second one is a dictionary, which can contain annotations to the packet that you might wanna add. So we have a couple blocks in here. We have this random PDU generator, which we can put in the middle here. And we will go to print PDU now. And let's make this smaller. So we'll say that we wanna generate PDUs that are between four and eight bytes. All right, so we run it and we see we're now basically generating these random chunks of bytes that are somewhere between four and eight bytes long, I think with the module of two length. So we always have an even length in bytes. So this is useful for testing radios. You might just want a bunch of random packets to send out. And so there's lots of things we can do with that. So all right, if we look at, so there's these tools that come with your radio, there's the socket PDU and the ton tap PDU. And these are built to interface with this message PDU construct. So the socket PDU is simple. This is just gonna set up whether we want a TCP client or server or a UDP client or server. Let's just do a TCP server on localhost 5201. All right, so if we run this, we see no output, which is fine. We disabled the debug. But if we tell that to localhost 5201, there we go. So we're getting our messages out of that socket. So this is a great way if you want to interface with some other software on your system to work with Gini Radio, you could quickly build up any kind of socket program you wanted to interface with that. And somehow we'll quit telling it. All right, you can do the same. So ton tap PDU is kind of cool. This brings up a tunnel interface on your computer. In this case, it'll be called tap zero. And so along with E0 and WLAN zero, you'll have tap zero. And essentially any PDUs that come into it will look like an ethernet packet arriving on that interface. And anything that goes into it will then go out so you see that there's a message in and a message out. So we could, for instance, put a message debug on the output and we'll see whatever the OS does sends into a new interface when it comes online. And I don't think I can do taps as root. So let's run this with sudo or non-root. Examples. All right. Actually, this user doesn't have CDF. All right. So we're back in examples directory. All right, so if we run example two, we first have to import the environment. Let me run it. Why is it, there should be no usurp in this waveform. Oh, I ran the wrong example. Great. Usually user error. All right. All right, so it should have set up our interface. All right, so we have tap zero. And if we were to bring up, run that command to set an IP, you would see a flood of ethernet traffic and whatever the OS likes to send out to volunteer to the local network. So another great way to interface your radios with Linux. So basically, if you build the modem side to these messages, you can now, you don't have a really standard way to just take any modem and plug it in as if it were a wifi adapter with any kind of fi that you want attached, which is really cool. All right, so then the last thing, there's also this pcap block. So, and I don't know why. So we can, if we want, just write pdus out to pcap file, which we just tell it it's ethernet. We're really just putting garbage in these, but if you were to use a real radio, you could put whatever you wanted in there over here. All right, so here we have, of course it's malformed because we just put garbage in there, which is what we expected. But we can pretty, this is a great way to use tools like Wireshark with Gini Radio. So we don't have to reinvent the whole Mac layer in Gini Radio. All right, there's also a playback. So if you want to have some traffic that you wanna play back into some kind of a radio, you can just play your pcap back through the messages in that way. And it's really cool. It uses the timing that's in the file so that everything is timed as if you had seen it previously. All right, I think we should be able to run this now, potentially. Now we have a firmware image. So Wi-Fi is bursting all over the place. So Tom added this control panel recently, which makes the QT GUI a little bit more friendly, kind of like WX was. And this was a complaint for people for a long time. But now you can come in here and kind of play with things pretty easily. Autoscale, all right. So basically, here's our nice spectrum plots. So we may wanna look at a few things. So if we look at the QT time sync and a waterfall sync. So one of the things in QT GUI is you can give it these GUI hints. And if you're, this basically tells you the position to put it in a window. So I think WX does the same thing. So we can kind of quickly lay out a little GUI type thing. All right, so now we should have a time plot, frequency plot, and a waterfall plot. And we're gonna overflow, but that's fine. We'll just ignore that. All right, so now we have Wi-Fi coming in. So triggering was also missing for a long time from QT GUI, but is now in, which is great. So if we look at, now we're going up to what, 0.1. So let's trigger at, let's say 0.1.5. All right, so now we're triggering. So if you wanted to look at some bursting data, kind of like any traditional oscilloscope, you can do the same sort of thing here. And I'm sure you could play with the thresholds and make it look nicer than that, if you wanted to. All right, so one of the things that has recently been added, there's these stream lambda blocks. And this is new, and it's gonna run terribly because it's Python at 32 mega samples a second. But we'll do it anyway because the overflows aren't that big a deal when you're just looking at stuff, in this case. So the idea of a, well, let's put this guy in the bottom right. So the idea of the stream lambda block is, if you just wanna drop some algorithm into Gineradio, and you don't wanna worry about an out-of-tree module or writing a Python block or a C block, this is like a super lazy way to just put some new function into a flow graph. And so in Gineradio, all of these fields are really Python, essentially. So you can just put Python expressions in a lot of these things. And so what we do here is we define a lambda function that gets passed into this lambda block, and then that gets run on the work function every time data comes through. So this is like a really quick way to just do simple things with your data. So in this case, the default is to take the magnitude squared, so we skip, we take every second element of the data, we square it, and then we scale it by 0.1. So this is kind of meaningless. It's just kind of the example lambda block. So let's instead say we just want the numpy abs. All right, so we've now written a block, essentially. It's crappy and it's slow because it's Python, but that's fine, we can optimize later. And seriously, like get things working before you optimize. All right, so we now have basically created a complex to abs block with our quick hackery and now we have the abs here. You may also see those red triangles flashing through here. Those are stream tags coming from the user that tell us the time, frequency, and sample rate that this thing is set up as, which are sent periodically downstream and they just kind of flash on screen briefly. I think if we change the number of points to be like, I don't know, what's gonna not crash it. You can't make this too big. Yeah, you could, that's a good point. I don't know if I've done that before. Let's figure out RX time. Yeah, except for the, UHD has this nasty, well, it's not really UHD's fault, it's USB3 chipsets suck. Anyway, all right, so you get the point. The last thing here that I wanna show is recording data. So let's say if this thing come back to life soon or we can always, can always X kill. All right, so, all right, so we're gonna put now a file sync and then we're gonna disable the plots. So let's just write out tempradio.dat and we'll do this the right way. A head block will basically make it run for end samples and then quit, so it doesn't just run forever. So let's say int of Samperate. So we'll record one second worth of data. All right, so we run this. He apparently needs the user to be rebooted and we'll destroy my video cable. Run that again, it's gonna flash the image. This is annoying. All right, I was running it as root instead. Apparently root wasn't allowed to use USB, which is interesting. Once again, flashing. Right, yeah, it doesn't, so there's no persistent memory. I don't know if I can correct me if I'm wrong, but all right, so we run and then it should exit. It's a GUI, so it'll just sit there. All right, so we have this file now. So gonradio has some tools for looking at files, but they've kind of, they've always been somewhat cumbersome on large data files. So there's this tool I put together recently called Such Samples and the whole idea here is to make it easier to look at large files on disk. So we just put our file in there. It assumes it's this complex 64 type, which it is. And then what's going on here is there's really just a couple of blocks here. You have a message file source, a range input, and then two plots, so these are not stream plots like we were showing before, but these are our message-based plotters, which take in a chunk of samples and then just plot that chunk. All right, so if we run this, we now have basically the beginning of our file. And you can kind of move around here at will. So this is just kind of an easier way to do things than some of the old tools that we had. So yeah, you can look at your wifi that we just recorded. All right, the last thing, there's also a Lambda, a message Lambda block, where you can do the exact same thing we were doing before with the stream Lambda using a message Lambda. And so if we, well, actually, let's use the one that's already been made in the interest of time. So this is basically, we've defined this variable F2 somewhere here, and if you look at it, this is basically just going to compute a simple autocorrelation of the input. So this is kind of like the fast autocorre that Ballant was showing yesterday. This is a really quick way to build something like that to look at your signal. And let's turn this one on to you. All right, so now we have autocorrelation, our time, our power envelope, and our spectrum. And we can move around in the file and kind of see how things change. So this is a great way to look at data and figure out what you're dealing with. All right, so lastly, so for the FSK modem, so this is kind of an example, a simple FSK transmitter using all of the message blocks that we've shown here. So we're basically strobing every 500 milliseconds, creating a random PDU, inserting a preamble. So we insert this kind of known series of bits on the front of each burst. We then just wrote the modem in three lambda blocks, essentially. And so what happens here, and this is, I fear a whole new level of hackery for good radio, but it's also like really, really convenient for prototyping. And you just have to know that you should optimize later and write things in C if you care about performance. This numpy is pretty good, but it's not like compiled C. All right, so here we're mapping zero and one bits to plus and minus one, essentially. Here we are reshaping it such that we take one bit and we have SPS of them, our samples per symbol. So we may have multiple samples for each symbol coming out. We then do our FSK modulator. So this is multiplying by a complex exponent at a certain deviation. So we're basically taking those plus and minus ones replicated and then multiplying them by these plus and minus sinusoids like an FSK modem would do. And then, so this is where event stream comes in. And the idea here is that event stream is kind of one way to bridge between the stream and the message domain. And so here we can throw messages in and we have essentially a stream of samples coming out. And this stream, it always comes out, right? So if there's no message in, it's gonna be spitting out zeros constantly. And so what happens is we just know that their sample's coming out and whenever a message comes along, he drops it into that stream, goes through a pulse shaping filter, through a throttle, through our channel model, and then gets plotted. So if we run this, we see that every 500 milliseconds, we get one of these bursts that gets dropped into the stream and this is the burst samples. And then you see here the spectrum of the FSK transmitter. You have your two peaks of kind of modulation on each one. And so this is just kind of a really quick way to throw together something like an FSK modem. And there is a demod half, but it's slightly more complicated. And I don't think that there's time at this point. So if there's any questions, I would like to take them. All right, I guess there's no time for questions. I will start five minutes early. But thanks, I'm excited to see this many people interested in getting radio and excited to see more people building projects with it and contributing. So please send pull requests and flame the mailing list.