from blocks import Block, Input import numpy as np bins = 256 class WaterfallLines(Block): #input = Input(type=(np.complex64, 256)) input = Input() def init(self): self.canvas = Canvas() self.widget = self.canvas.native self.gr_block.set_history(bins) self.win = np.blackman(bins) def general_work(self, input_items, output_items): self.gr_block.consume_each(256 / 30) C = np.fft.rfft(input_items[0][:bins] * self.win) C = abs(C) / 100 #print input_items #line = input_items[0][0] #line = np.abs(line) self.canvas.add_new_line(C) return 0 #!/usr/bin/env python # -*- coding: utf-8 -*- # vispy: gallery 2 # Copyright (c) 2015, Vispy Development Team. # Distributed under the (new) BSD License. See LICENSE.txt for more info. """ Multiple real-time digital signals with GLSL-based clipping. """ from vispy import gloo from vispy import app from vispy.color import Colormap import numpy as np import math num_bins = 128 num_lines = 64 VERT_SHADER = """ #version 120 //attribute vec2 a_position; attribute float index; attribute float line; //uniform float line; uniform sampler2D heightmap; uniform float map_offset; uniform float num_bins; uniform float num_lines; varying float height; varying float v_line; void main() { // Compute the x coordinate from the time index. //float x = -1 + 2*a_index.z / (u_n-1); //vec2 position = vec2(x - (1 - 1), a_position + index / u_n); float y = line / num_lines - 1.0; float x = index / num_bins + y / 2; float u = index / num_bins; float v = mod(line + map_offset, num_lines) / num_lines; height = texture2D(heightmap, vec2(u, v)).x ; gl_Position = vec4(x, y + height, 0.0, 1.0); v_line = line; } """ FRAG_SHADER = """ #version 120 varying float height; varying float v_line; uniform sampler1D colormap; void main() { gl_FragColor = texture1D(colormap, height); if (fract(v_line) > 0.) { discard; } // Discard the fragments between the signals (emulate glMultiDrawArrays). //if ((fract(v_index.x) > 0.) || (fract(v_index.y) > 0.)) // discard; } """ class Canvas(app.Canvas): def __init__(self): app.Canvas.__init__(self, keys='interactive') self.program = gloo.Program(VERT_SHADER, FRAG_SHADER) self.program['index'] = [(x,) for x in range(num_bins)] * num_lines self.program['line'] = [(x,) * num_bins for x in range(num_lines)] self.program['map_offset'] = 0 self.program['num_bins'] = num_bins self.program['num_lines'] = num_lines heightmap = np.random.random(size=(num_lines, num_bins)).astype('float32') self.program['heightmap'] = gloo.Texture2D(data=heightmap, internalformat='r32f') #print (dir(self.program['heightmap'])) self.program['colormap'] = Colormap(['r', 'g', 'b']).map(np.linspace(0, 1, 64)).astype('float32') gloo.set_viewport(0, 0, *self.physical_size) gloo.set_state(clear_color='black', blend=True, blend_func=('src_alpha', 'one_minus_src_alpha')) self.show() def on_resize(self, event): gloo.set_viewport(0, 0, *event.physical_size) def on_mouse_wheel(self, event): dx = np.sign(event.delta[1]) * .05 self.update() def add_new_line(self, data): map_offset = self.program['map_offset'] self.program['map_offset'] = (map_offset - 1) % num_lines map_offset = int(self.program['map_offset']) data = data.astype('float32') data = data[:128] #print 'add_new_line', len(data), map_offset, data[::16] #data = np.random.random(num_bins).astype('float32') self.program['heightmap'].set_data([data], (map_offset, 0)) self.update() def on_draw(self, event): gloo.clear() #self.program['a_position'] = #for line in range(num_lines): # self.program['line'] = line self.program.draw('line_strip')