#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# generated by wxGlade 0.3.5.1 on Wed Sep  7 14:04:24 2005
#
# Copyright 2005 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING.  If not, write to
# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
#


from gnuradio import gr
from gnuradio.wxgui import stdgui, fftsink, powermate
from gnuradio.wxgui import scopesink
import wx, math

ID_EXIT = wx.NewId()
ID_SLIDER_1 = wx.NewId()
ID_SLIDER_2 = wx.NewId()

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        # begin wxGlade: MyFrame.__init__
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        
        # Menu Bar
        self.frame_1_menubar = wx.MenuBar()
        self.SetMenuBar(self.frame_1_menubar)
        wxglade_tmp_menu = wx.Menu()
        wxglade_tmp_menu.Append(ID_EXIT, "Exit", "", wx.ITEM_NORMAL)
        self.frame_1_menubar.Append(wxglade_tmp_menu, "File")
        # Menu Bar end
        self.panel_1 = wx.Panel(self, -1)
        self.label_1 = wx.StaticText(self, -1, "Phase")
        self.label_2 = wx.StaticText(self, -1, "Measured Phase")
        self.slider_1 = wx.Slider(self, ID_SLIDER_1, 0, 0, 100, style=wx.SL_HORIZONTAL|wx.SL_LABELS)
        self.text_ctrl_1 = wx.TextCtrl(self, -1, "")
        self.label_3 = wx.StaticText(self, -1, "Amplitude")
        self.panel_2 = wx.Panel(self, -1)
        self.slider_2 = wx.Slider(self, ID_SLIDER_2, 0, 0, 100, style=wx.SL_HORIZONTAL|wx.SL_LABELS)
        self.panel_3 = wx.Panel(self, -1)

        self.__set_properties()
        self.__do_layout()
        # end wxGlade

        POWERMATE = True
        try:
            self.pm = powermate.powermate(self)
        except:
            POWERMATE = False

        if POWERMATE:
          powermate.EVT_POWERMATE_ROTATE(self, self.on_rotate)


	wx.EVT_MENU(self, ID_EXIT,  self.MenuExit)

	wx.EVT_SLIDER(self,ID_SLIDER_1,self.slider_phase)
	wx.EVT_SLIDER(self,ID_SLIDER_2,self.slider_amplitude)

	self.fg = gr.flow_graph()
        sample_freq = 1e6
        ampl = .1

        src0a = gr.sig_source_c (sample_freq, gr.GR_SIN_WAVE, 1e4, ampl)

        self.delay = 49
	self.slider_1.SetValue(self.delay)
	self.src1a = gr.multiply_const_cc(complex(-1,0))
        self.fg.connect (src0a, self.src1a)
	src0 = gr.complex_to_float()
	self.src1 = gr.complex_to_float()
	self.fg.connect(src0a,src0)
	self.fg.connect(self.src1a,self.src1)

	self.rot_ccw = complex(math.cos(math.pi/50),math.sin(math.pi/50))
	self.rot_cw = complex(math.cos(math.pi/50),math.sin(-math.pi/50))

	mul1 = gr.multiply_ff()
	self.meter = gr.signal_level2_ff()
	lp_taps = gr.firdes.low_pass ( 20, sample_freq, 1e4, 1e4, gr.firdes.WIN_HAMMING )
	lp = gr.fir_filter_fff(1,lp_taps)
	self.mul2 = gr.multiply_const_ff(2)
	self.slider_2.SetValue(50)

	# agc
	self.i_meter = gr.signal_level_ff(1,.001)
	self.o_meter = gr.signal_level_ff(1,.001)
	self.pga = gr.multiply_const_ff(1)


	self.fg.connect ( src0, self.i_meter )
	self.fg.connect ( self.i_meter, (mul1, 0) )
	self.fg.connect ( self.src1, self.mul2 )

        sink, win = scopesink.make_scope_sink_f (self, self.panel_1, "Rx Data", sample_freq)

	self.fg.connect (src0, (sink, 0))
	self.fg.connect (self.mul2, (sink, 1))
	self.fg.connect (self.mul2, self.o_meter)
	self.fg.connect (self.o_meter, self.pga)
	self.fg.connect (self.pga, (mul1, 1)) # x20 was here
	self.fg.connect (self.pga, (sink, 2))

	self.fg.connect (mul1, lp, self.meter, (sink, 3))

	self.fg.start()

	# start timer
        self.timer = UpdateTimer(self, 100) # every 100 mSec



    def __set_properties(self):
        # begin wxGlade: MyFrame.__set_properties
        self.SetTitle("Phase Lab")
        self.SetSize((680, 440))
        self.panel_1.SetSize((640, 240))
        self.slider_1.SetSize((200, 38))
        self.text_ctrl_1.SetSize((150, 25))
        self.slider_2.SetSize((200, 38))
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: MyFrame.__do_layout
        sizer_1 = wx.BoxSizer(wx.VERTICAL)
        grid_sizer_1 = wx.FlexGridSizer(2, 1, 0, 0)
        grid_sizer_2 = wx.FlexGridSizer(4, 2, 0, 0)
        grid_sizer_1.Add(self.panel_1, 1, wx.EXPAND, 0)
        grid_sizer_2.Add(self.label_1, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.FIXED_MINSIZE, 0)
        grid_sizer_2.Add(self.label_2, 0, wx.FIXED_MINSIZE, 0)
        grid_sizer_2.Add(self.slider_1, 0, wx.FIXED_MINSIZE, 0)
        grid_sizer_2.Add(self.text_ctrl_1, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL|wx.FIXED_MINSIZE, 0)
        grid_sizer_2.Add(self.label_3, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.FIXED_MINSIZE, 0)
        grid_sizer_2.Add(self.panel_2, 1, wx.EXPAND, 0)
        grid_sizer_2.Add(self.slider_2, 0, wx.FIXED_MINSIZE, 0)
        grid_sizer_2.Add(self.panel_3, 1, wx.EXPAND, 0)
        grid_sizer_1.Add(grid_sizer_2, 1, wx.EXPAND, 0)
        sizer_1.Add(grid_sizer_1, 1, wx.EXPAND, 0)
        self.SetAutoLayout(True)
        self.SetSizer(sizer_1)
        self.Layout()
        # end wxGlade

    def MenuExit(self, event):
        self.Close(True)

    def slider_phase(self, event):
	self.delay = self.slider_1.GetValue()
	self.set_phase()


    def slider_amplitude(self, event):
	self.mul2.set_k(self.slider_2.GetValue()/25.)

    def on_rotate(self, evt):
	self.delay = max(0, min(100, self.delay + evt.delta))
	self.delay = self.delay + evt.delta
	if self.delay <0 : self.delay = 99
	if self.delay > 100 : self.delay = 0
	self.slider_1.SetValue(self.delay)
	if evt.delta > 0:
	  self.src1a.set_k(self.src1a.k()*self.rot_ccw)
	else:
	  self.src1a.set_k(self.src1a.k()*self.rot_cw)

    def set_phase(self):
	accum = complex(1,0)
	for a in range(0,self.delay):
	   accum = accum * self.rot_ccw
        self.src1a.set_k(accum)

    def OnUpdate(self):
	self.text_ctrl_1.SetValue(str(self.meter.level()))
        in_level = self.i_meter.level()
        out_level = self.o_meter.level()
        if out_level > .000001 :
	   gain = math.sqrt(in_level/out_level)
           self.pga.set_k(gain)



# end of class MyFramei

# timer for output
class UpdateTimer(wx.Timer):
    def __init__(self, target, dur=1000):
        wx.Timer.__init__(self)
        self.target = target
        self.Start(dur)

    def Notify(self):
        """Called every timer interval"""
        if self.target:
            self.target.OnUpdate()


class MyApp(wx.App):
  def OnInit(self):
    frame = MyFrame(None, -1, "Phase Explorer")
    frame.Show(True)
    self.SetTopWindow(frame)
    return True

app = MyApp(0)
app.MainLoop()

