From 9fc200bf11a0a759ab123542612dda924a9045e4 Mon Sep 17 00:00:00 2001 From: Notou Date: Tue, 6 Jul 2021 17:47:05 +0200 Subject: [PATCH 1/8] Minor improvement to test flowgraphs --- examples/test_bokehgui.grc | 299 +++++- examples/tutorial.grc | 1813 +++++++++--------------------------- 2 files changed, 717 insertions(+), 1395 deletions(-) diff --git a/examples/test_bokehgui.grc b/examples/test_bokehgui.grc index eaf559b..36b7c0d 100644 --- a/examples/test_bokehgui.grc +++ b/examples/test_bokehgui.grc @@ -1,7 +1,6 @@ options: parameters: author: Kartik Patel - catch_exceptions: 'True' category: '[GRC Hier Blocks]' cmake_opt: '' comment: '' @@ -20,9 +19,10 @@ options: run: 'True' run_command: '{python} -u {filename}' run_options: prompt - sizing_mode: fixed + sizing_mode: stretch_both thread_safe_setters: '' title: Test GRC for Bokeh GUI + window_size: (1000,1000) states: bus_sink: false bus_source: false @@ -676,6 +676,301 @@ blocks: coordinate: [536, 284.0] rotation: 0 state: enabled +- name: bokehgui_vector_sink_x_0 + id: bokehgui_vector_sink_x + parameters: + affinity: '' + alias: '' + alpha1: '1.0' + alpha10: '1.0' + alpha2: '1.0' + alpha3: '1.0' + alpha4: '1.0' + alpha5: '1.0' + alpha6: '1.0' + alpha7: '1.0' + alpha8: '1.0' + alpha9: '1.0' + average: '1.0' + axislabels: 'True' + color1: '"blue"' + color10: '"dark blue"' + color2: '"red"' + color3: '"green"' + color4: '"black"' + color5: '"cyan"' + color6: '"magenta"' + color7: '"yellow"' + color8: '"dark red"' + color9: '"dark green"' + comment: '' + grid: 'False' + label1: '' + label10: '' + label2: '' + label3: '' + label4: '' + label5: '' + label6: '' + label7: '' + label8: '' + label9: '' + legend: 'True' + marker1: None + marker10: None + marker2: None + marker3: None + marker4: None + marker5: None + marker6: None + marker7: None + marker8: None + marker9: None + maxhold: 'True' + maxoutbuf: '0' + minoutbuf: '0' + name: '""' + nconnections: '1' + placement: (0,7,2,2) + style1: '"solid"' + style10: '"solid"' + style2: '"solid"' + style3: '"solid"' + style4: '"solid"' + style5: '"solid"' + style6: '"solid"' + style7: '"solid"' + style8: '"solid"' + style9: '"solid"' + type: complex + update_time: '100' + vec_len: '64' + width1: '1' + width10: '1' + width2: '1' + width3: '1' + width4: '1' + width5: '1' + width6: '1' + width7: '1' + width8: '1' + width9: '1' + x_values: list(range(64)) + xlabel: Frequency + xunit: '""' + ylabel: Relative Gain + ymax: '10' + ymin: '-140' + yunit: dB + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1379, 363] + rotation: 0 + state: true +- name: bokehgui_vector_sink_x_0_0 + id: bokehgui_vector_sink_x + parameters: + affinity: '' + alias: '' + alpha1: '1.0' + alpha10: '1.0' + alpha2: '1.0' + alpha3: '1.0' + alpha4: '1.0' + alpha5: '1.0' + alpha6: '1.0' + alpha7: '1.0' + alpha8: '1.0' + alpha9: '1.0' + average: '1.0' + axislabels: 'True' + color1: '"blue"' + color10: '"dark blue"' + color2: '"red"' + color3: '"green"' + color4: '"black"' + color5: '"cyan"' + color6: '"magenta"' + color7: '"yellow"' + color8: '"dark red"' + color9: '"dark green"' + comment: '' + grid: 'False' + label1: '' + label10: '' + label2: '' + label3: '' + label4: '' + label5: '' + label6: '' + label7: '' + label8: '' + label9: '' + legend: 'True' + marker1: None + marker10: None + marker2: None + marker3: None + marker4: None + marker5: None + marker6: None + marker7: None + marker8: None + marker9: None + maxhold: 'True' + maxoutbuf: '0' + minoutbuf: '0' + name: '""' + nconnections: '1' + placement: (2,7,2,2) + style1: '"solid"' + style10: '"solid"' + style2: '"solid"' + style3: '"solid"' + style4: '"solid"' + style5: '"solid"' + style6: '"solid"' + style7: '"solid"' + style8: '"solid"' + style9: '"solid"' + type: float + update_time: '100' + vec_len: '64' + width1: '1' + width10: '1' + width2: '1' + width3: '1' + width4: '1' + width5: '1' + width6: '1' + width7: '1' + width8: '1' + width9: '1' + x_values: list(range(64)) + xlabel: Frequency + xunit: '""' + ylabel: Relative Gain + ymax: '10' + ymin: '-140' + yunit: dB + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1374, 684] + rotation: 0 + state: true +- name: bokehgui_waterfall_sink_x_0 + id: bokehgui_waterfall_sink_x + parameters: + affinity: '' + alias: '' + bw: samp_rate + color: Inferno + comment: '' + fc: '0' + fftsize: '1024' + grid: 'False' + int_max: '10' + int_min: '-140' + label: '' + legend: 'True' + maxoutbuf: '0' + minoutbuf: '0' + name: '""' + placement: (0,5,2,2) + type: complex + update_time: '100' + wintype: firdes.WIN_BLACKMAN_hARRIS + xlabel: Frequency + xunit: Hz + ylabel: Time + yunit: '' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [602, 356] + rotation: 0 + state: true +- name: bokehgui_waterfall_sink_x_0_0 + id: bokehgui_waterfall_sink_x + parameters: + affinity: '' + alias: '' + bw: samp_rate + color: Inferno + comment: '' + fc: '0' + fftsize: '1024' + grid: 'False' + int_max: '10' + int_min: '-140' + label: '' + legend: 'True' + maxoutbuf: '0' + minoutbuf: '0' + name: '""' + placement: (2,5,2,2) + type: float + update_time: '100' + wintype: firdes.WIN_BLACKMAN_hARRIS + xlabel: Frequency + xunit: Hz + ylabel: Time + yunit: '' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [608, 731] + rotation: 0 + state: true +- name: fft_vxx_0 + id: fft_vxx + parameters: + affinity: '' + alias: '' + comment: '' + fft_size: '64' + forward: 'True' + maxoutbuf: '0' + minoutbuf: '0' + nthreads: '1' + shift: 'True' + type: complex + window: window.blackmanharris(64) + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1070, 306] + rotation: 0 + state: true +- name: logpwrfft_x_0 + id: logpwrfft_x + parameters: + affinity: '' + alias: '' + average: 'False' + avg_alpha: '1.0' + comment: '' + fft_size: '64' + frame_rate: '30' + maxoutbuf: '0' + minoutbuf: '0' + ref_scale: '2' + sample_rate: samp_rate + type: float + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [942, 675] + rotation: 0 + state: true connections: - [analog_noise_source_x_0, '0', blocks_add_xx_0, '1'] diff --git a/examples/tutorial.grc b/examples/tutorial.grc index 15ea51e..7208859 100644 --- a/examples/tutorial.grc +++ b/examples/tutorial.grc @@ -1,1393 +1,420 @@ - - - - Fri Jul 21 23:20:50 2017 - - options - - author - - - - window_size - (900,350) - - - category - [GRC Hier Blocks] - - - comment - - - - description - - - - _enabled - True - - - _coordinate - (8, 8) - - - _rotation - 0 - - - generate_options - bokeh_gui - - - hier_block_src_path - .: - - - id - tutorial - - - max_nouts - 0 - - - qt_qss_theme - - - - realtime_scheduling - - - - run_command - {python} -u {filename} - - - run_options - prompt - - - run - True - - - sizing_mode - fixed - - - thread_safe_setters - - - - title - Tutorial BokehGUI - - - placement - (0,0) - - - - variable_bokehgui_slider - - comment - - - - value - 1000 - - - _enabled - True - - - end - 10000 - - - _coordinate - (504, 200) - - - _rotation - 0 - - - id - frequency - - - label - Frequency - - - start - 100 - - - step - 1 - - - throttle - 1 - - - type - real - - - - variable_bokehgui_slider - - comment - - - - value - 0.01 - - - _enabled - True - - - end - 10 - - - _coordinate - (192, 200) - - - _rotation - 0 - - - id - noise_amp - - - label - Noise Amplitude - - - start - 0.01 - - - step - .01 - - - throttle - 1 - - - type - real - - - - variable - - comment - - - - _enabled - True - - - _coordinate - (64, 132) - - - _rotation - 0 - - - id - samp_rate - - - value - 32000 - - - - variable_bokehgui_slider - - comment - - - - value - 5 - - - _enabled - True - - - end - 10 - - - _coordinate - (352, 200) - - - _rotation - 0 - - - id - signal_amp - - - label - Signal Amplitude - - - start - 0 - - - step - 0.01 - - - throttle - 1 - - - type - real - - - - analog_noise_source_x - - amp - noise_amp - - - alias - - - - comment - - - - affinity - - - - _enabled - True - - - _coordinate - (192, 116) - - - _rotation - 0 - - - id - analog_noise_source_x_0 - - - maxoutbuf - 0 - - - minoutbuf - 0 - - - noise_type - analog.GR_GAUSSIAN - - - type - float - - - seed - 0 - - - - analog_sig_source_x - - amp - signal_amp - - - alias - - - - comment - - - - affinity - - - - _enabled - True - - - freq - frequency - - - _coordinate - (208, 8) - - - _rotation - 0 - - - id - analog_sig_source_x_0 - - - maxoutbuf - 0 - - - minoutbuf - 0 - - - offset - 0 - - - type - float - - - samp_rate - samp_rate - - - waveform - analog.GR_COS_WAVE - - - - blocks_add_xx - - alias - - - - comment - - - - affinity - - - - _enabled - True - - - _coordinate - (408, 24) - - - _rotation - 0 - - - id - blocks_add_xx_0 - - - type - float - - - maxoutbuf - 0 - - - minoutbuf - 0 - - - num_inputs - 2 - - - vlen - 1 - - - - blocks_throttle - - alias - - - - comment - - - - affinity - - - - _enabled - True - - - _coordinate - (496, 36) - - - _rotation - 0 - - - id - blocks_throttle_0 - - - ignoretag - True - - - maxoutbuf - 0 - - - minoutbuf - 0 - - - samples_per_second - samp_rate - - - type - float - - - vlen - 1 - - - - bokehgui_frequency_sink_x - - average - 1.0 - - - axislabels - True - - - bw - samp_rate - - - alias - - - - fc - 0 - - - comment - - - - affinity - - - - _enabled - True - - - fftsize - 1024 - - - _coordinate - (704, 164) - - - _rotation - 0 - - - grid - False - - - id - bokehgui_frequency_sink_x_0 - - - legend - True - - - alpha1 - 1.0 - - - color1 - "blue" - - - label1 - - - - marker1 - None - - - style1 - "solid" - - - width1 - 1 - - - alpha10 - 1.0 - - - color10 - "dark blue" - - - label10 - - - - marker10 - None - - - style10 - "solid" - - - width10 - 1 - - - alpha2 - 1.0 - - - color2 - "red" - - - label2 - - - - marker2 - None - - - style2 - "solid" - - - width2 - 1 - - - alpha3 - 1.0 - - - color3 - "green" - - - label3 - - - - marker3 - None - - - style3 - "solid" - - - width3 - 1 - - - alpha4 - 1.0 - - - color4 - "black" - - - label4 - - - - marker4 - None - - - style4 - "solid" - - - width4 - 1 - - - alpha5 - 1.0 - - - color5 - "cyan" - - - label5 - - - - marker5 - None - - - style5 - "solid" - - - width5 - 1 - - - alpha6 - 1.0 - - - color6 - "magenta" - - - label6 - - - - marker6 - None - - - style6 - "solid" - - - width6 - 1 - - - alpha7 - 1.0 - - - color7 - "yellow" - - - label7 - - - - marker7 - None - - - style7 - "solid" - - - width7 - 1 - - - alpha8 - 1.0 - - - color8 - "dark red" - - - label8 - - - - marker8 - None - - - style8 - "solid" - - - width8 - 1 - - - alpha9 - 1.0 - - - color9 - "dark green" - - - label9 - - - - marker9 - None - - - style9 - "solid" - - - width9 - 1 - - - maxhold - True - - - maxoutbuf - 0 - - - minoutbuf - 0 - - - name - "" - - - nconnections - 1 - - - placement - (0,1,2,1) - - - freqhalf - False - - - tr_chan - 0 - - - tr_level - 0.0 - - - tr_mode - bokehgui.TRIG_MODE_FREE - - - tr_tag - "" - - - type - float - - - update_time - 100 - - - wintype - firdes.WIN_BLACKMAN_hARRIS - - - xlabel - Frequency - - - xunit - "" - - - ylabel - Relative Gain - - - ymax - 10 - - - ymin - -140 - - - yunit - dB - - - - bokehgui_time_sink_x - - axislabels - True - - - alias - - - - comment - - - - affinity - - - - entags - True - - - _enabled - True - - - _coordinate - (704, 100) - - - _rotation - 0 - - - grid - False - - - id - bokehgui_time_sink_x_0 - - - legend - True - - - alpha1 - 1.0 - - - color1 - "blue" - - - label1 - - - - marker1 - None - - - style1 - "solid" - - - width1 - 1 - - - alpha10 - 1.0 - - - color10 - "blue" - - - label10 - - - - marker10 - None - - - style10 - "solid" - - - width10 - 1 - - - alpha2 - 1.0 - - - color2 - "red" - - - label2 - - - - marker2 - None - - - style2 - "solid" - - - width2 - 1 - - - alpha3 - 1.0 - - - color3 - "green" - - - label3 - - - - marker3 - None - - - style3 - "solid" - - - width3 - 1 - - - alpha4 - 1.0 - - - color4 - "black" - - - label4 - - - - marker4 - None - - - style4 - "solid" - - - width4 - 1 - - - alpha5 - 1.0 - - - color5 - "cyan" - - - label5 - - - - marker5 - None - - - style5 - "solid" - - - width5 - 1 - - - alpha6 - 1.0 - - - color6 - "magenta" - - - label6 - - - - marker6 - None - - - style6 - "solid" - - - width6 - 1 - - - alpha7 - 1.0 - - - color7 - "yellow" - - - label7 - - - - marker7 - None - - - style7 - "solid" - - - width7 - 1 - - - alpha8 - 1.0 - - - color8 - "blue" - - - label8 - - - - marker8 - None - - - style8 - "solid" - - - width8 - 1 - - - alpha9 - 1.0 - - - color9 - "blue" - - - label9 - - - - marker9 - None - - - style9 - "solid" - - - width9 - 1 - - - name - "" - - - nconnections - 1 - - - size - 1024 - - - placement - (1,0,1,1) - - - srate - samp_rate - - - tr_chan - 0 - - - tr_delay - 0 - - - tr_level - 0.0 - - - tr_mode - bokehgui.TRIG_MODE_FREE - - - tr_slope - bokehgui.TRIG_SLOPE_POS - - - tr_tag - "" - - - type - float - - - update_time - 100 - - - xlabel - Time - - - xlog - False - - - xunit - "" - - - ylabel - Amplitude - - - ylog - False - - - yunit - "" - - - ymax - 1 - - - ymin - -1 - - - - bokehgui_waterfall_sink_x - - bw - samp_rate - - - alias - - - - fc - 0 - - - comment - - - - affinity - - - - _enabled - True - - - fftsize - 1024 - - - _coordinate - (696, 20) - - - _rotation - 0 - - - grid - False - - - id - bokehgui_waterfall_sink_x_0 - - - int_max - 10 - - - int_min - -140 - - - label - - - - legend - True - - - color - Inferno - - - maxoutbuf - 0 - - - minoutbuf - 0 - - - name - "" - - - placement - (2,0,1,2) - - - type - float - - - update_time - 100 - - - wintype - firdes.WIN_BLACKMAN_hARRIS - - - xlabel - Frequency - - - xunit - Hz - - - ylabel - Time - - - yunit - - - - - analog_noise_source_x_0 - blocks_add_xx_0 - 0 - 1 - - - analog_sig_source_x_0 - blocks_add_xx_0 - 0 - 0 - - - blocks_add_xx_0 - blocks_throttle_0 - 0 - 0 - - - blocks_throttle_0 - bokehgui_frequency_sink_x_0 - 0 - 0 - - - blocks_throttle_0 - bokehgui_time_sink_x_0 - 0 - 0 - - - blocks_throttle_0 - bokehgui_waterfall_sink_x_0 - 0 - 0 - - +options: + parameters: + author: '' + category: '[GRC Hier Blocks]' + cmake_opt: '' + comment: '' + copyright: '' + description: '' + gen_cmake: 'On' + gen_linking: dynamic + generate_options: bokeh_gui + hier_block_src_path: '.:' + id: tutorial + max_nouts: '0' + output_language: python + placement: (0,0) + qt_qss_theme: '' + realtime_scheduling: '' + run: 'True' + run_command: '{python} -u {filename}' + run_options: prompt + sizing_mode: stretch_both + thread_safe_setters: '' + title: Tutorial BokehGUI + window_size: (900,350) + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 8] + rotation: 0 + state: enabled + +blocks: +- name: frequency + id: variable_bokehgui_slider + parameters: + comment: '' + end: '10000' + label: Frequency + start: '100' + step: '1' + throttle: '1' + type: real + value: '1000' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [504, 200] + rotation: 0 + state: enabled +- name: noise_amp + id: variable_bokehgui_slider + parameters: + comment: '' + end: '10' + label: Noise Amplitude + start: '0.01' + step: '.01' + throttle: '1' + type: real + value: '0.01' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [192, 200] + rotation: 0 + state: enabled +- name: samp_rate + id: variable + parameters: + comment: '' + value: '32000' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [64, 132] + rotation: 0 + state: enabled +- name: signal_amp + id: variable_bokehgui_slider + parameters: + comment: '' + end: '10' + label: Signal Amplitude + start: '0' + step: '0.01' + throttle: '1' + type: real + value: '5' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [352, 200] + rotation: 0 + state: enabled +- name: analog_noise_source_x_0 + id: analog_noise_source_x + parameters: + affinity: '' + alias: '' + amp: noise_amp + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + noise_type: analog.GR_GAUSSIAN + seed: '0' + type: float + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [192, 116] + rotation: 0 + state: enabled +- name: analog_sig_source_x_0 + id: analog_sig_source_x + parameters: + affinity: '' + alias: '' + amp: signal_amp + comment: '' + freq: frequency + maxoutbuf: '0' + minoutbuf: '0' + offset: '0' + phase: '0' + samp_rate: samp_rate + type: float + waveform: analog.GR_COS_WAVE + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [208, 8] + rotation: 0 + state: enabled +- name: blocks_add_xx_0 + id: blocks_add_xx + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + num_inputs: '2' + type: float + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [408, 24] + rotation: 0 + state: enabled +- name: blocks_throttle_0 + id: blocks_throttle + parameters: + affinity: '' + alias: '' + comment: '' + ignoretag: 'True' + maxoutbuf: '0' + minoutbuf: '0' + samples_per_second: samp_rate + type: float + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [496, 36] + rotation: 0 + state: enabled +- name: bokehgui_frequency_sink_x_0 + id: bokehgui_frequency_sink_x + parameters: + affinity: '' + alias: '' + alpha1: '1.0' + alpha10: '1.0' + alpha2: '1.0' + alpha3: '1.0' + alpha4: '1.0' + alpha5: '1.0' + alpha6: '1.0' + alpha7: '1.0' + alpha8: '1.0' + alpha9: '1.0' + average: '1.0' + axislabels: 'True' + bw: samp_rate + color1: '"blue"' + color10: '"dark blue"' + color2: '"red"' + color3: '"green"' + color4: '"black"' + color5: '"cyan"' + color6: '"magenta"' + color7: '"yellow"' + color8: '"dark red"' + color9: '"dark green"' + comment: '' + fc: '0' + fftsize: '1024' + freqhalf: 'False' + grid: 'False' + label1: '' + label10: '' + label2: '' + label3: '' + label4: '' + label5: '' + label6: '' + label7: '' + label8: '' + label9: '' + legend: 'True' + marker1: None + marker10: None + marker2: None + marker3: None + marker4: None + marker5: None + marker6: None + marker7: None + marker8: None + marker9: None + maxhold: 'True' + maxoutbuf: '0' + minoutbuf: '0' + name: '""' + nconnections: '1' + placement: (0,1,2,1) + style1: '"solid"' + style10: '"solid"' + style2: '"solid"' + style3: '"solid"' + style4: '"solid"' + style5: '"solid"' + style6: '"solid"' + style7: '"solid"' + style8: '"solid"' + style9: '"solid"' + tr_chan: '0' + tr_level: '0.0' + tr_mode: bokehgui.TRIG_MODE_FREE + tr_tag: '""' + type: float + update_time: '100' + width1: '1' + width10: '1' + width2: '1' + width3: '1' + width4: '1' + width5: '1' + width6: '1' + width7: '1' + width8: '1' + width9: '1' + wintype: firdes.WIN_BLACKMAN_hARRIS + xlabel: Frequency + xunit: '""' + ylabel: Relative Gain + ymax: '10' + ymin: '-140' + yunit: dB + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [704, 164] + rotation: 0 + state: enabled +- name: bokehgui_time_sink_x_0 + id: bokehgui_time_sink_x + parameters: + affinity: '' + alias: '' + alpha1: '1.0' + alpha10: '1.0' + alpha2: '1.0' + alpha3: '1.0' + alpha4: '1.0' + alpha5: '1.0' + alpha6: '1.0' + alpha7: '1.0' + alpha8: '1.0' + alpha9: '1.0' + axislabels: 'True' + color1: '"blue"' + color10: '"blue"' + color2: '"red"' + color3: '"green"' + color4: '"black"' + color5: '"cyan"' + color6: '"magenta"' + color7: '"yellow"' + color8: '"blue"' + color9: '"blue"' + comment: '' + entags: 'True' + grid: 'False' + label1: '' + label10: '' + label2: '' + label3: '' + label4: '' + label5: '' + label6: '' + label7: '' + label8: '' + label9: '' + legend: 'True' + marker1: None + marker10: None + marker2: None + marker3: None + marker4: None + marker5: None + marker6: None + marker7: None + marker8: None + marker9: None + name: '""' + nconnections: '1' + placement: (1,0,1,1) + size: '1024' + srate: samp_rate + style1: '"solid"' + style10: '"solid"' + style2: '"solid"' + style3: '"solid"' + style4: '"solid"' + style5: '"solid"' + style6: '"solid"' + style7: '"solid"' + style8: '"solid"' + style9: '"solid"' + tr_chan: '0' + tr_delay: '0' + tr_level: '0.0' + tr_mode: bokehgui.TRIG_MODE_FREE + tr_slope: bokehgui.TRIG_SLOPE_POS + tr_tag: '""' + type: float + update_time: '100' + width1: '1' + width10: '1' + width2: '1' + width3: '1' + width4: '1' + width5: '1' + width6: '1' + width7: '1' + width8: '1' + width9: '1' + xlabel: Time + xlog: 'False' + xunit: '""' + ylabel: Amplitude + ylog: 'False' + ymax: '1' + ymin: '-1' + yunit: '""' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [704, 100] + rotation: 0 + state: enabled +- name: bokehgui_waterfall_sink_x_0 + id: bokehgui_waterfall_sink_x + parameters: + affinity: '' + alias: '' + bw: samp_rate + color: Inferno + comment: '' + fc: '0' + fftsize: '1024' + grid: 'False' + int_max: '10' + int_min: '-140' + label: '' + legend: 'True' + maxoutbuf: '0' + minoutbuf: '0' + name: '""' + placement: (2,0,1,2) + type: float + update_time: '100' + wintype: firdes.WIN_BLACKMAN_hARRIS + xlabel: Frequency + xunit: Hz + ylabel: Time + yunit: '' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [696, 20] + rotation: 0 + state: enabled + +connections: +- [analog_noise_source_x_0, '0', blocks_add_xx_0, '1'] +- [analog_sig_source_x_0, '0', blocks_add_xx_0, '0'] +- [blocks_add_xx_0, '0', blocks_throttle_0, '0'] +- [blocks_throttle_0, '0', bokehgui_frequency_sink_x_0, '0'] +- [blocks_throttle_0, '0', bokehgui_time_sink_x_0, '0'] +- [blocks_throttle_0, '0', bokehgui_waterfall_sink_x_0, '0'] + +metadata: + file_format: 1 From 6bf365390680edb73a0023841d03e47830c9ffef Mon Sep 17 00:00:00 2001 From: Notou Date: Tue, 6 Jul 2021 17:47:48 +0200 Subject: [PATCH 2/8] Support for Bokeh above 2.3.1 (#41) --- README.md | 7 +++---- python/plots/waterfall.py | 2 +- python/plots/waterfall.ts | 41 ++++++++++++++++++++------------------- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 3050b8b..1ed08dd 100644 --- a/README.md +++ b/README.md @@ -4,16 +4,15 @@ ## Overview -The module provides various sinks and widgets to allow interaction with the live GNU Radio applications remotely over the network. The module uses [Bokeh](https://docs.bokeh.org/en/1.4.0/)'s client API and streaming features. Using widgets and plots from Bokeh, the module enables the GUI for GNU Radio that renders in web browser. Just like `gr-qtgui`, it is fully integrated with GRC to allow easy use. +The module provides various sinks and widgets to allow interaction with the live GNU Radio applications remotely over the network. The module uses [Bokeh](https://docs.bokeh.org/en/2.3.2/)'s client API and streaming features. Using widgets and plots from Bokeh, the module enables the GUI for GNU Radio that renders in web browser. Just like `gr-qtgui`, it is fully integrated with GRC to allow easy use. -The module was developed as a part of Google Summer of Code 2017 by Kartik Patel. +The module was first developed as a part of Google Summer of Code 2017 by Kartik Patel. ## Warning: The master branch does not yet support GNU Radio 3.9 since the change to pybind11. Please use the main-3.8 branch with GNU Radio 3.8 ## Dependency 1. GNU Radio 3.9 -2. [Bokeh library v1](https://docs.bokeh.org/en/1.4.0/) - (Tested on v1.4.0) +2. [Bokeh library above 2.3.1](https://docs.bokeh.org/en/2.3.2/) (earlier versions cause the waterfall display to crash) ## Installation ### Using PyBOMBS diff --git a/python/plots/waterfall.py b/python/plots/waterfall.py index b1ad442..cf7eaea 100644 --- a/python/plots/waterfall.py +++ b/python/plots/waterfall.py @@ -7,7 +7,7 @@ class WaterfallRenderer(Renderer): __implementation__ = join(dirname(__file__), "waterfall.ts") - latest = Seq(Float) + latest = Seq(Float, default=[]) palette = Seq(Color) diff --git a/python/plots/waterfall.ts b/python/plots/waterfall.ts index 8d9fb72..48f45fc 100644 --- a/python/plots/waterfall.ts +++ b/python/plots/waterfall.ts @@ -8,8 +8,8 @@ import * as p from "core/properties" export class WaterfallRendererView extends RendererView { model: WaterfallRenderer - private canvas: HTMLCanvasElement[] - private image: Uint32Array[] + private canvases: HTMLCanvasElement[] + private images: Uint32Array[] private y: number[] private row: number private tile: number @@ -29,11 +29,11 @@ export class WaterfallRendererView extends RendererView { this.tile_height = this.model.time_length / 10 const [w, h] = [this.model.fft_length, this.tile_height] - this.canvas = [] - this.image = [] + this.canvases = [] + this.images = [] for (let i = 0; i < N; i++) { - this.canvas.push(canvas({width: w, height: h})) - this.image.push(new Uint32Array(w*h)) + this.canvases.push(canvas({width: w, height: h})) + this.images.push(new Uint32Array(w*h)) } this.y = new Array(N) @@ -69,7 +69,7 @@ export class WaterfallRendererView extends RendererView { const sh = Math.ceil(this.yscale.compute(this.tile_height) - this.yscale.compute(0)) for (let i = 0; i < sy.length; i++) - ctx.drawImage(this.canvas[i], sx, sy[i], sw, sh) + ctx.drawImage(this.canvases[i], sx, sy[i], sw, sh) ctx.setImageSmoothingEnabled(smoothing) @@ -95,12 +95,12 @@ export class WaterfallRendererView extends RendererView { // apply the lastest column to the current tile image const buf32 = new Uint32Array(this.cmap.rgba_mapper.v_compute(this.model.latest).buffer) for (let i = 0; i < this.model.fft_length; i++) - this.image[this.tile][i+this.model.fft_length*this.row] = buf32[i] + this.images[this.tile][i+this.model.fft_length*this.row] = buf32[i] // update the tiles canvas with the image data - const cctx = this.canvas[this.tile].getContext('2d')! + const cctx = this.canvases[this.tile].getContext('2d')! const image = cctx.getImageData(0, 0, this.model.fft_length, this.tile_height) - image.data.set(new Uint8Array(this.image[this.tile].buffer)) + image.data.set(new Uint8Array(this.images[this.tile].buffer)) cctx.putImageData(image, 0, 0) } } @@ -131,17 +131,18 @@ export class WaterfallRenderer extends Renderer { static initClass(): void { this.prototype.default_view = WaterfallRendererView - this.define({ - latest: [ p.Any ], - palette: [ p.Any ], - time_length: [ p.Int ], - fft_length: [ p.Int ], - min_value: [ p.Any ], - max_value: [ p.Any ], - update: [ p.Any ], - }) + this.define(({Int, Number, Color, Array, Any}) =>({ + latest: [ Array(Number), [] ], + palette: [ Array(Color) ], + time_length: [ Int ], + fft_length: [ Int ], + min_value: [ Any ], + max_value: [ Any ], + update: [ Any ], + })) + - this.override({ + this.override({ level: "glyph", }) } From a9a4a0bb331036d55fa4eada4a97e52304e847f0 Mon Sep 17 00:00:00 2001 From: Notou Date: Wed, 24 Nov 2021 17:17:11 +0100 Subject: [PATCH 3/8] Porting to gr3.9 and pybind11 Also Revert support for Bokeh 2.3.1 --- .clang-format | 104 ++++++ CMakeLists.txt | 42 ++- README.md | 7 +- cmake/Modules/bokehguiConfig.cmake | 5 +- docs/doxygen/CMakeLists.txt | 1 + docs/doxygen/Doxyfile.in | 33 +- docs/doxygen/Doxyfile.swig_doc.in | 0 docs/doxygen/doxyxml/__init__.py | 1 - docs/doxygen/doxyxml/doxyindex.py | 10 - docs/doxygen/doxyxml/generated/__init__.py | 1 - docs/doxygen/doxyxml/generated/compound.py | 3 +- .../doxyxml/generated/compoundsuper.py | 9 +- docs/doxygen/doxyxml/generated/index.py | 2 - docs/doxygen/doxyxml/generated/indexsuper.py | 8 +- docs/doxygen/doxyxml/text.py | 3 +- docs/doxygen/pydoc_macros.h | 19 + docs/doxygen/swig_doc.py | 0 docs/doxygen/update_pydoc.py | 346 ++++++++++++++++++ grc/bokehgui_freq_sink_x.block.yml | 6 +- grc/bokehgui_waterfall_sink_x.block.yml | 8 +- include/bokehgui/base_sink.h | 38 +- include/bokehgui/waterfall_sink_c_proc.h | 2 +- include/bokehgui/waterfall_sink_f_proc.h | 2 +- lib/freq_sink_c_proc_impl.cc | 5 +- lib/freq_sink_c_proc_impl.h | 2 +- lib/freq_sink_f_proc_impl.cc | 4 +- lib/freq_sink_f_proc_impl.h | 2 +- lib/waterfall_sink_c_proc_impl.cc | 47 ++- lib/waterfall_sink_c_proc_impl.h | 7 +- lib/waterfall_sink_f_proc_impl.cc | 47 ++- lib/waterfall_sink_f_proc_impl.h | 7 +- python/CMakeLists.txt | 5 +- python/__init__.py | 9 +- python/bindings/CMakeLists.txt | 48 +++ python/bindings/README.md | 0 python/bindings/base_sink_python.cc | 80 ++++ python/bindings/bind_oot_file.py | 57 +++ python/bindings/docstrings/README.md | 1 + .../docstrings/base_sink_pydoc_template.h | 43 +++ .../freq_sink_c_proc_pydoc_template.h | 57 +++ .../freq_sink_f_proc_pydoc_template.h | 57 +++ .../time_sink_c_proc_pydoc_template.h | 48 +++ .../time_sink_f_proc_pydoc_template.h | 48 +++ .../vec_sink_c_proc_pydoc_template.h | 33 ++ .../vec_sink_f_proc_pydoc_template.h | 33 ++ .../waterfall_sink_c_proc_pydoc_template.h | 63 ++++ .../waterfall_sink_f_proc_pydoc_template.h | 63 ++++ python/bindings/freq_sink_c_proc_python.cc | 127 +++++++ python/bindings/freq_sink_f_proc_python.cc | 127 +++++++ python/bindings/header_utils.py | 78 ++++ python/bindings/python_bindings.cc | 70 ++++ python/bindings/time_sink_c_proc_python.cc | 107 ++++++ python/bindings/time_sink_f_proc_python.cc | 107 ++++++ python/bindings/vec_sink_c_proc_python.cc | 68 ++++ python/bindings/vec_sink_f_proc_python.cc | 68 ++++ .../bindings/waterfall_sink_c_proc_python.cc | 130 +++++++ .../bindings/waterfall_sink_f_proc_python.cc | 131 +++++++ python/plots/waterfall.py | 2 +- python/plots/waterfall.ts | 41 +-- 59 files changed, 2294 insertions(+), 178 deletions(-) create mode 100755 .clang-format mode change 100644 => 100755 CMakeLists.txt mode change 100644 => 100755 cmake/Modules/bokehguiConfig.cmake mode change 100644 => 100755 docs/doxygen/CMakeLists.txt mode change 100644 => 100755 docs/doxygen/Doxyfile.in mode change 100644 => 100755 docs/doxygen/Doxyfile.swig_doc.in mode change 100644 => 100755 docs/doxygen/doxyxml/__init__.py mode change 100644 => 100755 docs/doxygen/doxyxml/doxyindex.py mode change 100644 => 100755 docs/doxygen/doxyxml/generated/__init__.py mode change 100644 => 100755 docs/doxygen/doxyxml/generated/compound.py mode change 100644 => 100755 docs/doxygen/doxyxml/generated/compoundsuper.py mode change 100644 => 100755 docs/doxygen/doxyxml/generated/index.py mode change 100644 => 100755 docs/doxygen/doxyxml/generated/indexsuper.py mode change 100644 => 100755 docs/doxygen/doxyxml/text.py create mode 100755 docs/doxygen/pydoc_macros.h mode change 100644 => 100755 docs/doxygen/swig_doc.py create mode 100755 docs/doxygen/update_pydoc.py mode change 100644 => 100755 lib/freq_sink_c_proc_impl.cc mode change 100644 => 100755 lib/freq_sink_c_proc_impl.h mode change 100644 => 100755 lib/freq_sink_f_proc_impl.cc mode change 100644 => 100755 lib/freq_sink_f_proc_impl.h mode change 100644 => 100755 lib/waterfall_sink_c_proc_impl.cc mode change 100644 => 100755 lib/waterfall_sink_c_proc_impl.h mode change 100644 => 100755 lib/waterfall_sink_f_proc_impl.cc mode change 100644 => 100755 lib/waterfall_sink_f_proc_impl.h mode change 100644 => 100755 python/CMakeLists.txt mode change 100644 => 100755 python/__init__.py create mode 100755 python/bindings/CMakeLists.txt create mode 100755 python/bindings/README.md create mode 100644 python/bindings/base_sink_python.cc create mode 100755 python/bindings/bind_oot_file.py create mode 100755 python/bindings/docstrings/README.md create mode 100644 python/bindings/docstrings/base_sink_pydoc_template.h create mode 100755 python/bindings/docstrings/freq_sink_c_proc_pydoc_template.h create mode 100755 python/bindings/docstrings/freq_sink_f_proc_pydoc_template.h create mode 100755 python/bindings/docstrings/time_sink_c_proc_pydoc_template.h create mode 100755 python/bindings/docstrings/time_sink_f_proc_pydoc_template.h create mode 100755 python/bindings/docstrings/vec_sink_c_proc_pydoc_template.h create mode 100755 python/bindings/docstrings/vec_sink_f_proc_pydoc_template.h create mode 100755 python/bindings/docstrings/waterfall_sink_c_proc_pydoc_template.h create mode 100755 python/bindings/docstrings/waterfall_sink_f_proc_pydoc_template.h create mode 100755 python/bindings/freq_sink_c_proc_python.cc create mode 100755 python/bindings/freq_sink_f_proc_python.cc create mode 100755 python/bindings/header_utils.py create mode 100755 python/bindings/python_bindings.cc create mode 100755 python/bindings/time_sink_c_proc_python.cc create mode 100755 python/bindings/time_sink_f_proc_python.cc create mode 100755 python/bindings/vec_sink_c_proc_python.cc create mode 100755 python/bindings/vec_sink_f_proc_python.cc create mode 100755 python/bindings/waterfall_sink_c_proc_python.cc create mode 100755 python/bindings/waterfall_sink_f_proc_python.cc diff --git a/.clang-format b/.clang-format new file mode 100755 index 0000000..3e4ddd4 --- /dev/null +++ b/.clang-format @@ -0,0 +1,104 @@ +--- +Language: Cpp +# BasedOnStyle: LLVM +AccessModifierOffset: -4 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlinesLeft: true +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: true +BinPackArguments: false +BinPackParameters: false +BreakBeforeBraces: Custom +BraceWrapping: + AfterClass: true + AfterControlStatement: false + AfterEnum: false + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false +BreakBeforeBinaryOperators: None +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 90 +CommentPragmas: '^ IWYU pragma:' +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: false +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeCategories: + - Regex: '^"(gnuradio)/' + Priority: 1 + - Regex: '^<(gnuradio)/' + Priority: 2 + - Regex: '^<(boost)/' + Priority: 98 + - Regex: '^<[a-z]*>$' + Priority: 99 + - Regex: '^".*"$' + Priority: 0 + - Regex: '.*' + Priority: 10 + +IncludeIsMainRegex: '(Test)?$' +IndentCaseLabels: false +IndentWidth: 4 +IndentWrappedFunctionNames: false +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 2 +NamespaceIndentation: None +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Left +ReflowComments: true +SortIncludes: true +SpaceAfterCStyleCast: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +TabWidth: 8 +UseTab: Never diff --git a/CMakeLists.txt b/CMakeLists.txt old mode 100644 new mode 100755 index ce4c550..5d53400 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,11 +43,10 @@ list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_SOURCE_DIR}/cmake/Modules) # Set the version information here set(VERSION_MAJOR 1) -set(VERSION_API 0) -set(VERSION_ABI 0) -set(VERSION_PATCH git) +set(VERSION_API 0) +set(VERSION_ABI 0) +set(VERSION_PATCH 0) -set(PYTHON3_MIN_VERSION "3.6.5") cmake_policy(SET CMP0011 NEW) # Enable generation of compile_commands.json for code completion engines @@ -63,13 +62,12 @@ if((CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR add_definitions(-fvisibility=hidden) endif() - IF(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - SET(CMAKE_CXX_STANDARD 11) + SET(CMAKE_CXX_STANDARD 14) ELSEIF(CMAKE_CXX_COMPILER_ID MATCHES "Clang") - SET(CMAKE_CXX_STANDARD 11) + SET(CMAKE_CXX_STANDARD 14) ELSEIF(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") - SET(CMAKE_CXX_STANDARD 11) + SET(CMAKE_CXX_STANDARD 14) ELSE() message(WARNING "C++ standard could not be set because compiler is not GNU, Clang or MSVC.") ENDIF() @@ -87,6 +85,7 @@ ENDIF() ######################################################################## # Install directories ######################################################################## +include(FindPkgConfig) find_package(Gnuradio "3.9" REQUIRED runtime fft) include(GrVersion) @@ -127,8 +126,6 @@ endif(APPLE) # Find gnuradio build dependencies ######################################################################## find_package(Doxygen) -find_package(PythonInterp ${PYTHON_MIN_VERSION} COMPONENTS Interpreter Development NumPy) - ######################################################################## # Check if boheh module exists @@ -139,6 +136,18 @@ if(NOT BOKEH_FOUND) message(FATAL_ERROR "Bokeh library required to compile gr-bokehgui") endif() +######################################################################## +# PyBind11 Related +######################################################################## + +find_package(pybind11 REQUIRED) +execute_process( + COMMAND "${PYTHON_EXECUTABLE}" -c + "try:\n import numpy\n import os\n inc_path = numpy.get_include()\n if os.path.exists(os.path.join(inc_path, 'numpy', 'arrayobject.h')):\n print(inc_path, end='')\nexcept:\n pass" + OUTPUT_VARIABLE PYTHON_NUMPY_INCLUDE_DIR) +# format path in CMake-style for consistency with other path variables +# (a consistent style helps conda builds by using the same path separators) +file(TO_CMAKE_PATH "${PYTHON_NUMPY_INCLUDE_DIR}" PYTHON_NUMPY_INCLUDE_DIR) ######################################################################## # Setup doxygen option @@ -149,7 +158,6 @@ else(DOXYGEN_FOUND) option(ENABLE_DOXYGEN "Build docs using Doxygen" OFF) endif(DOXYGEN_FOUND) - ######################################################################## # Create uninstall target ######################################################################## @@ -162,7 +170,6 @@ add_custom_target(uninstall ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake ) - ######################################################################## # Add subdirectories ######################################################################## @@ -170,9 +177,14 @@ add_subdirectory(include/bokehgui) add_subdirectory(lib) add_subdirectory(apps) add_subdirectory(docs) -add_subdirectory(swig) -add_subdirectory(python) -add_subdirectory(grc) +# NOTE: manually update below to use GRC to generate C++ flowgraphs w/o python +if(ENABLE_PYTHON) + message(STATUS "PYTHON and GRC components are enabled") + add_subdirectory(python) + add_subdirectory(grc) +else(ENABLE_PYTHON) + message(STATUS "PYTHON and GRC components are disabled") +endif(ENABLE_PYTHON) ######################################################################## # Install cmake search helper for this library diff --git a/README.md b/README.md index 1ed08dd..3050b8b 100644 --- a/README.md +++ b/README.md @@ -4,15 +4,16 @@ ## Overview -The module provides various sinks and widgets to allow interaction with the live GNU Radio applications remotely over the network. The module uses [Bokeh](https://docs.bokeh.org/en/2.3.2/)'s client API and streaming features. Using widgets and plots from Bokeh, the module enables the GUI for GNU Radio that renders in web browser. Just like `gr-qtgui`, it is fully integrated with GRC to allow easy use. +The module provides various sinks and widgets to allow interaction with the live GNU Radio applications remotely over the network. The module uses [Bokeh](https://docs.bokeh.org/en/1.4.0/)'s client API and streaming features. Using widgets and plots from Bokeh, the module enables the GUI for GNU Radio that renders in web browser. Just like `gr-qtgui`, it is fully integrated with GRC to allow easy use. -The module was first developed as a part of Google Summer of Code 2017 by Kartik Patel. +The module was developed as a part of Google Summer of Code 2017 by Kartik Patel. ## Warning: The master branch does not yet support GNU Radio 3.9 since the change to pybind11. Please use the main-3.8 branch with GNU Radio 3.8 ## Dependency 1. GNU Radio 3.9 -2. [Bokeh library above 2.3.1](https://docs.bokeh.org/en/2.3.2/) (earlier versions cause the waterfall display to crash) +2. [Bokeh library v1](https://docs.bokeh.org/en/1.4.0/) + (Tested on v1.4.0) ## Installation ### Using PyBOMBS diff --git a/cmake/Modules/bokehguiConfig.cmake b/cmake/Modules/bokehguiConfig.cmake old mode 100644 new mode 100755 index c81d921..5e4f89e --- a/cmake/Modules/bokehguiConfig.cmake +++ b/cmake/Modules/bokehguiConfig.cmake @@ -1,4 +1,6 @@ -INCLUDE(FindPkgConfig) +if(NOT PKG_CONFIG_FOUND) + INCLUDE(FindPkgConfig) +endif() PKG_CHECK_MODULES(PC_BOKEHGUI bokehgui) FIND_PATH( @@ -29,4 +31,3 @@ include("${CMAKE_CURRENT_LIST_DIR}/bokehguiTarget.cmake") INCLUDE(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(BOKEHGUI DEFAULT_MSG BOKEHGUI_LIBRARIES BOKEHGUI_INCLUDE_DIRS) MARK_AS_ADVANCED(BOKEHGUI_LIBRARIES BOKEHGUI_INCLUDE_DIRS) - diff --git a/docs/doxygen/CMakeLists.txt b/docs/doxygen/CMakeLists.txt old mode 100644 new mode 100755 index f9e6aae..5345f9c --- a/docs/doxygen/CMakeLists.txt +++ b/docs/doxygen/CMakeLists.txt @@ -29,6 +29,7 @@ file(TO_NATIVE_PATH ${CMAKE_BINARY_DIR} abs_top_builddir) set(HAVE_DOT ${DOXYGEN_DOT_FOUND}) set(enable_html_docs YES) set(enable_latex_docs NO) +set(enable_mathjax NO) set(enable_xml_docs YES) configure_file( diff --git a/docs/doxygen/Doxyfile.in b/docs/doxygen/Doxyfile.in old mode 100644 new mode 100755 index ac66d0c..c2db8f1 --- a/docs/doxygen/Doxyfile.in +++ b/docs/doxygen/Doxyfile.in @@ -199,13 +199,6 @@ TAB_SIZE = 8 ALIASES = -# This tag can be used to specify a number of word-keyword mappings (TCL only). -# A mapping has the form "name=value". For example adding -# "class=itcl::class" will allow you to use the command class in the -# itcl::class meaning. - -TCL_SUBST = - # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list @@ -723,8 +716,6 @@ EXCLUDE_PATTERNS = */.deps/* \ EXCLUDE_SYMBOLS = ad9862 \ numpy \ - *swig* \ - *Swig* \ *my_top_block* \ *my_graph* \ *app_top_block* \ @@ -1220,14 +1211,14 @@ FORMULA_TRANSPARENT = YES # output. When enabled you may also need to install MathJax separately and # configure the path to it using the MATHJAX_RELPATH option. -USE_MATHJAX = NO +USE_MATHJAX = @enable_mathjax@ # When MathJax is enabled you can set the default output format to be used for # the MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and # SVG. The default value is HTML-CSS, which is slower, but has the best # compatibility. -MATHJAX_FORMAT = HTML-CSS +MATHJAX_FORMAT = SVG # When MathJax is enabled you need to specify the location relative to the # HTML output directory using the MATHJAX_RELPATH option. The destination @@ -1239,12 +1230,12 @@ MATHJAX_FORMAT = HTML-CSS # However, it is strongly recommended to install a local # copy of MathJax from http://www.mathjax.org before deployment. -MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest +MATHJAX_RELPATH = @MATHJAX2_PATH@ # The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension # names that should be enabled during MathJax rendering. -MATHJAX_EXTENSIONS = +MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols # The MATHJAX_CODEFILE tag can be used to specify a file with javascript # pieces of code that will be used on startup of the MathJax code. @@ -1680,11 +1671,6 @@ EXTERNAL_GROUPS = YES EXTERNAL_PAGES = YES -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- @@ -1697,15 +1683,6 @@ PERL_PATH = /usr/bin/perl CLASS_DIAGRAMS = YES -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see -# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. @@ -1834,7 +1811,7 @@ DIRECTORY_GRAPH = YES # HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible in IE 9+ (other browsers do not have this requirement). -DOT_IMAGE_FORMAT = png +DOT_IMAGE_FORMAT = svg # If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to # enable generation of interactive SVG images that allow zooming and panning. diff --git a/docs/doxygen/Doxyfile.swig_doc.in b/docs/doxygen/Doxyfile.swig_doc.in old mode 100644 new mode 100755 diff --git a/docs/doxygen/doxyxml/__init__.py b/docs/doxygen/doxyxml/__init__.py old mode 100644 new mode 100755 index 24d7609..d43af11 --- a/docs/doxygen/doxyxml/__init__.py +++ b/docs/doxygen/doxyxml/__init__.py @@ -64,7 +64,6 @@ u'Outputs the vital aadvark statistics.' """ -from __future__ import unicode_literals from .doxyindex import DoxyIndex, DoxyFunction, DoxyParam, DoxyClass, DoxyFile, DoxyNamespace, DoxyGroup, DoxyFriend, DoxyOther diff --git a/docs/doxygen/doxyxml/doxyindex.py b/docs/doxygen/doxyxml/doxyindex.py old mode 100644 new mode 100755 index ac58a09..20208d9 --- a/docs/doxygen/doxyxml/doxyindex.py +++ b/docs/doxygen/doxyxml/doxyindex.py @@ -23,8 +23,6 @@ Classes providing more user-friendly interfaces to the doxygen xml docs than the generated classes provide. """ -from __future__ import absolute_import -from __future__ import unicode_literals import os @@ -60,14 +58,6 @@ def _parse(self): self._members.append(converted) -def generate_swig_doc_i(self): - """ - %feature("docstring") gr_make_align_on_samplenumbers_ss::align_state " - Wraps the C++: gr_align_on_samplenumbers_ss::align_state"; - """ - pass - - class DoxyCompMem(Base): diff --git a/docs/doxygen/doxyxml/generated/__init__.py b/docs/doxygen/doxyxml/generated/__init__.py old mode 100644 new mode 100755 index 23095c1..3982397 --- a/docs/doxygen/doxyxml/generated/__init__.py +++ b/docs/doxygen/doxyxml/generated/__init__.py @@ -5,4 +5,3 @@ resultant classes are not very friendly to navigate so the rest of the doxyxml module processes them further. """ -from __future__ import unicode_literals diff --git a/docs/doxygen/doxyxml/generated/compound.py b/docs/doxygen/doxyxml/generated/compound.py old mode 100644 new mode 100755 index 0f55961..294f021 --- a/docs/doxygen/doxyxml/generated/compound.py +++ b/docs/doxygen/doxyxml/generated/compound.py @@ -3,8 +3,7 @@ """ Generated Mon Feb 9 19:08:05 2009 by generateDS.py. """ -from __future__ import absolute_import -from __future__ import unicode_literals + from xml.dom import minidom from xml.dom import Node diff --git a/docs/doxygen/doxyxml/generated/compoundsuper.py b/docs/doxygen/doxyxml/generated/compoundsuper.py old mode 100644 new mode 100755 index 6e984e1..05c4928 --- a/docs/doxygen/doxyxml/generated/compoundsuper.py +++ b/docs/doxygen/doxyxml/generated/compoundsuper.py @@ -4,17 +4,12 @@ # Generated Thu Jun 11 18:44:25 2009 by generateDS.py. # -from __future__ import print_function -from __future__ import unicode_literals import sys from xml.dom import minidom from xml.dom import Node -import six - - # # User methods # @@ -69,7 +64,7 @@ def showIndent(outfile, level): outfile.write(' ') def quote_xml(inStr): - s1 = (isinstance(inStr, six.string_types) and inStr or + s1 = (isinstance(inStr, str) and inStr or '%s' % inStr) s1 = s1.replace('&', '&') s1 = s1.replace('<', '<') @@ -77,7 +72,7 @@ def quote_xml(inStr): return s1 def quote_attrib(inStr): - s1 = (isinstance(inStr, six.string_types) and inStr or + s1 = (isinstance(inStr, str) and inStr or '%s' % inStr) s1 = s1.replace('&', '&') s1 = s1.replace('<', '<') diff --git a/docs/doxygen/doxyxml/generated/index.py b/docs/doxygen/doxyxml/generated/index.py old mode 100644 new mode 100755 index 0c63512..c58407d --- a/docs/doxygen/doxyxml/generated/index.py +++ b/docs/doxygen/doxyxml/generated/index.py @@ -3,8 +3,6 @@ """ Generated Mon Feb 9 19:08:05 2009 by generateDS.py. """ -from __future__ import absolute_import -from __future__ import unicode_literals from xml.dom import minidom diff --git a/docs/doxygen/doxyxml/generated/indexsuper.py b/docs/doxygen/doxyxml/generated/indexsuper.py old mode 100644 new mode 100755 index 11312db..cc2c112 --- a/docs/doxygen/doxyxml/generated/indexsuper.py +++ b/docs/doxygen/doxyxml/generated/indexsuper.py @@ -4,16 +4,12 @@ # Generated Thu Jun 11 18:43:54 2009 by generateDS.py. # -from __future__ import print_function -from __future__ import unicode_literals import sys from xml.dom import minidom from xml.dom import Node -import six - # # User methods # @@ -68,7 +64,7 @@ def showIndent(outfile, level): outfile.write(' ') def quote_xml(inStr): - s1 = (isinstance(inStr, six.string_types) and inStr or + s1 = (isinstance(inStr, str) and inStr or '%s' % inStr) s1 = s1.replace('&', '&') s1 = s1.replace('<', '<') @@ -76,7 +72,7 @@ def quote_xml(inStr): return s1 def quote_attrib(inStr): - s1 = (isinstance(inStr, six.string_types) and inStr or + s1 = (isinstance(inStr, str) and inStr or '%s' % inStr) s1 = s1.replace('&', '&') s1 = s1.replace('<', '<') diff --git a/docs/doxygen/doxyxml/text.py b/docs/doxygen/doxyxml/text.py old mode 100644 new mode 100755 index c2d43f9..26a2043 --- a/docs/doxygen/doxyxml/text.py +++ b/docs/doxygen/doxyxml/text.py @@ -22,13 +22,12 @@ """ Utilities for extracting text from generated classes. """ -from __future__ import unicode_literals def is_string(txt): if isinstance(txt, str): return True try: - if isinstance(txt, unicode): + if isinstance(txt, str): return True except NameError: pass diff --git a/docs/doxygen/pydoc_macros.h b/docs/doxygen/pydoc_macros.h new file mode 100755 index 0000000..98bf7cd --- /dev/null +++ b/docs/doxygen/pydoc_macros.h @@ -0,0 +1,19 @@ +#ifndef PYDOC_MACROS_H +#define PYDOC_MACROS_H + +#define __EXPAND(x) x +#define __COUNT(_1, _2, _3, _4, _5, _6, _7, COUNT, ...) COUNT +#define __VA_SIZE(...) __EXPAND(__COUNT(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1)) +#define __CAT1(a, b) a##b +#define __CAT2(a, b) __CAT1(a, b) +#define __DOC1(n1) __doc_##n1 +#define __DOC2(n1, n2) __doc_##n1##_##n2 +#define __DOC3(n1, n2, n3) __doc_##n1##_##n2##_##n3 +#define __DOC4(n1, n2, n3, n4) __doc_##n1##_##n2##_##n3##_##n4 +#define __DOC5(n1, n2, n3, n4, n5) __doc_##n1##_##n2##_##n3##_##n4##_##n5 +#define __DOC6(n1, n2, n3, n4, n5, n6) __doc_##n1##_##n2##_##n3##_##n4##_##n5##_##n6 +#define __DOC7(n1, n2, n3, n4, n5, n6, n7) \ + __doc_##n1##_##n2##_##n3##_##n4##_##n5##_##n6##_##n7 +#define DOC(...) __EXPAND(__EXPAND(__CAT2(__DOC, __VA_SIZE(__VA_ARGS__)))(__VA_ARGS__)) + +#endif // PYDOC_MACROS_H \ No newline at end of file diff --git a/docs/doxygen/swig_doc.py b/docs/doxygen/swig_doc.py old mode 100644 new mode 100755 diff --git a/docs/doxygen/update_pydoc.py b/docs/doxygen/update_pydoc.py new file mode 100755 index 0000000..e6b4544 --- /dev/null +++ b/docs/doxygen/update_pydoc.py @@ -0,0 +1,346 @@ +# +# Copyright 2010-2012 Free Software Foundation, Inc. +# +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gnuradio +# +# SPDX-License-Identifier: GPL-3.0-or-later +# +# +""" +Updates the *pydoc_h files for a module +Execute using: python update_pydoc.py xml_path outputfilename + +The file instructs Pybind11 to transfer the doxygen comments into the +python docstrings. + +""" + +import os, sys, time, glob, re, json +from argparse import ArgumentParser + +from doxyxml import DoxyIndex, DoxyClass, DoxyFriend, DoxyFunction, DoxyFile +from doxyxml import DoxyOther, base + +def py_name(name): + bits = name.split('_') + return '_'.join(bits[1:]) + +def make_name(name): + bits = name.split('_') + return bits[0] + '_make_' + '_'.join(bits[1:]) + + +class Block(object): + """ + Checks if doxyxml produced objects correspond to a gnuradio block. + """ + + @classmethod + def includes(cls, item): + if not isinstance(item, DoxyClass): + return False + # Check for a parsing error. + if item.error(): + return False + friendname = make_name(item.name()) + is_a_block = item.has_member(friendname, DoxyFriend) + # But now sometimes the make function isn't a friend so check again. + if not is_a_block: + is_a_block = di.has_member(friendname, DoxyFunction) + return is_a_block + +class Block2(object): + """ + Checks if doxyxml produced objects correspond to a new style + gnuradio block. + """ + + @classmethod + def includes(cls, item): + if not isinstance(item, DoxyClass): + return False + # Check for a parsing error. + if item.error(): + return False + is_a_block2 = item.has_member('make', DoxyFunction) and item.has_member('sptr', DoxyOther) + return is_a_block2 + + +def utoascii(text): + """ + Convert unicode text into ascii and escape quotes and backslashes. + """ + if text is None: + return '' + out = text.encode('ascii', 'replace') + # swig will require us to replace blackslash with 4 backslashes + # TODO: evaluate what this should be for pybind11 + out = out.replace(b'\\', b'\\\\\\\\') + out = out.replace(b'"', b'\\"').decode('ascii') + return str(out) + + +def combine_descriptions(obj): + """ + Combines the brief and detailed descriptions of an object together. + """ + description = [] + bd = obj.brief_description.strip() + dd = obj.detailed_description.strip() + if bd: + description.append(bd) + if dd: + description.append(dd) + return utoascii('\n\n'.join(description)).strip() + +def format_params(parameteritems): + output = ['Args:'] + template = ' {0} : {1}' + for pi in parameteritems: + output.append(template.format(pi.name, pi.description)) + return '\n'.join(output) + +entry_templ = '%feature("docstring") {name} "{docstring}"' +def make_entry(obj, name=None, templ="{description}", description=None, params=[]): + """ + Create a docstring key/value pair, where the key is the object name. + + obj - a doxyxml object from which documentation will be extracted. + name - the name of the C object (defaults to obj.name()) + templ - an optional template for the docstring containing only one + variable named 'description'. + description - if this optional variable is set then it's value is + used as the description instead of extracting it from obj. + """ + if name is None: + name=obj.name() + if hasattr(obj,'_parse_data') and hasattr(obj._parse_data,'definition'): + name=obj._parse_data.definition.split(' ')[-1] + if "operator " in name: + return '' + if description is None: + description = combine_descriptions(obj) + if params: + description += '\n\n' + description += utoascii(format_params(params)) + docstring = templ.format(description=description) + + return {name: docstring} + + +def make_class_entry(klass, description=None, ignored_methods=[], params=None): + """ + Create a class docstring key/value pair. + """ + if params is None: + params = klass.params + output = {} + output.update(make_entry(klass, description=description, params=params)) + for func in klass.in_category(DoxyFunction): + if func.name() not in ignored_methods: + name = klass.name() + '::' + func.name() + output.update(make_entry(func, name=name)) + return output + + +def make_block_entry(di, block): + """ + Create class and function docstrings of a gnuradio block + """ + descriptions = [] + # Get the documentation associated with the class. + class_desc = combine_descriptions(block) + if class_desc: + descriptions.append(class_desc) + # Get the documentation associated with the make function + make_func = di.get_member(make_name(block.name()), DoxyFunction) + make_func_desc = combine_descriptions(make_func) + if make_func_desc: + descriptions.append(make_func_desc) + # Get the documentation associated with the file + try: + block_file = di.get_member(block.name() + ".h", DoxyFile) + file_desc = combine_descriptions(block_file) + if file_desc: + descriptions.append(file_desc) + except base.Base.NoSuchMember: + # Don't worry if we can't find a matching file. + pass + # And join them all together to make a super duper description. + super_description = "\n\n".join(descriptions) + # Associate the combined description with the class and + # the make function. + output = {} + output.update(make_class_entry(block, description=super_description)) + output.update(make_entry(make_func, description=super_description, + params=block.params)) + return output + +def make_block2_entry(di, block): + """ + Create class and function docstrings of a new style gnuradio block + """ + # For new style blocks all the relevant documentation should be + # associated with the 'make' method. + class_description = combine_descriptions(block) + make_func = block.get_member('make', DoxyFunction) + make_description = combine_descriptions(make_func) + description = class_description + "\n\nConstructor Specific Documentation:\n\n" + make_description + # Associate the combined description with the class and + # the make function. + output = {} + output.update(make_class_entry( + block, description=description, + ignored_methods=['make'], params=make_func.params)) + makename = block.name() + '::make' + output.update(make_entry( + make_func, name=makename, description=description, + params=make_func.params)) + return output + +def get_docstrings_dict(di, custom_output=None): + + output = {} + if custom_output: + output.update(custom_output) + + # Create docstrings for the blocks. + blocks = di.in_category(Block) + blocks2 = di.in_category(Block2) + + make_funcs = set([]) + for block in blocks: + try: + make_func = di.get_member(make_name(block.name()), DoxyFunction) + # Don't want to risk writing to output twice. + if make_func.name() not in make_funcs: + make_funcs.add(make_func.name()) + output.update(make_block_entry(di, block)) + except block.ParsingError: + sys.stderr.write('Parsing error for block {0}\n'.format(block.name())) + raise + + for block in blocks2: + try: + make_func = block.get_member('make', DoxyFunction) + make_func_name = block.name() +'::make' + # Don't want to risk writing to output twice. + if make_func_name not in make_funcs: + make_funcs.add(make_func_name) + output.update(make_block2_entry(di, block)) + except block.ParsingError: + sys.stderr.write('Parsing error for block {0}\n'.format(block.name())) + raise + + # Create docstrings for functions + # Don't include the make functions since they have already been dealt with. + funcs = [f for f in di.in_category(DoxyFunction) + if f.name() not in make_funcs and not f.name().startswith('std::')] + for f in funcs: + try: + output.update(make_entry(f)) + except f.ParsingError: + sys.stderr.write('Parsing error for function {0}\n'.format(f.name())) + + # Create docstrings for classes + block_names = [block.name() for block in blocks] + block_names += [block.name() for block in blocks2] + klasses = [k for k in di.in_category(DoxyClass) + if k.name() not in block_names and not k.name().startswith('std::')] + for k in klasses: + try: + output.update(make_class_entry(k)) + except k.ParsingError: + sys.stderr.write('Parsing error for class {0}\n'.format(k.name())) + + # Docstrings are not created for anything that is not a function or a class. + # If this excludes anything important please add it here. + + return output + +def sub_docstring_in_pydoc_h(pydoc_files, docstrings_dict, output_dir, filter_str=None): + if filter_str: + docstrings_dict = {k: v for k, v in docstrings_dict.items() if k.startswith(filter_str)} + + with open(os.path.join(output_dir,'docstring_status'),'w') as status_file: + + for pydoc_file in pydoc_files: + if filter_str: + filter_str2 = "::".join((filter_str,os.path.split(pydoc_file)[-1].split('_pydoc_template.h')[0])) + docstrings_dict2 = {k: v for k, v in docstrings_dict.items() if k.startswith(filter_str2)} + else: + docstrings_dict2 = docstrings_dict + + + + file_in = open(pydoc_file,'r').read() + for key, value in docstrings_dict2.items(): + file_in_tmp = file_in + try: + doc_key = key.split("::") + # if 'gr' in doc_key: + # doc_key.remove('gr') + doc_key = '_'.join(doc_key) + regexp = r'(__doc_{} =\sR\"doc\()[^)]*(\)doc\")'.format(doc_key) + regexp = re.compile(regexp, re.MULTILINE) + + (file_in, nsubs) = regexp.subn(r'\1'+value+r'\2', file_in, count=1) + if nsubs == 1: + status_file.write("PASS: " + pydoc_file + "\n") + except KeyboardInterrupt: + raise KeyboardInterrupt + except: # be permissive, TODO log, but just leave the docstring blank + status_file.write("FAIL: " + pydoc_file + "\n") + file_in = file_in_tmp + + output_pathname = os.path.join(output_dir, os.path.basename(pydoc_file).replace('_template.h','.h')) + # FIXME: Remove this debug print + print('output docstrings to {}'.format(output_pathname)) + with open(output_pathname,'w') as file_out: + file_out.write(file_in) + +def copy_docstring_templates(pydoc_files, output_dir): + with open(os.path.join(output_dir,'docstring_status'),'w') as status_file: + for pydoc_file in pydoc_files: + file_in = open(pydoc_file,'r').read() + output_pathname = os.path.join(output_dir, os.path.basename(pydoc_file).replace('_template.h','.h')) + # FIXME: Remove this debug print + print('copy docstrings to {}'.format(output_pathname)) + with open(output_pathname,'w') as file_out: + file_out.write(file_in) + status_file.write("DONE") + +def argParse(): + """Parses commandline args.""" + desc='Scrape the doxygen generated xml for docstrings to insert into python bindings' + parser = ArgumentParser(description=desc) + + parser.add_argument("function", help="Operation to perform on docstrings", choices=["scrape","sub","copy"]) + + parser.add_argument("--xml_path") + parser.add_argument("--bindings_dir") + parser.add_argument("--output_dir") + parser.add_argument("--json_path") + parser.add_argument("--filter", default=None) + + return parser.parse_args() + +if __name__ == "__main__": + # Parse command line options and set up doxyxml. + args = argParse() + if args.function.lower() == 'scrape': + di = DoxyIndex(args.xml_path) + docstrings_dict = get_docstrings_dict(di) + with open(args.json_path, 'w') as fp: + json.dump(docstrings_dict, fp) + elif args.function.lower() == 'sub': + with open(args.json_path, 'r') as fp: + docstrings_dict = json.load(fp) + pydoc_files = glob.glob(os.path.join(args.bindings_dir,'*_pydoc_template.h')) + sub_docstring_in_pydoc_h(pydoc_files, docstrings_dict, args.output_dir, args.filter) + elif args.function.lower() == 'copy': + pydoc_files = glob.glob(os.path.join(args.bindings_dir,'*_pydoc_template.h')) + copy_docstring_templates(pydoc_files, args.output_dir) + + diff --git a/grc/bokehgui_freq_sink_x.block.yml b/grc/bokehgui_freq_sink_x.block.yml index 464ab6e..5773103 100644 --- a/grc/bokehgui_freq_sink_x.block.yml +++ b/grc/bokehgui_freq_sink_x.block.yml @@ -36,9 +36,9 @@ parameters: - id: wintype label: Window Type dtype: enum - default: firdes.WIN_BLACKMAN_hARRIS - options: [firdes.WIN_BLACKMAN_hARRIS, firdes.WIN_HAMMING, firdes.WIN_HANN, firdes.WIN_BLACKMAN, - firdes.WIN_RECTANGULAR, firdes.WIN_KAISER, firdes.WIN_FLATTOP] + default: window.WIN_BLACKMAN_hARRIS + options: [window.WIN_BLACKMAN_hARRIS, window.WIN_HAMMING, window.WIN_HANN, window.WIN_BLACKMAN, + window.WIN_RECTANGULAR, window.WIN_KAISER, window.WIN_FLATTOP] option_labels: [Blackman-harris, Hamming, Hann, Blackman, Rectangular, Kaiser, Flat-top] hide: part diff --git a/grc/bokehgui_waterfall_sink_x.block.yml b/grc/bokehgui_waterfall_sink_x.block.yml index 02f1e32..798a71e 100644 --- a/grc/bokehgui_waterfall_sink_x.block.yml +++ b/grc/bokehgui_waterfall_sink_x.block.yml @@ -29,10 +29,10 @@ parameters: hide: ${ ('all' if type.t == 'message' else 'none') } - id: wintype label: Window Type - dtype: int - default: firdes.WIN_BLACKMAN_hARRIS - options: [firdes.WIN_BLACKMAN_hARRIS, firdes.WIN_HAMMING, firdes.WIN_HANN, firdes.WIN_BLACKMAN, - firdes.WIN_RECTANGULAR, firdes.WIN_KAISER, firdes.WIN_FLATTOP] + dtype: enum + default: window.WIN_BLACKMAN_hARRIS + options: [window.WIN_BLACKMAN_hARRIS, window.WIN_HAMMING, window.WIN_HANN, window.WIN_BLACKMAN, + window.WIN_RECTANGULAR, window.WIN_KAISER, window.WIN_FLATTOP] option_labels: [Blackman-harris, Hamming, Hann, Blackman, Rectangular, Kaiser, Flat-top] hide: part diff --git a/include/bokehgui/base_sink.h b/include/bokehgui/base_sink.h index 3afe5d2..8abe9df 100644 --- a/include/bokehgui/base_sink.h +++ b/include/bokehgui/base_sink.h @@ -45,7 +45,7 @@ namespace gr { * by the child-class. If the functions are irrelevant for the child-class * then implementation of a blank function is required. * - * This class maintains a queue of 2D array is maintained. Each 2D array + * This class maintains a queue of 2D arrays. Each 2D array * is of size \p nconnection \p x \p d_size. For each call to get the * data from Python, first element of queue is sent. * @@ -101,26 +101,36 @@ namespace gr { * \param size Pointer to integer value representing number of elements * in a row. Generally \p d_size */ - void get_plot_data (float** output_items, int* nrows, int* size) { + float * get_plot_data () { gr::thread::scoped_lock lock(d_setlock); if (!d_buffers.size()) { - *size = 0; - *nrows = d_nconnections + 1; - return; + int size = 0; + int nrows = d_nconnections + 1; + float* arr = (float*) malloc(2*(nrows)*(size)*sizeof(float)); + return arr; } - *nrows = d_nconnections + 1; //Why the +1? why not d_buffers.front().size()? - *size = d_buffers.front()[0].size(); + int nrows = d_nconnections + 1; //Why the +1? why not d_buffers.front().size()? + int size = d_buffers.front()[0].size(); - float* arr = (float*) malloc(2*(*nrows)*(*size)*sizeof(float)); // Why the 2* and the size float and not T? - memset(arr, 0, 2*(*nrows)*(*size)*sizeof(float)); - process_plot(arr, nrows, size); - - *output_items = arr; + float* arr = (float*) malloc(2*(nrows)*(size)*sizeof(float)); // Why the 2* and the size float and not T? + memset(arr, 0, 2*(nrows)*(size)*sizeof(float)); + process_plot(arr, &nrows, &size); d_buffers.pop(); - return; + return arr; + } + + int get_buff_size(){ + if (!d_buffers.size()) { + return 0; + } + return d_buffers.front()[0].size(); + } + + int get_buff_cols(){ + return (sizeof(T)/sizeof(float))*d_nconnections; } int work(int noutput_items, @@ -131,7 +141,7 @@ namespace gr { // Consume all possible set of data. Each with nitems for(int d_index = 0; d_index < noutput_items;) { int nitems = std::min(d_size, noutput_items - d_index); - // TODO: See how to include auto/normal triggeres + // TODO: See how to include auto/normal triggers if(d_trigger_mode == TRIG_MODE_TAG) { _test_trigger_tags(d_index, nitems); } diff --git a/include/bokehgui/waterfall_sink_c_proc.h b/include/bokehgui/waterfall_sink_c_proc.h index 86237f2..be3cd7b 100644 --- a/include/bokehgui/waterfall_sink_c_proc.h +++ b/include/bokehgui/waterfall_sink_c_proc.h @@ -50,7 +50,7 @@ namespace gr { virtual gr::fft::window::win_type get_wintype() = 0; virtual void set_frequency_range(double, double) = 0; - virtual void get_plot_data (float** output_items, int* nrows, int* size) = 0; + virtual float * get_plot_data () = 0; }; } } diff --git a/include/bokehgui/waterfall_sink_f_proc.h b/include/bokehgui/waterfall_sink_f_proc.h index 0787835..06ff109 100644 --- a/include/bokehgui/waterfall_sink_f_proc.h +++ b/include/bokehgui/waterfall_sink_f_proc.h @@ -49,7 +49,7 @@ namespace gr { virtual gr::fft::window::win_type get_wintype() = 0; virtual void set_frequency_range(double, double) = 0; - virtual void get_plot_data (float** output_items, int* nrows, int* size) = 0; + virtual float * get_plot_data () = 0; }; } } diff --git a/lib/freq_sink_c_proc_impl.cc b/lib/freq_sink_c_proc_impl.cc old mode 100644 new mode 100755 index 8aa5c2a..fddff63 --- a/lib/freq_sink_c_proc_impl.cc +++ b/lib/freq_sink_c_proc_impl.cc @@ -59,7 +59,7 @@ namespace gr { // Perform fftshift operation // This is usually desired when plotting d_shift = true; - d_fft = new fft::fft_complex(d_size, true); + d_fft = new fft::fft_complex_fwd(d_size, true); // Used to save FFT values temporarily d_fbuf = std::vector (d_size, true); @@ -228,7 +228,7 @@ namespace gr { // Reset FFTW plan for new size delete d_fft; - d_fft = new fft::fft_complex(d_size, true); + d_fft = new fft::fft_complex_fwd(d_size, true); d_fbuf = std::vector (d_size, 0); d_tmpbuflen = (unsigned int) (floor(d_size/2.0)); @@ -327,4 +327,3 @@ namespace gr { } } /* namespace bokehgui */ } /* namespace gr */ - diff --git a/lib/freq_sink_c_proc_impl.h b/lib/freq_sink_c_proc_impl.h old mode 100644 new mode 100755 index ae468c3..e9a43ae --- a/lib/freq_sink_c_proc_impl.h +++ b/lib/freq_sink_c_proc_impl.h @@ -33,7 +33,7 @@ namespace gr { std::vector d_window; double d_center_freq, d_bandwidth; bool d_shift; - fft::fft_complex* d_fft; + fft::fft_complex_fwd* d_fft; std::vector d_fbuf; unsigned int d_tmpbuflen; std::vector d_tmpbuf; diff --git a/lib/freq_sink_f_proc_impl.cc b/lib/freq_sink_f_proc_impl.cc old mode 100644 new mode 100755 index c0bcba8..c164351 --- a/lib/freq_sink_f_proc_impl.cc +++ b/lib/freq_sink_f_proc_impl.cc @@ -54,7 +54,7 @@ namespace gr { // Perform fftshift operation; // This is usually desired when plotting d_shift = true; - d_fft = new fft::fft_complex(d_size, true); + d_fft = new fft::fft_complex_fwd(d_size, true); // Used to save FFT values temporarily d_fbuf = std::vector (d_size, 0); @@ -225,7 +225,7 @@ namespace gr { // Reset FFTW plan for new size delete d_fft; - d_fft = new fft::fft_complex(d_size, true); + d_fft = new fft::fft_complex_fwd(d_size, true); d_fbuf = std::vector (d_size, 0); d_tmpbuflen = (unsigned int)(floor(d_size/2.0)); diff --git a/lib/freq_sink_f_proc_impl.h b/lib/freq_sink_f_proc_impl.h old mode 100644 new mode 100755 index b9999f1..9511315 --- a/lib/freq_sink_f_proc_impl.h +++ b/lib/freq_sink_f_proc_impl.h @@ -33,7 +33,7 @@ namespace gr { std::vector d_window; double d_center_freq, d_bandwidth; bool d_shift; - fft::fft_complex* d_fft; + fft::fft_complex_fwd* d_fft; std::vector d_fbuf; unsigned int d_tmpbuflen; std::vector d_tmpbuf; diff --git a/lib/waterfall_sink_c_proc_impl.cc b/lib/waterfall_sink_c_proc_impl.cc old mode 100644 new mode 100755 index 2eed6dc..ea9ff67 --- a/lib/waterfall_sink_c_proc_impl.cc +++ b/lib/waterfall_sink_c_proc_impl.cc @@ -43,7 +43,7 @@ namespace gr { d_center_freq(fc), d_bandwidth(bw), d_nrows(200) { d_shift = true; - d_fft = new fft::fft_complex(d_size, true); + d_fft = new fft::fft_complex_fwd(d_size, true); // Used to save FFT values d_fbuf = std::vector (d_size, 0); @@ -66,34 +66,47 @@ namespace gr { d_fbuf = std::vector(); } - void - waterfall_sink_c_proc_impl::get_plot_data (float** output_items, int* nrows, int* size) { + float * + waterfall_sink_c_proc_impl::get_plot_data () { // Reimplementation of get_plot_data to handle // multiple rows to be sent in case of PDU message gr::thread::scoped_lock lock(d_setlock); + int nrows = 0; if (!d_buffers.size()) { - *size = 0; - *nrows = d_nconnections + 1; - return; + int size = 0; + nrows = d_nconnections + 1; + float* arr = (float*) malloc(2*(nrows)*(size)*sizeof(float)); + return arr; } if (d_nconnections) { - *nrows = d_nconnections + 1; + nrows = d_nconnections + 1; } else { - *nrows = d_nrows; + nrows = d_nrows; } - *size = d_buffers.front()[0].size(); - - float* arr = (float*) malloc(2*(*nrows)*(*size)*sizeof(float)); - memset(arr, 0, 2*(*nrows)*(*size)*sizeof(float)); + int size = d_buffers.front()[0].size(); - process_plot(arr, nrows, size); + float* arr = (float*) malloc(2*(nrows)*(size)*sizeof(float)); + memset(arr, 0, 2*(nrows)*(size)*sizeof(float)); - *output_items = arr; + process_plot(arr, &nrows, &size); d_buffers.pop(); - return; + return arr; + } + + int waterfall_sink_c_proc_impl::get_buff_size(){ + return d_buffers.front()[0].size(); + } + + int waterfall_sink_c_proc_impl::get_buff_cols(){ + if (d_nconnections) { + return d_nconnections + 1; + } + else { + return d_nrows; + } } void @@ -208,7 +221,7 @@ namespace gr { buildwindow(); delete d_fft; - d_fft = new fft::fft_complex(d_size, true); + d_fft = new fft::fft_complex_fwd(d_size, true); d_fbuf = std::vector (d_size, 0); @@ -282,5 +295,3 @@ namespace gr { } } /* namespace bokehgui */ } /* namespace gr */ - - diff --git a/lib/waterfall_sink_c_proc_impl.h b/lib/waterfall_sink_c_proc_impl.h old mode 100644 new mode 100755 index a6f2b56..6b1b09d --- a/lib/waterfall_sink_c_proc_impl.h +++ b/lib/waterfall_sink_c_proc_impl.h @@ -34,7 +34,7 @@ namespace gr { std::vector d_window; double d_center_freq, d_bandwidth; bool d_shift; - fft::fft_complex* d_fft; + fft::fft_complex_fwd* d_fft; std::vector d_fbuf; double d_time_per_fft; @@ -62,8 +62,11 @@ namespace gr { void set_size(int); void buildwindow(); + int get_buff_size(); + int get_buff_cols(); + // Virtual functions inherited from base_sink - void get_plot_data (float** output_items, int* nrows, int* size); + float * get_plot_data (); void process_plot(float* arr, int* nrows, int* size); void pop_other_queues(); void verify_datatype_PDU(const gr_complex*, pmt::pmt_t, size_t); diff --git a/lib/waterfall_sink_f_proc_impl.cc b/lib/waterfall_sink_f_proc_impl.cc old mode 100644 new mode 100755 index 68ee93d..38eb0ae --- a/lib/waterfall_sink_f_proc_impl.cc +++ b/lib/waterfall_sink_f_proc_impl.cc @@ -44,7 +44,7 @@ namespace gr { d_center_freq(fc), d_bandwidth(bw), d_nrows(200) { d_shift = true; - d_fft = new fft::fft_complex(d_size, true); + d_fft = new fft::fft_complex_fwd(d_size, true); // Used to save FFT values d_fbuf = std::vector (d_size, 0); @@ -67,34 +67,47 @@ namespace gr { d_fbuf = std::vector(); } - void - waterfall_sink_f_proc_impl::get_plot_data (float** output_items, int* nrows, int* size) { + float * + waterfall_sink_f_proc_impl::get_plot_data () { // Reimplementation of get_plot_data to handle // multiple rows to be sent in case of PDU message gr::thread::scoped_lock lock(d_setlock); + int nrows = 0; if (!d_buffers.size()) { - *size = 0; - *nrows = d_nconnections + 1; - return; + int size = 0; + nrows = d_nconnections + 1; + float* arr = (float*) malloc(2*(nrows)*(size)*sizeof(float)); + return arr; } if (d_nconnections) { - *nrows = d_nconnections + 1; + nrows = d_nconnections + 1; } else { - *nrows = d_nrows; + nrows = d_nrows; } - *size = d_buffers.front()[0].size(); - - float* arr = (float*) malloc(2*(*nrows)*(*size)*sizeof(float)); - memset(arr, 0, 2*(*nrows)*(*size)*sizeof(float)); + int size = d_buffers.front()[0].size(); - process_plot(arr, nrows, size); + float* arr = (float*) malloc(2*(nrows)*(size)*sizeof(float)); + memset(arr, 0, 2*(nrows)*(size)*sizeof(float)); - *output_items = arr; + process_plot(arr, &nrows, &size); d_buffers.pop(); - return; + return arr; + } + + int waterfall_sink_f_proc_impl::get_buff_size(){ + return d_buffers.front()[0].size(); + } + + int waterfall_sink_f_proc_impl::get_buff_cols(){ + if (d_nconnections) { + return d_nconnections + 1; + } + else { + return d_nrows; + } } void @@ -212,7 +225,7 @@ namespace gr { buildwindow(); delete d_fft; - d_fft = new fft::fft_complex(d_size, true); + d_fft = new fft::fft_complex_fwd(d_size, true); d_fbuf = std::vector (d_size, 0); @@ -286,5 +299,3 @@ namespace gr { } } /* namespace bokehgui */ } /* namespace gr */ - - diff --git a/lib/waterfall_sink_f_proc_impl.h b/lib/waterfall_sink_f_proc_impl.h old mode 100644 new mode 100755 index d5527ad..ab40842 --- a/lib/waterfall_sink_f_proc_impl.h +++ b/lib/waterfall_sink_f_proc_impl.h @@ -34,7 +34,7 @@ namespace gr { std::vector d_window; double d_center_freq, d_bandwidth; bool d_shift; - fft::fft_complex* d_fft; + fft::fft_complex_fwd* d_fft; std::vector d_fbuf; double d_time_per_fft; @@ -64,8 +64,11 @@ namespace gr { void set_size(int); void buildwindow(); + int get_buff_size(); + int get_buff_cols(); + // Virtual functions inherited from base_sink - void get_plot_data (float** output_items, int* nrows, int* size); + float * get_plot_data(); void process_plot(float* arr, int* nrows, int* size); void pop_other_queues(); void verify_datatype_PDU(const float*, pmt::pmt_t, size_t); diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt old mode 100644 new mode 100755 index 23f4d9f..70e14d6 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -26,6 +26,8 @@ if(NOT PYTHONINTERP_FOUND) return() endif() +add_subdirectory(bindings) + ######################################################################## # Install python sources ######################################################################## @@ -60,7 +62,6 @@ GR_PYTHON_INSTALL( plots/bokehgui.py DESTINATION ${GR_PYTHON_DIR}/bokehgui/plots ) - install(FILES plots/waterfall.ts DESTINATION ${GR_PYTHON_DIR}/bokehgui/plots PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) @@ -75,7 +76,7 @@ install(FILES scripts/check-port.sh include(GrTest) set(GR_TEST_TARGET_DEPS gnuradio-bokehgui) -set(GR_TEST_PYTHON_DIRS ${CMAKE_BINARY_DIR}/swig) +GR_ADD_TEST(qa_time_sink_c_proc ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_time_sink_c_proc.py) GR_ADD_TEST(qa_time_sink_f ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_time_sink_f.py) GR_ADD_TEST(qa_time_sink_c ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_time_sink_c.py) GR_ADD_TEST(qa_freq_sink_f ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_freq_sink_f.py) diff --git a/python/__init__.py b/python/__init__.py old mode 100644 new mode 100755 index 07894fd..5b78f23 --- a/python/__init__.py +++ b/python/__init__.py @@ -25,13 +25,13 @@ handled by `Bokeh` and corresponding callback functions are defined in each sinks. ''' -from __future__ import unicode_literals +import os -# import swig generated symbols into the bokehgui namespace +# import pybind11 generated symbols into the bokehgui namespace try: # this might fail if the module is python-only - from .bokehgui_swig import * -except ImportError: + from .bokehgui_python import * +except ModuleNotFoundError: pass # import any pure python here @@ -52,4 +52,3 @@ from .vec_sink_f import vec_sink_f from .waterfall_sink_c import waterfall_sink_c from .waterfall_sink_f import waterfall_sink_f -# diff --git a/python/bindings/CMakeLists.txt b/python/bindings/CMakeLists.txt new file mode 100755 index 0000000..27e71bb --- /dev/null +++ b/python/bindings/CMakeLists.txt @@ -0,0 +1,48 @@ +# Copyright 2020 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# SPDX-License-Identifier: GPL-3.0-or-later +# + +######################################################################## +# Check if there is C++ code at all +######################################################################## +if(NOT bokehgui_sources) + MESSAGE(STATUS "No C++ sources... skipping python bindings") + return() +endif(NOT bokehgui_sources) + +######################################################################## +# Check for pygccxml +######################################################################## +GR_PYTHON_CHECK_MODULE_RAW( + "pygccxml" + "import pygccxml" + PYGCCXML_FOUND + ) + +include(GrPybind) + +######################################################################## +# Python Bindings +######################################################################## + +list(APPEND bokehgui_python_files + time_sink_c_proc_python.cc + time_sink_f_proc_python.cc + freq_sink_f_proc_python.cc + vec_sink_c_proc_python.cc + vec_sink_f_proc_python.cc + freq_sink_c_proc_python.cc + waterfall_sink_f_proc_python.cc + waterfall_sink_c_proc_python.cc + base_sink_python.cc + python_bindings.cc) + +GR_PYBIND_MAKE_OOT(bokehgui + ../.. + gr::bokehgui + "${bokehgui_python_files}") + +install(TARGETS bokehgui_python DESTINATION ${GR_PYTHON_DIR}/bokehgui COMPONENT pythonapi) diff --git a/python/bindings/README.md b/python/bindings/README.md new file mode 100755 index 0000000..e69de29 diff --git a/python/bindings/base_sink_python.cc b/python/bindings/base_sink_python.cc new file mode 100644 index 0000000..bc641a5 --- /dev/null +++ b/python/bindings/base_sink_python.cc @@ -0,0 +1,80 @@ +/* + * Copyright 2021 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + + + +#include +#include +#include +#include + +namespace py = pybind11; + +#include +#include +// pydoc.h is automatically generated in the build directory +#include + + +template +void bind_base_sink_template(py::module& m, const char* classname) +{ + + using base_sink = ::gr::bokehgui::base_sink; + + + py::class_>(m, classname, D(base_sink), py::buffer_protocol()) + + + .def("clear_queue",&base_sink::clear_queue, + D(base_sink,clear_queue) + ) + + .def("get_size",&base_sink::get_size, + D(base_sink,get_size) + ) + + .def("get_vlen",&base_sink::get_vlen, + D(base_sink,get_vlen) + ) + .def("get_name",&base_sink::get_name, + D(base_sink,get_name) + ) + .def("get_nconnections",&base_sink::get_nconnections, + D(base_sink,get_nconnections) + ) + + .def("get_plot_data", [](base_sink &m){ + return py::array_t( + {m.get_buff_cols(), m.get_buff_size()}, // shape + m.get_plot_data() // the data pointer + ); + }); + ; +} + +void bind_base_sink(py::module& m) +{ + bind_base_sink_template(m, "base_sink_f"); + bind_base_sink_template(m, "base_sink_c"); + + // Handle the trigger enums + py::enum_(m, "trigger_mode") + .value("TRIG_MODE_FREE", gr::bokehgui::trigger_mode::TRIG_MODE_FREE) + .value("TRIG_MODE_AUTO", gr::bokehgui::trigger_mode::TRIG_MODE_AUTO) + .value("TRIG_MODE_NORM", gr::bokehgui::trigger_mode::TRIG_MODE_NORM) + .value("TRIG_MODE_TAG", gr::bokehgui::trigger_mode::TRIG_MODE_TAG) + .export_values(); + + py::enum_(m, "trigger_slope") + .value("TRIG_SLOPE_POS", gr::bokehgui::trigger_slope::TRIG_SLOPE_POS) + .value("TRIG_SLOPE_NEG", gr::bokehgui::trigger_slope::TRIG_SLOPE_NEG) + .export_values(); +} diff --git a/python/bindings/bind_oot_file.py b/python/bindings/bind_oot_file.py new file mode 100755 index 0000000..91719f7 --- /dev/null +++ b/python/bindings/bind_oot_file.py @@ -0,0 +1,57 @@ +import warnings +import argparse +import os +from gnuradio.bindtool import BindingGenerator +import pathlib +import sys + +parser = argparse.ArgumentParser(description='Bind a GR Out of Tree Block') +parser.add_argument('--module', type=str, + help='Name of gr module containing file to bind (e.g. fft digital analog)') + +parser.add_argument('--output_dir', default='/tmp', + help='Output directory of generated bindings') +parser.add_argument('--prefix', help='Prefix of Installed GNU Radio') +parser.add_argument('--src', help='Directory of gnuradio source tree', + default=os.path.dirname(os.path.abspath(__file__))+'/../../..') + +parser.add_argument( + '--filename', help="File to be parsed") + +parser.add_argument( + '--defines', help='Set additional defines for precompiler',default=(), nargs='*') +parser.add_argument( + '--include', help='Additional Include Dirs, separated', default=(), nargs='*') + +parser.add_argument( + '--status', help='Location of output file for general status (used during cmake)', default=None +) +parser.add_argument( + '--flag_automatic', default='0' +) +parser.add_argument( + '--flag_pygccxml', default='0' +) + +args = parser.parse_args() + +prefix = args.prefix +output_dir = args.output_dir +defines = tuple(','.join(args.defines).split(',')) +includes = ','.join(args.include) +name = args.module + +namespace = ['gr', name] +prefix_include_root = name + + +with warnings.catch_warnings(): + warnings.filterwarnings("ignore", category=DeprecationWarning) + + bg = BindingGenerator(prefix, namespace, + prefix_include_root, output_dir, define_symbols=defines, addl_includes=includes, + catch_exceptions=False, write_json_output=False, status_output=args.status, + flag_automatic=True if args.flag_automatic.lower() in [ + '1', 'true'] else False, + flag_pygccxml=True if args.flag_pygccxml.lower() in ['1', 'true'] else False) + bg.gen_file_binding(args.filename) diff --git a/python/bindings/docstrings/README.md b/python/bindings/docstrings/README.md new file mode 100755 index 0000000..295455a --- /dev/null +++ b/python/bindings/docstrings/README.md @@ -0,0 +1 @@ +This directory stores templates for docstrings that are scraped from the include header files for each block \ No newline at end of file diff --git a/python/bindings/docstrings/base_sink_pydoc_template.h b/python/bindings/docstrings/base_sink_pydoc_template.h new file mode 100644 index 0000000..a7087a9 --- /dev/null +++ b/python/bindings/docstrings/base_sink_pydoc_template.h @@ -0,0 +1,43 @@ +/* + * Copyright 2021 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ +#include "pydoc_macros.h" +#define D(...) DOC(gr,bokehgui, __VA_ARGS__ ) +/* + This file contains placeholders for docstrings for the Python bindings. + Do not edit! These were automatically extracted during the binding process + and will be overwritten during the build process + */ + + + + static const char *__doc_gr_bokehgui_base_sink = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_base_sink_base_sink_0 = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_base_sink_base_sink_1 = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_base_sink_clear_queue = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_base_sink_get_size = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_base_sink_get_vlen = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_base_sink_get_name = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_base_sink_get_nconnections = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_base_sink_get_plot_data = R"doc()doc"; diff --git a/python/bindings/docstrings/freq_sink_c_proc_pydoc_template.h b/python/bindings/docstrings/freq_sink_c_proc_pydoc_template.h new file mode 100755 index 0000000..9f9fc15 --- /dev/null +++ b/python/bindings/docstrings/freq_sink_c_proc_pydoc_template.h @@ -0,0 +1,57 @@ +/* + * Copyright 2021 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ +#include "pydoc_macros.h" +#define D(...) DOC(gr,bokehgui, __VA_ARGS__ ) +/* + This file contains placeholders for docstrings for the Python bindings. + Do not edit! These were automatically extracted during the binding process + and will be overwritten during the build process + */ + + + + static const char *__doc_gr_bokehgui_freq_sink_c_proc = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_freq_sink_c_proc_freq_sink_c_proc_0 = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_freq_sink_c_proc_freq_sink_c_proc_1 = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_freq_sink_c_proc_make = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_freq_sink_c_proc_reset = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_freq_sink_c_proc_get_center_freq = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_freq_sink_c_proc_get_bandwidth = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_freq_sink_c_proc_get_wintype = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_freq_sink_c_proc_set_fft_window = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_freq_sink_c_proc_buildwindow = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_freq_sink_c_proc_set_frequency_range = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_freq_sink_c_proc_handle_set_freq = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_freq_sink_c_proc_set_trigger_mode = R"doc()doc"; + + diff --git a/python/bindings/docstrings/freq_sink_f_proc_pydoc_template.h b/python/bindings/docstrings/freq_sink_f_proc_pydoc_template.h new file mode 100755 index 0000000..0046736 --- /dev/null +++ b/python/bindings/docstrings/freq_sink_f_proc_pydoc_template.h @@ -0,0 +1,57 @@ +/* + * Copyright 2021 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ +#include "pydoc_macros.h" +#define D(...) DOC(gr,bokehgui, __VA_ARGS__ ) +/* + This file contains placeholders for docstrings for the Python bindings. + Do not edit! These were automatically extracted during the binding process + and will be overwritten during the build process + */ + + + + static const char *__doc_gr_bokehgui_freq_sink_f_proc = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_freq_sink_f_proc_freq_sink_f_proc_0 = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_freq_sink_f_proc_freq_sink_f_proc_1 = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_freq_sink_f_proc_make = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_freq_sink_f_proc_reset = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_freq_sink_f_proc_get_center_freq = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_freq_sink_f_proc_get_bandwidth = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_freq_sink_f_proc_get_wintype = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_freq_sink_f_proc_set_fft_window = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_freq_sink_f_proc_buildwindow = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_freq_sink_f_proc_set_frequency_range = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_freq_sink_f_proc_handle_set_freq = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_freq_sink_f_proc_set_trigger_mode = R"doc()doc"; + + diff --git a/python/bindings/docstrings/time_sink_c_proc_pydoc_template.h b/python/bindings/docstrings/time_sink_c_proc_pydoc_template.h new file mode 100755 index 0000000..5849c6f --- /dev/null +++ b/python/bindings/docstrings/time_sink_c_proc_pydoc_template.h @@ -0,0 +1,48 @@ +/* + * Copyright 2021 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ +#include "pydoc_macros.h" +#define D(...) DOC(gr,bokehgui, __VA_ARGS__ ) +/* + This file contains placeholders for docstrings for the Python bindings. + Do not edit! These were automatically extracted during the binding process + and will be overwritten during the build process + */ + + + + static const char *__doc_gr_bokehgui_time_sink_c_proc = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_time_sink_c_proc_time_sink_c_proc_0 = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_time_sink_c_proc_time_sink_c_proc_1 = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_time_sink_c_proc_make = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_time_sink_c_proc_get_tags = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_time_sink_c_proc_set_size = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_time_sink_c_proc_set_samp_rate = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_time_sink_c_proc_get_samp_rate = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_time_sink_c_proc_reset = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_time_sink_c_proc_set_trigger_mode = R"doc()doc"; + + diff --git a/python/bindings/docstrings/time_sink_f_proc_pydoc_template.h b/python/bindings/docstrings/time_sink_f_proc_pydoc_template.h new file mode 100755 index 0000000..98aab8b --- /dev/null +++ b/python/bindings/docstrings/time_sink_f_proc_pydoc_template.h @@ -0,0 +1,48 @@ +/* + * Copyright 2021 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ +#include "pydoc_macros.h" +#define D(...) DOC(gr,bokehgui, __VA_ARGS__ ) +/* + This file contains placeholders for docstrings for the Python bindings. + Do not edit! These were automatically extracted during the binding process + and will be overwritten during the build process + */ + + + + static const char *__doc_gr_bokehgui_time_sink_f_proc = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_time_sink_f_proc_time_sink_f_proc_0 = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_time_sink_f_proc_time_sink_f_proc_1 = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_time_sink_f_proc_make = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_time_sink_f_proc_get_tags = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_time_sink_f_proc_set_size = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_time_sink_f_proc_set_samp_rate = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_time_sink_f_proc_get_samp_rate = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_time_sink_f_proc_reset = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_time_sink_f_proc_set_trigger_mode = R"doc()doc"; + + diff --git a/python/bindings/docstrings/vec_sink_c_proc_pydoc_template.h b/python/bindings/docstrings/vec_sink_c_proc_pydoc_template.h new file mode 100755 index 0000000..392784b --- /dev/null +++ b/python/bindings/docstrings/vec_sink_c_proc_pydoc_template.h @@ -0,0 +1,33 @@ +/* + * Copyright 2021 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ +#include "pydoc_macros.h" +#define D(...) DOC(gr,bokehgui, __VA_ARGS__ ) +/* + This file contains placeholders for docstrings for the Python bindings. + Do not edit! These were automatically extracted during the binding process + and will be overwritten during the build process + */ + + + + static const char *__doc_gr_bokehgui_vec_sink_c_proc = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_vec_sink_c_proc_vec_sink_c_proc_0 = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_vec_sink_c_proc_vec_sink_c_proc_1 = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_vec_sink_c_proc_make = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_vec_sink_c_proc_reset = R"doc()doc"; + + diff --git a/python/bindings/docstrings/vec_sink_f_proc_pydoc_template.h b/python/bindings/docstrings/vec_sink_f_proc_pydoc_template.h new file mode 100755 index 0000000..5696850 --- /dev/null +++ b/python/bindings/docstrings/vec_sink_f_proc_pydoc_template.h @@ -0,0 +1,33 @@ +/* + * Copyright 2021 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ +#include "pydoc_macros.h" +#define D(...) DOC(gr,bokehgui, __VA_ARGS__ ) +/* + This file contains placeholders for docstrings for the Python bindings. + Do not edit! These were automatically extracted during the binding process + and will be overwritten during the build process + */ + + + + static const char *__doc_gr_bokehgui_vec_sink_f_proc = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_vec_sink_f_proc_vec_sink_f_proc_0 = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_vec_sink_f_proc_vec_sink_f_proc_1 = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_vec_sink_f_proc_make = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_vec_sink_f_proc_reset = R"doc()doc"; + + diff --git a/python/bindings/docstrings/waterfall_sink_c_proc_pydoc_template.h b/python/bindings/docstrings/waterfall_sink_c_proc_pydoc_template.h new file mode 100755 index 0000000..c3002cd --- /dev/null +++ b/python/bindings/docstrings/waterfall_sink_c_proc_pydoc_template.h @@ -0,0 +1,63 @@ +/* + * Copyright 2021 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ +#include "pydoc_macros.h" +#define D(...) DOC(gr,bokehgui, __VA_ARGS__ ) +/* + This file contains placeholders for docstrings for the Python bindings. + Do not edit! These were automatically extracted during the binding process + and will be overwritten during the build process + */ + + + + static const char *__doc_gr_bokehgui_waterfall_sink_c_proc = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_waterfall_sink_c_proc_waterfall_sink_c_proc_0 = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_waterfall_sink_c_proc_waterfall_sink_c_proc_1 = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_waterfall_sink_c_proc_make = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_waterfall_sink_c_proc_reset = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_waterfall_sink_c_proc_set_size = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_waterfall_sink_c_proc_get_center_freq = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_waterfall_sink_c_proc_get_bandwidth = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_waterfall_sink_c_proc_get_time_per_fft = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_waterfall_sink_c_proc_buildwindow = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_waterfall_sink_c_proc_set_time_per_fft = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_waterfall_sink_c_proc_set_fft_window = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_waterfall_sink_c_proc_get_wintype = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_waterfall_sink_c_proc_set_frequency_range = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_waterfall_sink_c_proc_get_plot_data = R"doc()doc"; + + diff --git a/python/bindings/docstrings/waterfall_sink_f_proc_pydoc_template.h b/python/bindings/docstrings/waterfall_sink_f_proc_pydoc_template.h new file mode 100755 index 0000000..c857603 --- /dev/null +++ b/python/bindings/docstrings/waterfall_sink_f_proc_pydoc_template.h @@ -0,0 +1,63 @@ +/* + * Copyright 2021 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ +#include "pydoc_macros.h" +#define D(...) DOC(gr,bokehgui, __VA_ARGS__ ) +/* + This file contains placeholders for docstrings for the Python bindings. + Do not edit! These were automatically extracted during the binding process + and will be overwritten during the build process + */ + + + + static const char *__doc_gr_bokehgui_waterfall_sink_f_proc = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_waterfall_sink_f_proc_waterfall_sink_f_proc_0 = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_waterfall_sink_f_proc_waterfall_sink_f_proc_1 = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_waterfall_sink_f_proc_make = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_waterfall_sink_f_proc_reset = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_waterfall_sink_f_proc_set_size = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_waterfall_sink_f_proc_get_center_freq = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_waterfall_sink_f_proc_get_bandwidth = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_waterfall_sink_f_proc_get_time_per_fft = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_waterfall_sink_f_proc_buildwindow = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_waterfall_sink_f_proc_set_time_per_fft = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_waterfall_sink_f_proc_set_fft_window = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_waterfall_sink_f_proc_get_wintype = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_waterfall_sink_f_proc_set_frequency_range = R"doc()doc"; + + + static const char *__doc_gr_bokehgui_waterfall_sink_f_proc_get_plot_data = R"doc()doc"; + + diff --git a/python/bindings/freq_sink_c_proc_python.cc b/python/bindings/freq_sink_c_proc_python.cc new file mode 100755 index 0000000..0db7b06 --- /dev/null +++ b/python/bindings/freq_sink_c_proc_python.cc @@ -0,0 +1,127 @@ +/* + * Copyright 2021 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +/***********************************************************************************/ +/* This file is automatically generated using bindtool and can be manually edited */ +/* The following lines can be configured to regenerate this file during cmake */ +/* If manual edits are made, the following tags should be modified accordingly. */ +/* BINDTOOL_GEN_AUTOMATIC(0) */ +/* BINDTOOL_USE_PYGCCXML(0) */ +/* BINDTOOL_HEADER_FILE(freq_sink_c_proc.h) */ +/* BINDTOOL_HEADER_FILE_HASH(2c856903adac6c039877cacfc240e1e7) */ +/***********************************************************************************/ + +#include +#include +#include + +namespace py = pybind11; + +#include +// pydoc.h is automatically generated in the build directory +#include + +void bind_freq_sink_c_proc(py::module& m) +{ + + using freq_sink_c_proc = ::gr::bokehgui::freq_sink_c_proc; + + + py::class_ >, + std::shared_ptr>(m, "freq_sink_c_proc", D(freq_sink_c_proc)) + + .def(py::init(&freq_sink_c_proc::make), + py::arg("fftsize"), + py::arg("wintype"), + py::arg("fc"), + py::arg("bw"), + py::arg("name"), + py::arg("nconnections"), + D(freq_sink_c_proc,make) + ) + + + + + + + .def("reset",&freq_sink_c_proc::reset, + D(freq_sink_c_proc,reset) + ) + + + + .def("get_center_freq",&freq_sink_c_proc::get_center_freq, + D(freq_sink_c_proc,get_center_freq) + ) + + + + .def("get_bandwidth",&freq_sink_c_proc::get_bandwidth, + D(freq_sink_c_proc,get_bandwidth) + ) + + + + .def("get_wintype",&freq_sink_c_proc::get_wintype, + D(freq_sink_c_proc,get_wintype) + ) + + + + .def("set_fft_window",&freq_sink_c_proc::set_fft_window, + py::arg("newwintype"), + D(freq_sink_c_proc,set_fft_window) + ) + + + + .def("buildwindow",&freq_sink_c_proc::buildwindow, + D(freq_sink_c_proc,buildwindow) + ) + + + + .def("set_frequency_range",&freq_sink_c_proc::set_frequency_range, + py::arg("arg0"), + py::arg("arg1"), + D(freq_sink_c_proc,set_frequency_range) + ) + + + + .def("handle_set_freq",&freq_sink_c_proc::handle_set_freq, + py::arg("arg0"), + D(freq_sink_c_proc,handle_set_freq) + ) + + + + .def("set_trigger_mode",&freq_sink_c_proc::set_trigger_mode, + py::arg("mode"), + py::arg("level"), + py::arg("channel"), + py::arg("tag_key"), + D(freq_sink_c_proc,set_trigger_mode) + ) + + ; + + + + +} + + + + + + + + diff --git a/python/bindings/freq_sink_f_proc_python.cc b/python/bindings/freq_sink_f_proc_python.cc new file mode 100755 index 0000000..8257c65 --- /dev/null +++ b/python/bindings/freq_sink_f_proc_python.cc @@ -0,0 +1,127 @@ +/* + * Copyright 2021 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +/***********************************************************************************/ +/* This file is automatically generated using bindtool and can be manually edited */ +/* The following lines can be configured to regenerate this file during cmake */ +/* If manual edits are made, the following tags should be modified accordingly. */ +/* BINDTOOL_GEN_AUTOMATIC(0) */ +/* BINDTOOL_USE_PYGCCXML(0) */ +/* BINDTOOL_HEADER_FILE(freq_sink_f_proc.h) */ +/* BINDTOOL_HEADER_FILE_HASH(6040cc1d226766a0325c9d5e6debb3f3) */ +/***********************************************************************************/ + +#include +#include +#include + +namespace py = pybind11; + +#include +// pydoc.h is automatically generated in the build directory +#include + +void bind_freq_sink_f_proc(py::module& m) +{ + + using freq_sink_f_proc = ::gr::bokehgui::freq_sink_f_proc; + + + py::class_, + std::shared_ptr>(m, "freq_sink_f_proc", D(freq_sink_f_proc)) + + .def(py::init(&freq_sink_f_proc::make), + py::arg("fftsize"), + py::arg("wintype"), + py::arg("fc"), + py::arg("bw"), + py::arg("name"), + py::arg("nconnections"), + D(freq_sink_f_proc,make) + ) + + + + + + + .def("reset",&freq_sink_f_proc::reset, + D(freq_sink_f_proc,reset) + ) + + + + .def("get_center_freq",&freq_sink_f_proc::get_center_freq, + D(freq_sink_f_proc,get_center_freq) + ) + + + + .def("get_bandwidth",&freq_sink_f_proc::get_bandwidth, + D(freq_sink_f_proc,get_bandwidth) + ) + + + + .def("get_wintype",&freq_sink_f_proc::get_wintype, + D(freq_sink_f_proc,get_wintype) + ) + + + + .def("set_fft_window",&freq_sink_f_proc::set_fft_window, + py::arg("newwintype"), + D(freq_sink_f_proc,set_fft_window) + ) + + + + .def("buildwindow",&freq_sink_f_proc::buildwindow, + D(freq_sink_f_proc,buildwindow) + ) + + + + .def("set_frequency_range",&freq_sink_f_proc::set_frequency_range, + py::arg("arg0"), + py::arg("arg1"), + D(freq_sink_f_proc,set_frequency_range) + ) + + + + .def("handle_set_freq",&freq_sink_f_proc::handle_set_freq, + py::arg("arg0"), + D(freq_sink_f_proc,handle_set_freq) + ) + + + + .def("set_trigger_mode",&freq_sink_f_proc::set_trigger_mode, + py::arg("mode"), + py::arg("level"), + py::arg("channel"), + py::arg("tag_key"), + D(freq_sink_f_proc,set_trigger_mode) + ) + + ; + + + + +} + + + + + + + + diff --git a/python/bindings/header_utils.py b/python/bindings/header_utils.py new file mode 100755 index 0000000..165124e --- /dev/null +++ b/python/bindings/header_utils.py @@ -0,0 +1,78 @@ +# Utilities for reading values in header files + +from argparse import ArgumentParser +import re + + +class PybindHeaderParser: + def __init__(self, pathname): + with open(pathname,'r') as f: + self.file_txt = f.read() + + def get_flag_automatic(self): + # p = re.compile(r'BINDTOOL_GEN_AUTOMATIC\(([^\s])\)') + # m = p.search(self.file_txt) + m = re.search(r'BINDTOOL_GEN_AUTOMATIC\(([^\s])\)', self.file_txt) + if (m and m.group(1) == '1'): + return True + else: + return False + + def get_flag_pygccxml(self): + # p = re.compile(r'BINDTOOL_USE_PYGCCXML\(([^\s])\)') + # m = p.search(self.file_txt) + m = re.search(r'BINDTOOL_USE_PYGCCXML\(([^\s])\)', self.file_txt) + if (m and m.group(1) == '1'): + return True + else: + return False + + def get_header_filename(self): + # p = re.compile(r'BINDTOOL_HEADER_FILE\(([^\s]*)\)') + # m = p.search(self.file_txt) + m = re.search(r'BINDTOOL_HEADER_FILE\(([^\s]*)\)', self.file_txt) + if (m): + return m.group(1) + else: + return None + + def get_header_file_hash(self): + # p = re.compile(r'BINDTOOL_HEADER_FILE_HASH\(([^\s]*)\)') + # m = p.search(self.file_txt) + m = re.search(r'BINDTOOL_HEADER_FILE_HASH\(([^\s]*)\)', self.file_txt) + if (m): + return m.group(1) + else: + return None + + def get_flags(self): + return f'{self.get_flag_automatic()};{self.get_flag_pygccxml()};{self.get_header_filename()};{self.get_header_file_hash()};' + + + +def argParse(): + """Parses commandline args.""" + desc='Reads the parameters from the comment block in the pybind files' + parser = ArgumentParser(description=desc) + + parser.add_argument("function", help="Operation to perform on comment block of pybind file", choices=["flag_auto","flag_pygccxml","header_filename","header_file_hash","all"]) + parser.add_argument("pathname", help="Pathname of pybind c++ file to read, e.g. blockname_python.cc") + + return parser.parse_args() + +if __name__ == "__main__": + # Parse command line options and set up doxyxml. + args = argParse() + + pbhp = PybindHeaderParser(args.pathname) + + if args.function == "flag_auto": + print(pbhp.get_flag_automatic()) + elif args.function == "flag_pygccxml": + print(pbhp.get_flag_pygccxml()) + elif args.function == "header_filename": + print(pbhp.get_header_filename()) + elif args.function == "header_file_hash": + print(pbhp.get_header_file_hash()) + elif args.function == "all": + print(pbhp.get_flags()) \ No newline at end of file diff --git a/python/bindings/python_bindings.cc b/python/bindings/python_bindings.cc new file mode 100755 index 0000000..9341ffd --- /dev/null +++ b/python/bindings/python_bindings.cc @@ -0,0 +1,70 @@ +/* + * Copyright 2020 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include + +#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION +#include + +namespace py = pybind11; + +// Headers for binding functions +/**************************************/ +// The following comment block is used for +// gr_modtool to insert function prototypes +// Please do not delete +/**************************************/ +// BINDING_FUNCTION_PROTOTYPES( + void bind_time_sink_c_proc(py::module& m); + void bind_time_sink_f_proc(py::module& m); + void bind_freq_sink_f_proc(py::module& m); + void bind_vec_sink_c_proc(py::module& m); + void bind_vec_sink_f_proc(py::module& m); + void bind_freq_sink_c_proc(py::module& m); + void bind_waterfall_sink_f_proc(py::module& m); + void bind_waterfall_sink_c_proc(py::module& m); + void bind_base_sink(py::module& m); +// ) END BINDING_FUNCTION_PROTOTYPES + +// We need this hack because import_array() returns NULL +// for newer Python versions. +// This function is also necessary because it ensures access to the C API +// and removes a warning. +void* init_numpy() +{ + import_array(); + return NULL; +} + +PYBIND11_MODULE(bokehgui_python, m) +{ + // Initialize the numpy C API + // (otherwise we will see segmentation faults) + init_numpy(); + + // Allow access to base block methods + py::module::import("gnuradio.gr"); + + bind_base_sink(m); + /**************************************/ + // The following comment block is used for + // gr_modtool to insert binding function calls + // Please do not delete + /**************************************/ + // BINDING_FUNCTION_CALLS( + bind_time_sink_c_proc(m); + bind_time_sink_f_proc(m); + bind_freq_sink_f_proc(m); + bind_vec_sink_c_proc(m); + bind_vec_sink_f_proc(m); + bind_freq_sink_c_proc(m); + bind_waterfall_sink_f_proc(m); + bind_waterfall_sink_c_proc(m); + // ) END BINDING_FUNCTION_CALLS +} diff --git a/python/bindings/time_sink_c_proc_python.cc b/python/bindings/time_sink_c_proc_python.cc new file mode 100755 index 0000000..aeb7df6 --- /dev/null +++ b/python/bindings/time_sink_c_proc_python.cc @@ -0,0 +1,107 @@ +/* + * Copyright 2021 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +/***********************************************************************************/ +/* This file is automatically generated using bindtool and can be manually edited */ +/* The following lines can be configured to regenerate this file during cmake */ +/* If manual edits are made, the following tags should be modified accordingly. */ +/* BINDTOOL_GEN_AUTOMATIC(0) */ +/* BINDTOOL_USE_PYGCCXML(0) */ +/* BINDTOOL_HEADER_FILE(time_sink_c_proc.h) */ +/* BINDTOOL_HEADER_FILE_HASH(3ee60702342a877a505b24ea096beb3b) */ +/***********************************************************************************/ + +#include +#include +#include + +namespace py = pybind11; + +#include +// pydoc.h is automatically generated in the build directory +#include + +void bind_time_sink_c_proc(py::module& m) +{ + + using time_sink_c_proc = ::gr::bokehgui::time_sink_c_proc; + + + py::class_ >, + std::shared_ptr>(m, "time_sink_c_proc", D(time_sink_c_proc)) + + .def(py::init(&time_sink_c_proc::make), + py::arg("size"), + py::arg("samp_rate"), + py::arg("name"), + py::arg("nconnections"), + D(time_sink_c_proc,make) + ) + + + + + + + .def("get_tags",&time_sink_c_proc::get_tags, + D(time_sink_c_proc,get_tags) + ) + + + + .def("set_size",&time_sink_c_proc::set_size, + py::arg("newsize"), + D(time_sink_c_proc,set_size) + ) + + + + .def("set_samp_rate",&time_sink_c_proc::set_samp_rate, + py::arg("samp_rate"), + D(time_sink_c_proc,set_samp_rate) + ) + + + + .def("get_samp_rate",&time_sink_c_proc::get_samp_rate, + D(time_sink_c_proc,get_samp_rate) + ) + + + + .def("reset",&time_sink_c_proc::reset, + D(time_sink_c_proc,reset) + ) + + + + .def("set_trigger_mode",&time_sink_c_proc::set_trigger_mode, + py::arg("mode"), + py::arg("slope"), + py::arg("level"), + py::arg("delay"), + py::arg("channel"), + py::arg("tag_key"), + D(time_sink_c_proc,set_trigger_mode) + ) + + ; + + + + +} + + + + + + + + diff --git a/python/bindings/time_sink_f_proc_python.cc b/python/bindings/time_sink_f_proc_python.cc new file mode 100755 index 0000000..2778f7c --- /dev/null +++ b/python/bindings/time_sink_f_proc_python.cc @@ -0,0 +1,107 @@ +/* + * Copyright 2021 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +/***********************************************************************************/ +/* This file is automatically generated using bindtool and can be manually edited */ +/* The following lines can be configured to regenerate this file during cmake */ +/* If manual edits are made, the following tags should be modified accordingly. */ +/* BINDTOOL_GEN_AUTOMATIC(0) */ +/* BINDTOOL_USE_PYGCCXML(0) */ +/* BINDTOOL_HEADER_FILE(time_sink_f_proc.h) */ +/* BINDTOOL_HEADER_FILE_HASH(fbfa2c5631d2039cf90076ac144e3ae7) */ +/***********************************************************************************/ + +#include +#include +#include + +namespace py = pybind11; + +#include +// pydoc.h is automatically generated in the build directory +#include + +void bind_time_sink_f_proc(py::module& m) +{ + + using time_sink_f_proc = ::gr::bokehgui::time_sink_f_proc; + + + py::class_, + std::shared_ptr>(m, "time_sink_f_proc", D(time_sink_f_proc)) + + .def(py::init(&time_sink_f_proc::make), + py::arg("size"), + py::arg("samp_rate"), + py::arg("name"), + py::arg("nconnections"), + D(time_sink_f_proc,make) + ) + + + + + + + .def("get_tags",&time_sink_f_proc::get_tags, + D(time_sink_f_proc,get_tags) + ) + + + + .def("set_size",&time_sink_f_proc::set_size, + py::arg("newsize"), + D(time_sink_f_proc,set_size) + ) + + + + .def("set_samp_rate",&time_sink_f_proc::set_samp_rate, + py::arg("samp_rate"), + D(time_sink_f_proc,set_samp_rate) + ) + + + + .def("get_samp_rate",&time_sink_f_proc::get_samp_rate, + D(time_sink_f_proc,get_samp_rate) + ) + + + + .def("reset",&time_sink_f_proc::reset, + D(time_sink_f_proc,reset) + ) + + + + .def("set_trigger_mode",&time_sink_f_proc::set_trigger_mode, + py::arg("mode"), + py::arg("slope"), + py::arg("level"), + py::arg("delay"), + py::arg("channel"), + py::arg("tag_key"), + D(time_sink_f_proc,set_trigger_mode) + ) + + ; + + + + +} + + + + + + + + diff --git a/python/bindings/vec_sink_c_proc_python.cc b/python/bindings/vec_sink_c_proc_python.cc new file mode 100755 index 0000000..2969deb --- /dev/null +++ b/python/bindings/vec_sink_c_proc_python.cc @@ -0,0 +1,68 @@ +/* + * Copyright 2021 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +/***********************************************************************************/ +/* This file is automatically generated using bindtool and can be manually edited */ +/* The following lines can be configured to regenerate this file during cmake */ +/* If manual edits are made, the following tags should be modified accordingly. */ +/* BINDTOOL_GEN_AUTOMATIC(0) */ +/* BINDTOOL_USE_PYGCCXML(0) */ +/* BINDTOOL_HEADER_FILE(vec_sink_c_proc.h) */ +/* BINDTOOL_HEADER_FILE_HASH(0230b3ea4add6cbc7923120461cd0ef8) */ +/***********************************************************************************/ + +#include +#include +#include + +namespace py = pybind11; + +#include +// pydoc.h is automatically generated in the build directory +#include + +void bind_vec_sink_c_proc(py::module& m) +{ + + using vec_sink_c_proc = ::gr::bokehgui::vec_sink_c_proc; + + + py::class_ >, + std::shared_ptr>(m, "vec_sink_c_proc", D(vec_sink_c_proc)) + + .def(py::init(&vec_sink_c_proc::make), + py::arg("vlen"), + py::arg("name"), + py::arg("nconnections"), + D(vec_sink_c_proc,make) + ) + + + + + + + .def("reset",&vec_sink_c_proc::reset, + D(vec_sink_c_proc,reset) + ) + + ; + + + + +} + + + + + + + + diff --git a/python/bindings/vec_sink_f_proc_python.cc b/python/bindings/vec_sink_f_proc_python.cc new file mode 100755 index 0000000..163e21d --- /dev/null +++ b/python/bindings/vec_sink_f_proc_python.cc @@ -0,0 +1,68 @@ +/* + * Copyright 2021 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +/***********************************************************************************/ +/* This file is automatically generated using bindtool and can be manually edited */ +/* The following lines can be configured to regenerate this file during cmake */ +/* If manual edits are made, the following tags should be modified accordingly. */ +/* BINDTOOL_GEN_AUTOMATIC(0) */ +/* BINDTOOL_USE_PYGCCXML(0) */ +/* BINDTOOL_HEADER_FILE(vec_sink_f_proc.h) */ +/* BINDTOOL_HEADER_FILE_HASH(ac2443596de577249e1f80ae306aca91) */ +/***********************************************************************************/ + +#include +#include +#include + +namespace py = pybind11; + +#include +// pydoc.h is automatically generated in the build directory +#include + +void bind_vec_sink_f_proc(py::module& m) +{ + + using vec_sink_f_proc = ::gr::bokehgui::vec_sink_f_proc; + + + py::class_, + std::shared_ptr>(m, "vec_sink_f_proc", D(vec_sink_f_proc)) + + .def(py::init(&vec_sink_f_proc::make), + py::arg("vlen"), + py::arg("name"), + py::arg("nconnections"), + D(vec_sink_f_proc,make) + ) + + + + + + + .def("reset",&vec_sink_f_proc::reset, + D(vec_sink_f_proc,reset) + ) + + ; + + + + +} + + + + + + + + diff --git a/python/bindings/waterfall_sink_c_proc_python.cc b/python/bindings/waterfall_sink_c_proc_python.cc new file mode 100755 index 0000000..5056769 --- /dev/null +++ b/python/bindings/waterfall_sink_c_proc_python.cc @@ -0,0 +1,130 @@ +/* + * Copyright 2021 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + + +#include +#include +#include +#include +namespace py = pybind11; + +#include +// pydoc.h is automatically generated in the build directory +#include + +void bind_waterfall_sink_c_proc(py::module& m) +{ + + using waterfall_sink_c_proc = ::gr::bokehgui::waterfall_sink_c_proc; + + + py::class_>, gr::sync_block, gr::block, gr::basic_block, + std::shared_ptr>(m, "waterfall_sink_c_proc", D(waterfall_sink_c_proc)) + + .def(py::init(&waterfall_sink_c_proc::make), + py::arg("size"), + py::arg("wintype"), + py::arg("fc"), + py::arg("bw"), + py::arg("name"), + D(waterfall_sink_c_proc,make) + ) + + + + + + + .def("reset",&waterfall_sink_c_proc::reset, + D(waterfall_sink_c_proc,reset) + ) + + + + .def("set_size",&waterfall_sink_c_proc::set_size, + py::arg("arg0"), + D(waterfall_sink_c_proc,set_size) + ) + + + + .def("get_center_freq",&waterfall_sink_c_proc::get_center_freq, + D(waterfall_sink_c_proc,get_center_freq) + ) + + + + .def("get_bandwidth",&waterfall_sink_c_proc::get_bandwidth, + D(waterfall_sink_c_proc,get_bandwidth) + ) + + + + .def("get_time_per_fft",&waterfall_sink_c_proc::get_time_per_fft, + D(waterfall_sink_c_proc,get_time_per_fft) + ) + + + + .def("buildwindow",&waterfall_sink_c_proc::buildwindow, + D(waterfall_sink_c_proc,buildwindow) + ) + + + + .def("set_time_per_fft",&waterfall_sink_c_proc::set_time_per_fft, + py::arg("arg0"), + D(waterfall_sink_c_proc,set_time_per_fft) + ) + + + + .def("set_fft_window",&waterfall_sink_c_proc::set_fft_window, + py::arg("win"), + D(waterfall_sink_c_proc,set_fft_window) + ) + + + + .def("get_wintype",&waterfall_sink_c_proc::get_wintype, + D(waterfall_sink_c_proc,get_wintype) + ) + + + + .def("set_frequency_range",&waterfall_sink_c_proc::set_frequency_range, + py::arg("arg0"), + py::arg("arg1"), + D(waterfall_sink_c_proc,set_frequency_range) + ) + + .def("get_plot_data", [](waterfall_sink_c_proc &m){ + return py::array_t( + {m.get_buff_cols(), m.get_buff_size()}, // shape + m.get_plot_data() // the data pointer + ); + }); + // .def_buffer([] (waterfall_sink_c_proc &m) -> py::buffer_info { + // return py::buffer_info( + // m.get_plot_data(), /* Pointer to buffer */ + // sizeof(float), /* Size of one scalar */ + // py::format_descriptor::format(), /* Python struct-style format descriptor */ + // 2, /* Number of dimensions */ + // { m.get_nconnections(), 2*m.get_buff_size() }, /* Buffer dimensions */ + // { sizeof(float) * m.get_nconnections(), /* Strides (in bytes) for each index */ + // sizeof(float) } + // ); + // }); + + ; + + + + +} diff --git a/python/bindings/waterfall_sink_f_proc_python.cc b/python/bindings/waterfall_sink_f_proc_python.cc new file mode 100755 index 0000000..449e533 --- /dev/null +++ b/python/bindings/waterfall_sink_f_proc_python.cc @@ -0,0 +1,131 @@ +/* + * Copyright 2021 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + + +// #include +#include +#include +#include +namespace py = pybind11; + +#include +// pydoc.h is automatically generated in the build directory +#include + +void bind_waterfall_sink_f_proc(py::module& m) +{ + + using waterfall_sink_f_proc = ::gr::bokehgui::waterfall_sink_f_proc; + + + py::class_, gr::sync_block, gr::block, gr::basic_block, + std::shared_ptr>(m, "waterfall_sink_f_proc", D(waterfall_sink_f_proc)) + + .def(py::init(&waterfall_sink_f_proc::make), + py::arg("size"), + py::arg("wintype"), + py::arg("fc"), + py::arg("bw"), + py::arg("name"), + D(waterfall_sink_f_proc,make) + ) + + + + + + + .def("reset",&waterfall_sink_f_proc::reset, + D(waterfall_sink_f_proc,reset) + ) + + + + .def("set_size",&waterfall_sink_f_proc::set_size, + py::arg("arg0"), + D(waterfall_sink_f_proc,set_size) + ) + + + + .def("get_center_freq",&waterfall_sink_f_proc::get_center_freq, + D(waterfall_sink_f_proc,get_center_freq) + ) + + + + .def("get_bandwidth",&waterfall_sink_f_proc::get_bandwidth, + D(waterfall_sink_f_proc,get_bandwidth) + ) + + + + .def("get_time_per_fft",&waterfall_sink_f_proc::get_time_per_fft, + D(waterfall_sink_f_proc,get_time_per_fft) + ) + + + + .def("buildwindow",&waterfall_sink_f_proc::buildwindow, + D(waterfall_sink_f_proc,buildwindow) + ) + + + + .def("set_time_per_fft",&waterfall_sink_f_proc::set_time_per_fft, + py::arg("arg0"), + D(waterfall_sink_f_proc,set_time_per_fft) + ) + + + + .def("set_fft_window",&waterfall_sink_f_proc::set_fft_window, + py::arg("win"), + D(waterfall_sink_f_proc,set_fft_window) + ) + + + + .def("get_wintype",&waterfall_sink_f_proc::get_wintype, + D(waterfall_sink_f_proc,get_wintype) + ) + + + + .def("set_frequency_range",&waterfall_sink_f_proc::set_frequency_range, + py::arg("arg0"), + py::arg("arg1"), + D(waterfall_sink_f_proc,set_frequency_range) + ) + + + .def("get_plot_data", [](waterfall_sink_f_proc &m){ + return py::array_t( + {m.get_buff_cols(), m.get_buff_size()}, // shape + m.get_plot_data() // the data pointer + ); + }); + // .def_buffer([] (waterfall_sink_f_proc &m) -> py::buffer_info { + // return py::buffer_info( + // m.get_plot_data(), /* Pointer to buffer */ + // sizeof(float), /* Size of one scalar */ + // py::format_descriptor::format(), /* Python struct-style format descriptor */ + // 2, /* Number of dimensions */ + // { m.get_nconnections(), 2*m.get_buff_size() }, /* Buffer dimensions */ + // { sizeof(float) * m.get_nconnections(), /* Strides (in bytes) for each index */ + // sizeof(float) } + // ); + // }); + + ; + + + + +} diff --git a/python/plots/waterfall.py b/python/plots/waterfall.py index cf7eaea..b1ad442 100644 --- a/python/plots/waterfall.py +++ b/python/plots/waterfall.py @@ -7,7 +7,7 @@ class WaterfallRenderer(Renderer): __implementation__ = join(dirname(__file__), "waterfall.ts") - latest = Seq(Float, default=[]) + latest = Seq(Float) palette = Seq(Color) diff --git a/python/plots/waterfall.ts b/python/plots/waterfall.ts index 48f45fc..8d9fb72 100644 --- a/python/plots/waterfall.ts +++ b/python/plots/waterfall.ts @@ -8,8 +8,8 @@ import * as p from "core/properties" export class WaterfallRendererView extends RendererView { model: WaterfallRenderer - private canvases: HTMLCanvasElement[] - private images: Uint32Array[] + private canvas: HTMLCanvasElement[] + private image: Uint32Array[] private y: number[] private row: number private tile: number @@ -29,11 +29,11 @@ export class WaterfallRendererView extends RendererView { this.tile_height = this.model.time_length / 10 const [w, h] = [this.model.fft_length, this.tile_height] - this.canvases = [] - this.images = [] + this.canvas = [] + this.image = [] for (let i = 0; i < N; i++) { - this.canvases.push(canvas({width: w, height: h})) - this.images.push(new Uint32Array(w*h)) + this.canvas.push(canvas({width: w, height: h})) + this.image.push(new Uint32Array(w*h)) } this.y = new Array(N) @@ -69,7 +69,7 @@ export class WaterfallRendererView extends RendererView { const sh = Math.ceil(this.yscale.compute(this.tile_height) - this.yscale.compute(0)) for (let i = 0; i < sy.length; i++) - ctx.drawImage(this.canvases[i], sx, sy[i], sw, sh) + ctx.drawImage(this.canvas[i], sx, sy[i], sw, sh) ctx.setImageSmoothingEnabled(smoothing) @@ -95,12 +95,12 @@ export class WaterfallRendererView extends RendererView { // apply the lastest column to the current tile image const buf32 = new Uint32Array(this.cmap.rgba_mapper.v_compute(this.model.latest).buffer) for (let i = 0; i < this.model.fft_length; i++) - this.images[this.tile][i+this.model.fft_length*this.row] = buf32[i] + this.image[this.tile][i+this.model.fft_length*this.row] = buf32[i] // update the tiles canvas with the image data - const cctx = this.canvases[this.tile].getContext('2d')! + const cctx = this.canvas[this.tile].getContext('2d')! const image = cctx.getImageData(0, 0, this.model.fft_length, this.tile_height) - image.data.set(new Uint8Array(this.images[this.tile].buffer)) + image.data.set(new Uint8Array(this.image[this.tile].buffer)) cctx.putImageData(image, 0, 0) } } @@ -131,18 +131,17 @@ export class WaterfallRenderer extends Renderer { static initClass(): void { this.prototype.default_view = WaterfallRendererView - this.define(({Int, Number, Color, Array, Any}) =>({ - latest: [ Array(Number), [] ], - palette: [ Array(Color) ], - time_length: [ Int ], - fft_length: [ Int ], - min_value: [ Any ], - max_value: [ Any ], - update: [ Any ], - })) - + this.define({ + latest: [ p.Any ], + palette: [ p.Any ], + time_length: [ p.Int ], + fft_length: [ p.Int ], + min_value: [ p.Any ], + max_value: [ p.Any ], + update: [ p.Any ], + }) - this.override({ + this.override({ level: "glyph", }) } From 22e053a0038252970d5f7a77b951ade842fa3034 Mon Sep 17 00:00:00 2001 From: Notou Date: Wed, 24 Nov 2021 19:17:29 +0100 Subject: [PATCH 4/8] Fixes waterfall display shift issue --- python/plots/waterfall.ts | 2 +- python/waterfall_sink_f.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/python/plots/waterfall.ts b/python/plots/waterfall.ts index 8d9fb72..7fd309b 100644 --- a/python/plots/waterfall.ts +++ b/python/plots/waterfall.ts @@ -89,7 +89,7 @@ export class WaterfallRendererView extends RendererView { this.tile -= 1 if (this.tile < 0) this.tile = this.y.length - 1 - this.y[this.tile] = this.model.time_length + this.tile_height + this.y[this.tile] = this.model.time_length //- this.tile_height } // apply the lastest column to the current tile image diff --git a/python/waterfall_sink_f.py b/python/waterfall_sink_f.py index 52bc005..27c577b 100644 --- a/python/waterfall_sink_f.py +++ b/python/waterfall_sink_f.py @@ -60,7 +60,7 @@ def initialize(self, legend_list = utils.default_labels_f, self.nrows = number_of_samples self.time_per_sample = time_per_sample - self.plot = figure(tools = ['save', 'reset'], + self.plot = figure(tools = utils.default_tools(), y_range = [0, self.nrows], x_range = [self.frequency_range[0], self.frequency_range[-1]], From 509f272a39bcac1a4084581beb48450a2621d376 Mon Sep 17 00:00:00 2001 From: Notou Date: Fri, 26 Nov 2021 16:55:26 +0100 Subject: [PATCH 5/8] Fix vector sink MaxHold issue --- grc/bokehgui_vec_sink_x.block.yml | 10 +++++++++- python/vec_sink_f.py | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/grc/bokehgui_vec_sink_x.block.yml b/grc/bokehgui_vec_sink_x.block.yml index d0ed1e2..99bc48d 100644 --- a/grc/bokehgui_vec_sink_x.block.yml +++ b/grc/bokehgui_vec_sink_x.block.yml @@ -43,6 +43,13 @@ parameters: options: ['1.0', '0.2', '0.1', '0.05'] option_labels: [None, Low, Medium, High] hide: part +- id: maxhold + label: Max Hold + dtype: enum + default: 'False' + options: ['True', 'False'] + option_labels: ['Yes', 'No'] + hide: part - id: ymin label: Y min dtype: real @@ -566,7 +573,7 @@ templates: self.${id}_plot.disable_legend(not ${legend}) self.${id}_plot.set_layout(*(${placement})) % if maxhold == 'True': - self.${id}_plot.enable_max_hold() + self.${id}_plot.enable_max_hold(${maxhold}) % endif colors = [${color1}, ${color2}, ${color3}, ${color4}, ${color5}, ${color6}, ${color7}, ${color8}, ${color9}, ${color10}] @@ -603,6 +610,7 @@ templates: # - set_title(${which}, ${title}) # - set_color(${which}, ${color}) - self.${id}_plot.set_y_axis([${ymin}, ${ymax}]) + - self.${id}_plot.enable_max_hold(${maxhold}) documentation: "" diff --git a/python/vec_sink_f.py b/python/vec_sink_f.py index be758d2..bcd634b 100644 --- a/python/vec_sink_f.py +++ b/python/vec_sink_f.py @@ -110,7 +110,7 @@ def update(self): def set_x_values(self, values): if len(values) != self.size: - print("Error: x values has not the size of the input vector") + print(f"Error: x values has not the size ({len(values)}) of the input vector ({self.size})") return self.x_values = values # def set_x_values(self, start, step): From 9b9ee3ba01df7da47de5aef5c951508516604ea4 Mon Sep 17 00:00:00 2001 From: Notou Date: Fri, 26 Nov 2021 16:56:08 +0100 Subject: [PATCH 6/8] Test graph tests more sinks and features --- examples/test_bokehgui.grc | 292 ++++++++++++++++++++++++++----------- 1 file changed, 206 insertions(+), 86 deletions(-) diff --git a/examples/test_bokehgui.grc b/examples/test_bokehgui.grc index 36b7c0d..9be3f29 100644 --- a/examples/test_bokehgui.grc +++ b/examples/test_bokehgui.grc @@ -1,6 +1,7 @@ options: parameters: author: Kartik Patel + catch_exceptions: 'True' category: '[GRC Hier Blocks]' cmake_opt: '' comment: '' @@ -22,12 +23,11 @@ options: sizing_mode: stretch_both thread_safe_setters: '' title: Test GRC for Bokeh GUI - window_size: (1000,1000) states: bus_sink: false bus_source: false bus_structure: null - coordinate: [536, 364.0] + coordinate: [0, 4.0] rotation: 0 state: enabled @@ -43,7 +43,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [248, 340.0] + coordinate: [808, 4.0] rotation: 0 state: enabled - name: frequency @@ -57,25 +57,9 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [728, 324.0] + coordinate: [392, 4.0] rotation: 0 state: enabled -- name: funct_probe - id: variable_function_probe - parameters: - block_id: SNA - comment: '' - function_args: signal_amp/noise_amp - function_name: set_value - poll_rate: '1' - value: str(0) - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [728, 32] - rotation: 0 - state: disabled - name: noise_amp id: variable_bokehgui_slider parameters: @@ -91,7 +75,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [728, 172.0] + coordinate: [672, 4.0] rotation: 0 state: enabled - name: samp_rate @@ -103,7 +87,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [424, 356.0] + coordinate: [184, 4.0] rotation: 0 state: enabled - name: signal_amp @@ -121,9 +105,21 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [904, 172.0] + coordinate: [528, 4.0] rotation: 0 state: enabled +- name: up_freq + id: variable + parameters: + comment: "Update frequency \nof the Bokeh plots" + value: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [280, 4.0] + rotation: 0 + state: true - name: analog_noise_source_x_0 id: analog_noise_source_x parameters: @@ -140,7 +136,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [16, 132.0] + coordinate: [56, 316.0] rotation: 0 state: enabled - name: analog_noise_source_x_1 @@ -159,7 +155,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [16, 332.0] + coordinate: [56, 604.0] rotation: 0 state: enabled - name: analog_sig_source_x_0 @@ -181,7 +177,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [16, 8] + coordinate: [56, 196.0] rotation: 0 state: enabled - name: analog_sig_source_x_1 @@ -203,7 +199,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [16, 208] + coordinate: [56, 476.0] rotation: 0 state: enabled - name: blocks_add_xx_0 @@ -221,7 +217,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [248, 48.0] + coordinate: [288, 232.0] rotation: 0 state: enabled - name: blocks_add_xx_1 @@ -239,7 +235,25 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [248, 248.0] + coordinate: [288, 520.0] + rotation: 0 + state: enabled +- name: blocks_stream_to_vector_0 + id: blocks_stream_to_vector + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + num_items: '32' + type: complex + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [808, 168.0] rotation: 0 state: enabled - name: blocks_throttle_0 @@ -258,7 +272,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [344, 60.0] + coordinate: [384, 244.0] rotation: 0 state: enabled - name: blocks_throttle_1 @@ -277,7 +291,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [344, 260.0] + coordinate: [384, 532.0] rotation: 0 state: enabled - name: bokehgui_frequency_sink_x_0 @@ -297,7 +311,7 @@ blocks: alpha9: '1.0' average: '1.0' axislabels: 'True' - bw: samp_rate/2 + bw: samp_rate color1: '"blue"' color10: '"dark blue"' color2: '"red"' @@ -339,7 +353,7 @@ blocks: minoutbuf: '0' name: Complex Frequency Sink nconnections: '1' - placement: (1,0,2,1) + placement: (2,0,1,1) style1: '"solid"' style10: '"solid"' style2: '"solid"' @@ -355,7 +369,7 @@ blocks: tr_mode: bokehgui.TRIG_MODE_FREE tr_tag: '""' type: complex - update_time: '100' + update_time: int(1000*(1/up_freq)) width1: '1' width10: '1' width2: '1' @@ -366,7 +380,7 @@ blocks: width7: '1' width8: '1' width9: '1' - wintype: firdes.WIN_RECTANGULAR + wintype: window.WIN_BLACKMAN_hARRIS xlabel: Frequency xunit: '""' ylabel: Relative Gain @@ -377,9 +391,9 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [536, -4.0] + coordinate: [576, 156.0] rotation: 0 - state: disabled + state: enabled - name: bokehgui_frequency_sink_x_1 id: bokehgui_frequency_sink_x parameters: @@ -397,7 +411,7 @@ blocks: alpha9: '1.0' average: '1.0' axislabels: 'True' - bw: samp_rate/2 + bw: samp_rate color1: '"blue"' color10: '"dark blue"' color2: '"red"' @@ -439,7 +453,7 @@ blocks: minoutbuf: '0' name: Float Frequency Sink nconnections: '1' - placement: (3,0,2,1) + placement: (4,0,1,1) style1: '"solid"' style10: '"solid"' style2: '"solid"' @@ -455,7 +469,7 @@ blocks: tr_mode: bokehgui.TRIG_MODE_FREE tr_tag: '""' type: float - update_time: '100' + update_time: int(1000*(1/up_freq)) width1: '1' width10: '1' width2: '1' @@ -466,7 +480,7 @@ blocks: width7: '1' width8: '1' width9: '1' - wintype: firdes.WIN_RECTANGULAR + wintype: window.WIN_BLACKMAN_hARRIS xlabel: Frequency xunit: '""' ylabel: Relative Gain @@ -477,9 +491,106 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [536, 188.0] + coordinate: [576, 460.0] rotation: 0 - state: disabled + state: enabled +- name: bokehgui_time_const_x_0 + id: bokehgui_time_const_x + parameters: + affinity: '' + alias: '' + alpha1: '1.0' + alpha10: '1.0' + alpha2: '1.0' + alpha3: '1.0' + alpha4: '1.0' + alpha5: '1.0' + alpha6: '1.0' + alpha7: '1.0' + alpha8: '1.0' + alpha9: '1.0' + axislabels: 'True' + color1: '"blue"' + color10: '"blue"' + color2: '"red"' + color3: '"green"' + color4: '"black"' + color5: '"cyan"' + color6: '"magenta"' + color7: '"yellow"' + color8: '"blue"' + color9: '"blue"' + comment: '' + entags: 'True' + grid: 'False' + label1: '' + label10: '' + label2: '' + label3: '' + label4: '' + label5: '' + label6: '' + label7: '' + label8: '' + label9: '' + legend: 'True' + marker1: '''o''' + marker10: '''o''' + marker2: '''o''' + marker3: '''o''' + marker4: '''o''' + marker5: '''o''' + marker6: '''o''' + marker7: '''o''' + marker8: '''o''' + marker9: '''o''' + name: '""' + nconnections: '1' + placement: (2,1,2,2) + size: '1024' + srate: samp_rate + style10: '' + style2: '' + style3: '' + style4: '' + style5: '' + style6: '' + style7: '' + style8: '' + style9: '' + tr_chan: '0' + tr_delay: '0' + tr_level: '0.0' + tr_mode: bokehgui.TRIG_MODE_FREE + tr_slope: bokehgui.TRIG_SLOPE_POS + tr_tag: '""' + type: complex + update_time: int(1000*(1/up_freq)) + width1: '1' + width10: '1' + width2: '1' + width3: '1' + width4: '1' + width5: '1' + width6: '1' + width7: '1' + width8: '1' + width9: '1' + xlabel: I Channel + xmax: '100' + xmin: '-100' + xunit: '""' + ylabel: Q Channel + ymax: '100' + ymin: '-100' + yunit: '""' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [808, 236.0] + rotation: 0 + state: enabled - name: bokehgui_time_sink_x_0 id: bokehgui_time_sink_x parameters: @@ -532,7 +643,7 @@ blocks: marker9: None name: Complex Time Sink nconnections: '1' - placement: (0,1,3,2) + placement: (0,1,2,2) size: '1000' srate: samp_rate style1: '"solid"' @@ -552,7 +663,7 @@ blocks: tr_slope: bokehgui.TRIG_SLOPE_POS tr_tag: '""' type: complex - update_time: '100' + update_time: int(1000*(1/up_freq)) width1: '1' width10: '1' width2: '1' @@ -575,7 +686,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [536, 108.0] + coordinate: [576, 340.0] rotation: 0 state: enabled - name: bokehgui_time_sink_x_1 @@ -630,7 +741,7 @@ blocks: marker9: None name: Float Time Sink nconnections: '1' - placement: (3,1,2,2) + placement: (4,1,2,2) size: '1000' srate: samp_rate style1: '"solid"' @@ -650,7 +761,7 @@ blocks: tr_slope: bokehgui.TRIG_SLOPE_POS tr_tag: '""' type: float - update_time: '100' + update_time: int(1000*(1/up_freq)) width1: '1' width10: '1' width2: '1' @@ -673,7 +784,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [536, 284.0] + coordinate: [576, 628.0] rotation: 0 state: enabled - name: bokehgui_vector_sink_x_0 @@ -729,9 +840,9 @@ blocks: maxhold: 'True' maxoutbuf: '0' minoutbuf: '0' - name: '""' + name: '"Float vector"' nconnections: '1' - placement: (0,7,2,2) + placement: (2,3,2,2) style1: '"solid"' style10: '"solid"' style2: '"solid"' @@ -742,9 +853,9 @@ blocks: style7: '"solid"' style8: '"solid"' style9: '"solid"' - type: complex - update_time: '100' - vec_len: '64' + type: float + update_time: int(1000*(1/up_freq)) + vec_len: '32' width1: '1' width10: '1' width2: '1' @@ -755,7 +866,7 @@ blocks: width7: '1' width8: '1' width9: '1' - x_values: list(range(64)) + x_values: '[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31.0]' xlabel: Frequency xunit: '""' ylabel: Relative Gain @@ -766,10 +877,10 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [1379, 363] + coordinate: [1040, 340.0] rotation: 0 - state: true -- name: bokehgui_vector_sink_x_0_0 + state: enabled +- name: bokehgui_vector_sink_x_1 id: bokehgui_vector_sink_x parameters: affinity: '' @@ -797,7 +908,7 @@ blocks: color8: '"dark red"' color9: '"dark green"' comment: '' - grid: 'False' + grid: 'True' label1: '' label10: '' label2: '' @@ -822,9 +933,9 @@ blocks: maxhold: 'True' maxoutbuf: '0' minoutbuf: '0' - name: '""' + name: '"Complex vector sink"' nconnections: '1' - placement: (2,7,2,2) + placement: (0,3,2,2) style1: '"solid"' style10: '"solid"' style2: '"solid"' @@ -835,9 +946,9 @@ blocks: style7: '"solid"' style8: '"solid"' style9: '"solid"' - type: float - update_time: '100' - vec_len: '64' + type: complex + update_time: int(1000*(1/up_freq)) + vec_len: '32' width1: '1' width10: '1' width2: '1' @@ -848,8 +959,8 @@ blocks: width7: '1' width8: '1' width9: '1' - x_values: list(range(64)) - xlabel: Frequency + x_values: '[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31.0]' + xlabel: Bin xunit: '""' ylabel: Relative Gain ymax: '10' @@ -859,9 +970,9 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [1374, 684] + coordinate: [1144, 148.0] rotation: 0 - state: true + state: enabled - name: bokehgui_waterfall_sink_x_0 id: bokehgui_waterfall_sink_x parameters: @@ -879,11 +990,11 @@ blocks: legend: 'True' maxoutbuf: '0' minoutbuf: '0' - name: '""' - placement: (0,5,2,2) + name: '"Complex waterfall"' + placement: (1,0,1,1) type: complex - update_time: '100' - wintype: firdes.WIN_BLACKMAN_hARRIS + update_time: int(1000*(1/up_freq)) + wintype: window.WIN_BLACKMAN_hARRIS xlabel: Frequency xunit: Hz ylabel: Time @@ -892,10 +1003,10 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [602, 356] + coordinate: [576, 244.0] rotation: 0 - state: true -- name: bokehgui_waterfall_sink_x_0_0 + state: enabled +- name: bokehgui_waterfall_sink_x_1 id: bokehgui_waterfall_sink_x parameters: affinity: '' @@ -913,10 +1024,10 @@ blocks: maxoutbuf: '0' minoutbuf: '0' name: '""' - placement: (2,5,2,2) + placement: (3,0,1,1) type: float - update_time: '100' - wintype: firdes.WIN_BLACKMAN_hARRIS + update_time: int(1000*(1/up_freq)) + wintype: window.WIN_BLACKMAN_hARRIS xlabel: Frequency xunit: Hz ylabel: Time @@ -925,7 +1036,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [608, 731] + coordinate: [576, 556.0] rotation: 0 state: true - name: fft_vxx_0 @@ -934,21 +1045,21 @@ blocks: affinity: '' alias: '' comment: '' - fft_size: '64' + fft_size: '32' forward: 'True' maxoutbuf: '0' minoutbuf: '0' nthreads: '1' shift: 'True' type: complex - window: window.blackmanharris(64) + window: window.blackmanharris(32) states: bus_sink: false bus_source: false bus_structure: null - coordinate: [1070, 306] + coordinate: [936, 132.0] rotation: 0 - state: true + state: enabled - name: logpwrfft_x_0 id: logpwrfft_x parameters: @@ -957,18 +1068,19 @@ blocks: average: 'False' avg_alpha: '1.0' comment: '' - fft_size: '64' + fft_size: '32' frame_rate: '30' maxoutbuf: '0' minoutbuf: '0' ref_scale: '2' sample_rate: samp_rate - type: float + shift: 'True' + type: complex states: bus_sink: false bus_source: false bus_structure: null - coordinate: [942, 675] + coordinate: [872, 308.0] rotation: 0 state: true @@ -979,10 +1091,18 @@ connections: - [analog_sig_source_x_1, '0', blocks_add_xx_1, '0'] - [blocks_add_xx_0, '0', blocks_throttle_0, '0'] - [blocks_add_xx_1, '0', blocks_throttle_1, '0'] +- [blocks_stream_to_vector_0, '0', fft_vxx_0, '0'] +- [blocks_throttle_0, '0', blocks_stream_to_vector_0, '0'] - [blocks_throttle_0, '0', bokehgui_frequency_sink_x_0, '0'] +- [blocks_throttle_0, '0', bokehgui_time_const_x_0, '0'] - [blocks_throttle_0, '0', bokehgui_time_sink_x_0, '0'] +- [blocks_throttle_0, '0', bokehgui_waterfall_sink_x_0, '0'] +- [blocks_throttle_0, '0', logpwrfft_x_0, '0'] - [blocks_throttle_1, '0', bokehgui_frequency_sink_x_1, '0'] - [blocks_throttle_1, '0', bokehgui_time_sink_x_1, '0'] +- [blocks_throttle_1, '0', bokehgui_waterfall_sink_x_1, '0'] +- [fft_vxx_0, '0', bokehgui_vector_sink_x_1, '0'] +- [logpwrfft_x_0, '0', bokehgui_vector_sink_x_0, '0'] metadata: file_format: 1 From 3456c6c4ae9be9191dda96d22dddeea1052a0e7a Mon Sep 17 00:00:00 2001 From: Notou Date: Fri, 26 Nov 2021 16:58:28 +0100 Subject: [PATCH 7/8] Cleanup vec sink c python file --- python/vec_sink_c.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/vec_sink_c.py b/python/vec_sink_c.py index 4138602..52905fb 100644 --- a/python/vec_sink_c.py +++ b/python/vec_sink_c.py @@ -70,7 +70,7 @@ def initialize(self, legend_list = utils.default_labels_c, self.lines = [] self.lines_markers = [] self.legend_list = legend_list[:] - print(self.legend_list) + for i in range(2 * nconn): self.lines.append(self.plot.line(x = 'x', y = 'y' + str(i), source = self.stream, @@ -111,7 +111,7 @@ def update(self): def set_x_values(self, values): if len(values) != self.size: - print("Error: x values has not the size of the input vector") + print(f"Error: x values has not the size ({len(values)}) of the input vector ({self.size})") return self.x_values = values # def set_x_values(self, start, step): From fc0b1d84097f8bc969bf92283e816f65b699b2df Mon Sep 17 00:00:00 2001 From: Notou Date: Fri, 26 Nov 2021 17:15:22 +0100 Subject: [PATCH 8/8] Update the readme --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 3050b8b..6962b49 100644 --- a/README.md +++ b/README.md @@ -8,12 +8,12 @@ The module provides various sinks and widgets to allow interaction with the live The module was developed as a part of Google Summer of Code 2017 by Kartik Patel. -## Warning: The master branch does not yet support GNU Radio 3.9 since the change to pybind11. Please use the main-3.8 branch with GNU Radio 3.8 ## Dependency 1. GNU Radio 3.9 2. [Bokeh library v1](https://docs.bokeh.org/en/1.4.0/) (Tested on v1.4.0) +3. NodeJS ## Installation ### Using PyBOMBS @@ -35,7 +35,6 @@ $ mkdir build $ cd build/ $ cmake ../ $ make -$ make test $ sudo make install ```