|
|
@@ -8,10 +8,8 @@ import struct
|
|
|
import colorsys
|
|
|
import math
|
|
|
|
|
|
-import pygame
|
|
|
-import pygame.gfxdraw
|
|
|
-
|
|
|
parser = optparse.OptionParser()
|
|
|
+parser.add_option('-E', '--engine', dest='engine', default='pygame', help='Rendering engine to use')
|
|
|
parser.add_option('--map-file', dest='map_file', default='client_map', help='File mapped by -G mapped')
|
|
|
parser.add_option('--map-samples', dest='map_samples', type='int', default=4096, help='Number of samples in the map file (MUST agree with client)')
|
|
|
parser.add_option('--pg-samp-width', dest='samp_width', type='int', help='Set the width of the sample pane (by default display width / 2)')
|
|
|
@@ -42,107 +40,476 @@ STREAMS = strfmtsz / struct.calcsize('>Lf')
|
|
|
strfmt = '>' + 'Lf' * STREAMS
|
|
|
print 'Detected', STREAMS, 'streams'
|
|
|
|
|
|
-pygame.init()
|
|
|
-
|
|
|
-WIDTH, HEIGHT = 640, 480
|
|
|
-dispinfo = pygame.display.Info()
|
|
|
-if dispinfo.current_h > 0 and dispinfo.current_w > 0:
|
|
|
- WIDTH, HEIGHT = dispinfo.current_w, dispinfo.current_h
|
|
|
-
|
|
|
-flags = 0
|
|
|
-if options.fullscreen:
|
|
|
- flags |= pygame.FULLSCREEN
|
|
|
-
|
|
|
-disp = pygame.display.set_mode((WIDTH, HEIGHT), flags)
|
|
|
-WIDTH, HEIGHT = disp.get_size()
|
|
|
-SAMP_WIDTH = WIDTH / 2
|
|
|
-if options.samp_width:
|
|
|
- SAMP_WIDTH = options.samp_width
|
|
|
-BGR_WIDTH = WIDTH - SAMP_WIDTH
|
|
|
-HALFH = HEIGHT / 2
|
|
|
-PFAC = HEIGHT / 128.0
|
|
|
-sampwin = pygame.Surface((SAMP_WIDTH, HEIGHT))
|
|
|
-sampwin.set_colorkey((0, 0, 0))
|
|
|
-lastsy = HALFH
|
|
|
-bgrwin = pygame.Surface((BGR_WIDTH, HEIGHT))
|
|
|
-bgrwin.set_colorkey((0, 0, 0))
|
|
|
-
|
|
|
-clock = pygame.time.Clock()
|
|
|
-font = pygame.font.SysFont(pygame.font.get_default_font(), 24)
|
|
|
-
|
|
|
-def rgb_for_freq_amp(f, a):
|
|
|
- a = max((min((a, 1.0)), 0.0))
|
|
|
- pitchval = float(f - options.low_freq) / (options.high_freq - options.low_freq)
|
|
|
- if options.log_base == 0:
|
|
|
- try:
|
|
|
- pitchval = math.log(pitchval) / math.log(options.log_base)
|
|
|
- except ValueError:
|
|
|
- pass
|
|
|
- bgcol = colorsys.hls_to_rgb(min((1.0, max((0.0, pitchval)))), 0.5 * (a ** 2), 1.0)
|
|
|
- return [int(i*255) for i in bgcol]
|
|
|
-
|
|
|
-while True:
|
|
|
- DISP_FACTOR = struct.unpack(fixfmt, mapping[:fixfmtsz])[0]
|
|
|
- LAST_SAMPLES = struct.unpack(sigfmt, mapping[fixfmtsz:fixfmtsz+sigfmtsz])
|
|
|
- VALUES = struct.unpack(strfmt, mapping[fixfmtsz+sigfmtsz:])
|
|
|
- FREQS, AMPS = VALUES[::2], VALUES[1::2]
|
|
|
- if options.no_colback:
|
|
|
- disp.fill((0, 0, 0), (0, 0, WIDTH, HEIGHT))
|
|
|
- else:
|
|
|
- gap = WIDTH / STREAMS
|
|
|
+if options.engine == 'pygame':
|
|
|
+ import pygame
|
|
|
+ import pygame.gfxdraw
|
|
|
+
|
|
|
+ pygame.init()
|
|
|
+
|
|
|
+ WIDTH, HEIGHT = 640, 480
|
|
|
+ dispinfo = pygame.display.Info()
|
|
|
+ if dispinfo.current_h > 0 and dispinfo.current_w > 0:
|
|
|
+ WIDTH, HEIGHT = dispinfo.current_w, dispinfo.current_h
|
|
|
+
|
|
|
+ flags = 0
|
|
|
+ if options.fullscreen:
|
|
|
+ flags |= pygame.FULLSCREEN
|
|
|
+
|
|
|
+ disp = pygame.display.set_mode((WIDTH, HEIGHT), flags)
|
|
|
+ WIDTH, HEIGHT = disp.get_size()
|
|
|
+ SAMP_WIDTH = WIDTH / 2
|
|
|
+ if options.samp_width:
|
|
|
+ SAMP_WIDTH = options.samp_width
|
|
|
+ BGR_WIDTH = WIDTH - SAMP_WIDTH
|
|
|
+ HALFH = HEIGHT / 2
|
|
|
+ PFAC = HEIGHT / 128.0
|
|
|
+ sampwin = pygame.Surface((SAMP_WIDTH, HEIGHT))
|
|
|
+ sampwin.set_colorkey((0, 0, 0))
|
|
|
+ lastsy = HALFH
|
|
|
+ bgrwin = pygame.Surface((BGR_WIDTH, HEIGHT))
|
|
|
+ bgrwin.set_colorkey((0, 0, 0))
|
|
|
+
|
|
|
+ clock = pygame.time.Clock()
|
|
|
+ font = pygame.font.SysFont(pygame.font.get_default_font(), 24)
|
|
|
+
|
|
|
+ def rgb_for_freq_amp(f, a):
|
|
|
+ a = max((min((a, 1.0)), 0.0))
|
|
|
+ pitchval = float(f - options.low_freq) / (options.high_freq - options.low_freq)
|
|
|
+ if options.log_base == 0:
|
|
|
+ try:
|
|
|
+ pitchval = math.log(pitchval) / math.log(options.log_base)
|
|
|
+ except ValueError:
|
|
|
+ pass
|
|
|
+ bgcol = colorsys.hls_to_rgb(min((1.0, max((0.0, pitchval)))), 0.5 * (a ** 2), 1.0)
|
|
|
+ return [int(i*255) for i in bgcol]
|
|
|
+
|
|
|
+ while True:
|
|
|
+ DISP_FACTOR = struct.unpack(fixfmt, mapping[:fixfmtsz])[0]
|
|
|
+ LAST_SAMPLES = struct.unpack(sigfmt, mapping[fixfmtsz:fixfmtsz+sigfmtsz])
|
|
|
+ VALUES = struct.unpack(strfmt, mapping[fixfmtsz+sigfmtsz:])
|
|
|
+ FREQS, AMPS = VALUES[::2], VALUES[1::2]
|
|
|
+ if options.no_colback:
|
|
|
+ disp.fill((0, 0, 0), (0, 0, WIDTH, HEIGHT))
|
|
|
+ else:
|
|
|
+ gap = WIDTH / STREAMS
|
|
|
+ for i in xrange(STREAMS):
|
|
|
+ FREQ = FREQS[i]
|
|
|
+ AMP = AMPS[i]
|
|
|
+ if FREQ > 0:
|
|
|
+ bgcol = rgb_for_freq_amp(FREQ, AMP)
|
|
|
+ else:
|
|
|
+ bgcol = (0, 0, 0)
|
|
|
+ disp.fill(bgcol, (i*gap, 0, gap, HEIGHT))
|
|
|
+
|
|
|
+ bgrwin.scroll(-1, 0)
|
|
|
+ bgrwin.fill((0, 0, 0), (BGR_WIDTH - 1, 0, 1, HEIGHT))
|
|
|
for i in xrange(STREAMS):
|
|
|
FREQ = FREQS[i]
|
|
|
AMP = AMPS[i]
|
|
|
if FREQ > 0:
|
|
|
- bgcol = rgb_for_freq_amp(FREQ, AMP)
|
|
|
+ try:
|
|
|
+ pitch = 12 * math.log(FREQ / 440.0, 2) + 69
|
|
|
+ except ValueError:
|
|
|
+ pitch = 0
|
|
|
else:
|
|
|
- bgcol = (0, 0, 0)
|
|
|
- disp.fill(bgcol, (i*gap, 0, gap, HEIGHT))
|
|
|
-
|
|
|
- bgrwin.scroll(-1, 0)
|
|
|
- bgrwin.fill((0, 0, 0), (BGR_WIDTH - 1, 0, 1, HEIGHT))
|
|
|
- for i in xrange(STREAMS):
|
|
|
- FREQ = FREQS[i]
|
|
|
- AMP = AMPS[i]
|
|
|
- if FREQ > 0:
|
|
|
- try:
|
|
|
- pitch = 12 * math.log(FREQ / 440.0, 2) + 69
|
|
|
- except ValueError:
|
|
|
pitch = 0
|
|
|
- else:
|
|
|
- pitch = 0
|
|
|
- col = [min(max(int(AMP * 255), 0), 255)] * 3
|
|
|
- bgrwin.fill(col, (BGR_WIDTH - 1, HEIGHT - pitch * PFAC - PFAC, 1, PFAC))
|
|
|
-
|
|
|
- sampwin.fill((0, 0, 0), (0, 0, SAMP_WIDTH, HEIGHT))
|
|
|
- x = 0
|
|
|
- for i in LAST_SAMPLES:
|
|
|
- sy = int(i * HALFH + HALFH)
|
|
|
- pygame.gfxdraw.line(sampwin, x - 1, lastsy, x, sy, (0, 255, 0))
|
|
|
- x += 1
|
|
|
- lastsy = sy
|
|
|
-
|
|
|
- disp.blit(bgrwin, (0, 0))
|
|
|
- disp.blit(sampwin, (BGR_WIDTH, 0))
|
|
|
-
|
|
|
- if DISP_FACTOR != 0:
|
|
|
- tsurf = font.render('%+011.6g'%(DISP_FACTOR,), True, (255, 255, 255), (0, 0, 0))
|
|
|
- disp.fill((0, 0, 0), tsurf.get_rect())
|
|
|
- disp.blit(tsurf, (0, 0))
|
|
|
-
|
|
|
- pygame.display.flip()
|
|
|
-
|
|
|
- for ev in pygame.event.get():
|
|
|
- if ev.type == pygame.KEYDOWN:
|
|
|
- if ev.key == pygame.K_ESCAPE:
|
|
|
+ col = [min(max(int(AMP * 255), 0), 255)] * 3
|
|
|
+ bgrwin.fill(col, (BGR_WIDTH - 1, HEIGHT - pitch * PFAC - PFAC, 1, PFAC))
|
|
|
+
|
|
|
+ sampwin.fill((0, 0, 0), (0, 0, SAMP_WIDTH, HEIGHT))
|
|
|
+ x = 0
|
|
|
+ for i in LAST_SAMPLES:
|
|
|
+ sy = int(i * HALFH + HALFH)
|
|
|
+ pygame.gfxdraw.line(sampwin, x - 1, lastsy, x, sy, (0, 255, 0))
|
|
|
+ x += 1
|
|
|
+ lastsy = sy
|
|
|
+
|
|
|
+ disp.blit(bgrwin, (0, 0))
|
|
|
+ disp.blit(sampwin, (BGR_WIDTH, 0))
|
|
|
+
|
|
|
+ if DISP_FACTOR != 0:
|
|
|
+ tsurf = font.render('%+011.6g'%(DISP_FACTOR,), True, (255, 255, 255), (0, 0, 0))
|
|
|
+ disp.fill((0, 0, 0), tsurf.get_rect())
|
|
|
+ disp.blit(tsurf, (0, 0))
|
|
|
+
|
|
|
+ pygame.display.flip()
|
|
|
+
|
|
|
+ for ev in pygame.event.get():
|
|
|
+ if ev.type == pygame.KEYDOWN:
|
|
|
+ if ev.key == pygame.K_ESCAPE:
|
|
|
+ pygame.quit()
|
|
|
+ exit()
|
|
|
+ elif ev.type == pygame.QUIT:
|
|
|
pygame.quit()
|
|
|
exit()
|
|
|
- elif ev.type == pygame.QUIT:
|
|
|
+
|
|
|
+ if not os.path.exists(options.map_file):
|
|
|
pygame.quit()
|
|
|
exit()
|
|
|
|
|
|
- if not os.path.exists(options.map_file):
|
|
|
- pygame.quit()
|
|
|
+ clock.tick(60)
|
|
|
+
|
|
|
+elif options.engine == 'glfw':
|
|
|
+ import array, ctypes
|
|
|
+ import glfw
|
|
|
+ from OpenGL import GL
|
|
|
+ from OpenGL.GL import *
|
|
|
+
|
|
|
+ if not glfw.init():
|
|
|
+ print 'GLFW: Init failed'
|
|
|
exit()
|
|
|
|
|
|
- clock.tick(60)
|
|
|
+ monitor = glfw.get_primary_monitor()
|
|
|
+ mode = glfw.get_video_mode(monitor)
|
|
|
+
|
|
|
+ glfw.window_hint(glfw.RED_BITS, mode.bits.red)
|
|
|
+ glfw.window_hint(glfw.GREEN_BITS, mode.bits.green)
|
|
|
+ glfw.window_hint(glfw.BLUE_BITS, mode.bits.blue)
|
|
|
+ glfw.window_hint(glfw.REFRESH_RATE, mode.refresh_rate)
|
|
|
+ glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 4)
|
|
|
+ glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3)
|
|
|
+ glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
|
|
|
+
|
|
|
+ win = glfw.create_window(mode.size.width, mode.size.height, 'render', monitor, None)
|
|
|
+ if not win:
|
|
|
+ print 'GLFW: Window creation failed'
|
|
|
+ glfw.terminate()
|
|
|
+ exit()
|
|
|
+
|
|
|
+ glfw.make_context_current(win)
|
|
|
+
|
|
|
+ print 'Version:', glGetString(GL_VERSION)
|
|
|
+ print 'Renderer:', glGetString(GL_RENDERER)
|
|
|
+
|
|
|
+ rect_data = array.array('f', [
|
|
|
+ -1.0, -1.0,
|
|
|
+ 1.0, -1.0,
|
|
|
+ 1.0, 1.0,
|
|
|
+ -1.0, -1.0,
|
|
|
+ 1.0, 1.0,
|
|
|
+ -1.0, 1.0,
|
|
|
+ ])
|
|
|
+
|
|
|
+ rect = glGenBuffers(1)
|
|
|
+ glBindBuffer(GL_ARRAY_BUFFER, rect)
|
|
|
+ glBufferData(GL_ARRAY_BUFFER, rect_data.tostring(), GL_STATIC_DRAW)
|
|
|
+
|
|
|
+ rect_zo_data = array.array('f', [
|
|
|
+ 0.0, 0.0,
|
|
|
+ 1.0, 0.0,
|
|
|
+ 1.0, 1.0,
|
|
|
+ 0.0, 0.0,
|
|
|
+ 1.0, 1.0,
|
|
|
+ 0.0, 1.0,
|
|
|
+ ])
|
|
|
+
|
|
|
+ rect_zo = glGenBuffers(1)
|
|
|
+ glBindBuffer(GL_ARRAY_BUFFER, rect_zo)
|
|
|
+ glBufferData(GL_ARRAY_BUFFER, rect_zo_data.tostring(), GL_STATIC_DRAW)
|
|
|
+
|
|
|
+ samp_buf = glGenBuffers(1)
|
|
|
+ glBindBuffer(GL_ARRAY_BUFFER, samp_buf)
|
|
|
+ glBufferData(GL_ARRAY_BUFFER, mapping[fixfmtsz:fixfmtsz+sigfmtsz], GL_STREAM_DRAW)
|
|
|
+ glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, samp_buf)
|
|
|
+
|
|
|
+ freq_buf = glGenBuffers(1)
|
|
|
+ glBindBuffer(GL_ARRAY_BUFFER, freq_buf)
|
|
|
+ glBufferData(GL_ARRAY_BUFFER, STREAMS * 4, None, GL_STREAM_DRAW)
|
|
|
+ glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, freq_buf)
|
|
|
+
|
|
|
+ amp_buf = glGenBuffers(1)
|
|
|
+ glBindBuffer(GL_ARRAY_BUFFER, amp_buf)
|
|
|
+ glBufferData(GL_ARRAY_BUFFER, STREAMS * 4, None, GL_STREAM_DRAW)
|
|
|
+ glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, amp_buf)
|
|
|
+
|
|
|
+ lin_buf = glGenBuffers(1)
|
|
|
+ glBindBuffer(GL_ARRAY_BUFFER, lin_buf)
|
|
|
+ lin_arr = array.array('f', [(float(i) / options.map_samples) * 2.0 - 1.0 for i in range(options.map_samples)])
|
|
|
+ #print lin_arr
|
|
|
+ glBufferData(GL_ARRAY_BUFFER, lin_arr.tostring(), GL_STATIC_DRAW)
|
|
|
+
|
|
|
+ bg_tex = glGenTextures(1)
|
|
|
+ glBindTexture(GL_TEXTURE_2D, bg_tex)
|
|
|
+ bg_data = array.array('B', [0 for i in range(mode.size.width * mode.size.height)])
|
|
|
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, mode.size.width, mode.size.height, 0, GL_RED, GL_UNSIGNED_BYTE, bg_data.tostring())
|
|
|
+ glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
|
|
|
+ glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
|
|
|
+ glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
|
|
|
+ glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
|
|
|
+
|
|
|
+ bg_swp = glGenTextures(1)
|
|
|
+ glBindTexture(GL_TEXTURE_2D, bg_swp)
|
|
|
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, mode.size.width, mode.size.height, 0, GL_RED, GL_UNSIGNED_BYTE, bg_data.tostring())
|
|
|
+ glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
|
|
|
+ glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
|
|
|
+ glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
|
|
|
+ glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
|
|
|
+
|
|
|
+ # Some *4s below because the texture is packed as RGBA8 despite only indexing R
|
|
|
+
|
|
|
+ bar_pfac = mode.size.height / 128.0
|
|
|
+ bg_bar_h = int(bar_pfac)
|
|
|
+ bg_bar_sz = (bg_bar_h*4)
|
|
|
+
|
|
|
+ block_d = '\x7f' * (64*64*4)
|
|
|
+ clear_d = '\x00' * (mode.size.height*4)
|
|
|
+
|
|
|
+ fbs = glGenFramebuffers(1)
|
|
|
+ fbd = glGenFramebuffers(1)
|
|
|
+
|
|
|
+ def make_prog(vss, fss):
|
|
|
+ vs = glCreateShader(GL_VERTEX_SHADER)
|
|
|
+ glShaderSource(vs, vss)
|
|
|
+ glCompileShader(vs)
|
|
|
+ if not glGetShaderiv(vs, GL_COMPILE_STATUS):
|
|
|
+ print 'Vertex error:', glGetShaderInfoLog(vs)
|
|
|
+ exit()
|
|
|
+
|
|
|
+ fs = glCreateShader(GL_FRAGMENT_SHADER)
|
|
|
+ glShaderSource(fs, fss)
|
|
|
+ glCompileShader(fs)
|
|
|
+ if not glGetShaderiv(fs, GL_COMPILE_STATUS):
|
|
|
+ print 'Fragment error:', glGetShaderInfoLog(fs)
|
|
|
+ exit()
|
|
|
+
|
|
|
+ prog = glCreateProgram()
|
|
|
+ glAttachShader(prog, vs)
|
|
|
+ glAttachShader(prog, fs)
|
|
|
+ glLinkProgram(prog)
|
|
|
+ if not glGetProgramiv(prog, GL_LINK_STATUS):
|
|
|
+ print 'Program error:', glGetProgramInfoLog(prog)
|
|
|
+ exit()
|
|
|
+
|
|
|
+ return prog
|
|
|
+
|
|
|
+ prog_bg = make_prog('''
|
|
|
+#version 430
|
|
|
+
|
|
|
+in vec2 vPosition;
|
|
|
+in vec2 vTex;
|
|
|
+
|
|
|
+out vec2 vUV;
|
|
|
+
|
|
|
+void main(void) {
|
|
|
+ gl_Position = vec4(vPosition,0.0,1.0);
|
|
|
+ vUV = vTex;
|
|
|
+}''', '''
|
|
|
+#version 430
|
|
|
+
|
|
|
+in vec2 vUV;
|
|
|
+
|
|
|
+layout (location = 0) out vec4 FragColor;
|
|
|
+layout (std430, binding = 2) buffer bfreq {
|
|
|
+ uint freq[];
|
|
|
+};
|
|
|
+layout (std430, binding = 3) buffer bamp {
|
|
|
+ float amp[];
|
|
|
+};
|
|
|
+
|
|
|
+vec3 map_col(uint fr, float intensity) {
|
|
|
+ if(fr == 0) return vec3(0.0,0.0,0.0);
|
|
|
+ return vec3(
|
|
|
+ 0.66 * clamp((float(fr) - 40.0) / (1500.0 - 40.0), 0.0, 1.0),
|
|
|
+ 1.0,
|
|
|
+ clamp(intensity, 0.0, 1.0)
|
|
|
+ );
|
|
|
+}
|
|
|
+
|
|
|
+vec3 hsv2rgb(vec3 c)
|
|
|
+{
|
|
|
+ vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
|
|
+ vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
|
|
+ return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
|
|
+}
|
|
|
+
|
|
|
+void main(void) {
|
|
|
+ float zox = (vUV.x + 1.0) / 2.0;
|
|
|
+ uint v = uint(zox * freq.length());
|
|
|
+ FragColor = vec4(
|
|
|
+ hsv2rgb(map_col(freq[v], amp[v])),
|
|
|
+ 1.0
|
|
|
+ );
|
|
|
+}''')
|
|
|
+
|
|
|
+ glUseProgram(prog_bg)
|
|
|
+ vao_bg = glGenVertexArrays(1)
|
|
|
+ glBindVertexArray(vao_bg)
|
|
|
+ glBindBuffer(GL_ARRAY_BUFFER, rect)
|
|
|
+ a_vPosition = glGetProgramResourceLocation(prog_bg, GL_PROGRAM_INPUT, 'vPosition')
|
|
|
+ print 'prog_bg a_vPosition', a_vPosition
|
|
|
+ glVertexAttribPointer(a_vPosition, 2, GL_FLOAT, False, 0, None)
|
|
|
+ glEnableVertexAttribArray(a_vPosition)
|
|
|
+ a_vTex = glGetProgramResourceLocation(prog_bg, GL_PROGRAM_INPUT, 'vTex')
|
|
|
+ print 'prog_bg a_vTex', a_vTex
|
|
|
+ glVertexAttribPointer(a_vTex, 2, GL_FLOAT, False, 0, None)
|
|
|
+ glEnableVertexAttribArray(a_vTex)
|
|
|
+
|
|
|
+ prog_scope = make_prog('''
|
|
|
+#version 430
|
|
|
+
|
|
|
+in float vX;
|
|
|
+in float vY;
|
|
|
+
|
|
|
+void main(void) {
|
|
|
+ gl_Position = vec4(vX, vY, 0.0, 1.0);
|
|
|
+}
|
|
|
+''', '''
|
|
|
+#version 430
|
|
|
+
|
|
|
+layout (location = 0) out vec4 FragColor;
|
|
|
+
|
|
|
+void main(void) {
|
|
|
+ FragColor = vec4(0.0, 1.0, 0.0, 1.0);
|
|
|
+}
|
|
|
+''')
|
|
|
+
|
|
|
+ glUseProgram(prog_scope)
|
|
|
+ vao_scope = glGenVertexArrays(1)
|
|
|
+ glBindVertexArray(vao_scope)
|
|
|
+ glBindBuffer(GL_ARRAY_BUFFER, lin_buf)
|
|
|
+ a_vX = glGetProgramResourceLocation(prog_scope, GL_PROGRAM_INPUT, 'vX')
|
|
|
+ print 'prog_scope a_vX', a_vX
|
|
|
+ glVertexAttribPointer(a_vX, 1, GL_FLOAT, False, 0, None)
|
|
|
+ glEnableVertexAttribArray(a_vX)
|
|
|
+ glBindBuffer(GL_ARRAY_BUFFER, samp_buf)
|
|
|
+ a_vY = glGetProgramResourceLocation(prog_scope, GL_PROGRAM_INPUT, 'vY')
|
|
|
+ print 'prog_scope a_vY', a_vY
|
|
|
+ glVertexAttribPointer(a_vY, 1, GL_FLOAT, False, 0, None)
|
|
|
+ glEnableVertexAttribArray(a_vY)
|
|
|
+
|
|
|
+ prog_bar = make_prog('''
|
|
|
+#version 430
|
|
|
+
|
|
|
+in vec2 vPosition;
|
|
|
+in vec2 vTex;
|
|
|
+
|
|
|
+out vec2 vUV;
|
|
|
+
|
|
|
+void main(void) {
|
|
|
+ gl_Position = vec4(vPosition, 0.0, 1.0);
|
|
|
+ vUV = vTex;
|
|
|
+}''', '''
|
|
|
+#version 430
|
|
|
+
|
|
|
+in vec2 vUV;
|
|
|
+
|
|
|
+layout (location = 0) out vec4 FragColor;
|
|
|
+
|
|
|
+uniform sampler2D uTex;
|
|
|
+
|
|
|
+void main(void) {
|
|
|
+ vec4 col = texture(uTex, vUV);
|
|
|
+ FragColor = vec4(1.0, 1.0, 1.0, col.r);
|
|
|
+}''')
|
|
|
+
|
|
|
+ glUseProgram(prog_bar)
|
|
|
+ vao_bar = glGenVertexArrays(1)
|
|
|
+ glBindVertexArray(vao_bar)
|
|
|
+ glBindBuffer(GL_ARRAY_BUFFER, rect)
|
|
|
+ a_vPosition = glGetProgramResourceLocation(prog_bar, GL_PROGRAM_INPUT, 'vPosition')
|
|
|
+ print 'prog_bar a_vPosition', a_vPosition
|
|
|
+ glVertexAttribPointer(a_vPosition, 2, GL_FLOAT, False, 0, None)
|
|
|
+ glEnableVertexAttribArray(a_vPosition)
|
|
|
+ a_vTex = glGetProgramResourceLocation(prog_bar, GL_PROGRAM_INPUT, 'vTex')
|
|
|
+ print 'prog_bar a_vTex', a_vTex
|
|
|
+ glBindBuffer(GL_ARRAY_BUFFER, rect_zo)
|
|
|
+ glVertexAttribPointer(a_vTex, 2, GL_FLOAT, False, 0, None)
|
|
|
+ glEnableVertexAttribArray(a_vTex)
|
|
|
+ u_uTex = glGetProgramResourceLocation(prog_bar, GL_UNIFORM, 'uTex')
|
|
|
+ print 'prog_bar u_uTex', u_uTex
|
|
|
+ glUniform1i(u_uTex, 0)
|
|
|
+ glActiveTexture(GL_TEXTURE0)
|
|
|
+ glBindTexture(GL_TEXTURE_2D, bg_tex)
|
|
|
+
|
|
|
+ glClearColor(0.2, 0.0, 0.0, 1.0)
|
|
|
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
|
|
|
+
|
|
|
+ while not glfw.window_should_close(win):
|
|
|
+ glfw.make_context_current(win)
|
|
|
+ glClear(GL_COLOR_BUFFER_BIT)
|
|
|
+
|
|
|
+ arr = array.array('f')
|
|
|
+ arr.fromstring(mapping[fixfmtsz:fixfmtsz+sigfmtsz])
|
|
|
+ arr.byteswap()
|
|
|
+ glBindBuffer(GL_ARRAY_BUFFER, samp_buf)
|
|
|
+ glBufferSubData(GL_ARRAY_BUFFER, 0, arr.tostring())
|
|
|
+
|
|
|
+ arr = array.array('I')
|
|
|
+ arr.fromstring(mapping[fixfmtsz+sigfmtsz:])
|
|
|
+ #print len(arr)
|
|
|
+ arr.byteswap()
|
|
|
+ glBindBuffer(GL_ARRAY_BUFFER, freq_buf)
|
|
|
+ glBufferSubData(GL_ARRAY_BUFFER, 0, arr[::2].tostring())
|
|
|
+ arr_fq = arr[::2]
|
|
|
+
|
|
|
+ arr = array.array('f')
|
|
|
+ arr.fromstring(mapping[fixfmtsz+sigfmtsz:])
|
|
|
+ #print len(arr)
|
|
|
+ arr.byteswap()
|
|
|
+ glBindBuffer(GL_ARRAY_BUFFER, amp_buf)
|
|
|
+ glBufferSubData(GL_ARRAY_BUFFER, 0, arr[1::2].tostring())
|
|
|
+ arr_am = arr[1::2]
|
|
|
+
|
|
|
+ #print len(arr_fq), len(arr_am)
|
|
|
+ #print zip(arr_fq, arr_am)
|
|
|
+
|
|
|
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, fbs)
|
|
|
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbd)
|
|
|
+ glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, bg_tex, 0)
|
|
|
+ glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, bg_swp, 0)
|
|
|
+ stat = glCheckFramebufferStatus(GL_READ_FRAMEBUFFER)
|
|
|
+ if stat != GL_FRAMEBUFFER_COMPLETE:
|
|
|
+ print 'Incomplete read buffer:', stat
|
|
|
+ stat = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER)
|
|
|
+ if stat != GL_FRAMEBUFFER_COMPLETE:
|
|
|
+ print 'Incomplete draw buffer:', stat
|
|
|
+ glBlitFramebuffer(
|
|
|
+ 1, 0, mode.size.width, mode.size.height,
|
|
|
+ 0, 0, mode.size.width - 1, mode.size.height,
|
|
|
+ GL_COLOR_BUFFER_BIT, GL_NEAREST
|
|
|
+ )
|
|
|
+ glBindFramebuffer(GL_FRAMEBUFFER, 0)
|
|
|
+
|
|
|
+ bg_swp, bg_tex = bg_tex, bg_swp
|
|
|
+ glBindTexture(GL_TEXTURE_2D, bg_tex)
|
|
|
+ glTexSubImage2D(GL_TEXTURE_2D, 0, mode.size.width - 1, 0, 1, mode.size.height, GL_RED, GL_UNSIGNED_BYTE, clear_d)
|
|
|
+ for f, a in zip(arr_fq, arr_am):
|
|
|
+ if f == 0:
|
|
|
+ continue
|
|
|
+ try:
|
|
|
+ pitch = 12 * math.log(f / 440.0, 2) + 69
|
|
|
+ except ValueError:
|
|
|
+ pitch = 0
|
|
|
+ bg_bar_d = chr(int(255 * max((0.0, min((1.0, a)))))) * bg_bar_sz
|
|
|
+ glTexSubImage2D(GL_TEXTURE_2D, 0, mode.size.width - 1, int(pitch * bar_pfac), 1, bg_bar_h, GL_RED, GL_UNSIGNED_BYTE, bg_bar_d)
|
|
|
+ #print 'plot', mode.size.width - 1, int(pitch * bg_bar_h), 1, bg_bar_h, repr(bg_bar_d)
|
|
|
+ #glTexSubImage2D(GL_TEXTURE_2D, 0, mode.size.width - 64, int(pitch * bg_bar_h), 64, 64, GL_RED, GL_UNSIGNED_BYTE, block_d)
|
|
|
+
|
|
|
+ #glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 64, 64, GL_RED, GL_UNSIGNED_BYTE, block_d)
|
|
|
+ #glTexSubImage2D(GL_TEXTURE_2D, 0, mode.size.width - 64, mode.size.height - 64, 64, 64, GL_RED, GL_UNSIGNED_BYTE, block_d)
|
|
|
+
|
|
|
+ glActiveTexture(GL_TEXTURE0)
|
|
|
+ glBindTexture(GL_TEXTURE_2D, 0)
|
|
|
+
|
|
|
+ glUseProgram(prog_bg)
|
|
|
+ glBindVertexArray(vao_bg)
|
|
|
+ glDrawArrays(GL_TRIANGLES, 0, 6)
|
|
|
+
|
|
|
+ glUseProgram(prog_bar)
|
|
|
+ glBindVertexArray(vao_bar)
|
|
|
+ glBindTexture(GL_TEXTURE_2D, bg_tex)
|
|
|
+ #print bg_tex, bg_swp
|
|
|
+ #print glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH), glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT)
|
|
|
+ glEnable(GL_BLEND)
|
|
|
+ glDrawArrays(GL_TRIANGLES, 0, 6)
|
|
|
+ glDisable(GL_BLEND)
|
|
|
+ glBindTexture(GL_TEXTURE_2D, 0)
|
|
|
+
|
|
|
+ glUseProgram(prog_scope)
|
|
|
+ glBindVertexArray(vao_scope)
|
|
|
+ glDrawArrays(GL_LINE_STRIP, 0, options.map_samples)
|
|
|
+
|
|
|
+ glfw.swap_buffers(win)
|
|
|
+ glfw.poll_events()
|
|
|
+
|
|
|
+ glfw.terminate()
|