commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] r9177 - in gnuradio/branches/features/experimental-gui


From: jblum
Subject: [Commit-gnuradio] r9177 - in gnuradio/branches/features/experimental-gui: . plotter
Date: Tue, 5 Aug 2008 20:32:07 -0600 (MDT)

Author: jblum
Date: 2008-08-05 20:32:05 -0600 (Tue, 05 Aug 2008)
New Revision: 9177

Modified:
   gnuradio/branches/features/experimental-gui/const_window.py
   gnuradio/branches/features/experimental-gui/constsink.py
   gnuradio/branches/features/experimental-gui/fft_window.py
   gnuradio/branches/features/experimental-gui/grc_waterfallsink_test.py
   gnuradio/branches/features/experimental-gui/plotter/waterfall_plotter.py
   gnuradio/branches/features/experimental-gui/waterfall_window.py
Log:
waterfall use texture

Modified: gnuradio/branches/features/experimental-gui/const_window.py
===================================================================
--- gnuradio/branches/features/experimental-gui/const_window.py 2008-08-06 
00:15:23 UTC (rev 9176)
+++ gnuradio/branches/features/experimental-gui/const_window.py 2008-08-06 
02:32:05 UTC (rev 9177)
@@ -178,10 +178,10 @@
                x_divs = self[X_DIVS_KEY]
                y_divs = self[Y_DIVS_KEY]
                #update the x axis
-               x_max = 1.2
+               x_max = 2.0
                self.plotter.set_x_grid(-x_max, x_max, 
common.get_clean_num(2.0*x_max/x_divs))
                #update the y axis
-               y_max = 1.2
+               y_max = 2.0
                self.plotter.set_y_grid(-y_max, y_max, 
common.get_clean_num(2.0*y_max/y_divs))
                #update plotter
                self.plotter.update()

Modified: gnuradio/branches/features/experimental-gui/constsink.py
===================================================================
--- gnuradio/branches/features/experimental-gui/constsink.py    2008-08-06 
00:15:23 UTC (rev 9176)
+++ gnuradio/branches/features/experimental-gui/constsink.py    2008-08-06 
02:32:05 UTC (rev 9177)
@@ -101,6 +101,8 @@
                #connect
                self.connect(self, sync, agc, sd, sink)
                #controller
+               def setter(p, k, x): # lambdas can't have assignments :(
+                   p[k] = x
                self.controller = pubsub()
                self.controller.subscribe(ALPHA_KEY, sync.set_alpha)
                self.controller.publish(ALPHA_KEY, sync.alpha)
@@ -113,11 +115,11 @@
                self.controller.subscribe(GAIN_OMEGA_KEY, sync.set_gain_omega)
                self.controller.publish(GAIN_OMEGA_KEY, sync.gain_omega)
                self.controller.subscribe(SAMPLE_RATE_KEY, sd.set_sample_rate)
-               self.controller.subscribe(SAMPLE_RATE_KEY, lambda x: 
self.controller.set(OMEGA_KEY, float(x)/symbol_rate))
+               self.controller.subscribe(SAMPLE_RATE_KEY, lambda x: 
setter(self.controller, OMEGA_KEY, float(x)/symbol_rate))
                self.controller.publish(SAMPLE_RATE_KEY, sd.sample_rate)
+               #initial update
+               self.controller[SAMPLE_RATE_KEY] = sample_rate
                #start input watcher
-               def setter(p, k, x): # lambdas can't have assignments :(
-                   p[k] = x
                common.input_watcher(msgq, lambda x: setter(self.controller, 
MSG_KEY, x))
                #create window
                self.win = const_window.const_window(

Modified: gnuradio/branches/features/experimental-gui/fft_window.py
===================================================================
--- gnuradio/branches/features/experimental-gui/fft_window.py   2008-08-06 
00:15:23 UTC (rev 9176)
+++ gnuradio/branches/features/experimental-gui/fft_window.py   2008-08-06 
02:32:05 UTC (rev 9177)
@@ -203,7 +203,7 @@
                num_samps = len(samples)
                #reorder fft
                if self.real: samples = samples[:num_samps/2]
-               else: samples = numpy.concatenate((samples[num_samps/2+1:], 
samples[:num_samps/2]))
+               else: samples = numpy.concatenate((samples[num_samps/2:], 
samples[:num_samps/2]))
                #peak hold calculation
                if self[PEAK_HOLD_KEY]:
                        if len(self.peak_vals) != len(samples): self.peak_vals 
= samples

Modified: gnuradio/branches/features/experimental-gui/grc_waterfallsink_test.py
===================================================================
--- gnuradio/branches/features/experimental-gui/grc_waterfallsink_test.py       
2008-08-06 00:15:23 UTC (rev 9176)
+++ gnuradio/branches/features/experimental-gui/grc_waterfallsink_test.py       
2008-08-06 02:32:05 UTC (rev 9177)
@@ -80,7 +80,7 @@
                        dynamic_range=40,
                        ref_level=-20,
                        sample_rate=samp_rate,
-                       fft_size=512,
+                       fft_size=1024,
                        frame_rate=7,
                        average=False,
                        avg_alpha=None,

Modified: 
gnuradio/branches/features/experimental-gui/plotter/waterfall_plotter.py
===================================================================
--- gnuradio/branches/features/experimental-gui/plotter/waterfall_plotter.py    
2008-08-06 00:15:23 UTC (rev 9176)
+++ gnuradio/branches/features/experimental-gui/plotter/waterfall_plotter.py    
2008-08-06 02:32:05 UTC (rev 9177)
@@ -92,7 +92,8 @@
                self._minimum = 0
                self._maximum = 0
                self._fft_size = 0
-               self._buffer = ''
+               self._buffer = list()
+               self._pointer = 0
                self._counter = 0
                self.set_num_lines(0)
                self.set_color_mode(COLORS.keys()[0])
@@ -102,6 +103,7 @@
                Run gl initialization tasks.
                """
                self._grid_compiled_list_id = glGenLists(1)
+               self._waterfall_texture = glGenTextures(1)
 
        def draw(self):
                """!
@@ -118,27 +120,53 @@
                self.clear()
                #draw the grid
                glCallList(self._grid_compiled_list_id)
-               if self._buffer:
-                       #use scissor to prevent drawing outside grid
-                       glEnable(GL_SCISSOR_TEST)
-                       glScissor(
-                               self.padding_left+1,
-                               self.padding_bottom+1,
-                               
self.width-self.padding_left-self.padding_right-1,
-                               
self.height-self.padding_top-self.padding_bottom-1,
-                       )
-                       #draw the waterfall
-                       glPixelZoom(
-                               
float(self.width-self.padding_left-self.padding_right)/self._fft_size,
-                               
float(self.height-self.padding_top-self.padding_bottom+1)/self._num_lines,
-                       )
-                       glRasterPos2f(self.padding_left+1, 
self.height-self.padding_bottom-1)
-                       glDrawPixels(self._fft_size, self._num_lines, GL_RGBA, 
GL_UNSIGNED_BYTE, self._buffer)
-                       glDisable(GL_SCISSOR_TEST)
+               self._draw_waterfall()
                #swap buffer into display
                self.SwapBuffers()
                self.semaphore.release()
 
+       def _draw_waterfall(self):
+               """!
+               Draw the waterfall from the texture.
+               The texture is circularly filled and will wrap around.
+               Use matrix modeling to shift and scale the texture onto the 
coordinate plane.
+               """
+               #setup texture
+               glBindTexture(GL_TEXTURE_2D, self._waterfall_texture)
+               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
+               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
+               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
+               glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE)
+               #write the buffer to the texture
+               while self._buffer:
+                       glTexSubImage2D(GL_TEXTURE_2D, 0, 0, self._pointer, 
self._fft_size, 1, GL_RGBA, GL_UNSIGNED_BYTE, self._buffer.pop(0))
+                       self._pointer = (self._pointer + 1)%self._num_lines
+               #begin drawing
+               glEnable(GL_TEXTURE_2D)
+               glPushMatrix()
+               #matrix scaling
+               glTranslatef(self.padding_left+1, self.padding_top, 0)
+               glScalef(
+                       
float(self.width-self.padding_left-self.padding_right-1),
+                       
float(self.height-self.padding_top-self.padding_bottom-1),
+                       1.0,
+               )
+               #draw texture in 2 pieces
+               glBegin(GL_QUADS)
+               prop = float(self._pointer)/(self._num_lines-1)
+               off = 1.0/(self._num_lines-1)
+               glTexCoord2f(0, prop+1-off)
+               glVertex2f(0, 1)
+               glTexCoord2f(1, prop+1-off)
+               glVertex2f(1, 1)
+               glTexCoord2f(1, prop)
+               glVertex2f(1, 0)
+               glTexCoord2f(0, prop)
+               glVertex2f(0, 0)
+               glEnd()
+               glPopMatrix()
+               glDisable(GL_TEXTURE_2D)
+
        def _draw_legend(self):
                """!
                Draw the color scale legend.
@@ -171,7 +199,12 @@
                Resize the buffer to fit the fft_size X num_lines.
                If the buffer is too large, set samples will auto shrink.
                """
-               self._buffer = self._buffer + 
numpy.zeros(self._num_lines*self._fft_size*4, numpy.uint8).tostring()
+               self._buffer = list()
+               self._pointer = 0
+               if self._num_lines and self._fft_size:
+                       glBindTexture(GL_TEXTURE_2D, self._waterfall_texture)
+                       data = numpy.zeros(self._num_lines*self._fft_size*4, 
numpy.uint8).tostring()
+                       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, self._fft_size, 
self._num_lines, 0, GL_RGBA, GL_UNSIGNED_BYTE, data)
 
        def set_color_mode(self, color_mode):
                """!
@@ -213,7 +246,7 @@
                        self.changed(True)
                if self._fft_size != len(samples):
                        self._fft_size = len(samples)
-                       self._buffer = '' #empty buffer before resize
+                       self._buffer = list() #empty buffer before resize
                        self._resize_buffer()
                #normalize the samples to min/max
                samples = (samples - minimum)*float(255/(maximum-minimum))
@@ -221,8 +254,5 @@
                samples = numpy.array(samples, numpy.uint8)
                #convert the samples to RGBA data
                data = numpy.choose(samples, 
COLORS[self._color_mode]).tostring()
-               self._buffer = (data + 
self._buffer)[:self._num_lines*self._fft_size*4]
-               #selective update, dont update for sub-pixel counts
-               if self._counter == 0: self.update()
-               self._counter = (self._counter + 1)%max(2, 
2*self._num_lines/self.height)
+               self._buffer.append(data)
                self.semaphore.release()

Modified: gnuradio/branches/features/experimental-gui/waterfall_window.py
===================================================================
--- gnuradio/branches/features/experimental-gui/waterfall_window.py     
2008-08-06 00:15:23 UTC (rev 9176)
+++ gnuradio/branches/features/experimental-gui/waterfall_window.py     
2008-08-06 02:32:05 UTC (rev 9177)
@@ -35,7 +35,7 @@
 SLIDER_STEPS = 100
 AVG_ALPHA_MIN_EXP, AVG_ALPHA_MAX_EXP = -3, 0
 DEFAULT_FRAME_RATE = 30
-DEFAULT_WIN_SIZE = (600, 300)
+DEFAULT_WIN_SIZE = (600, 400)
 DIV_LEVELS = (1, 2, 5, 10, 20)
 MIN_NUM_LINES, MAX_NUM_LINES = 10, 1000
 MIN_DYNAMIC_RANGE, MAX_DYNAMIC_RANGE = 10, 200
@@ -214,13 +214,15 @@
                num_samps = len(samples)
                #reorder fft
                if self.real: samples = samples[:num_samps/2]
-               else: samples = numpy.concatenate((samples[num_samps/2+1:], 
samples[:num_samps/2]))
+               else: samples = numpy.concatenate((samples[num_samps/2:], 
samples[:num_samps/2]))
                #plot the fft
                self.plotter.set_samples(
                        samples=samples,
                        minimum=self[REF_LEVEL_KEY], 
                        maximum=self[DYNAMIC_RANGE_KEY] + self[REF_LEVEL_KEY],
                )
+               #update the plotter
+               self.plotter.update()
 
        def update_grid(self, *args):
                """!





reply via email to

[Prev in Thread] Current Thread [Next in Thread]