Streams and Vectors

This tutorial describes the differences between a Stream and a Vector.

The previous tutorial, Packing Bits, describes how to pack a stream of bits into the byte or char data type, and then unpack them back into a stream of bits. The next tutorial, Creating Your First Block, describes how to use the Embedded Python Block to create your first signal processing block in GNU Radio.

Streams
Streams in GNU Radio are what convey the information between blocks and are represented by the arrows connecting blocks in a flowgraph. A stream must have a data type, such as Float 32 or Byte. A stream carries 1 sample for each time instance and are used to represent and process serial data.

The Signal Source block produces a Complex Float 32 stream. The output of the block at each time instance contains 1 complex sample:



Vectors
Vectors carry multiple samples per time instance, representing data in parallel. By analogy, a stream represents a scalar at each time instance whereas a vector represents an array at each time instance.

GRC uses lighter colors to represent streams and darker colors to represent vector outputs:



Streams to Vector Flowgraph Example
The following example will describe how to convert a stream to a vector and back to a stream. Two complex sinusoid streams will be converted to a 2-element vector, displayed, and then converted back to their independent streams.

Add two Signal Source blocks to the workspace:



Edit the parameters of the second Signal Source to have a frequency of 100 and amplitude of 0.1 to distinguish it visually from the first Signal Source:



Click OK to accept the parameters.

Search for the Streams to Vector block, drag it into the workspace and connect it to the Signal Source blocks:



The Streams to Vector block acts as an interleaver, taking the two serial stream inputs and converting them to a two-dimensional vector output. The block takes the sample from the in0 port and places it into the first element in the output vector, and then takes the a sample from the in1 port and places into the second element in the vector.

Search for the Vector to Stream block which will serialize the vector data, and then add three QT GUI Time Sink blocks:



Edit the titles for the three QT GUI Time Sink blocks so the can be distinguished from one another. First, edit the block connected to the Signal Source with frequency 1000 and amplitude 1 to have the title Signal Source A:





Now edit the QT GUI Time Sink connected to the second Signal Source with frequency 100 and Amplitude 0.1 to have the title Signal Source B:





Finally, edit the QT GUI Time Sink connected to the Vector to Stream block to have the title Interleaved Signal Sources:





Running the flowgraph will now display three time sinks, Signal Source A, Signal Source B, and Interleaved Signal Sources. Note that the Interleaved Signal Sources time sink displays interleaved samples from Signal Source A and Signal Source B:



Vector to Streams Flowgraph Example
The following example will deinterleave the vectorized data and convert it back into two streams.

Search for the Vector to Streams block, add it to the workspace, and connect it to the Streams to Vector block:



The Vector to Streams block deserializes vector samples and converts them into streams, performing the inverse operation to the Streams to Vector block. Right-click and delete the arrows connecting the two Signal Source blocks to the QT GUI Time Sink blocks:



Then move and reconnect the two QT GUI Time Sink blocks to the Vector to Streams outputs:



Running the flowgraph shows the vectorized samples have been separated back into the two correct streams:



The next tutorial, Creating Your First Block, describes how to use the Embedded Python Block to create your first signal processing block in GNU Radio.