 In the previous lecture we have gone through the raised cosine waveform and how using sink and raised cosine waveform of course can solve the problem of the rectangular pulse being banned and limited. But we also saw that using the sink has disadvantages especially in terms of the rate of decay and it is not being robust in the case there is jitter. In this lecture we are going to put together some simple simulations on GNU radio wherein we will explore the characteristics of the raised cosine and in particular using the root raised cosine waveform. We will then repeat our amplitude shift keying simulation that we did some time ago using root raised cosine. We will use both the root raised cosine at the transmitter as well as the receiver and show that this particular approach yields a way wherein you can recover the symbols that are sent at the transmitter at the receiver without any issues while generating a signal that is banned limited. So that is the purpose of this particular lecture I urge you to try it out on your own as well. Before we begin our pursuit of pulse shaping for modulation we will first inspect a couple of useful blocks that allow us to do interpolation and decimation easily. First let us introduce the interpolating FIR filter block that you have seen already. So ctrl f or command f interpolating FIR filter and we will place it over here we will begin with float to float real tabs. We will then also use a vector source that will provide initial data for this filter. So ctrl f command f type vector grab this vector source double click the vector source to keep it simple we will set the vector source to float and we will give the inputs as some set of numbers let us say 1 comma minus 1 comma 3 comma 2 let us say these as a sequence of 4 numbers 1 minus 1 3 and 2. Now these numbers are going to be generated at around the sample rate and fed to the interpolating FIR filter. Now we will also add a throttle ctrl f or command f type throttle double click the throttle we will set the throttle to float connect the interpolating FIR filter to the throttle and we will then get a time sink ctrl f or command f type time hit this time sink set this time sink to float we will add a grid and auto scale say ok and then we will connect this over here there is only one thing missing which is setting the interpolation and the tabs. Let us do this right now as an example let us set the interpolation to 2 which basically means that for every input sample this filter is going to output two samples then what are the tabs this is the filter that is going to be applied on the input samples before outputting them from the output of this interpolating FIR filter as a simple example let us set this to be square bracket 1 comma 1 square bracket what this will do is that it will repeat every sample twice let us actually have a look at whether that is the case if we execute this flow graph let us actually middle click and choose stem plot and let us zoom into a particular region what you can see is that you have this one one you have this minus one minus one and then you have this three three and then this two two which is exactly the same samples as the original vector source except that they are repeated two times the same weightage let us actually change this and let us set this to let us say 0.5 so the second tab of this filter is 0.5 now if I execute this flow graph again middle click set it to stem plot zoom in you can see that we start with let us say we go to the absolute beginning so that we have no ambiguities it's one half because it's one followed by half so the impulse response of your filter which is one comma half is imposed here minus one minus half here you have three and one and a half followed by two and one an important point is that this filter did not have the same length as the interpolation as an example let's actually set this to something like one one one one in which case you can imagine that this one is essentially replaced with one one one one one and then this minus one is going to get become minus one minus one minus one minus one shifted by two samples and added let's visualize this one we'll go to the stem mode we'll go to the absolute beginning so the original one became one one one one subsequently the minus one became minus one minus one minus one minus one and is added after a shift of two because our interpolation is two and those ones and minus ones got cancelled these subsequently the minus one minus one minus one got added with these threes so three three three three on the second and third so you have a two two over here sorry you have a two two over here and then the effect of this three and two come together and become five so an important point to remember is that the taps of the filter need not be the same length as the interpolation in fact if it is less for example let's say it is square bracket one this is going to do the traditional up sampling by insertion of zeros in other words you're going to get one zero minus one zero three zero two zero if you look over here make it stem one zero minus one zero three zero two zero which is exactly what happens over here the corresponding undo operation is called the decimation so in this particular case let's actually say go back to our one comma one which is basically up sampling by repeating the sample twice so now your one minus one three two is going to become one one minus one minus one three three two two let's make this a stem as you can see it's one one minus one minus one three three two two now let us get back these original samples by decimating this interpolated value okay so to decimate this interpolated value we are going to fetch our decimation filter so controller for command F decimate and we will get the decimating FIR filter we will double-click it set it to float to float real tabs set the decimation to two and now the question is what should the taps be let us start with the most basic one which is square bracket one which is the same as square bracket one comma zero and let us repeat a Qt GUI time sink I'll do control C control V or kind of one C command V connect this and connect interpolating FIR filter to the decimating filter and see what we get let us label our sinks so that we don't have any confusion we will double-click this and call it interpolated we will double-click this and call it decimated let us now execute this so this is the decimated and I can just go to middle click and say stem plot this is the interpolated so now let us zoom into the beginning of both of these so here we have one one minus one three three two two over here we have one minus one three two one minus one three two which is the exact same input sequence at the exact same rate which makes complete sense now let us change this decimating filter to make it one one and see what we get if you make it one one and let's look at the stem plot we end up getting something like three zero two five three zero two five why do we get this this is because this filter is applied on the interpolated output and the result is essentially presented after decimation so in this particular case let us make both stems over here what we have is let me go to the beginning of this as well we have a three here the reason is because if you essentially take this one one filter and flip it what is to the left of minus one to the left of minus one over here there's nothing but if you go to the right let's look at this particular one to the left of minus one is three over here you can see that two rather the left of minus one is two so the one multiplies this two and the one multiplies this three and you end up getting three then the one multiplies this one and the one multiplies this minus one and you end up getting zero then the one multiplies this particular three and this particular minus 1 and you end up getting 2. Finally the one ends up multiplying this particular 2 and 3 and you end up getting 5. Therefore in this case the filter essentially applies on the interpolated input and the result is presented to you and because of down sampling you have to go one off so every other output is what you get. In other words you apply the filter 1 1 onto this input and take every other sample to get this decimated output. You can see that this particular this particular pattern repeats and you end up getting what you expect if the input is 1 1 minus 1 minus 1 3 3 2 2 you filter take every other sample. Interpolating and decimating are very common operations and this will come in handy when we do our pulse shaping. Now to get an idea of how we can do the pulse shaping let us actually inspect how our root trace cosine pulse looks like. Let us first see how we can create the RRC filter using GNU radio. Now to this end we are going to use an inbuilt GNU radio functionality which is in Python to create the filter tabs. So let us do that by just putting it in a variable so I am going to say control f for command f and variable and grab the variable over here double-click it and call it rrc underscore tabs. Now this rrc tabs is going to contain our rrc filter samples. To design this rrc filter we are going to use the filter design tools inbuilt in GNU radio but write the code for it or rather the one line code for it. You double-click this and you say FIR DES short for filter FIR filter design dot root underscore raised cosine. We will first need to specify the gain which is 1 followed by the symbol rate which in our case is a thousand symbols per second then we need to give the excess bandwidth which we can choose as let us say 0.35 to begin with and finally the number of filter samples let's say 8192 seems to be a good number although this is only an indicative number your actual filter may be a slightly different length. Let us say okay now if you put your mouse over this you put your mouse over this you will get an 8193 length filter which looks like some you know it looks like there are zero values and it looks to be symmetric also because it starts and ends with similar values fine let us now inspect how this filter looks like we'll get a vector source control F command F vector source double-click the vector source the output type we will set to float and we will just make the vector rrc underscore tabs next we will add a throttle the throttle we will double click make it to float I notice that our sampling rate should be 64k so let us change by double-clicking in that to 64000 we will then connect our vector source to the throttle and just add a time sink so control F or command F and get a time sink double-click the time sink and make it float add a grid add auto scale and for viewing it conveniently let us just set the number of points to the length of the rrc tabs we can do that by just writing a python expression len and in brackets rrc underscore tabs this will make it convenient to visualize you will say okay connect this run the flow graph and you will essentially see what looks like a sink or what looks like a raised cosine but it is not really a sink it is a root raised cosine because if you inspect it very carefully we want the zero crossings to be perfect so let's say that if you look over here this is going to be at 64 milliseconds there is a peak and at 65 milliseconds you expect a zero crossing which is not there this is not a cause for concern because the raised cosine pulse is what is guaranteed to have the appropriate zero crossing not the root raised cosine okay let us see what happens if we get a raised cosine to get a raised cosine we just need to convolve the root raised cosine with itself alternately in the Fourier domain you have to multiply the Fourier transform of the root rate cosine filter with itself so let us do the convolution we'll just say control f for command f and get an interpolating FIR filter take that and place it here we will double click it interpolation we will keep as one we'll float to float real tabs we will set the tabs to RRC underscore taps and say okay and we will view it on the same time sink we will double click it change the number of inputs to two then connect the RRC taps over here connect this over here now if you visualize you will see that this pulse is essentially shifted out the reason is because there is a delay which this interpolating FIR filter encounters so add another delay element so we'll say control f for command f we'll grab the delay block place it over here we will double click this delay block set the delay to float and the delay to lend RRC taps double divided by 2 and connect the original root raise cosine pulse through this delay and now we can visualize you can see that the both the peaks are close but it's still very inconvenient so let us make let us remove this delay from here and let us instead connect it to the second one connect the output directly connect this delay over here and let us execute this and now we can see that the red one is what we should expect should have the zero crossings so let's zoom in a little the red one seems to have a peak over here 0.0157 why that is we will see momentarily it has a peak at 64 milliseconds and it goes to 0 at 65 milliseconds which satisfies our Nyquist ISI free criterion much like the sync another thing is that you can see these little oscillations let us actually handle those things one by one the first thing is that we can change the gain over here for example we can set the gain to be let's say 64 we set the gain to be 64 if you then run you can see that there is a high peak over here of 64 the reason this happens is because if you convolve this filter with itself there is a significant amplification so what we can do is we can just take away that gain over here by dividing all the values by 64 but to do that we must first convert this to a numpy array so let us do control f for command f and say import we will double click this and say import numpy and then we will change this FIR variable FIR dash variable to numpy dot a r r a y parenthesis and close the parenthesis over here and now we can just divide this by Sam rate upon 1000 which is 64 and let us inspect it over here now you can see the amplitudes match this is an issue with the scaling which we have addressed by just adding a gain of 64 and taking it away when we do the raised cosine so now when you have the raised cosine at 64 milliseconds it is a peak and at 65 milliseconds there is a zero at 66 milliseconds there is again a zero city 7 milliseconds again there is a zero which is exactly what we need next let's have a look at these oscillations let's say around 66 67 around 68 milliseconds this goes away let's now change the RRC taps to have this 0.35 becomes something very small let's say 0.0001 0.0001 is very close to a sink so let's execute this you can clearly see that this is a very sink-like behavior and even around 81 83 90 100 milliseconds it doesn't really die down because this is very close to a sink there is almost no excess bandwidth let us now double click our variable and let us actually make this we check 0.35 let's make it 0.9 which is 90% excess bandwidth remember that at 0.35 around 69 milliseconds we had a very small amount of amplitude now if you zoom in you can see that even around 66 milliseconds the amplitude essentially dies down so here you can clearly see that the excess bandwidth which is being used makes the pulse thinner in the time domain at the cost of making it fatter or increasing the bandwidth usage in the frequency domain so now this particular picture allows us to understand how the root trace cosine and raised cosine work so if you inspect this particular command that we have used to generate the root trace cosine this will come in handy when we generate roots trace cosines for up sampling and down sampling with our interpolating and decimating FIR filters and that is something we will see subsequently we are now going to repeat our or Pam for experiment but this time we will use the root trace cosine pulse and use the root trace cosine to recover our symbols as well since we are going to use our same modus operandi let us double click this sample rate set it to 64000 first control f for command f we will grab a random source the random source we will place here and let's say it goes from 0 to 4 which will give us numbers 0 1 2 3 and we will make it a 1024 samples which keep repeating we will then grab the chunks to symbols and the chunks to symbols will connect the random source symbol table let's make it 0 1 2 3 output type let's keep it as float and one dimension next we are going to up sample this and using an interpolating FIR filter but before that let us design our root trace cosine filter so I am just going to say control f or command f and say variable and grab the variable block place it here change the id to rrc underscore taps and the value will be FIR dis dot root underscore raised underscore cosine and let's we will set the gain to exactly the amount of up sampling that we are going to do so Sam rate upon 1000 then we are going to specify the sampling rate then we will specify the symbol rate which is 1000 then we will set an excess bandwidth of about 0.4 and finally we will set the length to be 8192 any reasonable which is enough 8192 is good for us next we will get the interpolating FIR filter so control f or command f and type enter and get the interpolating FIR filter double click it set it to float to float the interpolation will be 64 or will write Sam rate Sam underscore rate upon 1000 which is basically we want a thousand you know want one symbol every millisecond so we set it to Sam rate upon a thousand taps rrc underscore taps what this will do is that it will essentially place 64 zeros in between each of these Sam symbols that are being generated and then filter them with this rrc taps so that you get a nice root trace cosine response connect this over here we will set the throttle so control f for command f we will grab a throttle we will double click the throttle and set it to a float and finally control f for command f and type time and get a time sync will double click the time sync set it to float we will say rrc and number of points let's make it 8192 and let's make it yes and yes for grid and auto scale and let's connect these and inspect what we get so we end up getting some waveform which seems to indicate that there is some data that is going on we can't really make out the values well the values seem to be between zero and near three which makes sense but exactly figuring out the zero crossings etc is not really possible because that makes sense only when you do a race cosine as a quick example let us just double click this and then make it two inputs and pass the same sequence to the same filter and inspect what happens with a race cosine so I can click here hit control c or command c control v or command v to paste double click it and set the interpolation to one and connect this FIR filter to this FIR filter and over here we can visualize and we will be able to see our actual data in this particular signal how if you run like this of course there is a gain issue to address the gain issue we will again close this is a control f or command f say import we will import numpy type import numpy change the rrc taps to be a numpy.array which is convenient for doing arithmetic so we are just enclosing this within a numpy.array now these rrc these rrc taps we are going to divide by Sam weight upon a thousand what is the double divide for integer division now let us stop and let us see if we can make something out over here so let's see it appears that over here there is zero around the 40th millisecond so now let's go to the 41st millisecond at the 41st millisecond the value seems to be around three at the 42nd millisecond the value seems to be three again at the 43rd millisecond the value seems to fall down to one and at the 44th millisecond it seems to be three so it does appear that when we have an actual raised cosine we are able to see the actual data with that is embedded within this root raised cosine signal our next task is to decimate after putting the raised root raised cosine and recover the data for this we are going to get a decimating FIR filter so control f for command f decimate thing FIR filter we will double click this decimating IR filter set the decimation to 64 or rather sample rate upon thousand taps are RRC taps the same ones we are choosing they are symmetric we do not really mind say okay we will set it to float to float real taps we will get a separate time sync so we will say control f for command f and qt gi time sync we will double click it we will set it to recovered data we will require a grid we use auto scale let us also set it to a stem plot for convenience and we will also make it float and connect this output over here and interpolating filter output to this and let us try executing this now let us look at what this recovered data is of course there is a scaling what is that scaling the decimating filter we will divide by 64 or sample rate upon 1000 now let us actually inspect this so as we can see the recovered data seems to make sense because it takes values 0 1 2 and 3 in a random sequence indicating that this is likely related to the input random source to check we can just get the random source also over here we double click this GUI time sync set the number of inputs to 2 we then get an int to float so control f for command f say int to float we connect this random source over here and before we connect this particular int to float directly there is a delay because this interpolating FIR filter is going to cause some amount of delay this decimating FIR filter is going to cause some amount of delay so we are going to add control f for command f a delay block and we will double click this delay block set it to float and we will set the delay to 128 the reason we choose the delay as 128 is because this is the effective delay between the received and the transmitted signals due to the causal nature of this particular RRC filter so now we connect this over here and connect this over here we can hit play and we see that the input and output match exactly the final step for us is to ensure that the data rather the spectrum usage is as promised for example in this case we have said that we are using about 40% of excess bandwidth let us do control f for command f and grab an FRA queue QTGUI frequency sync we will double click it we will set the type to float we will set the window type to rectangular we will also set a grid and auto scale and let us connect the output of the interpolating FIR filter over here and see what the actual excess bandwidth usage is so there is an extra peak that can be attributed to the fact that our symbols are between 0 and 3 as opposed to between you know something which has a midpoint around 0 if you really wish to address that you can choose a different set of symbols like minus 3, minus 1, 1, 3 these do not suffer from that problem because this will give you 0 average DC so in this case you will now see that the spectrum usage is around you know minus 0.6 to around 0.6 which indicates like when you compare 0.5 to 0.6 that is about a 20% 20% over here corresponding to 40%. Let us go to the one extreme let us set this to not 0.4 but 0.0001 which is very much like a sink in which case you will see a very flat spectrum ranging between minus half and a half kilohertz which is exactly the amount you need in order for you to get the in order for you to get the 1 kilo sample per second symbol. Let us go back to our original 0, 1, 2, 3 and let us go to the other extreme where we set the excess bandwidth to 0.9 in which case you will see that you end up using almost the whole bandwidth from about minus 1 kilohertz to about 1 kilohertz it is actually star you know let us say max hold or let us do an average we will start averaging it so you can see that the pulse is being used from about minus 1 to 1 kilohertz minus 0.9 to 0.9 kilohertz which is strongly indicative of the fact that we are using a lot of excess bandwidth the waveform also looks very much like a sink related one which sorry the root trace cosine one where you can almost directly make out the original sequence and at around the midpoint let us say around 0.5 you will get about 50 percent bandwidth usage so it will go till around 0.7 or 0.8 kilohertz so it is about minus 0.7 to 0.7 kilohertz. So in this manner we were able to put together a baseband waveform that utilizes the root trace cosine and this enables us to design pulse shaping that honors the bandwidth constraints much much better than using a rectangular pulse. In this lecture we have put together a simulation of the root trace cosine we have seen how using the root trace cosine both at the transmitter and the receiver allows you to have an ISI free communication that is you get the raised cosine that satisfies the Nyquist ISI free signaling criterion. This of course is satisfied by the sink as well but the excess bandwidth that the root trace cosine allows allows you to trade off some properties particularly the 1 by t cube decay that makes the raised cosine much more robust to jitter. The root trace cosine at both the transmitter and receiver is a very practical approach that is often employed in many practical communication systems. Of course in this simulation we have ignored the presence of the channel GCFT in future lectures after we cover demodulation we will carefully look at a way by which GCFT that is the channel is also present and can be compensated for by using equalization. Thank you.