diff --git a/examples/pu_tx_1_channel_mod.grc b/examples/pu_tx_1_channel_mod.grc
index 3c3e74fc11e56e7ce9fc66c99d46f36c2e6c4937..17939d330e70832844080cfe3e08de8690e5a3c6 100644
--- a/examples/pu_tx_1_channel_mod.grc
+++ b/examples/pu_tx_1_channel_mod.grc
@@ -32,23 +32,6 @@ options:
     state: enabled
 
 blocks:
-- name: channel0
-  id: variable_qtgui_check_box
-  parameters:
-    comment: ''
-    'false': 'False'
-    gui_hint: ''
-    label: Channel 0
-    'true': 'True'
-    type: int
-    value: 'True'
-  states:
-    bus_sink: false
-    bus_source: false
-    bus_structure: null
-    coordinate: [782, 105]
-    rotation: 0
-    state: true
 - name: fft_len
   id: variable
   parameters:
@@ -73,6 +56,35 @@ blocks:
     coordinate: [259, 71]
     rotation: 0
     state: enabled
+- name: random_scenario
+  id: variable_qtgui_chooser
+  parameters:
+    comment: ''
+    gui_hint: ''
+    label: Random Scenario
+    label0: 'False'
+    label1: 'True'
+    label2: ''
+    label3: ''
+    label4: ''
+    labels: '[]'
+    num_opts: '2'
+    option1: 'True'
+    option2: '2'
+    option3: '3'
+    option4: '4'
+    options: '[0, 1, 2]'
+    orient: Qt.QVBoxLayout
+    type: raw
+    value: 'False'
+    widget: combo_box
+  states:
+    bus_sink: false
+    bus_source: false
+    bus_structure: null
+    coordinate: [808, 8]
+    rotation: 0
+    state: true
 - name: rf_freq
   id: variable_qtgui_range
   parameters:
@@ -106,42 +118,61 @@ blocks:
     coordinate: [182, 8]
     rotation: 0
     state: enabled
-- name: tx_gain
+- name: scenario
   id: variable_qtgui_range
   parameters:
     comment: ''
     gui_hint: ''
-    label: Tx Gain
+    label: Scenario
     min_len: '200'
     orient: Qt.Horizontal
     rangeType: int
     start: '0'
     step: '1'
-    stop: '92'
-    value: '40'
+    stop: '1'
+    value: '1'
     widget: counter
   states:
     bus_sink: false
     bus_source: false
     bus_structure: null
-    coordinate: [472, 8]
+    coordinate: [695, 9]
     rotation: 0
     state: true
-- name: analog_const_source_x_0
-  id: analog_const_source_x
+- name: scenario_duration
+  id: variable_qtgui_entry
   parameters:
-    affinity: ''
-    alias: ''
     comment: ''
-    const: '0'
-    maxoutbuf: '0'
-    minoutbuf: '0'
-    type: complex
+    gui_hint: ''
+    label: Scenario Duration (ms)
+    type: real
+    value: '1000.0'
   states:
     bus_sink: false
     bus_source: false
     bus_structure: null
-    coordinate: [599, 121]
+    coordinate: [960, 9]
+    rotation: 0
+    state: true
+- name: tx_gain
+  id: variable_qtgui_range
+  parameters:
+    comment: ''
+    gui_hint: ''
+    label: Tx Gain
+    min_len: '200'
+    orient: Qt.Horizontal
+    rangeType: int
+    start: '0'
+    step: '1'
+    stop: '92'
+    value: '40'
+    widget: counter
+  states:
+    bus_sink: false
+    bus_source: false
+    bus_structure: null
+    coordinate: [472, 8]
     rotation: 0
     state: true
 - name: analog_random_source_x_0
@@ -182,29 +213,6 @@ blocks:
     coordinate: [247, 517]
     rotation: 0
     state: true
-- name: blocks_selector_0
-  id: blocks_selector
-  parameters:
-    affinity: ''
-    alias: ''
-    comment: ''
-    enabled: 'True'
-    input_index: channel0
-    maxoutbuf: '0'
-    minoutbuf: '0'
-    num_inputs: '2'
-    num_outputs: '1'
-    output_index: '0'
-    showports: 'True'
-    type: complex
-    vlen: '1'
-  states:
-    bus_sink: false
-    bus_source: false
-    bus_structure: null
-    coordinate: [742, 226]
-    rotation: 0
-    state: true
 - name: blocks_stream_to_tagged_stream_0
   id: blocks_stream_to_tagged_stream
   parameters:
@@ -240,9 +248,30 @@ blocks:
     bus_sink: false
     bus_source: false
     bus_structure: null
-    coordinate: [449, 550]
+    coordinate: [477, 540]
     rotation: 0
-    state: true
+    state: enabled
+- name: cdc_dsa_pu_scenario_2_0
+  id: cdc_dsa_pu_scenario_2
+  parameters:
+    affinity: ''
+    alias: ''
+    comment: ''
+    duration_ms: scenario_duration
+    maxoutbuf: '0'
+    minoutbuf: '0'
+    num_channels: '1'
+    random: random_scenario
+    samp_rate: samp_rate
+    scenario: scenario
+    seed: '1'
+  states:
+    bus_sink: false
+    bus_source: false
+    bus_structure: null
+    coordinate: [722, 218]
+    rotation: 0
+    state: enabled
 - name: digital_ofdm_tx_0
   id: digital_ofdm_tx
   parameters:
@@ -356,7 +385,7 @@ blocks:
     bus_sink: false
     bus_source: false
     bus_structure: null
-    coordinate: [655, 613]
+    coordinate: [674, 613]
     rotation: 0
     state: true
 - name: qtgui_time_sink_x_0
@@ -453,7 +482,7 @@ blocks:
     bus_sink: false
     bus_source: false
     bus_structure: null
-    coordinate: [656, 534]
+    coordinate: [694, 524]
     rotation: 0
     state: true
 - name: uhd_usrp_sink_0
@@ -742,7 +771,7 @@ blocks:
     bus_sink: false
     bus_source: false
     bus_structure: null
-    coordinate: [953, 258]
+    coordinate: [933, 258]
     rotation: 0
     state: true
 - name: virtual_source_1
@@ -760,15 +789,14 @@ blocks:
     state: true
 
 connections:
-- [analog_const_source_x_0, '0', blocks_selector_0, '0']
 - [analog_random_source_x_0, '0', blocks_stream_to_tagged_stream_0, '0']
 - [blocks_multiply_const_vxx_0, '0', blocks_throttle_0, '0']
 - [blocks_multiply_const_vxx_0, '0', uhd_usrp_sink_0, '0']
-- [blocks_selector_0, '0', virtual_sink_1, '0']
 - [blocks_stream_to_tagged_stream_0, '0', digital_ofdm_tx_0, '0']
 - [blocks_throttle_0, '0', qtgui_freq_sink_x_0, '0']
 - [blocks_throttle_0, '0', qtgui_time_sink_x_0, '0']
-- [digital_ofdm_tx_0, '0', blocks_selector_0, '1']
+- [cdc_dsa_pu_scenario_2_0, '0', virtual_sink_1, '0']
+- [digital_ofdm_tx_0, '0', cdc_dsa_pu_scenario_2_0, '0']
 - [virtual_source_1, '0', blocks_multiply_const_vxx_0, '0']
 
 metadata:
diff --git a/examples/pu_tx_4_channel_mod.grc b/examples/pu_tx_4_channel_mod.grc
index 9463866a89a30a9da89481cfa6588d44e17112d2..e55df26aded12d5b0ccf015bb12f1fed1c7703d1 100644
--- a/examples/pu_tx_4_channel_mod.grc
+++ b/examples/pu_tx_4_channel_mod.grc
@@ -32,86 +32,33 @@ options:
     state: enabled
 
 blocks:
-- name: channel0
-  id: variable_qtgui_check_box
-  parameters:
-    comment: ''
-    'false': 'False'
-    gui_hint: ''
-    label: Channel 0
-    'true': 'True'
-    type: int
-    value: 'True'
-  states:
-    bus_sink: false
-    bus_source: false
-    bus_structure: null
-    coordinate: [814, 77]
-    rotation: 0
-    state: true
-- name: channel1
-  id: variable_qtgui_check_box
-  parameters:
-    comment: ''
-    'false': 'False'
-    gui_hint: ''
-    label: Channel 1
-    'true': 'True'
-    type: int
-    value: 'True'
-  states:
-    bus_sink: false
-    bus_source: false
-    bus_structure: null
-    coordinate: [818, 302]
-    rotation: 0
-    state: true
-- name: channel2
-  id: variable_qtgui_check_box
+- name: decim_factor
+  id: variable
   parameters:
     comment: ''
-    'false': 'False'
-    gui_hint: ''
-    label: Channel 2
-    'true': 'True'
-    type: int
-    value: 'True'
+    value: '1'
   states:
     bus_sink: false
     bus_source: false
     bus_structure: null
-    coordinate: [820, 530]
+    coordinate: [431, 8]
     rotation: 0
-    state: true
-- name: channel3
-  id: variable_qtgui_check_box
+    state: enabled
+- name: duration_scenario
+  id: variable_qtgui_entry
   parameters:
     comment: ''
-    'false': 'False'
     gui_hint: ''
-    label: Channel 3
-    'true': 'True'
-    type: int
-    value: 'True'
+    label: Scenario Duration (ms)
+    type: real
+    value: '50.0'
   states:
     bus_sink: false
     bus_source: false
     bus_structure: null
-    coordinate: [822, 764]
+    coordinate: [973, 8]
     rotation: 0
     state: true
-- name: decim_factor
-  id: variable
-  parameters:
-    comment: ''
-    value: '1'
-  states:
-    bus_sink: false
-    bus_source: false
-    bus_structure: null
-    coordinate: [431, 8]
-    rotation: 0
-    state: enabled
 - name: fft_len
   id: variable
   parameters:
@@ -148,6 +95,35 @@ blocks:
     coordinate: [255, 69]
     rotation: 0
     state: enabled
+- name: random_scenario
+  id: variable_qtgui_chooser
+  parameters:
+    comment: ''
+    gui_hint: ''
+    label: Random Scenario
+    label0: 'False'
+    label1: 'True'
+    label2: ''
+    label3: ''
+    label4: ''
+    labels: '[]'
+    num_opts: '2'
+    option1: 'True'
+    option2: '2'
+    option3: '3'
+    option4: '4'
+    options: '[0, 1, 2]'
+    orient: Qt.QVBoxLayout
+    type: raw
+    value: 'False'
+    widget: combo_box
+  states:
+    bus_sink: false
+    bus_source: false
+    bus_structure: null
+    coordinate: [824, 7]
+    rotation: 0
+    state: true
 - name: rf_freq
   id: variable_qtgui_range
   parameters:
@@ -160,13 +136,13 @@ blocks:
     start: 70e6
     step: 1e3
     stop: 6e9
-    value: 920e6
+    value: 2.45e9
     widget: counter
   states:
     bus_sink: false
     bus_source: false
     bus_structure: null
-    coordinate: [1958, 102]
+    coordinate: [1959, 9]
     rotation: 0
     state: true
 - name: samp_rate
@@ -181,6 +157,27 @@ blocks:
     coordinate: [176, 8]
     rotation: 0
     state: enabled
+- name: scenario
+  id: variable_qtgui_range
+  parameters:
+    comment: ''
+    gui_hint: ''
+    label: Scenario
+    min_len: '200'
+    orient: Qt.Horizontal
+    rangeType: int
+    start: '0'
+    step: '1'
+    stop: '15'
+    value: '15'
+    widget: counter
+  states:
+    bus_sink: false
+    bus_source: false
+    bus_structure: null
+    coordinate: [705, 7]
+    rotation: 0
+    state: true
 - name: taps
   id: variable
   parameters:
@@ -211,75 +208,7 @@ blocks:
     bus_sink: false
     bus_source: false
     bus_structure: null
-    coordinate: [1837, 102]
-    rotation: 0
-    state: true
-- name: analog_const_source_x_0
-  id: analog_const_source_x
-  parameters:
-    affinity: ''
-    alias: ''
-    comment: ''
-    const: '0'
-    maxoutbuf: '0'
-    minoutbuf: '0'
-    type: complex
-  states:
-    bus_sink: false
-    bus_source: false
-    bus_structure: null
-    coordinate: [652, 134]
-    rotation: 0
-    state: true
-- name: analog_const_source_x_0_1
-  id: analog_const_source_x
-  parameters:
-    affinity: ''
-    alias: ''
-    comment: ''
-    const: '0'
-    maxoutbuf: '0'
-    minoutbuf: '0'
-    type: complex
-  states:
-    bus_sink: false
-    bus_source: false
-    bus_structure: null
-    coordinate: [652, 357]
-    rotation: 0
-    state: true
-- name: analog_const_source_x_0_1_0
-  id: analog_const_source_x
-  parameters:
-    affinity: ''
-    alias: ''
-    comment: ''
-    const: '0'
-    maxoutbuf: '0'
-    minoutbuf: '0'
-    type: complex
-  states:
-    bus_sink: false
-    bus_source: false
-    bus_structure: null
-    coordinate: [655, 585]
-    rotation: 0
-    state: true
-- name: analog_const_source_x_0_1_0_0
-  id: analog_const_source_x
-  parameters:
-    affinity: ''
-    alias: ''
-    comment: ''
-    const: '0'
-    maxoutbuf: '0'
-    minoutbuf: '0'
-    type: complex
-  states:
-    bus_sink: false
-    bus_source: false
-    bus_structure: null
-    coordinate: [656, 819]
+    coordinate: [1838, 9]
     rotation: 0
     state: true
 - name: analog_random_source_x_0
@@ -467,7 +396,7 @@ blocks:
     bus_structure: null
     coordinate: [1503, 243]
     rotation: 0
-    state: true
+    state: enabled
 - name: blocks_multiply_const_vxx_0
   id: blocks_multiply_const_vxx
   parameters:
@@ -485,7 +414,7 @@ blocks:
     bus_structure: null
     coordinate: [1619, 287]
     rotation: 0
-    state: true
+    state: enabled
 - name: blocks_multiply_xx_0
   id: blocks_multiply_xx
   parameters:
@@ -558,98 +487,6 @@ blocks:
     coordinate: [1285, 889]
     rotation: 0
     state: enabled
-- name: blocks_selector_0
-  id: blocks_selector
-  parameters:
-    affinity: ''
-    alias: ''
-    comment: ''
-    enabled: 'True'
-    input_index: channel0
-    maxoutbuf: '0'
-    minoutbuf: '0'
-    num_inputs: '2'
-    num_outputs: '1'
-    output_index: '0'
-    showports: 'True'
-    type: complex
-    vlen: '1'
-  states:
-    bus_sink: false
-    bus_source: false
-    bus_structure: null
-    coordinate: [731, 190]
-    rotation: 0
-    state: true
-- name: blocks_selector_0_0
-  id: blocks_selector
-  parameters:
-    affinity: ''
-    alias: ''
-    comment: ''
-    enabled: 'True'
-    input_index: channel1
-    maxoutbuf: '0'
-    minoutbuf: '0'
-    num_inputs: '2'
-    num_outputs: '1'
-    output_index: '0'
-    showports: 'True'
-    type: complex
-    vlen: '1'
-  states:
-    bus_sink: false
-    bus_source: false
-    bus_structure: null
-    coordinate: [733, 413]
-    rotation: 0
-    state: true
-- name: blocks_selector_0_0_0
-  id: blocks_selector
-  parameters:
-    affinity: ''
-    alias: ''
-    comment: ''
-    enabled: 'True'
-    input_index: channel2
-    maxoutbuf: '0'
-    minoutbuf: '0'
-    num_inputs: '2'
-    num_outputs: '1'
-    output_index: '0'
-    showports: 'True'
-    type: complex
-    vlen: '1'
-  states:
-    bus_sink: false
-    bus_source: false
-    bus_structure: null
-    coordinate: [736, 641]
-    rotation: 0
-    state: true
-- name: blocks_selector_0_0_0_0
-  id: blocks_selector
-  parameters:
-    affinity: ''
-    alias: ''
-    comment: ''
-    enabled: 'True'
-    input_index: channel3
-    maxoutbuf: '0'
-    minoutbuf: '0'
-    num_inputs: '2'
-    num_outputs: '1'
-    output_index: '0'
-    showports: 'True'
-    type: complex
-    vlen: '1'
-  states:
-    bus_sink: false
-    bus_source: false
-    bus_structure: null
-    coordinate: [737, 875]
-    rotation: 0
-    state: true
 - name: blocks_stream_to_tagged_stream_0
   id: blocks_stream_to_tagged_stream
   parameters:
@@ -744,6 +581,27 @@ blocks:
     bus_structure: null
     coordinate: [1819, 385]
     rotation: 0
+    state: enabled
+- name: cdc_dsa_pu_scenario_2_0
+  id: cdc_dsa_pu_scenario_2
+  parameters:
+    affinity: ''
+    alias: ''
+    comment: ''
+    duration_ms: duration_scenario
+    maxoutbuf: '0'
+    minoutbuf: '0'
+    num_channels: '4'
+    random: random_scenario
+    samp_rate: samp_rate // interp_factor
+    scenario: scenario
+    seed: '1'
+  states:
+    bus_sink: false
+    bus_source: false
+    bus_structure: null
+    coordinate: [770, 511]
+    rotation: 0
     state: true
 - name: digital_ofdm_tx_0
   id: digital_ofdm_tx
@@ -917,7 +775,7 @@ blocks:
     bus_structure: null
     coordinate: [2032, 369]
     rotation: 0
-    state: true
+    state: enabled
 - name: qtgui_time_sink_x_0
   id: qtgui_time_sink_x
   parameters:
@@ -1014,7 +872,7 @@ blocks:
     bus_structure: null
     coordinate: [2031, 481]
     rotation: 0
-    state: true
+    state: enabled
 - name: rational_resampler_xxx_0_0
   id: rational_resampler_xxx
   parameters:
@@ -1373,10 +1231,6 @@ blocks:
     state: disabled
 
 connections:
-- [analog_const_source_x_0, '0', blocks_selector_0, '0']
-- [analog_const_source_x_0_1, '0', blocks_selector_0_0, '0']
-- [analog_const_source_x_0_1_0, '0', blocks_selector_0_0_0, '0']
-- [analog_const_source_x_0_1_0_0, '0', blocks_selector_0_0_0_0, '0']
 - [analog_random_source_x_0, '0', blocks_stream_to_tagged_stream_0, '0']
 - [analog_random_source_x_0_0, '0', blocks_stream_to_tagged_stream_0_0, '0']
 - [analog_random_source_x_0_0_0, '0', blocks_stream_to_tagged_stream_0_0_0, '0']
@@ -1392,20 +1246,20 @@ connections:
 - [blocks_multiply_xx_0_0, '0', blocks_add_xx_0, '1']
 - [blocks_multiply_xx_0_0_0, '0', blocks_add_xx_0, '2']
 - [blocks_multiply_xx_0_0_0_0, '0', blocks_add_xx_0, '3']
-- [blocks_selector_0, '0', rational_resampler_xxx_0_0, '0']
-- [blocks_selector_0_0, '0', rational_resampler_xxx_0_0_0, '0']
-- [blocks_selector_0_0_0, '0', rational_resampler_xxx_0_0_0_0, '0']
-- [blocks_selector_0_0_0_0, '0', rational_resampler_xxx_0_0_0_0_0, '0']
 - [blocks_stream_to_tagged_stream_0, '0', digital_ofdm_tx_0, '0']
 - [blocks_stream_to_tagged_stream_0_0, '0', digital_ofdm_tx_0_0, '0']
 - [blocks_stream_to_tagged_stream_0_0_0, '0', digital_ofdm_tx_0_0_0, '0']
 - [blocks_stream_to_tagged_stream_0_0_0_0, '0', digital_ofdm_tx_0_0_0_0, '0']
 - [blocks_throttle_0, '0', qtgui_sink_x_0, '0']
 - [blocks_throttle_0, '0', qtgui_time_sink_x_0, '0']
-- [digital_ofdm_tx_0, '0', blocks_selector_0, '1']
-- [digital_ofdm_tx_0_0, '0', blocks_selector_0_0, '1']
-- [digital_ofdm_tx_0_0_0, '0', blocks_selector_0_0_0, '1']
-- [digital_ofdm_tx_0_0_0_0, '0', blocks_selector_0_0_0_0, '1']
+- [cdc_dsa_pu_scenario_2_0, '0', rational_resampler_xxx_0_0, '0']
+- [cdc_dsa_pu_scenario_2_0, '1', rational_resampler_xxx_0_0_0, '0']
+- [cdc_dsa_pu_scenario_2_0, '2', rational_resampler_xxx_0_0_0_0, '0']
+- [cdc_dsa_pu_scenario_2_0, '3', rational_resampler_xxx_0_0_0_0_0, '0']
+- [digital_ofdm_tx_0, '0', cdc_dsa_pu_scenario_2_0, '0']
+- [digital_ofdm_tx_0_0, '0', cdc_dsa_pu_scenario_2_0, '1']
+- [digital_ofdm_tx_0_0_0, '0', cdc_dsa_pu_scenario_2_0, '2']
+- [digital_ofdm_tx_0_0_0_0, '0', cdc_dsa_pu_scenario_2_0, '3']
 - [rational_resampler_xxx_0_0, '0', blocks_multiply_xx_0, '0']
 - [rational_resampler_xxx_0_0_0, '0', blocks_multiply_xx_0_0, '0']
 - [rational_resampler_xxx_0_0_0_0, '0', blocks_multiply_xx_0_0_0, '0']
diff --git a/grc/CMakeLists.txt b/grc/CMakeLists.txt
index 6df79221e204825df08da874c940f72f9ca334f1..84e2ad5da77f69f2d0580ce583b8fc2368cde50b 100644
--- a/grc/CMakeLists.txt
+++ b/grc/CMakeLists.txt
@@ -19,6 +19,7 @@
 # Boston, MA 02110-1301, USA.
 install(FILES
     cdc_dsa_pu_scenario.block.yml
+    cdc_dsa_pu_scenario_2.block.yml
     cdc_dsa_db_connect.block.yml
     cdc_dsa_database.block.yml
     cdc_dsa_db_interface.block.yml
diff --git a/grc/cdc_dsa_pu_scenario_2.block.yml b/grc/cdc_dsa_pu_scenario_2.block.yml
new file mode 100644
index 0000000000000000000000000000000000000000..6d8722f9f59625f294b59430281ede95027fe781
--- /dev/null
+++ b/grc/cdc_dsa_pu_scenario_2.block.yml
@@ -0,0 +1,50 @@
+id: cdc_dsa_pu_scenario_2
+label: DSA PU Scenario 2
+category: '[cdc]'
+templates:
+  imports: import cdc
+  make: cdc.dsa_pu_scenario_2(${scenario}, ${random}, ${seed}, ${samp_rate}, ${duration_ms})
+  callbacks:
+  - set_scenario(${scenario})
+  - set_random(${random})
+  - set_duration_ms(${duration_ms})
+
+parameters:
+- id: scenario
+  label: Scenario
+  dtype: int
+  default: 0
+- id: random
+  label: Random Scenario
+  dtype: raw
+  default: 'False'
+- id: seed
+  label: Seed
+  dtype: int
+  default: 1
+- id: samp_rate
+  label: Sample rate
+  dtype: int
+  default: 'samp_rate'
+- id: duration_ms
+  label: Duration (ms)
+  dtype: float
+  default: 50.0
+- id: num_channels
+  label: Num_channels
+  default: '1'
+  dtype: int
+
+inputs:
+- label: in
+  domain: stream
+  dtype: complex
+  multiplicity: ${num_channels}
+
+outputs:
+- label: out
+  domain: stream
+  dtype: complex
+  multiplicity: ${num_channels}
+
+file_format: 1
diff --git a/include/cdc/CMakeLists.txt b/include/cdc/CMakeLists.txt
index 4ab4ae27d13bc4ea6d7cb4a82ce083b3c5fdb5f5..060300f67a4c26412941659df3ca9d6b4e63b390 100644
--- a/include/cdc/CMakeLists.txt
+++ b/include/cdc/CMakeLists.txt
@@ -25,6 +25,7 @@ install(FILES
     api.h
     dsa.h
     dsa_pu_scenario.h
+    dsa_pu_scenario_2.h
     dsa_db_connect.h
     dsa_database.h
     dsa_db_interface.h DESTINATION include/cdc
diff --git a/include/cdc/dsa_pu_scenario_2.h b/include/cdc/dsa_pu_scenario_2.h
new file mode 100644
index 0000000000000000000000000000000000000000..87ce879505742b46fb3952ede81e2182b41a377b
--- /dev/null
+++ b/include/cdc/dsa_pu_scenario_2.h
@@ -0,0 +1,84 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2021 University of Melbourne.
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_CDC_DSA_PU_SCENARIO_2_H
+#define INCLUDED_CDC_DSA_PU_SCENARIO_2_H
+
+#include <cdc/api.h>
+#include <gnuradio/sync_block.h>
+
+namespace gr {
+namespace cdc {
+
+/*!
+ * \brief Implements primary user scenario control for CDC dynamic spectrum
+          access project.
+ * \ingroup cdc
+ *
+ */
+class CDC_API dsa_pu_scenario_2 : virtual public gr::sync_block
+{
+public:
+    typedef boost::shared_ptr<dsa_pu_scenario_2> sptr;
+
+    /*!
+    * \brief DSA PU Scenario Constructor
+    *
+    * \param scenario       Primary user scenario - bitmap of active channels,
+    *                       e.g., for 4 PU channels SCENARIO = 10 = 0b1010
+                            indicates channels 2 and 4 are active. Set to -1
+    *                       for randomly selected scenarios.
+    * \param random         Randomly select primary user scenario
+    * \param seed           Seed used used in random scenario selection.
+    * \param samp_rate      Sample rate of incoming data streams
+    * \param duration_ms    Duration (in ms) of scenario before randomly
+    *                       selecting new scenario.
+    */
+    static sptr make(int scenario,
+                     bool random,
+                     int seed,
+                     int samp_rate,
+                     float duration_ms);
+    
+    //! Set primary user scenario
+    virtual void set_scenario(int scenario) = 0;
+
+    //! Get current primary user scenario
+    virtual int get_scenario(void) = 0;
+
+    //! Set random selection of primary user scenarios
+    virtual void set_random(bool random) = 0;
+
+    //! Get random selection of primary user scenarios
+    virtual bool get_random(void) = 0;
+    
+    //! Set duration (in ms) of random primary user scenarios
+    virtual void set_duration_ms(float duration_ms) = 0;
+
+    //! Get duration (in ms) of random primary user scenarios
+    virtual float get_duration_ms(void) = 0;
+
+};
+
+} // namespace cdc
+} // namespace gr
+
+#endif /* INCLUDED_CDC_DSA_PU_SCENARIO_2_H */
+
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index 156fe652a85c541aa2de839cb585ba1307d263e5..2830891cd53d2895669511305856d26758d8677e 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -24,6 +24,7 @@
 include(GrPlatform) #define LIB_SUFFIX
 list(APPEND cdc_sources
     dsa_pu_scenario_impl.cc
+    dsa_pu_scenario_2_impl.cc
     dsa_db_connect_impl.cc
     dsa_database.cc
     dsa_db_interface.cc )
diff --git a/lib/dsa_pu_scenario_2_impl.cc b/lib/dsa_pu_scenario_2_impl.cc
new file mode 100644
index 0000000000000000000000000000000000000000..7913e86833a07f02604b31f21010126ee0cd6231
--- /dev/null
+++ b/lib/dsa_pu_scenario_2_impl.cc
@@ -0,0 +1,117 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2021 University of Melbourne.
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gnuradio/io_signature.h>
+#include "dsa_pu_scenario_2_impl.h"
+
+namespace gr {
+namespace cdc {
+
+dsa_pu_scenario_2::sptr
+dsa_pu_scenario_2::make(int scenario,
+                        bool random,
+                        int seed,
+                        int samp_rate,
+                        float duration_ms)
+{
+    return gnuradio::get_initial_sptr (new dsa_pu_scenario_2_impl(
+        scenario, random, seed, samp_rate, duration_ms));
+}
+
+/*
+ * The private constructor
+ */
+dsa_pu_scenario_2_impl::dsa_pu_scenario_2_impl(int scenario,
+                                               bool random,
+                                               int seed,
+                                               int samp_rate,
+                                               float duration_ms)
+    : gr::sync_block("dsa_pu_scenario_2",
+          gr::io_signature::make(1, -1, sizeof(gr_complex)),
+          gr::io_signature::make(1, -1, sizeof(gr_complex))),
+      d_scenario(scenario),
+      d_random(random),
+      d_engine(seed),
+      d_samp_rate(samp_rate),
+      d_duration_ms(duration_ms)
+{
+}
+
+/*
+ * Our virtual destructor.
+ */
+dsa_pu_scenario_2_impl::~dsa_pu_scenario_2_impl()
+{
+    if (d_uniform)
+        delete d_uniform;
+}
+
+void
+dsa_pu_scenario_2_impl::update_scenario(int n_chan)
+{
+    if (!d_active.size())
+    {
+        d_active.resize(n_chan);
+        int n_scenarios = (0x1 << n_chan);
+        d_uniform = new std::uniform_int_distribution<int>(0, n_scenarios - 1);
+    }
+
+    if (d_samp_cnt <= 0)
+    {
+        d_samp_cnt = int(d_duration_ms * d_samp_rate / 1000.0);
+        if (d_random)
+            d_scenario = (*d_uniform)(d_engine);
+    }
+
+    for (int i_chan=0; i_chan < n_chan; i_chan++)
+        d_active[i_chan] = d_scenario & (0x1 << i_chan);
+}
+
+int
+dsa_pu_scenario_2_impl::work(int noutput_items,
+                             gr_vector_const_void_star &input_items,
+                             gr_vector_void_star &output_items)
+{
+    int n_chan = output_items.size();
+
+    update_scenario(n_chan);
+
+    int n_samps = (d_samp_cnt < noutput_items) ? d_samp_cnt : noutput_items;
+    for (int i_chan = 0; i_chan < n_chan; i_chan++)
+    {
+        gr_complex *in = (gr_complex *)input_items[i_chan];
+        gr_complex *out = (gr_complex *)output_items[i_chan];
+        if (d_active[i_chan])
+            memcpy(out, in, n_samps * sizeof(gr_complex));
+        else
+            memset(out, 0x0, n_samps * sizeof(gr_complex));
+    }
+    d_samp_cnt -= n_samps;
+
+    return n_samps;
+}
+
+} /* namespace cdc */
+} /* namespace gr */
+
diff --git a/lib/dsa_pu_scenario_2_impl.h b/lib/dsa_pu_scenario_2_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..2976f138e28c81c7a232cde0ba6251fe82c13400
--- /dev/null
+++ b/lib/dsa_pu_scenario_2_impl.h
@@ -0,0 +1,75 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2021 University of Melbourne.
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_CDC_DSA_PU_SCENARIO_2_IMPL_H
+#define INCLUDED_CDC_DSA_PU_SCENARIO_2_IMPL_H
+
+#include <cdc/dsa_pu_scenario_2.h>
+#include <random>
+
+namespace gr {
+namespace cdc {
+
+class dsa_pu_scenario_2_impl : public dsa_pu_scenario_2
+{
+private:
+    int d_scenario;
+    bool d_random;
+    int d_samp_rate;
+    float d_duration_ms;
+
+    std::default_random_engine d_engine;
+    std::uniform_int_distribution<int>* d_uniform = nullptr;
+    std::vector<bool> d_active;
+    int d_samp_cnt = 0;
+
+    void update_scenario(int n_chan);
+
+public:
+    dsa_pu_scenario_2_impl(int scenario,
+                           bool random,
+                           int seed,
+                           int samp_rate,
+                           float duration_ms);
+    ~dsa_pu_scenario_2_impl();
+
+    void set_scenario(int scenario) { d_scenario = scenario; };
+    
+    int get_scenario(void) { return d_scenario; };
+    
+    void set_random(bool random) { d_random = random; };
+    
+    bool get_random(void) { return random; };
+    
+    void set_duration_ms(float duration_ms) { d_duration_ms = duration_ms; };
+    
+    float get_duration_ms(void) { return d_duration_ms; };
+
+    int work(int noutput_items,
+             gr_vector_const_void_star &input_items,
+             gr_vector_void_star &output_items);
+
+};
+
+} // namespace cdc
+} // namespace gr
+
+#endif /* INCLUDED_CDC_DSA_PU_SCENARIO_IMPL_H */
+
diff --git a/swig/cdc_swig.i b/swig/cdc_swig.i
index 5d817a3fd7da89890702ec9300d95f9f51600934..5702e9df95294491ac7089ed4170067920eaadf1 100644
--- a/swig/cdc_swig.i
+++ b/swig/cdc_swig.i
@@ -10,6 +10,7 @@
 %{
 #include "cdc/dsa.h"
 #include "cdc/dsa_pu_scenario.h"
+#include "cdc/dsa_pu_scenario_2.h"
 #include "cdc/dsa_db_connect.h"
 #include "cdc/dsa_database.h"
 #include "cdc/dsa_db_interface.h"
@@ -18,6 +19,8 @@
 %include "cdc/dsa.h"
 %include "cdc/dsa_pu_scenario.h"
 GR_SWIG_BLOCK_MAGIC2(cdc, dsa_pu_scenario);
+%include "cdc/dsa_pu_scenario_2.h"
+GR_SWIG_BLOCK_MAGIC2(cdc, dsa_pu_scenario_2);
 %include "cdc/dsa_db_connect.h"
 GR_SWIG_BLOCK_MAGIC2(cdc, dsa_db_connect);
 %include "cdc/dsa_database.h"