# uncompyle6 version 3.9.3 # Python bytecode version base 2.6 (62161) # Decompiled from: Python 3.9.25 (main, Oct 31 2025, 23:16:49) # [GCC 14.2.0] # Embedded file name: diagram.pyc # Compiled at: 2023-05-16 13:01:50 if __name__ == '__main__': import main main.run() import math, os.path, mytime, wx, MyOGLlike, svg_panel, protocol, data_model, traceback, one_unit, sys, wx.lib.buttons as buttons support_maximize_on_osx = True clip_gain = True fir_opts_text = {1: 'Currently active FIR filter (uncheck to reset FIR filter)', 2: 'High Pass Filter', 4: 'Low Pass Filter', 8: 'PEQ 1', 16: 'PEQ 2', 32: 'PEQ 3', 64: 'PEQ 4', 128: 'PEQ 5', 256: 'PEQ 6', 512: 'PEQ 7', 1024: 'PEQ 8', 2048: 'PEQ 9', 4096: 'PEQ 10', 8192: 'Track Changes', 16384: 'Invert RTA Measurement', 32768: 'Data from File'} fir_opts_keys = {1: 'Currently active FIR filter (uncheck to reset FIR filter)', 2: (data_model.Key(protocol.STRUCT_ID_HPF, protocol.MEMBER_ID_FREQ, -1, 0)), 4: (data_model.Key(protocol.STRUCT_ID_LPF, protocol.MEMBER_ID_FREQ, -1, 0)), 8: (data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_FREQ, -1, 0)), 16: (data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_FREQ, -1, 1)), 32: (data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_FREQ, -1, 2)), 64: (data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_FREQ, -1, 3)), 128: (data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_FREQ, -1, 4)), 256: (data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_FREQ, -1, 5)), 512: (data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_FREQ, -1, 6)), 1024: (data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_FREQ, -1, 7)), 2048: (data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_FREQ, -1, 8)), 4096: (data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_FREQ, -1, 9)), 8192: 'Track Changes', 16384: 'Invert RTA Measurement', 32768: 'Data from File'} fir_enable_keys = {1: 'Currently active FIR filter (uncheck to reset FIR filter)', 2: (data_model.Key(protocol.STRUCT_ID_HPF, protocol.MEMBER_ID_ON, -1, 0)), 4: (data_model.Key(protocol.STRUCT_ID_LPF, protocol.MEMBER_ID_ON, -1, 0)), 8: (data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_ON, -1, 0)), 16: (data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_ON, -1, 1)), 32: (data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_ON, -1, 2)), 64: (data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_ON, -1, 3)), 128: (data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_ON, -1, 4)), 256: (data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_ON, -1, 5)), 512: (data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_ON, -1, 6)), 1024: (data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_ON, -1, 7)), 2048: (data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_ON, -1, 8)), 4096: (data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_ON, -1, 9)), 8192: 'Track Changes', 16384: 'Invert RTA Measurement', 32768: 'Data from File'} import dialog, fir_dialog from scipy import signal import numpy as np, future def dependencies_for_myprogram(): from scipy.sparse.csgraph import _validation return ALPHA_LEVEL_PEQ = 50 ALPHA_LEVEL_XO = 50 FREQ_MIN = 10.0 FREQ_MAX = 20000.0 Q_MIN = 0.2 Q_MAX = 25.0 GAIN_MIN = -12.0 GAIN_MAX = 12.0 mac_names = 'posix' if os.name in mac_names: newline = '\n' else: newline = '\r\n' def dec2hex(n): """return the hexadecimal string representation of integer n""" return '%X' % n def hex2dec(s): """return the integer value of a hexadecimal string s""" return int(s, 16) class Diagram_canvas(MyOGLlike.ShapeCanvas): def __init__(self, parent, id=-1, pos=( -1, -1), size=( -1, -1), style=0, name='', max_freq=FREQ_MAX): MyOGLlike.ShapeCanvas.__init__(self, parent, id, pos, size, style, name) self.screen_style = 'normal' self.SetDiagram(MyOGLlike.ContainerBlock()) self.SetBackgroundColour(wx.BLACK) self.LastMove = mytime.clock() top_window = wx.GetApp().GetTopWindow() self.parent = parent self.win_width = 0 self.win_height = 0 self.UpdatingDiagram = False self.screen_style = None self.last_channel = None self.left_down = False self.muteTime = None self.max_freq = max_freq self.cursor = None self.need_to_draw_total_gain = False self.max_x = 0 self.rta_spline = None self.saved_rta_spline = {} self.show_data = False self.mouse_down = False self.rta_sum_spline = None self.set_arrow_cursor = False self.drag_point = None self.ctrl_down = False self.shift_down = False self.alt_down = False self.zoom = False self.event_counter = 0 self.link_key = None self.right_selected_node = None if one_unit.app.rta_enabled == True: self.fir_opts_mask = 65535 else: self.fir_opts_mask = 49151 self.timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.on_timer, self.timer) self.handling_drag = False if os.name not in mac_names: try: im = wx.Image(os.path.join(one_unit.app.bitmap_dir, 'ch.png'), wx.BITMAP_TYPE_PNG) im.SetOptionInt(wx.IMAGE_OPTION_CUR_HOTSPOT_X, 7) im.SetOptionInt(wx.IMAGE_OPTION_CUR_HOTSPOT_Y, 7) cursor = wx.CursorFromImage(im) except: print mytime.displayTime() + ' diagram.Could not load cursor image' cursor = wx.StockCursor(wx.CURSOR_CROSS) else: try: im = wx.Image(os.path.join(one_unit.app.bitmap_dir, 'h_cursor.png'), wx.BITMAP_TYPE_PNG) im.SetOptionInt(wx.IMAGE_OPTION_CUR_HOTSPOT_X, 7) im.SetOptionInt(wx.IMAGE_OPTION_CUR_HOTSPOT_Y, 7) h_cursor = wx.CursorFromImage(im) except: print mytime.displayTime() + ' diagram.Could not load cursor image' cursor = wx.StockCursor(wx.CURSOR_CROSS) else: try: im = wx.Image(os.path.join(one_unit.app.bitmap_dir, 'v_cursor.png'), wx.BITMAP_TYPE_PNG) im.SetOptionInt(wx.IMAGE_OPTION_CUR_HOTSPOT_X, 7) im.SetOptionInt(wx.IMAGE_OPTION_CUR_HOTSPOT_Y, 7) v_cursor = wx.CursorFromImage(im) except: print mytime.displayTime() + ' diagram.Could not load cursor image' cursor = wx.StockCursor(wx.CURSOR_CROSS) else: try: im = wx.Image(os.path.join(one_unit.app.bitmap_dir, 'dragging_cursor.png'), wx.BITMAP_TYPE_PNG) im.SetOptionInt(wx.IMAGE_OPTION_CUR_HOTSPOT_X, 7) im.SetOptionInt(wx.IMAGE_OPTION_CUR_HOTSPOT_Y, 7) dragging_cursor = wx.CursorFromImage(im) except: print mytime.displayTime() + ' diagram.Could not load cursor image' cursor = wx.StockCursor(wx.CURSOR_CROSS) else: try: im = wx.Image(os.path.join(one_unit.app.bitmap_dir, 'qc.png'), wx.BITMAP_TYPE_PNG) im.SetOptionInt(wx.IMAGE_OPTION_CUR_HOTSPOT_X, 7) im.SetOptionInt(wx.IMAGE_OPTION_CUR_HOTSPOT_Y, 7) q_cursor = wx.CursorFromImage(im) except: print mytime.displayTime() + ' diagram.Could not load cursor image' q_cursor = wx.StockCursor(wx.CURSOR_CROSS) else: cursor = wx.StockCursor(wx.CURSOR_CROSS) h_cursor = wx.StockCursor(wx.CURSOR_HAND) v_cursor = wx.StockCursor(wx.CURSOR_HAND) dragging_cursor = wx.StockCursor(wx.CURSOR_HAND) q_cursor = wx.StockCursor(wx.CURSOR_HAND) self.q_cursor = q_cursor self.cross_cursor = cursor self.v_cursor = v_cursor self.h_cursor = h_cursor self.dragging_cursor = dragging_cursor self.SetCursor(cursor) return def Refresh(self): if self.drag_point != None: return else: MyOGLlike.ShapeCanvas.Refresh(self) return def SetMinSize(self, size): self.win_width = size.GetWidth() - 50 self.win_height = size.GetHeight() MyOGLlike.ShapeCanvas.SetMinSize(self, size) self.timer.Start(50) return def OnSnapshot(self): import time releasetime = time.localtime() timestring = str(releasetime.tm_year) + '_' + str(releasetime.tm_mon) + '_' + str(releasetime.tm_mday) + '_' + str(releasetime.tm_hour) + '_' + str(releasetime.tm_min) + '_' + str(releasetime.tm_sec) self.SaveFile(one_unit.app.library_path, 'Graph_' + timestring + '.png') return def OnZoom(self): if self.zoom == False: self.zoom = True else: self.zoom = False self.bg_drawn = False self.Refresh() return def save_rta(self): import rta_measurements dial = rta_measurements.rtaDialog(self) dial.ShowModal() dial.Destroy() self.update_rta_spline(update_all=True) return def rta_settings(self): self.last_fft_len = one_unit.app.FFT_len import rta_measurements dial = rta_measurements.rtaDialog(self, settings=True) dial.ShowModal() dial.Destroy() self.initFIR() try: fft_scale = math.sqrt(1.0 * one_unit.app.FFT_len / (1.0 * self.last_fft_len)) except: fft_scale = 1.0 if self.last_fft_len != one_unit.app.FFT_len: for i in range(len(one_unit.app.rta_data)): if one_unit.app.rta_data[i][5] != None: if len(one_unit.app.rta_data[i][5]) > 1: one_unit.app.rta_data[i][5] = signal.resample(one_unit.app.rta_data[i][5], one_unit.app.FFT_len) for val in range(len(one_unit.app.rta_data[i][5])): one_unit.app.rta_data[i][5][val] *= fft_scale self.update_rta_spline(update_all=True) return def goToFullScreen(self): (width, height) = self.parent.display_buffer.GetSize() print 'Reset display buffer', width, height self.parent.display_buffer = wx.EmptyBitmap(width, height) self.Freeze() self.fs_diagram = PEQ_diagram(self.parent, self.config, self.section, self.name) self.fs_diagram.parent = self.parent self.fs_diagram.SetSize(self.parent.GetSize()) print 'd.gtfs.1', self.parent.GetSize() self.fs_diagram.SetPosition((0, 0)) self.fs_diagram.SetMinSize(self.parent.GetSize()) self.parent.last_control_state = {} for ctrl_name in self.parent.controls.keys(): (ctrl, key, var_name) = self.parent.controls[ctrl_name] try: self.parent.last_control_state[ctrl_name] = ctrl.IsShown() except: self.parent.last_control_state[ctrl_name] = True if ctrl_name == self.name: self.parent.controls[self.name + '_fs'] = ( self.fs_diagram, key, var_name) self.parent.control_types[self.name + '_fs'] = self.parent.control_types[self.name] ctrl.Show(False) self.fs_diagram.set_change_handler(self.parent.on_value_change) self.fs_diagram.name = self.name + '_fs' self.fs_diagram.Show(True) self.fs_diagram.screen_style = 'full' self.parent.full_screen_diagram = True self.Show(False) self.Thaw() print 'd.gtfs.x' return def goToMaximized(self): (width, height) = self.parent.display_buffer.GetSize() print 'Reset display buffer', width, height self.parent.display_buffer = wx.EmptyBitmap(width, height) self.Freeze() name = self.name[:-3] self.parent.last_size = self.parent.GetSize() self.parent.last_pos = self.parent.GetPosition() self.parent.parent.ShowFullScreen(True) self.parent.parent.menubar.Show(False) self.fs_diagram = PEQ_diagram(self.parent, self.config, self.section, name) self.fs_diagram.parent = self.parent self.parent.SetSize(self.parent.parent.GetSize()) self.fs_diagram.SetSize(self.parent.GetSize()) self.fs_diagram.SetMinSize(self.parent.GetSize()) self.fs_diagram.set_change_handler(self.parent.on_value_change) self.fs_diagram.name = self.name self.parent.SetPosition((0, 0)) self.fs_diagram.SetPosition((0, 0)) self.fs_diagram.Show(True) for ctrl_name in self.parent.controls.keys(): (ctrl, key, var_name) = self.parent.controls[ctrl_name] if ctrl_name == self.name: self.parent.controls[self.name] = ( self.fs_diagram, key, var_name) self.fs_diagram.screen_style = 'maximized' self.parent.full_screen_diagram = True self.parent.timer.Stop() self.parent.timer.Start(200) self.Destroy() return def returnFromFullScreen(self): (width, height) = self.parent.display_buffer.GetSize() print 'Reset display buffer', width, height self.parent.display_buffer = wx.EmptyBitmap(width, height) self.Freeze() for ctrl_name in self.parent.controls.keys(): (ctrl, key, var_name) = self.parent.controls[ctrl_name] if ctrl_name == self.name: del self.parent.controls[self.name] del self.parent.control_types[self.name] elif self.parent.last_control_state[ctrl_name] == True: ctrl.Show(True) self.parent.full_screen_diagram = False self.parent.svg_doc.set_element_render_all() self.parent.Refresh() self.Destroy() return def goToNormalScreen(self): (width, height) = self.parent.display_buffer.GetSize() print 'Reset display buffer', width, height self.parent.display_buffer = wx.EmptyBitmap(width, height) self.Freeze() self.parent.parent.ShowFullScreen(False) self.parent.SetSize(self.parent.last_size) self.parent.SetPosition(self.parent.last_pos) self.parent.parent.menubar.Show(True) for ctrl_name in self.parent.controls.keys(): (ctrl, key, var_name) = self.parent.controls[ctrl_name] if ctrl_name == self.name: del self.parent.controls[self.name] del self.parent.control_types[self.name] elif self.parent.last_control_state[ctrl_name] == True: ctrl.Show(True) self.Show(False) self.parent.full_screen_diagram = False self.parent.svg_doc.set_element_render_all() self.parent.Refresh() self.Destroy() return def OnLeftDown(self, event): self.SetFocus() self.ctrl_down = event.CmdDown() or event.ControlDown() self.shift_down = event.ShiftDown() self.alt_down = event.AltDown() x = event.GetX() y = event.GetY() bitmapdir = os.path.normpath(one_unit.app.cwd + '/bitmaps/') if self.screen_style == 'maximized': if x <= 24 and y <= 24: wx.CallAfter(self.goToNormalScreen) return if x <= 54 and y <= 24: if self.show_data == False: self.show_data = True else: self.show_data = False self.bg_drawn = False return if x <= 84 and y <= 24: self.OnSnapshot() return if x <= 114 and y <= 24: self.OnZoom() return if x <= 138 and y <= 24: if one_unit.app.rta_on == True: one_unit.app.rta_on = False else: one_unit.app.rta_on = True one_unit.app.rta_running = False self.bg_drawn = False return if x >= 15 and x <= 47 and y >= 30 and y < 62: if one_unit.app.rta_on == True: if one_unit.app.rta_running == True: one_unit.app.rta_running = False one_unit.app.last_rta_measurement_saved = False if one_unit.app.rta_auto_mute == True: self.mute() else: one_unit.app.rta_running = True if one_unit.app.rta_auto_mute == True: self.unmute() self.bg_drawn = False return elif x >= 49 and x <= 79 and y >= 30 and y < 62 and one_unit.app.rta_running == False: if one_unit.app.rta_on == True: self.save_rta() return elif x >= 85 and x <= 107 and y >= 30 and y < 62 and one_unit.app.rta_running == False: if one_unit.app.rta_on == True: self.rta_settings() return elif x >= self.max_x - 65 and x <= self.max_x - 4: if self.parent.FIR_enabled == True: if y >= 48 and y <= 64: self.ApplyFIR() elif y >= 30 and y <= 46: self.CalcFIR() return elif x >= self.max_x - 95 and x <= self.max_x - 65 and y <= 32: if self.parent.FIR_enabled == True: self.save_fir() return elif self.screen_style == 'full': if x <= 24 and y <= 24: wx.CallAfter(self.goToMaximized) return if x <= 54 and y <= 24: wx.CallAfter(self.returnFromFullScreen) return if x <= 84 and y <= 24: if self.show_data == False: self.show_data = True else: self.show_data = False self.bg_drawn = False return if x <= 114 and y <= 24: self.OnSnapshot() return if x <= 144 and y <= 24: self.OnZoom() return if x <= 174 and y <= 24: if one_unit.app.rta_on == True: one_unit.app.rta_on = False else: one_unit.app.rta_on = True one_unit.app.rta_running = False self.bg_drawn = False return if x >= 12 and x <= 44 and y >= 25 and y < 57: if one_unit.app.rta_on == True: if one_unit.app.rta_running == True: one_unit.app.rta_running = False one_unit.app.last_rta_measurement_saved = False if one_unit.app.rta_auto_mute == True: self.mute() else: one_unit.app.rta_running = True if one_unit.app.rta_auto_mute == True: self.unmute() self.bg_drawn = False return elif x >= 47 and x <= 79 and y >= 25 and y < 57 and one_unit.app.rta_running == False: if one_unit.app.rta_on == True: self.save_rta() return elif x >= 82 and x <= 114 and y >= 25 and y < 57 and one_unit.app.rta_running == False: if one_unit.app.rta_on == True: self.rta_settings() return elif x >= self.max_x - 65 and x <= self.max_x - 4: if self.parent.FIR_enabled == True: if y >= 40 and y <= 56: self.ApplyFIR() elif y >= 22 and y <= 38: self.CalcFIR() return elif x >= self.max_x - 95 and x <= self.max_x - 65 and y <= 32: if self.parent.FIR_enabled == True: self.save_fir() return elif self.screen_style == 'normal': if x <= 15 and y <= 15: if support_maximize_on_osx == False and os.name in mac_names: return print 'd.old.call after: Going to full screen' wx.CallAfter(self.goToFullScreen) return if x <= 15 and y <= 30: self.OnSnapshot() return if x <= 15 and y <= 45: self.OnZoom() return if x <= 15 and y <= 63: if self.show_data == False: self.show_data = True else: self.show_data = False self.bg_drawn = False return if x <= 15 and y <= 83: if one_unit.app.rta_on == True: one_unit.app.rta_on = False else: one_unit.app.rta_on = True one_unit.app.rta_running = False self.bg_drawn = False return if x >= 23 and x <= 55 and y >= 10 and y < 42: if one_unit.app.rta_on == True: if one_unit.app.rta_running == True: one_unit.app.rta_running = False one_unit.app.last_rta_measurement_saved = False if one_unit.app.rta_auto_mute == True: self.mute() else: one_unit.app.rta_running = True if one_unit.app.rta_auto_mute == True: self.unmute() self.bg_drawn = False return elif x >= 58 and x <= 90 and y >= 10 and y < 42 and one_unit.app.rta_running == False: if one_unit.app.rta_on == True: self.save_rta() return elif x >= 93 and x <= 125 and y >= 10 and y < 42 and one_unit.app.rta_running == False: if one_unit.app.rta_on == True: self.rta_settings() return elif x >= self.max_x - 36 and x <= self.max_x - 4: if self.parent.FIR_enabled == True: if y >= 25 and y <= 34: self.ApplyFIR() return if y >= 14 and y <= 23: self.CalcFIR() return elif x >= self.max_x - 56 and x <= self.max_x - 36 and y <= 22: if self.parent.FIR_enabled == True: self.save_fir() return if x > self.max_x + 5 and x < self.max_x + 21: if y > self.center_y - 22 and y < self.center_y - 6: self.y_top -= 6 if self.y_top < 3: self.y_top = 3 self.init_bg() self.bg_drawn = False self.Refresh() return if y > self.center_y + 6 and y < self.center_y + 22: self.y_top += 6 if self.y_top > 48: self.y_top = 48 self.init_bg() self.bg_drawn = False self.Refresh() return if y > self.min_y + 6 and y < self.min_y + 22: if self.y_range > 36: self.y_range -= 18 self.y_top -= 9 elif self.y_range > 6: self.y_range -= 6 self.y_top -= 3 if self.y_top < 3: self.y_top = 3 self.init_bg() self.bg_drawn = False self.Refresh() return if y > self.max_y - 22 and y < self.max_y - 6: if self.y_range >= 36: self.y_range += 18 self.y_top += 9 else: self.y_range += 6 self.y_top += 3 if self.y_range > 144: self.y_range = 144 if self.y_top > 48: self.y_top = 48 self.init_bg() self.bg_drawn = False self.Refresh() return hit_test = False for node in self.control_nodes: if self.control_nodes[node].HitTest(x, y) == True: hit_test = True else: self.mouse_down = True self.MyCurrentPoint = (x, y) if hit_test == True: self.mouse_down = False key = self.parent.key_with_current_channel(data_model.Key(0, 0, 0, 0)) if self.parent.access_granted(key) == False: return self.f_range = self.get_freq_range() self.update_all_splines() self.left_down = True self.Refresh() MyOGLlike.ShapeCanvas.OnLeftDown(self, event) return def muted(self): res = self.parent.parent.peers.units[self.parent.parent.active_unit.MAC].Muted return eval(res) def mute(self): self.parent.remote_link.MuteSingleUnit(self.parent.parent.active_unit.MAC, True) return def unmute(self): self.parent.remote_link.MuteSingleUnit(self.parent.parent.active_unit.MAC, False) return def OnLeftUp(self, event): self.left_down = False self.mouse_down = False if event != None: MyOGLlike.ShapeCanvas.OnLeftUp(self, event) for item in self.selectedShapes[:]: if isinstance(item, CenterNode): self.deselect(item) self.parent.editing_diagram = False self.right_selected_node = None self.selected_key = None if self.set_arrow_cursor == True: self.SetCursor(self.cross_cursor) self.set_arrow_cursor = False self.SetCursor(self.cross_cursor) self.update_all_splines() if one_unit.app.rta_on == True: self.update_rta_spline(True) self.bg_drawn = False self.Refresh() return def OnLeftDClick(self, event): x = event.GetX() y = event.GetY() for node in self.control_nodes: if self.control_nodes[node].HitTest(x, y) == True: self.control_nodes[node].OnLeftDClick() break return def OnRightDown(self, event): if isinstance(self, XV_diagram): return self.SetCursor(self.q_cursor) self.set_arrow_cursor = True self.alt_down = event.AltDown() key = self.parent.key_with_current_channel(data_model.Key(0, 0, 0, 0)) if self.parent.access_granted(key) == False: return item = self.getCurrentShape(event) if isinstance(item, CenterNode): self.right_selected_node = item item.set_start_q() if isinstance(item, MyOGLlike.ShapeEvtHandler): item.OnRightDown(event) return def OnRightUp(self, event): if isinstance(self, XV_diagram): return else: item = self.getCurrentShape(event) if isinstance(item, MyOGLlike.ShapeEvtHandler): item.OnRightUp(event) self.right_selected_node = None self.selected_key = None if self.set_arrow_cursor == True: self.SetCursor(self.cross_cursor) self.set_arrow_cursor = False self.update_all_splines() return def OnMove(self, event): MyOGLlike.ShapeCanvas.OnMove(self, event) return def OnMotion(self, event): x = event.GetX() y = event.GetY() if self.right_selected_node == None: if self.screen_style == 'normal': if one_unit.app.rta_enabled: max_y = 83 else: max_y = 63 if x <= 15 and y <= max_y or self.parent.FIR_enabled and (x >= self.max_x - 36 and x <= self.max_x - 4 and (y >= 25 and y <= 34 or y >= 14 and y <= 23) or x >= self.max_x - 60 and x < self.max_x - 36 and y < 22) or one_unit.app.rta_running == True and x < 55 and y < 40 or one_unit.app.rta_running == False and one_unit.app.rta_on == True and x < 120 and y < 40: cursor = wx.StockCursor(wx.CURSOR_ARROW) self.SetCursor(cursor) self.set_arrow_cursor = True else: self.SetCursor(self.cross_cursor) self.set_arrow_cursor = False elif self.screen_style == 'full': if one_unit.app.rta_enabled: max_x = 174 else: max_x = 144 if x <= max_x and y <= 24 or self.parent.FIR_enabled and (x >= self.max_x - 65 and x <= self.max_x - 4 and (y >= 40 and y <= 56 or y >= 22 and y <= 38) or x >= self.max_x - 93 and x < self.max_x - 65 and y < 32) or one_unit.app.rta_running == True and x < 45 and y < 65 and x > 10 or one_unit.app.rta_running == False and one_unit.app.rta_on == True and x < 115 and y < 65 and x > 10: cursor = wx.StockCursor(wx.CURSOR_ARROW) self.SetCursor(cursor) self.set_arrow_cursor = True else: self.SetCursor(self.cross_cursor) self.set_arrow_cursor = False elif self.screen_style == 'maximized': if one_unit.app.rta_enabled: max_x = 138 else: max_x = 114 if x <= max_x and y <= 24 or self.parent.FIR_enabled and (x >= self.max_x - 65 and x <= self.max_x - 4 and (y >= 48 and y <= 64 or y >= 30 and y <= 46) or x >= self.max_x - 91 and x < self.max_x - 63 and y <= 42 and y > 12) or one_unit.app.rta_running == True and x < 45 and y < 65 and x > 10 or one_unit.app.rta_running == False and one_unit.app.rta_on == True and x < 115 and y < 65 and x > 10: cursor = wx.StockCursor(wx.CURSOR_ARROW) self.SetCursor(cursor) self.set_arrow_cursor = True else: self.SetCursor(self.cross_cursor) self.set_arrow_cursor = False if self.set_arrow_cursor == False and self.left_down == False and self.right_selected_node == None: for node in self.control_nodes: if self.control_nodes[node].HitTest(x, y) == True: if self.ctrl_down == True: if self.cursor != 'h': self.SetCursor(self.h_cursor) self.cursor = 'h' break elif self.shift_down == True: if self.cursor != 'v': self.SetCursor(self.v_cursor) self.cursor = 'v' break elif self.cursor != 'd': self.SetCursor(self.dragging_cursor) self.cursor = 'd' break elif self.cursor != 'c': self.SetCursor(self.cross_cursor) self.cursor = 'c' if self.left_down == False: if self.right_selected_node == None: return else: self.right_selected_node.handle_Q_change(self.getEventCoordinates(event)) point = self.getEventCoordinates(event) self.drag_point = point self.timer.Stop() self.timer.Start(10) if self.handling_drag == False: self.on_timer(None) return def save_fir(self): print mytime.displayTime() + ' Saving FIR file...' wildcard = 'Text File (*.txt)|*.txt' path = None dlg = wx.FileDialog(self, message='Save as....', defaultDir=one_unit.app.library_path, defaultFile='', wildcard=wildcard, style=wx.SAVE | wx.CHANGE_DIR) if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() try: dlg.Destroy() except: pass if path == None: return else: one_unit.app.library_path = os.path.split(path)[0] print mytime.displayTime() + ' Set library path to', one_unit.app.library_path if path.endswith('.txt') == False: path += '.txt' firstring = 'FIR filter generated by ALLDSP ALLCONTROL software. Sample rate: ' + str(self.Fs) + 'Hz, ' + str(len(self.active_fir_taps)) + 'taps' + newline firfile = open(path, 'wb') firfile.write(firstring) for tap in self.active_fir_taps: firfile.write(str(tap) + newline) firfile.close() return def update_rta_spline(self, update_all=False): canvas = self try: canvas.DeleteShape(self.rta_spline) except: pass avg = None if one_unit.app.rta_data[1][5] != None: avg = one_unit.app.rta_scale if one_unit.app.rta_enabled == True and len(one_unit.app.rta_data[0][5]) != 0 and (one_unit.app.rta_data[0][3] == True or one_unit.app.rta_running == True or one_unit.app.last_rta_measurement_saved == False): (scaled_data, avg) = one_unit.app.resample_fft(one_unit.app.rta_data[0][5], self.f_range, avg, smoothing=one_unit.app.rta_smoothing) colour = '#bbbbbb' self.rta_spline = SplineShape(color=colour, pen_width=1, *canvas.screen_coord(self.f_range, scaled_data)) canvas.AppendShape(self.rta_spline) if update_all == False or len(one_unit.app.rta_data) == 2: if one_unit.app.rta_data[1][5] == None: one_unit.app.rta_scale = avg canvas.Refresh() return else: for i in range(0, len(one_unit.app.rta_data)): try: canvas.DeleteShape(self.saved_rta_spline[i]) except: pass try: canvas.DeleteShape(self.rta_sum_spline) except: pass one_unit.app.rta_data[1][5] = [ 0.0] * one_unit.app.FFT_len weight = [ 0.0] * one_unit.app.FFT_len freqstep = 48000.0 / one_unit.app.FFT_len / 2.0 for i in range(2, len(one_unit.app.rta_data)): try: if one_unit.app.rta_data[i][2] == True: for j in range(one_unit.app.FFT_len): freq = j * freqstep if freq >= one_unit.app.rta_data[i][6] and freq <= one_unit.app.rta_data[i][7]: one_unit.app.rta_data[1][5][j] += one_unit.app.rta_data[i][5][j] * one_unit.app.rta_data[i][0] weight[j] += one_unit.app.rta_data[i][0] except: pass first_val = None last_val = None f_low = None f_high = None startpos = 0 for j in range(one_unit.app.FFT_len): if weight[j] == 0: weight[j] = 10000.0 one_unit.app.rta_data[1][5][j] /= weight[j] if one_unit.app.rta_data[1][5][j] != 0: f_high = freqstep * j if first_val == None: if f_low == None: f_low = freqstep * j first_val = one_unit.app.rta_data[1][5][j] for k in range(startpos, j): one_unit.app.rta_data[1][5][k] = one_unit.app.rta_data[1][5][j] last_val = one_unit.app.rta_data[1][5][j] else: if first_val != None: startpos = j first_val = None if last_val != None: one_unit.app.rta_data[1][5][j] = last_val if f_low == None or f_high == None: print mytime.displayTime() + ' rta.Sum frequency range error' print first_val, last_val, f_low, f_high, one_unit.app.FFT_len, len(one_unit.app.rta_data[1][5]) return (scaled_sum_data, dummy) = one_unit.app.resample_fft(one_unit.app.rta_data[1][5], self.f_range, avg, smoothing=one_unit.app.rta_smoothing) frange = [] rdata = [] for j in range(len(self.f_range)): if self.f_range[j] > f_low and self.f_range[j] < f_high: frange.append(self.f_range[j]) rdata.append(scaled_sum_data[j]) if one_unit.app.rta_data[1][3] == True: self.rta_sum_spline = SplineShape(color=one_unit.app.rta_data[1][4], pen_width=1, *canvas.screen_coord(frange, rdata)) canvas.AppendShape(self.rta_sum_spline) for i in range(2, len(one_unit.app.rta_data)): (scaled_data, dummy) = one_unit.app.resample_fft(one_unit.app.rta_data[i][5], self.f_range, one_unit.app.rta_scale, smoothing=one_unit.app.rta_smoothing) frange = [] rdata = [] if one_unit.app.rta_data[i][2] == True and one_unit.app.rta_data[i][3] == True: for j in range(0, len(scaled_data)): if self.f_range[j] >= one_unit.app.rta_data[i][6] and self.f_range[j] <= one_unit.app.rta_data[i][7]: frange.append(self.f_range[j]) rdata.append(scaled_data[j]) self.saved_rta_spline[i] = SplineShape(color=one_unit.app.rta_data[i][4], pen_width=1, *canvas.screen_coord(frange, rdata)) canvas.AppendShape(self.saved_rta_spline[i]) self.bg_drawn = False canvas.Refresh() self.update_rta_spline(update_all=False) return def on_timer(self, evt): if self.parent.parent.current_view != self.parent: self.timer.Stop() self.timer.Start(2500) return else: if self.last_channel != self.parent.current_channel: self.update_rta_spline(update_all=True) self.last_channel = self.parent.current_channel if one_unit.app.rta_enabled == True and self.IsShown() == True and self.parent.IsShownOnScreen() == True: if one_unit.app.rta_on == True: if one_unit.app.rta_running == True and one_unit.app.rta_new_data == True: go = True if one_unit.app.rta_auto_mute == True: if self.muted() == True: self.unmute() if one_unit.app.rta_one_shot == True: go = False elif one_unit.app.rta_one_shot == True: avgtime = one_unit.app.rta_time_avg * float(one_unit.app.FFT_len) / float(self.Fs) if avgtime > 1: avgtime += 1 else: avgtime *= 2 if self.muteTime == None: self.muteTime = mytime.clock() one_unit.app.reset_rta_avg() print mytime.clock(), 'Recording', round(avgtime, 1), 'seconds of audio...' go = False elif mytime.clock() - self.muteTime < avgtime: go = False else: print mytime.clock(), 'Fetching RTA data...' if go: try: data = one_unit.app.getfft() one_unit.app.rta_new_data = False except: traceback.print_exc(file=sys.stdout) data = [0.0] * one_unit.app.FFT_len else: self.last_rta_update = mytime.clock() one_unit.app.rta_data[0][5] = data self.update_rta_spline() if one_unit.app.rta_one_shot == True: one_unit.app.rta_running = False self.bg_drawn = False self.Refresh() if one_unit.app.rta_auto_mute == True: self.mute() self.muteTime = None elif self.rta_spline != None: try: self.DeleteShape(self.rta_spline) except: pass else: self.rta_spline = None if self.need_to_draw_total_gain == True: self.add_spline(None, True) if self.parent.current_channel != None and self.parent.current_channel >= 0 and self.parent.parent.FIR_taps != None and self.parent.current_channel in self.parent.parent.FIR_taps and self.maxnumtaps != self.parent.parent.FIR_taps[self.parent.current_channel]: print 'd.ot.Setting maximum number of FIR taps to', self.parent.parent.FIR_taps[self.parent.current_channel], 'for channel', self.parent.current_channel fir_taps = self.parent.parent.FIR_taps if fir_taps == None: self.maxnumtaps = 0 self.bg_drawn = False self.Refresh() elif self.parent.current_channel in fir_taps: numtaps = fir_taps[self.parent.current_channel] if numtaps > 2: self.maxnumtaps = numtaps self.parent.FIR_enabled = True self.bg_drawn = False self.Refresh() else: self.maxnumtaps = 0 self.bg_drawn = False self.Refresh() else: self.maxnumtaps = 0 self.bg_drawn = False self.Refresh() if self.drag_point == None: self.timer.Stop() self.timer.Start(100) return self.handling_drag = True point = self.drag_point self.drag_point = None timestamp = mytime.clock() MyOGLlike.ShapeCanvas.OnDragCenterNode(self, point) self.handling_drag = False return def screen_coord(self, x_coords, y_coords): """Translate from logical coordinates (Hertz, gain in DB) to screen coords. The X axis is logarithmic.""" x_scale = self.win_width / (math.log(self.max_freq) - math.log(10)) x_offset = -x_scale * math.log(10) + 16 y_scale = -self.win_height / (self.y_range + self.y_division) y_screen_offset = self.win_height / 2.0 y_val_offset = self.y_top - 18 - (self.y_range / 2.0 - 18) res = [[_[1] for x in x_coords], [_[2] for y in y_coords]] return res def from_screen_coord(self, x, y): """Translate from screen to logical coordinates (Hertz, gain in DB) The X axis is logarithmic.""" x_scale = self.win_width / (math.log(self.max_freq) - math.log(10)) x_offset = -x_scale * math.log(10) + 16 y_scale = -self.win_height / (self.y_range + self.y_division) y_screen_offset = self.win_height / 2.0 y_val_offset = self.y_top - 18 - (self.y_range / 2.0 - 18) new_x = math.exp((x - x_offset) / x_scale) new_y = (y - y_screen_offset) / y_scale + y_val_offset return (new_x, new_y) def remove_spline(self, num): if not self.splines.has_key(num): return try: self.DeleteShape(self.splines[num]) del self.splines[num] except: pass return def remove_all_splines(self): for num in range(len(self.vals)): self.remove_spline(num) return def remove_center_node(self, num): try: self.DeleteShape(self.control_nodes[num]) del self.control_nodes[num] except: pass return def get_freq_range(self, acc=1.0, points=None): if points == None: points = self.win_width res = [] freq = FREQ_MIN if points < 1: points = 1 mult = pow(self.max_freq / FREQ_MIN, acc / float(points)) p = 0 while p < points: res.append(freq) freq *= mult p += 1 return res class SplineShape(MyOGLlike.Shape): def __init__(self, x=[], y=[], color='RED', pen_width=1, alpha=wx.ALPHA_OPAQUE, fill_ground=None): MyOGLlike.Shape.__init__(self, x, y) self.pen_width = pen_width self.alpha = alpha self.fill_ground = fill_ground if not isinstance(color, wx.Colour): color = wx.NamedColour(color) self.color = color r = color.Red() g = color.Green() b = color.Blue() alpha_color = wx.Colour(r, g, b, alpha) self.pen_color = color self.fill_color = alpha_color self.contour_pen = wx.Pen(self.pen_color, self.pen_width, wx.SOLID) self.brush = wx.Brush(self.fill_color, wx.SOLID) return def draw(self, dc): dc.SetPen(self.contour_pen) points = map((lambda x, y: (x, y)), self.x, self.y) try: dc.DrawLines(points) except: return else: if self.fill_ground is not None: dc.SetPen(wx.Pen(self.fill_color, 1, wx.SOLID)) dc.SetBrush(self.brush) points.insert(0, (self.x[0], self.fill_ground)) points.append((self.x[-1], self.fill_ground)) dc.DrawPolygon(points) return def SetPen(self, pen): self.contour_pen = pen return def HitTest(self, x, y): return False class CenterNode(MyOGLlike.PointShape): def __init__(self, key, peq_grid, x, y, size, shape, text, pos, line1='', line2='', line3='', enabled=True, readOnly=False): self.key = key self.peq_grid = peq_grid MyOGLlike.PointShape.__init__(self, x, y, size, shape, text, pos, line1=line1, line2=line2, line3=line3, enabled=enabled, readOnly=readOnly) alpha_color = wx.Colour(0, 0, 0, 100) self.fill_color = alpha_color self.brush = wx.Brush(self.fill_color, wx.TRANSPARENT) return def move(self, x, y): MyOGLlike.PointShape.move(self, x, y) if self.peq_grid is not None: self.peq_grid.handle_center_change(self.key, self.x[0], self.y[0]) return def OnLeftUp(self, event): return def OnLeftDown(self, event): if self.peq_grid is not None: self.peq_grid.on_left_down(self.key) return def OnLeftDClick(self): if self.peq_grid is not None: self.peq_grid.on_left_dclick(self.key) return def OnRightDown(self, event): if self.peq_grid is not None: self.peq_grid.on_right_down(self.key) return def handle_center_change(self, x, y): self.x = [ x] self.y = [y] if self.peq_grid is not None: self.peq_grid.handle_center_change(self.key, self.x[0], self.y[0]) return def handle_Q_change(self, pos): if self.peq_grid is not None: self.peq_grid.handle_Q_change(self.key, pos[0], pos[1]) return def set_start_q(self): if self.peq_grid is not None: self.peq_grid.set_start_q(self.key) return class Grid(MyOGLlike.Shape): def __init__(self, canvas): MyOGLlike.Shape.__init__(self) self.max_freq = FREQ_MAX self.canvas = canvas self.thick_x_lines = (10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000) self.x_notches = ('10', '20', '50', '100', '200', '500', '1k', '2k', '5k', '10k', '20k') self.canvas.y_range = 36.0 self.canvas.y_top = 18.0 self.canvas.init_bg = self.init_bg self.init_bg() return def init_bg(self): self.canvas.y_division = self.canvas.y_range / 6.0 self.thick_y_lines = range(int(self.canvas.y_top - self.canvas.y_range), int(self.canvas.y_top + self.canvas.y_division), int(self.canvas.y_division)) self.y_notches = [_[1] for y in self.thick_y_lines] self.line_color = '#333333' self.thick_line_color = '#444444' self.text_color = '#999999' self.thin_line_pen = wx.Pen(self.line_color, 1, wx.DOT) self.medium_line_pen = wx.Pen(self.line_color, 1, wx.SOLID) self.thick_line_pen = wx.Pen(self.thick_line_color, 1, wx.SOLID) x_lines = range(10, 100, 10) + range(100, 1000, 100) + range(1000, 10000, 1000) + range(10000, 30000, 10000) y_lines = range(int(self.canvas.y_top - self.canvas.y_range), int(self.canvas.y_top + 1)) (self.x_lines, self.y_lines) = self.canvas.screen_coord(x_lines, y_lines) (self.thick_x_coord, self.thick_y_coord) = self.canvas.screen_coord(self.thick_x_lines, self.thick_y_lines) self.name = 'bg' self.bg_drawn = False return def draw(self, dc): thick_x_lines = [] for l in self.thick_x_lines: if l <= self.max_freq: thick_x_lines.append(l) self.thick_x_lines = thick_x_lines (self.thick_x_coord, self.thick_y_coord) = self.canvas.screen_coord(self.thick_x_lines, self.thick_y_lines) min_x = self.x_lines[0] max_x = self.x_lines[-1] self.canvas.max_x = max_x min_y = self.y_lines[-1] max_y = self.y_lines[0] self.canvas.min_y = min_y self.canvas.max_y = max_y self.canvas.center_y = self.y_lines[len(self.y_lines) / 2] dc.SetTextForeground(self.text_color) dc.SetTextBackground(wx.BLACK) self.scale = self.max_freq / self.thick_x_coord[-1] try: font = one_unit.app.font dc.SetFont(font) except: pass for x in self.x_lines: if self.scale * x > self.max_freq: break max_x = x if x in self.thick_x_coord: text = self.x_notches[self.thick_x_coord.index(x)] (w, h) = dc.GetTextExtent(text) dc.DrawText(text, x - w / 2, max_y + 3) dc.SetPen(self.thick_line_pen) else: dc.SetPen(self.thin_line_pen) dc.DrawLine(x, min_y, x, max_y + 2) for y in self.y_lines: if y in self.thick_y_coord: text = self.y_notches[self.thick_y_coord.index(y)] (w, h) = dc.GetTextExtent(text) dc.DrawText(text, max_x + 5, y - h / 2) dc.SetPen(self.thick_line_pen) else: dc.SetPen(self.thin_line_pen) dc.DrawLine(min_x, y, max_x + 2, y) bitmapdir = os.path.normpath(one_unit.app.cwd + '/bitmaps/') if self.canvas.screen_style == 'full': img = wx.Bitmap(os.path.join(bitmapdir, 'full_screen_large.png')) dc.DrawBitmap(img, 0, 0) img = wx.Bitmap(os.path.join(bitmapdir, 'full_screen_close.png')) dc.DrawBitmap(img, 30, 0) if self.canvas.show_data == False: img = wx.Bitmap(os.path.join(bitmapdir, 'text_button.png')) else: img = wx.Bitmap(os.path.join(bitmapdir, 'text_button_on.png')) dc.DrawBitmap(img, 60, 4) img = wx.Bitmap(os.path.join(bitmapdir, 'snapshot.png')) dc.DrawBitmap(img, 90, 0) if self.canvas.zoom == False: img = wx.Bitmap(os.path.join(bitmapdir, 'zoom_off.png')) else: img = wx.Bitmap(os.path.join(bitmapdir, 'zoom_on.png')) dc.DrawBitmap(img, 120, 0) if one_unit.app.rta_enabled == True: if one_unit.app.rta_on == True: img = wx.Bitmap(os.path.join(bitmapdir, 'RTA2.png')) dc.DrawBitmap(img, 150, 4) if one_unit.app.rta_running == True: img = wx.Bitmap(os.path.join(bitmapdir, 'pause_grey.png')) dc.DrawBitmap(img, 15, 30) else: img = wx.Bitmap(os.path.join(bitmapdir, 'play_grey.png')) dc.DrawBitmap(img, 15, 30) if one_unit.app.rta_data[0][5] != None: img = wx.Bitmap(os.path.join(bitmapdir, 'save.png')) dc.DrawBitmap(img, 50, 30) img = wx.Bitmap(os.path.join(bitmapdir, 'settings.png')) dc.DrawBitmap(img, 85, 30) else: img = wx.Bitmap(os.path.join(bitmapdir, 'RTA2_off.png')) dc.DrawBitmap(img, 150, 4) if self.canvas.parent.FIR_enabled == True and self.canvas.maxnumtaps > 0: img = wx.Bitmap(os.path.join(bitmapdir, 'FIR_window.png')) dc.DrawBitmap(img, max_x - 65, 3) img = wx.Bitmap(os.path.join(bitmapdir, 'save.png')) dc.DrawBitmap(img, max_x - 95, 1) elif self.canvas.screen_style == 'maximized': img = wx.Bitmap(os.path.join(bitmapdir, 'full_screen_close.png')) dc.DrawBitmap(img, 0, 0) if self.canvas.show_data == False: img = wx.Bitmap(os.path.join(bitmapdir, 'text_button.png')) else: img = wx.Bitmap(os.path.join(bitmapdir, 'text_button_on.png')) dc.DrawBitmap(img, 30, 4) img = wx.Bitmap(os.path.join(bitmapdir, 'snapshot.png')) dc.DrawBitmap(img, 60, 0) if self.canvas.zoom == False: img = wx.Bitmap(os.path.join(bitmapdir, 'zoom_off.png')) else: img = wx.Bitmap(os.path.join(bitmapdir, 'zoom_on.png')) dc.DrawBitmap(img, 90, 0) if one_unit.app.rta_enabled == True: if one_unit.app.rta_on == True: img = wx.Bitmap(os.path.join(bitmapdir, 'RTA2.png')) dc.DrawBitmap(img, 120, 3) if one_unit.app.rta_running == True: img = wx.Bitmap(os.path.join(bitmapdir, 'pause_grey.png')) dc.DrawBitmap(img, 12, 25) else: img = wx.Bitmap(os.path.join(bitmapdir, 'play_grey.png')) dc.DrawBitmap(img, 12, 25) if one_unit.app.rta_data[0][5] != None: img = wx.Bitmap(os.path.join(bitmapdir, 'save.png')) dc.DrawBitmap(img, 47, 25) img = wx.Bitmap(os.path.join(bitmapdir, 'settings.png')) dc.DrawBitmap(img, 82, 25) else: img = wx.Bitmap(os.path.join(bitmapdir, 'RTA2_off.png')) dc.DrawBitmap(img, 120, 3) margin = 4 top = self.thick_y_coord[-1] + margin left = self.thick_x_coord[0] + margin if len(one_unit.app.rta_data) > 2: dc.SetBrush(wx.Brush('black', wx.SOLID)) dc.SetPen(wx.Pen('black', style=wx.TRANSPARENT)) for i in range(0, len(one_unit.app.rta_data)): if one_unit.app.rta_data[i][2] == True and one_unit.app.rta_data[i][3] == True: dc.DrawRectangle(left - margin + 1, top - margin + 1, self.thick_x_coord[1] - self.thick_x_coord[0] - 1, 20 + margin) dc.SetTextForeground(one_unit.app.rta_data[i][4]) dc.DrawText(one_unit.app.rta_data[i][1], left, top) top += 20 dc.SetTextForeground(self.text_color) if self.canvas.parent.FIR_enabled == True: img = wx.Bitmap(os.path.join(bitmapdir, 'FIR_window.png')) dc.DrawBitmap(img, max_x - 62, 15) img = wx.Bitmap(os.path.join(bitmapdir, 'save.png')) dc.DrawBitmap(img, max_x - 92, 13) elif support_maximize_on_osx == True or os.name not in mac_names: img = wx.Bitmap(os.path.join(bitmapdir, 'full_screen_small.png')) dc.DrawBitmap(img, 0, 0) img = wx.Bitmap(os.path.join(bitmapdir, 'snapshot_small.png')) dc.DrawBitmap(img, 0, 15) if self.canvas.zoom == False: img = wx.Bitmap(os.path.join(bitmapdir, 'zoom_off_small.png')) else: img = wx.Bitmap(os.path.join(bitmapdir, 'zoom_on_small.png')) dc.DrawBitmap(img, 0, 30) if self.canvas.show_data == False: img = wx.Bitmap(os.path.join(bitmapdir, 'text_button_small.png')) else: img = wx.Bitmap(os.path.join(bitmapdir, 'text_button_on_small.png')) dc.DrawBitmap(img, 1, 50) if one_unit.app.rta_enabled == True: if one_unit.app.rta_on == True: img = wx.Bitmap(os.path.join(bitmapdir, 'RTA2_small.png')) dc.DrawBitmap(img, 1, 70) if one_unit.app.rta_running == True: img = wx.Bitmap(os.path.join(bitmapdir, 'pause_grey.png')) dc.DrawBitmap(img, 23, 10) else: img = wx.Bitmap(os.path.join(bitmapdir, 'play_grey.png')) dc.DrawBitmap(img, 23, 10) if one_unit.app.rta_data[0][5] != None: img = wx.Bitmap(os.path.join(bitmapdir, 'save.png')) dc.DrawBitmap(img, 58, 10) img = wx.Bitmap(os.path.join(bitmapdir, 'settings.png')) dc.DrawBitmap(img, 93, 10) else: img = wx.Bitmap(os.path.join(bitmapdir, 'RTA2_small_off.png')) dc.DrawBitmap(img, 1, 70) if self.canvas.parent.FIR_enabled == True: img = wx.Bitmap(os.path.join(bitmapdir, 'FIR_window_small.png')) dc.DrawBitmap(img, max_x - 42, 2) img = wx.Bitmap(os.path.join(bitmapdir, 'save_small.png')) dc.DrawBitmap(img, max_x - 62, 1) img = wx.Bitmap(os.path.join(bitmapdir, 'arrow_up.png')) dc.DrawBitmap(img, max_x + 5, self.thick_y_coord[-1] + 6) img = wx.Bitmap(os.path.join(bitmapdir, 'arrow_down.png')) dc.DrawBitmap(img, max_x + 5, self.thick_y_coord[0] - 22) img = wx.Bitmap(os.path.join(bitmapdir, 'arrow_up.png')) dc.DrawBitmap(img, max_x + 5, self.thick_y_coord[3] - 18) img = wx.Bitmap(os.path.join(bitmapdir, 'arrow_down.png')) dc.DrawBitmap(img, max_x + 5, self.thick_y_coord[3] + 2) return def onFullScreen(self, e): print mytime.displayTime() + ' Full screen' return def HitTest(self, x, y): return False class XO_Grid(MyOGLlike.Shape): def __init__(self, canvas): MyOGLlike.Shape.__init__(self) self.canvas = canvas self.thick_x_lines = (10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000) self.x_notches = ('10', '20', '50', '100', '200', '500', '1k', '2k', '5k', '10k', '20k') self.canvas.init_bg = self.init_bg self.canvas.y_range = 60.0 self.canvas.y_top = 10.0 self.init_bg() return def init_bg(self): self.canvas.y_division = self.canvas.y_range / 6.0 self.thick_y_lines = range(int(self.canvas.y_top - self.canvas.y_range), int(self.canvas.y_top + self.canvas.y_division), int(self.canvas.y_division)) self.y_notches = [_[1] for y in self.thick_y_lines] self.line_color = '#333333' self.thick_line_color = '#444444' self.text_color = '#999999' self.thin_line_pen = wx.Pen(self.line_color, 1, wx.DOT) self.medium_line_pen = wx.Pen(self.line_color, 1, wx.SOLID) self.thick_line_pen = wx.Pen(self.thick_line_color, 1, wx.SOLID) x_lines = range(10, 100, 10) + range(100, 1000, 100) + range(1000, 10000, 1000) + range(10000, 30000, 10000) y_lines = range(int(self.canvas.y_top - self.canvas.y_range), int(self.canvas.y_top + 1)) (self.x_lines, self.y_lines) = self.canvas.screen_coord(x_lines, y_lines) (self.thick_x_coord, self.thick_y_coord) = self.canvas.screen_coord(self.thick_x_lines, self.thick_y_lines) self.name = 'bg' return def draw(self, dc): min_x = self.x_lines[0] max_x = self.x_lines[-1] min_y = self.y_lines[-1] max_y = self.y_lines[0] self.canvas.max_x = max_x self.canvas.min_y = min_y self.canvas.max_y = max_y self.canvas.center_y = self.y_lines[len(self.y_lines) / 2] dc.SetTextForeground(self.text_color) dc.SetTextBackground(wx.WHITE) try: font = one_unit.app.font dc.SetFont(font) except: pass for x in self.x_lines: if x in self.thick_x_coord: text = self.x_notches[self.thick_x_coord.index(x)] (w, h) = dc.GetTextExtent(text) dc.DrawText(text, x - w / 2, max_y + 3) dc.SetPen(self.thick_line_pen) else: dc.SetPen(self.thin_line_pen) dc.DrawLine(x, min_y, x, max_y + 2) for y in self.y_lines: if y in self.thick_y_coord: text = self.y_notches[self.thick_y_coord.index(y)] (w, h) = dc.GetTextExtent(text) dc.DrawText(text, max_x + 5, y - h / 2) dc.SetPen(self.thick_line_pen) else: dc.SetPen(self.thin_line_pen) dc.DrawLine(min_x, y, max_x + 2, y) return def HitTest(self, x, y): return False PEQ_COLORS = ( ( 255, 182, 193), 'orange', 'yellow', 'green', 'cyan', 'blue', 'magenta', (255, 69, 0), 'gold', (144, 255, 144), ( 110, 110, 110), (110, 110, 110), (110, 110, 110), (110, 110, 110), (110, 110, 110)) sum_colours = {0: '#BBBBFF', 1: '#BBFFBB'} class PEQ_diagram(Diagram_canvas, svg_panel.SVG_control): def __init__(self, parent, config, section, name='diagram', id=-1, pos=(-1, -1), size=(-1, -1), style=0, max_freq=FREQ_MAX): """Contructor""" Diagram_canvas.__init__(self, parent, id, pos, size, style, name) svg_panel.SVG_control.__init__(self, name) self.config = config self.section = section self.max_freq = max_freq var_names = config.get(section, name + '_values') var_names = [_[1] for s in var_names.split(',')] self.channels = [] self.peq_colours = PEQ_COLORS try: self.peq_colours = eval(config.get(section, 'peq_colours')) except: pass try: self.hideHPF = eval(config.get(section, 'hideHPF')) except: self.hideHPF = False try: self.hideLPF = eval(config.get(section, 'hideLPF')) except: self.hideLPF = False self.selected_key = None self.freqs = {} self.fir_file = '' self.last_rta_update = 0 self.parent = parent self.fir_skiplist = [] self.track_changes = True self.parent.numtaps = None try: self.calc_fir_options = self.parent.calc_fir_options self.apply_fir_options = self.parent.apply_fir_options skiplist = [] for i in range(len(fir_opts_keys)): mask = 1 << i if self.calc_fir_options & mask == 0: skiplist.append(fir_opts_keys[mask]) self.fir_skiplist = skiplist if 'Track Changes' not in skiplist: print mytime.displayTime() + ' Tracking Changes' self.track_changes = True except: self.calc_fir_options = 0 self.apply_fir_options = 1 self.active_fir_taps = None self.qs = {} self.switches = {} self.maxnumtaps = 0 self.screen_style = 'normal' self.grid = Grid(self) self.grid.max_freq = self.max_freq self.gains = {} self.last_draw_total = 0 self.types = {} self.applyingFIR = False self.max_gains = {} self.min_gains = {} self.dirty = {} self.key_hpf_freq = {} self.key_hpf_shape = {} self.key_hpf_on = {} self.key_lpf_freq = {} self.key_lpf_shape = {} self.key_lpf_on = {} self.hpf_freq = {} self.hpf_shape = {} self.lpf_freq = {} self.lpf_shape = {} self.hpf_on = {} self.lpf_on = {} self.total_gain = {} self.sum_spline = {} self.active_fir_gain = {} self.calculated_fir_gain = {} self.active_fir_spline = {} self.calculated_fir_spline = {} self.f_range = self.get_freq_range() self.initFIR() self.splines = {} self.control_nodes = {} self.vals = {} self.parent.FIR_enabled = False for var in var_names: try: struct_id = config.getint(var, 'struct_id') member_id = config.getint(var, 'member_id') num = config.getint(var, 'num') val = config.getfloat(var, 'default_value') except: print 'd.pd.i.Failed to get data for variable', var traceback.print_exc(file=sys.stdout) continue try: channel = config.get(var, 'channel') x_pos = channel.find('x') + 1 if x_pos > 0: channel = hex2dec(channel) except: channel = -1 channel = int(channel) if channel not in self.channels: self.channels.append(channel) key = data_model.Key(struct_id, member_id, channel, num) if member_id == protocol.MEMBER_ID_FREQ and struct_id == protocol.STRUCT_ID_PEQ: self.freqs[key] = val self.vals[key] = [0.0] * len(self.f_range) channel = key.channel struct_id = key.struct_id num = key.num key = data_model.Key(struct_id, protocol.MEMBER_ID_ON, channel, num) self.switches[key] = 0 key = data_model.Key(struct_id, protocol.MEMBER_ID_Q, channel, num) self.qs[key] = 1 key = data_model.Key(struct_id, protocol.MEMBER_ID_GAIN, channel, num) self.gains[key] = 0 key = data_model.Key(struct_id, protocol.MEMBER_ID_TYPE, channel, num) self.types[key] = None if member_id == protocol.MEMBER_ID_GAIN and struct_id == protocol.STRUCT_ID_PEQ: my_max = config.getfloat(var, 'max_value') my_min = config.getfloat(var, 'min_value') self.max_gains[key] = my_max self.min_gains[key] = my_min else: continue for channel in self.channels: self.key_hpf_freq[channel] = data_model.Key(protocol.STRUCT_ID_HPF, protocol.MEMBER_ID_FREQ, channel, 0) self.key_hpf_shape[channel] = data_model.Key(protocol.STRUCT_ID_HPF, protocol.MEMBER_ID_TYPE, channel, 0) self.key_hpf_on[channel] = data_model.Key(protocol.STRUCT_ID_HPF, protocol.MEMBER_ID_ON, channel, 0) self.key_lpf_freq[channel] = data_model.Key(protocol.STRUCT_ID_LPF, protocol.MEMBER_ID_FREQ, channel, 0) self.key_lpf_shape[channel] = data_model.Key(protocol.STRUCT_ID_LPF, protocol.MEMBER_ID_TYPE, channel, 0) self.key_lpf_on[channel] = data_model.Key(protocol.STRUCT_ID_LPF, protocol.MEMBER_ID_ON, channel, 0) self.hpf_freq[channel] = 19 self.hpf_shape[channel] = 0 self.lpf_freq[channel] = 20001 self.lpf_shape[channel] = 0 self.hpf_on[channel] = True self.lpf_on[channel] = True self.total_gain[channel] = [ 0.0] * len(self.f_range) self.calculated_fir_gain[channel] = [0.0] * len(self.f_range) self.active_fir_gain[channel] = [0.0] * len(self.f_range) self.sum_spline[channel] = None self.active_fir_spline[channel] = None self.calculated_fir_spline[channel] = None self.calculated_fir_taps = [] if len(self.channels) > 1: self.link_key = data_model.Key(protocol.STRUCT_ID_LINK, protocol.MEMBER_ID_LINK, self.channels[0], self.channels[1] - self.channels[0] + 1) self.link = None self.Refresh() return def on_add(self, parent): self.parent = parent bb = parent.svg_doc.get_bb(self.name) if bb is None: print mytime.displayTime() + ' No diagram found in SVG' self.Show(False) return -1 else: self.x = bb.left * parent.svg_scale_x if os.name in mac_names: self.y = 15 - bb.bottom * parent.svg_scale_y self.width = (bb.right - bb.left) * parent.svg_scale_x self.height = (bb.bottom - bb.top) * parent.svg_scale_y else: self.y = bb.top * parent.svg_scale_y self.width = (bb.right - bb.left) * parent.svg_scale_x self.height = (bb.bottom - bb.top) * parent.svg_scale_y pos = wx.Point(self.x, self.y) size = wx.Size(self.width, self.height) self.SetSize(size) self.SetPosition(pos) self.SetMinSize(size) return 0 def SetMinSize(self, size): Diagram_canvas.SetMinSize(self, size) self.f_range = self.get_freq_range() self.splines = {} self.control_nodes = {} self.vals = {} for channel in self.channels: self.total_gain[channel] = [0.0] * len(self.f_range) self.active_fir_gain[channel] = [0.0] * len(self.f_range) self.calculated_fir_gain[channel] = [0.0] * len(self.f_range) self.sum_spline[channel] = None self.active_fir_spline[channel] = None self.calculated_fir_spline[channel] = None parent = self.GetParent() config = self.config self.parent = parent for key in self.freqs: new_key = parent.key_with_current_channel(key) val = self.parent.parent.model.get(new_key) if val is not None: self.freqs[key] = val self.grid = Grid(self) self.grid.max_freq = self.max_freq self.AddShape(self.grid) for key in self.freqs: self.add_spline(key) if len(self.freqs) > 0: self.update_spline(self.freqs.keys()[0]) self.update_rta_spline(update_all=True) return def on_left_down(self, key): skiplist = [] skiplist.append(key) self.calc_total_gain(skiplist) self.selected_key = key gain_key = data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_GAIN, key.channel, key.num) self.last_gain = self.gains[gain_key] freq_key = data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_FREQ, key.channel, key.num) self.last_freq = self.freqs[freq_key] return def on_left_dclick(self, key): switch_key = data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_ON, key.channel, key.num) if switch_key.channel < 0: switch_key = self.parent.key_with_current_channel(switch_key) switch = self.parent.parent.model.get(switch_key) if switch != None: if switch == True: self.parent.set_value(switch_key, False) else: self.parent.set_value(switch_key, True) return def on_right_down(self, key): skiplist = [] skiplist.append(key) self.calc_total_gain(skiplist) self.selected_key = key gain_key = data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_GAIN, key.channel, key.num) self.last_gain = self.gains[gain_key] q_key = data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_Q, key.channel, key.num) self.last_q = self.qs[q_key] return def HitTest(self, x, y): return False def add_spline(self, key, draw_total=False): if key != None: self.need_to_draw_total_gain = True if len(self.f_range) < 10: return canvas = self if key != None: f = self.freqs[data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_FREQ, key.channel, key.num)] q = self.qs[data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_Q, key.channel, key.num)] gain = self.gains[data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_GAIN, key.channel, key.num)] peq_type = self.types[data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_TYPE, key.channel, key.num)] if peq_type == None: peq_type = protocol.fBELL if f is None or q is None or gain is None or peq_type == None: return try: color = self.peq_colours[key.num] except: print mytime.displayTime() + ' Error: Colour index ', key.num, ' out of range, setting default colour (red)' color = 'red' self.vals[key] = [_[1] for x in self.f_range] fill_ground = int(canvas.screen_coord([FREQ_MIN], [0.0])[1][0]) switch = self.parent.parent.model.get(self.parent.key_with_current_channel(data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_ON, key.channel, key.num))) self.splines[key] = SplineShape(fill_ground=fill_ground, color=color, alpha=ALPHA_LEVEL_PEQ, pen_width=0, *canvas.screen_coord(self.f_range, self.vals[key])) if len(self.channels) > 1 and self.parent.is_locked_slave(key.channel): try: canvas.DeleteShape(self.sum_spline[key.channel]) canvas.DeleteShape(self.active_fir_spline[key.channel]) canvas.DeleteShape(self.calculated_fir_spline[key.channel]) except: pass return if (self.left_down == True or self.right_selected_node != None) and key != self.selected_key: return canvas.AppendShape(self.splines[key]) dragging = False if self.left_down == True or self.right_selected_node != None: dragging = True qtext = str(round(q, 1)) + 'Q' if peq_type in (protocol.fNOTCH, protocol.fAllpass, protocol.fHighPass, protocol.fLowPass, protocol.fBandPass): coords = canvas.screen_coord([f], [2]) pos = (2, -15) if peq_type == protocol.fNOTCH: gaintext = 'Notch' qtext = str(int(q * 10)) + 'Q' if peq_type == protocol.fHighPass: gaintext = 'High Pass' qtext = str(q / 10.0) + 'Q' if peq_type == protocol.fLowPass: gaintext = 'Low Pass' qtext = str(q / 10.0) + 'Q' if peq_type == protocol.fBandPass: gaintext = 'Band Pass' if peq_type == protocol.fAllpass: gaintext = 'AllPass' else: coords = canvas.screen_coord([f], [gain]) if gain < 0: pos = (2, 9) else: pos = (2, -15) gaintext = str(round(gain, 2)) + 'dB' if gain == 0: gaintext = '' if self.control_nodes.has_key(key) or key.num < 10: nodeID = str(key.num + 1) try: readOnly = not eval(self.config.get(self.parent.name, 'diagram_enabled')) except: readOnly = False else: nodeID = 'G' + str(key.num - 9) try: readOnly = not eval(self.config.get(self.parent.name, 'diagram_group_eq_enabled')) except: readOnly = True if (self.show_data == True or dragging == True) and gaintext != '': cn = CenterNode(key, self, coords[0][0], coords[1][0], 4, 'rect', nodeID, pos, line1=str(int(f)) + 'Hz', line2=qtext, line3=gaintext, enabled=switch, readOnly=readOnly) else: cn = CenterNode(key, self, coords[0][0], coords[1][0], 4, 'rect', nodeID, pos, readOnly=readOnly) self.control_nodes[key] = cn cn.pen = [color, 1] canvas.AppendShape(cn) elif self.show_data == True or dragging == True: if gaintext != '': self.control_nodes[key].moveto(coords[0][0], coords[1][0], pos, line1=str(int(f)) + 'Hz', line2=qtext, line3=gaintext, enabled=switch) else: self.control_nodes[key].moveto(coords[0][0], coords[1][0], pos) if draw_total == True: if key == None: key = data_model.Key(0, 0, self.channels[0], 0) self.need_to_draw_total_gain = False try: canvas.DeleteShape(self.sum_spline[key.channel]) canvas.DeleteShape(self.active_fir_spline[key.channel]) canvas.DeleteShape(self.calculated_fir_spline[key.channel]) except: pass else: if self.left_down == True or self.right_selected_node != None: try: total_gain = map((lambda x, y: x + y), self.vals[key], self.total_gain[key.channel]) except: return else: if self.parent.FIR_enabled == True: active_fir_gain = self.active_fir_gain[key.channel] calculated_fir_gain = self.calculated_fir_gain[key.channel] else: self.calc_total_gain() try: total_gain = self.total_gain[key.channel] except: return else: if self.parent.FIR_enabled == True: active_fir_gain = self.active_fir_gain[key.channel] calculated_fir_gain = self.calculated_fir_gain[key.channel] if self.parent.FIR_enabled == True: colour = '#ff0000' self.active_fir_spline[key.channel] = SplineShape(color=colour, pen_width=1, *canvas.screen_coord(self.f_range, active_fir_gain)) canvas.AppendShape(self.active_fir_spline[key.channel]) try: colour = sum_colours[key.channel] except: colour = '#ffffff' else: if clip_gain: drawn = False f_range = [] tgain = [] tgain2 = [] for i in range(len(self.f_range)): if drawn or total_gain[i] >= self.y_top - self.y_range: if drawn == False and i > 0: f_range.append(self.f_range[i - 1]) tgain.append(self.y_top - self.y_range) f_range.append(self.f_range[i]) tgain.append(total_gain[i]) drawn = True drawn = False f_range2 = [] for i in reversed(range(len(tgain))): if drawn or tgain[i] >= self.y_top - self.y_range: if drawn == False and i < len(tgain) - 1: f_range2.append(f_range[i + 1]) tgain2.append(self.y_top - self.y_range) f_range2.append(f_range[i]) tgain2.append(tgain[i]) drawn = True f_range = f_range2 tgain = tgain2 else: f_range = self.f_range tgain = total_gain self.sum_spline[key.channel] = SplineShape(color=colour, pen_width=1, *canvas.screen_coord(f_range, tgain)) canvas.AppendShape(self.sum_spline[key.channel]) if self.parent.FIR_enabled == True and len(calculated_fir_gain) > 0: colour = '#ff0000' pen = wx.Pen(colour, 1, wx.DOT) self.calculated_fir_spline[key.channel] = SplineShape(color=colour, pen_width=1, *canvas.screen_coord(self.f_range, calculated_fir_gain)) self.calculated_fir_spline[key.channel].SetPen(pen) canvas.AppendShape(self.calculated_fir_spline[key.channel]) self.Refresh() return def initFIR(self): self.Fs = 48828 try: self.Fs = int(self.config.get('DEFAULT', 'Fs')) except: pass self.fir_window = 'blackmanharris' self.nyq = self.Fs / 2 self.rta_f_range = self.get_freq_range(points=one_unit.app.FFT_len) firfreqs = [] firfreqs.append(0) firfreqs += self.rta_f_range firfreqs.append(self.nyq) self.firfreqs = firfreqs return def calc_total_gain(self, skiplist=None, target='draw', myres='total gain'): if skiplist == None: skiplist = [] for channel in self.channels: total_gain = [] try: if self.hpf_shape[channel] is not None: order = 1 + (int(self.hpf_shape[channel]) & 15) q = int(self.hpf_shape[channel]) & 240 if q == 0: q = 0.7071067811865476 elif q == 16: q = 0.769 * pow(0.866, order) elif q == 32: q = 0.5 else: q = 0.7071067811865476 else: q = 1 order = 1 if self.lpf_shape[channel] is not None: lpforder = 1 + (int(self.lpf_shape[channel]) & 15) lpfq = int(self.lpf_shape[channel]) & 240 if lpfq == 0: lpfq = 0.7071067811865476 elif lpfq == 16: lpfq = 0.769 * pow(0.866, lpforder) elif lpfq == 32: lpfq = 0.5 else: lpfq = 0.7071067811865476 else: lpfq = 1 lpforder = 1 q = 1 / pow(q, 2) / 4 lpfq = 1 / pow(lpfq, 2) / 4 hpf_key = data_model.Key(protocol.STRUCT_ID_HPF, protocol.MEMBER_ID_FREQ, -1, 0) if self.hpf_on[channel] == False or self.hpf_freq[channel] == None or hpf_key in skiplist or self.hideHPF == True: hpf_freq = 19 else: hpf_freq = int(self.hpf_freq[channel]) lpf_key = data_model.Key(protocol.STRUCT_ID_LPF, protocol.MEMBER_ID_FREQ, -1, 0) if self.lpf_on[channel] == False or self.lpf_freq[channel] == None or lpf_key in skiplist or self.hideLPF == True: lpf_freq = 20001 else: lpf_freq = int(self.lpf_freq[channel]) for x in self.f_range: y = gain_level_hpf(hpf_freq, x, order, q) + gain_level_lpf(lpf_freq, x, lpforder, lpfq) total_gain.append(y) except: traceback.print_exc(file=sys.stdout) total_gain = [0.0] * len(self.f_range) for key in self.vals.keys(): if key in skiplist: continue if key.channel != channel: continue if key.channel < 0: switch_channel = self.parent.current_channel else: switch_channel = key.channel switch_key = data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_ON, switch_channel, key.num) switch = self.parent.parent.model.get(switch_key) if switch == True or switch == None: try: total_gain = map((lambda x, y: x + y), self.vals[key], total_gain) except: pass if self.parent.numtaps == None or self.maxnumtaps != self.parent.parent.FIR_taps[self.parent.current_channel]: fir_taps = self.parent.parent.FIR_taps if fir_taps == None: self.parent.FIR_enabled = False self.maxnumtaps = 0 self.bg_drawn = False self.Refresh() elif self.parent.current_channel in fir_taps: numtaps = fir_taps[self.parent.current_channel] if numtaps > 2: self.parent.FIR_enabled = True self.maxnumtaps = numtaps self.initFIR() self.bg_drawn = False self.Refresh() else: self.maxnumtaps = 0 self.bg_drawn = False self.Refresh() else: self.parent.FIR_enabled = False else: numtaps = self.parent.numtaps if self.track_changes and self.active_fir_taps != None and myres == 'total gain': self.ExecCalcFIR() if self.parent.FIR_enabled == True and target == 'draw': taps = [ 0] * numtaps if one_unit.app.server.peers.units[self.parent.parent.MAC].numericalFWVersion >= one_unit.app.server.peers.units[self.parent.parent.MAC].minFIRgainVersion: gainkey = data_model.Key(protocol.STRUCT_ID_FIR, protocol.MEMBER_ID_GAIN, self.parent.current_channel, 0) try: self.fir_gain = float(self.parent.parent.model.get(gainkey)) except: self.fir_gain = 1.0 else: if self.fir_gain < 0.01: self.fir_gain = 1.0 else: self.fir_gain = 1.0 activenumtaps = 0 got_all_taps = True for i in range(len(taps)): key = data_model.Key(protocol.STRUCT_ID_FIR, protocol.MEMBER_ID_FIR, self.parent.current_channel, i) tap = self.parent.parent.model.get(key) if tap == None: tap = 0.0 got_all_taps = False tap = self.fir_gain * tap / 2147483647 taps[i] = tap if tap != 0: activenumtaps = i + 1 if self.parent.parent.MAC.startswith('DEMO') == True and activenumtaps == 0: taps[0] = 1 activenumtaps = 1 if got_all_taps and self.parent.numtaps == None: print mytime.displayTime() + ' Adjusting number of taps from', self.parent.numtaps, 'to', activenumtaps self.parent.numtaps = activenumtaps self.active_fir_taps = taps plotfreqs = [] for f in self.f_range: plotfreqs.append(f * math.pi / self.nyq) self.plotfreqs = plotfreqs (w, h) = signal.freqz(taps, worN=plotfreqs) res = [] for gain in h: if abs(gain) == 0: gain = 1e-20 res.append(20 * math.log10(abs(gain))) self.active_fir_gain[channel] = res total_gain = map((lambda x, y: x + y), res, total_gain) if myres == 'total gain': self.total_gain[channel] = total_gain if myres == 'fir gain': self.total_fir_gain = total_gain return def update_spline(self, key): canvas = self self.remove_center_node(key) self.remove_spline(key) if one_unit.app.rta_show_peq == False and one_unit.app.rta_on == True: try: canvas.DeleteShape(self.sum_spline[key.channel]) canvas.DeleteShape(self.active_fir_spline[key.channel]) canvas.DeleteShape(self.calculated_fir_spline[key.channel]) except: pass return self.add_spline(key) return def update_all_splines(self): for key in self.vals.keys(): self.update_spline(key) self.Refresh() return def handle_center_change(self, key, new_x, new_y): timestamp = mytime.clock() self.parent.editing_diagram = True (f, gain) = self.from_screen_coord(new_x, new_y) if self.shift_down == False: f = int(f) if f < 1: f = 1 if self.zoom == True or self.alt_down == True: f = math.log(f, 10.0) lf = math.log(self.last_freq, 10.0) f = (lf * 49.0 + f) / 50.0 f = round(pow(10, f)) if f < 20: f = 20 elif f > self.max_freq: f = self.max_freq self.freqs[key] = f self.dirty[key] = 1 if self.ctrl_down == False: gain_key = data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_GAIN, key.channel, key.num) if self.zoom == True or self.alt_down == True: gain = (self.last_gain * 59.0 + gain) / 60.0 if gain < self.min_gains[gain_key]: gain = self.min_gains[gain_key] elif gain > self.max_gains[gain_key]: gain = self.max_gains[gain_key] self.gains[gain_key] = gain self.dirty[gain_key] = 1 peq_type = self.types[data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_TYPE, key.channel, key.num)] if peq_type == protocol.fNOTCH: self.gains[gain_key] = -50 self.update_spline(key) return def set_start_q(self, key): self.start_q = self.qs[data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_Q, key.channel, key.num)] return def handle_Q_change(self, key, new_x, new_y): self.parent.editing_diagram = True (m, gain) = self.from_screen_coord(new_x, new_y) if self.shift_down == False: f = float(self.freqs[key]) q_key = data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_Q, key.channel, key.num) if self.zoom == True or self.alt_down == True: m = pow(m / f, 0.1) q = m * float(self.start_q) else: m = pow(m / f, 1.5) q = m * float(self.start_q) if q < Q_MIN: q = Q_MIN if q > Q_MAX: q = Q_MAX peq_type = self.types[data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_TYPE, key.channel, key.num)] if peq_type == protocol.fNOTCH: if q < 1: q = 1 if q > 8: q = 8 if peq_type in (protocol.fHighPass, protocol.fLowPass): if q < 5: q = 5 if q > 20: q = 20 if peq_type in (protocol.fHighShelf, protocol.fLowShelf): if q < 3: q = 3 self.qs[q_key] = round(q, 1) self.dirty[q_key] = 1 self.update_spline(key) return def get_values(self, changed_only=False): parent = self.GetParent() values = {} for (key, val) in self.freqs.items() + self.qs.items() + self.gains.items() + self.switches.items() + self.types.items(): if changed_only and not self.dirty.has_key(key): continue values[key] = val if changed_only == False: if len(self.channels) > 1: values[self.link_key] = self.link for channel in self.channels: values[self.key_hpf_freq[channel]] = self.hpf_freq[channel] values[self.key_hpf_shape[channel]] = self.hpf_shape[channel] values[self.key_hpf_on[channel]] = self.hpf_on[channel] for channel in self.channels: values[self.key_lpf_freq[channel]] = self.lpf_freq[channel] values[self.key_lpf_shape[channel]] = self.lpf_shape[channel] values[self.key_lpf_on[channel]] = self.lpf_on[channel] self.dirty = {} return values def set_values(self, values): for test_key in values: val = values[test_key] if test_key == self.link_key: self.link = val continue for channel in self.channels: if test_key == self.key_hpf_freq[channel]: self.hpf_freq[channel] = val break if test_key == self.key_hpf_shape[channel]: self.hpf_shape[channel] = val break if test_key == self.key_hpf_on[channel]: self.hpf_on[channel] = val break if test_key == self.key_lpf_freq[channel]: self.lpf_freq[channel] = val break if test_key == self.key_lpf_shape[channel]: self.lpf_shape[channel] = val break if test_key == self.key_lpf_on[channel]: self.lpf_on[channel] = val break if self.freqs.has_key(test_key): if self.freqs[test_key] != val: self.freqs[test_key] = val elif self.qs.has_key(test_key): if self.qs[test_key] != val: self.qs[test_key] = val elif self.switches.has_key(test_key): if self.switches[test_key] != val: self.switches[test_key] = val elif self.gains.has_key(test_key): if self.gains[test_key] != val: self.gains[test_key] = val elif self.types.has_key(test_key): if self.types[test_key] != val: self.types[test_key] = val if self.dirty.has_key(test_key): del self.dirty[test_key] self.update_all_splines() return def RecalculateFIR(self, src, totaps): res = [ 0.0] * totaps (virgin, peak_pos) = self.GetPeakPos(src) if peak_pos == None: return res else: offset = int(peak_pos - totaps / 2) for i in range(0, totaps): if i + offset < 0: continue if i + offset == len(src): break res[i] = src[i + offset] return res def CalcFIR(self): print mytime.displayTime() + ' Calc FIR' dial_numtaps = self.parent.numtaps if dial_numtaps in (None, 0): dial_numtaps = self.maxnumtaps dial = fir_dialog.Dialog(self, -1, 'Calculate FIR Filter', 'Select the items you would like to include in the filter:', optkey='fir', optmask=self.fir_opts_mask, opttext=fir_opts_text, numtaps=dial_numtaps, maxnumtaps=self.maxnumtaps, Wrap=300, default_options=self.calc_fir_options, Set=False, Fs=self.Fs) dial.ShowModal() response = dial.response options = dial.options requested_numtaps = dial.numtaps dial.Destroy() if response != 'OK': return else: try: requested_numtaps = int(requested_numtaps) if requested_numtaps > self.maxnumtaps: requested_numtaps = self.maxnumtaps if requested_numtaps < self.parent.numtaps: dial = wx.MessageBox('You are reducing the number of taps in the FIR filter. This may have severe effects on the currently active filter. Continue?', 'Set number of taps', wx.OK | wx.CANCEL) if dial == wx.CANCEL: return if requested_numtaps != self.parent.numtaps: self.parent.numtaps = requested_numtaps except: traceback.print_exc(file=sys.stdout) self.calc_fir_options = options skiplist = [] for i in range(len(fir_opts_keys)): mask = 1 << i if options & mask == 0: skiplist.append(fir_opts_keys[mask]) self.fir_skiplist = skiplist if 'Track Changes' not in skiplist: print mytime.displayTime() + ' Tracking Changes' self.track_changes = True self.ExecCalcFIR() self.calc_total_gain() self.parent.calc_fir_options = self.calc_fir_options self.update_all_splines() return def GetPeakPos(self, src): peak1 = 0 peak2 = 0 peak1_pos = None peak2_pos = None for i in range(len(src)): if abs(src[i]) > peak1: peak1 = abs(src[i]) peak1_pos = i peak2 = 0 peak2_pos = None continue if peak1_pos == None: continue if abs(src[i]) == peak1: peak2 = peak1 peak2_pos = i virgin = False if peak2_pos == None: peak_pos = peak1_pos num_not_zero = 0 for i in range(len(src)): if src[i] != 0.0: num_not_zero += 1 if num_not_zero == 1: virgin = True else: peak_pos = (peak1_pos + peak2_pos) / 2.0 return ( virgin, peak_pos) def ExecCalcFIR(self): if self.parent.numtaps == None: return else: self.calc_total_gain(target='fir', skiplist=self.fir_skiplist, myres='fir gain') for channel in self.channels: fir_gainsdB = [] fir_gainsdB.append(self.total_fir_gain[0]) fir_gainsdB += self.total_fir_gain fir_gains = [] for fir_gain in fir_gainsdB: gain = pow(10, fir_gain / 20.0) if gain < 1e-12: gain = 1e-12 fir_gains.append(gain) for i in range(len(fir_gainsdB)): fir_gains.append(gain) fir_gains = signal.resample(fir_gains, int(2 * one_unit.app.FFT_len) + 1)[:one_unit.app.FFT_len + 1] fir_gains = np.append(fir_gains, fir_gains[-1]) if self.calc_fir_options & 16384 == 16384: if len(one_unit.app.rta_data) == 2: one_unit.app.rta_data[1][5] = one_unit.app.rta_data[0][5] (rta_fir_data, avg) = one_unit.app.resample_fft(one_unit.app.rta_data[1][5], self.rta_f_range, one_unit.app.rta_scale, smoothing=one_unit.app.rta_smoothing) rta_fft_low_limit = self.Fs / self.parent.numtaps rta_fft_high_limit = 0 for i in range(len(one_unit.app.rta_data)): if one_unit.app.rta_data[i][7] > rta_fft_high_limit: rta_fft_high_limit = one_unit.app.rta_data[i][7] last_val_rta = None for i in range(one_unit.app.FFT_len): rta_gain = -rta_fir_data[i] if self.rta_f_range[i] < rta_fft_low_limit: delta = (rta_fft_low_limit - self.rta_f_range[i]) / (rta_fft_low_limit / 2) factor = 1 - delta if factor < 0: factor = 0 rta_gain *= factor if self.rta_f_range[i] > rta_fft_high_limit: if last_val_rta == None: last_val_rta = rta_fir_data[i - 1] rta_gain = -last_val_rta delta = self.rta_f_range[i] - rta_fft_high_limit factor = 1 - delta / 1000 if factor < 0: factor = 0 rta_gain *= factor if rta_gain > 15: rta_gain = 15 if rta_gain < -15: rta_gain = -15 fir_gains[i] *= pow(10, rta_gain / 20.0) numtaps = self.parent.numtaps if numtaps & 1 == 0: numtaps -= 1 if numtaps > 0: if len(self.firfreqs) != len(fir_gains): firgains = signal.resample(fir_gains, len(self.firfreqs)) taps = signal.firwin2(numtaps, self.firfreqs, fir_gains, nyq=self.nyq, window=self.fir_window, antisymmetric=False) else: taps = [] if self.calc_fir_options & 1: (virgin, peak_pos) = self.GetPeakPos(self.active_fir_taps) if not virgin: oldlen = len(taps) active_taps = self.active_fir_taps if numtaps == 0: numtaps = 1 if len(active_taps) != numtaps and active_taps != None: active_taps = signal.resample(active_taps, numtaps) if len(taps) == 0 or len(active_taps) == 0: taps = [ 0] else: taps = signal.convolve(taps, active_taps) diff = (len(taps) - oldlen) / 2 newlen = len(taps) (virgin, peak_pos) = self.GetPeakPos(taps) if peak_pos != None: taps = taps[peak_pos - oldlen / 2:peak_pos + oldlen / 2 + 1] if self.calc_fir_options & 32768 == 32768 and self.parent.fir_taps_from_file != None: print 'd.ecf.fir options:', hex(self.calc_fir_options) if self.calc_fir_options & 32768 != 32768: taps = signal.convolve(taps, self.parent.fir_taps_from_file) if len(taps) > numtaps: diff = (len(taps) - numtaps) / 2 newlen = len(taps) (virgin, peak_pos) = self.GetPeakPos(taps) if peak_pos != None: taps = taps[peak_pos - numtaps / 2:peak_pos + numtaps / 2 + 1] else: taps = self.parent.fir_taps_from_file (w, h) = signal.freqz(taps, worN=self.plotfreqs) res = [] for gain in h: if abs(gain) == 0: res.append(-100) else: res.append(20 * math.log10(abs(gain))) self.calculated_fir_gain[channel] = res self.calculated_fir_taps = taps return def ApplyFIR(self): if self.applyingFIR == True: dial = wx.MessageBox('Please wait for the current filter to be applied.', 'Apply FIR', wx.OK) return else: if len(self.calculated_fir_taps) == 0: wx.MessageBox('No FIR filter has been calculated yet.', 'Apply FIR Filter', wx.ICON_ERROR | wx.OK) return if self.apply_fir_options & 2 == 0: dial = dialog.Dialog(self, -1, 'Apply FIR Filter', 'Apply FIR filter? The currently active filter will be overwritten. This action can not be undone. Proceed?', optkey='fir', optmask=3, opttext={1: 'Reset converted IIR filters', 2: 'Do not show this dialog again'}, Wrap=300, default_options=3, Set=False) dial.ShowModal() response = dial.response options = dial.options dial.Destroy() if response != 'OK': return else: options = self.apply_fir_options self.apply_fir_options = options self.parent.apply_fir_options = options taps = self.calculated_fir_taps max_gain = 1.0 for tap in taps: if abs(tap) > max_gain: max_gain = abs(tap) if one_unit.app.server.peers.units[self.parent.parent.MAC].numericalFWVersion >= one_unit.app.server.peers.units[self.parent.parent.MAC].minFIRgainVersion: if max_gain > 24.0: print mytime.displayTime() + ' Maximum FIR gain error 1: ', max_gain print taps wx.MessageBox('The calculated gain exceeds the maximum allowed FIR gain of 24dB.', 'ERROR', wx.ICON_ERROR) return elif max_gain > 1.0: if max_gain > 1.001: print mytime.displayTime() + ' Maximum FIR gain error 2: ', max_gain print taps wx.MessageBox('The calculated gain exceeds the maximum allowed FIR gain of 1.0. Update the firmware to a newer version to allow positive gain.', 'ERROR', wx.ICON_ERROR) return print mytime.displayTime() + ' Maximum FIR gain error 3: ', max_gain newTaps = [] for tap in taps: tap = tap / 1.001 newTaps.append(tap) taps = newTaps max_gain = 1.0 for tap in taps: if abs(tap) > max_gain: if tap > 0.5: print abs(tap) max_gain = abs(tap) print mytime.displayTime() + ' Filter scaled down by 0.01dB, new maximum:', max_gain if max_gain > 1.0: print mytime.displayTime() + ' Maximum FIR gain error 4: ', max_gain print taps wx.MessageBox('The calculated gain exceeds the maximum allowed FIR gain of 1.0. Update the firmware to a newer version to allow positive gain.', 'ERROR', wx.ICON_ERROR) return self.applyingFIR = True print mytime.displayTime() + ' Applying FIR' self.fir_gain_calculated = max_gain if len(taps) > self.maxnumtaps: print 'Probleem: Te veel taps, hoe kan dat?' print mytime.displayTime() + ' Setting', len(taps), 'taps' for i in range(len(taps)): key = data_model.Key(protocol.STRUCT_ID_FIR, protocol.MEMBER_ID_FIR, self.parent.current_channel, i) if one_unit.app.server.peers.units[self.parent.parent.MAC].numericalFWVersion >= one_unit.app.server.peers.units[self.parent.parent.MAC].minFIRgainVersion: val = int(taps[i] / self.fir_gain_calculated * 1073741823) else: val = int(taps[i] * 1073741823) val = val * 2 self.parent.parent.set_value(key, val) if len(taps) < self.maxnumtaps: for i in range(len(taps), self.maxnumtaps): key = data_model.Key(protocol.STRUCT_ID_FIR, protocol.MEMBER_ID_FIR, self.parent.current_channel, i) self.parent.parent.set_value(key, 0) print mytime.displayTime() + ' Syncing FIR coefs...' completion = 0 if self.parent.parent.remote_link.Connected == True: self.parent.noProgressWindow = True self.progress = one_unit.ProgressScreen(self, -1, 'Progress', 'Applying...') self.progress.Show(True) self.progress.Update(1) start_completion = one_unit.app.server.peers.units[self.parent.parent.MAC].process.conn.percent_vars_to_update() while self.parent.parent.remote_link.Connected == True and self.parent.parent.model.synced() == False and one_unit.app.application_stopping == False and self.parent.parent.stopping == False: try: completion = 100.0 * (one_unit.app.server.peers.units[self.parent.parent.MAC].process.conn.percent_vars_to_update() - start_completion) / (100 - start_completion) except: print 'd.AF.connection interrupted' break print mytime.displayTime() + ' d.af.Completion:', completion if completion > 99: completion = 99 try: self.progress.Update(completion * 99 / 100) except: pass mytime.sleep(0.1) try: completion = 100.0 * (one_unit.app.server.peers.units[self.parent.parent.MAC].process.conn.percent_vars_to_update() - start_completion) / (100 - start_completion) except: print 'd.AF.connection interrupted (2)' else: print mytime.displayTime() + ' d.af.Finished with completion:', completion, 'synced:', self.parent.parent.model.synced() else: print '2' try: self.progress.Destroy() except: pass self.parent.noProgressWindow = False if one_unit.app.application_stopping == True or self.parent.parent.stopping == True: self.applyingFIR = False return firstring = 'ALLDSP generated FIR filter, sample rate: ' + str(self.Fs) + 'Hz, ' + str(self.parent.numtaps) + 'taps' + newline firfile = open(one_unit.app.asys_config_path + '/_tmpfir.txt', 'wb') firfile.write(firstring) for tap in taps: firfile.write(str(tap) + newline) firfile.close() print mytime.displayTime() + ' Written', one_unit.app.asys_config_path + '/_tmpfir.txt' self.calculated_fir_taps = [] self.parent.update_controls() self.update_all_splines() if one_unit.app.server.peers.units[self.parent.parent.MAC].numericalFWVersion >= one_unit.app.server.peers.units[self.parent.parent.MAC].minFIRgainVersion: gainkey = data_model.Key(protocol.STRUCT_ID_FIR, protocol.MEMBER_ID_GAIN, self.parent.current_channel, 0) print mytime.displayTime() + ' Setting FIR gain to', self.fir_gain_calculated, self.fir_gain_calculated self.parent.parent.set_value(gainkey, self.fir_gain_calculated) if self.parent.parent.remote_link.Connected == True: while self.parent.parent.remote_link.Connected == True and self.parent.parent.model.synced() == False and one_unit.app.application_stopping == False and self.parent.parent.stopping == False: mytime.sleep(0.1) dummykey = data_model.Key(protocol.STRUCT_ID_PEQ, protocol.MEMBER_ID_ON, self.parent.current_channel, 9) dummyval = None while dummyval == None: dummyval = self.parent.parent.model.get(dummykey) mytime.sleep(0.1) self.parent.parent.set_value(dummykey, int(dummyval) ^ 1) if self.parent.parent.remote_link.Connected == True: while self.parent.parent.remote_link.Connected == True and self.parent.parent.model.synced() == False and one_unit.app.application_stopping == False and self.parent.parent.stopping == False: mytime.sleep(0.1) self.parent.parent.set_value(dummykey, dummyval) if self.parent.parent.remote_link.Connected == True: while self.parent.parent.remote_link.Connected == True and self.parent.parent.model.synced() == False and one_unit.app.application_stopping == False and self.parent.parent.stopping == False: mytime.sleep(0.1) print mytime.displayTime() + ' d.Sending mirrorFIR command' key = data_model.Key(protocol.STRUCT_ID_COMMAND, protocol.MEMBER_ID_COMMAND, 0, protocol.cmdMirrorFIR) self.parent.parent.set_value(key, 1) self.parent.parent.waitForSync('d.aff.1') mytime.sleep(0.5) self.parent.parent.set_value(key, 0) self.parent.parent.waitForSync('d.aff.2') print mytime.displayTime() + ' d.5.FIR mirrored' if options & 1 == 1: for i in range(len(fir_enable_keys)): if i == 0: continue mask = 1 << i if self.calc_fir_options & mask != 0: try: key = self.parent.key_with_current_channel(fir_enable_keys[mask]) self.parent.parent.set_value(key, 0) except: pass print mytime.displayTime() + ' Apply FIR done. ' self.applyingFIR = False return class XV_diagram(Diagram_canvas, svg_panel.SVG_control): def __init__(self, parent, config, section, name='diagram', id=-1, pos=(-1, -1), size=(-1, -1), style=0): """Contructor""" Diagram_canvas.__init__(self, parent, id, pos, size, style, name) self.remote_link = parent.remote_link svg_panel.SVG_control.__init__(self, name) self.config = config self.section = section self.thisid = 0 var_names = config.get(section, name + '_values') var_names = [_[1] for s in var_names.split(',')] type_names = config.get(section, name + '_shapes') type_names = [_[2] for s in type_names.split(',')] try: link_names = config.get(section, name + '_links') link_names = [_[3] for s in link_names.split(',')] except: link_names = [] self.freqs = {} self.ids = {} self.maxnumtaps = 0 self.shapes = {} self.peq_colours = PEQ_COLORS try: self.peq_colours = eval(config.get(section, 'peq_colours')) except: pass self.links = {} self.linkees = {} self.shapekeys = {} self.linkkeys = {} self.freqkeys = {} self.switches = {} self.switchkeys = {} self.dirty = {} for var in var_names: try: struct_id = config.getint(var, 'struct_id') except: wx.MessageBox('Variable not defined:' + str(var)) if struct_id != protocol.STRUCT_ID_HPF and struct_id != protocol.STRUCT_ID_LPF: print mytime.displayTime() + ' XV_diagram.init:Invalid Var', var, struct_id member_id = config.getint(var, 'member_id') num = config.getint(var, 'num') val = config.getfloat(var, 'default_value') try: channel = config.get(var, 'channel') except: print 'channel not specified', var channel = -1 x_pos = channel.find('x') + 1 if x_pos > 0: channel = hex2dec(channel) channel = int(channel) if channel not in parent.parent.unit_channels: val = None if member_id == protocol.MEMBER_ID_FREQ: key = data_model.Key(struct_id, member_id, channel, num) self.freqs[key] = val self.ids[key] = self.thisid self.thisid = self.thisid + 1 switchkey = data_model.Key(struct_id, protocol.MEMBER_ID_ON, channel, num) self.switches[switchkey] = 0 self.switchkeys[key] = switchkey shapekey = data_model.Key(struct_id, protocol.MEMBER_ID_TYPE, channel, num) self.shapes[shapekey] = 0 self.shapekeys[key] = shapekey self.freqkeys[shapekey] = key continue for var in link_names: struct_id = config.getint(var, 'struct_id') member_id = config.getint(var, 'member_id') if struct_id != protocol.STRUCT_ID_LINK: print mytime.displayTime() + ' XV_diagram.init:Invalid Var', var, struct_id num = config.getint(var, 'num') linkee = config.getint(var, 'linkee') val = config.getint(var, 'default_value') try: channel = config.get(var, 'channel') except: print 'channel not specified', var channel = -1 x_pos = channel.find('x') + 1 if x_pos > 0: channel = hex2dec(channel) channel = int(channel) linkkey = data_model.Key(struct_id, member_id, channel, num) self.remote_link.get_by_key(linkkey) for key in self.freqs: if key.channel == channel: self.links[linkkey] = val self.linkees[linkkey] = linkee self.linkkeys[key] = linkkey self.freqkeys[linkkey] = key self.f_range = self.get_freq_range() self.splines = {} self.control_nodes = {} self.vals = {} return def on_left_dclick(self, key): return def on_right_down(self, key): return def on_left_down(self, num): return def set_start_q(self, num): return def handle_Q_change(self, num, new_x, new_y): return def on_add(self, parent): self.parent = parent bb = parent.svg_doc.get_bb(self.name) if bb is None: print mytime.displayTime() + ' No diagram found in SVG' self.Show(False) return -1 else: self.x = bb.left * parent.svg_scale_x if os.name in mac_names: self.y = 15 - bb.bottom * parent.svg_scale_y self.width = (bb.right - bb.left) * parent.svg_scale_x self.height = (bb.bottom - bb.top) * parent.svg_scale_y else: self.y = bb.top * parent.svg_scale_y self.width = (bb.right - bb.left) * parent.svg_scale_x self.height = (bb.bottom - bb.top) * parent.svg_scale_y pos = wx.Point(self.x, self.y) size = wx.Size(self.width, self.height) self.SetSize(size) self.SetPosition(pos) self.SetMinSize(size) return 0 def SetMinSize(self, size): Diagram_canvas.SetMinSize(self, size) self.f_range = self.get_freq_range() self.splines = {} self.control_nodes = {} self.vals = {} self.total_gain = [ 0.0] * len(self.f_range) self.sum_spline = None self.active_fir_spline = None self.calculated_fir_spline = None self.AddShape(XO_Grid(self)) for key in self.freqs: if self.freqs[key] == None: continue self.add_spline(self.ids[key]) self.timer.Start(1000) return def HitTest(self, x, y): return False def add_spline(self, num): key_freq = None key_id = None key_type = None key_channel = None key_shape = None my_lpf_id = None my_lpf_freq = None my_lpf_shape = None f = None for key in self.freqs: if self.ids[key] == num: key_freq = key key_channel = key.channel key_shape = self.shapes[self.shapekeys[key]] try: hpf_switch = self.switches[self.switchkeys[key]] except: print mytime.displayTime() + ' HPF switch not found!!' hpf_switch = 1 else: try: lpf_switch = self.switches[data_model.Key(protocol.STRUCT_ID_LPF, protocol.MEMBER_ID_ON, key.channel, key.num)] except: print mytime.displayTime() + ' LPF switch not found!!!' lpf_switch = 1 else: f = self.freqs[key] if key.struct_id == protocol.STRUCT_ID_HPF: key_type = 'hpf' else: key_type = 'lpf' break canvas = self channel_linked = False for key in self.linkees: if self.linkees[key] == key_channel: if self.links[key] == 1: master_key = key channel_linked = True break if f < 19: f = 19 if f > 20001: f = 20001 if key_type == 'hpf': for key in self.freqs: if key.channel == key_channel and key.struct_id == protocol.STRUCT_ID_LPF: my_lpf_id = self.ids[key] my_lpf_freq = self.freqs[key] my_lpf_shape = self.shapes[self.shapekeys[key]] break if my_lpf_freq < 19: my_lpf_freq = 19 if my_lpf_freq > 20001: my_lpf_freq = 20001 if f is None: print mytime.displayTime() + ' add_spline(%s): invalid hpf data' % num return if my_lpf_freq is None: print mytime.displayTime() + ' add_spline(%s): invalid lpf data' % num return try: color = self.peq_colours[key_channel & 127] except: print mytime.displayTime() + ' Error: Colour index ', key_channel & 127, ' out of range, setting default colour (red)' color = 'red' else: if key_shape == None: key_shape = 0 if my_lpf_shape == None: my_lpf_shape = 0 order = 1 + (int(key_shape) & 15) q = int(key_shape) & 240 if q == 0: q = 0.7071067811865476 elif q == 16: q = 0.769 * pow(0.866, order) elif q == 32: q = 0.5 else: q = 0.7071067811865476 lpforder = 1 + (int(my_lpf_shape) & 15) lpfq = int(my_lpf_shape) & 240 if lpfq == 0: lpfq = 0.7071067811865476 elif lpfq == 16: lpfq = 0.769 * pow(0.866, lpforder) elif lpfq == 32: lpfq = 0.5 else: lpfq = 0.7071067811865476 q = 1 / pow(q, 2) / 4 lpfq = 1 / pow(lpfq, 2) / 4 self.my_f_range = [] self.my_values = [] all_zero = True for x in self.f_range: y = gain_level_hpf(f, x, order, q, hpf_switch) + gain_level_lpf(my_lpf_freq, x, lpforder, lpfq, lpf_switch) if y >= -50: self.my_f_range.append(x) self.my_values.append(y) if y < 0: all_zero = False if len(self.my_f_range) < 10: return fill_ground = int(canvas.screen_coord([FREQ_MIN], [-50.0])[1][0]) self.splines[num] = SplineShape(fill_ground=fill_ground, color=color, alpha=ALPHA_LEVEL_XO, pen_width=0, *canvas.screen_coord(self.my_f_range, self.my_values)) if channel_linked == False and all_zero == False: canvas.AppendShape(self.splines[num]) if channel_linked == True: if self.control_nodes.has_key(num): self.control_nodes[num].visible = False return coords = canvas.screen_coord([f], [0]) pos = (6, -13) cn = self.control_nodes.has_key(num) or CenterNode(num, self, coords[0][0], coords[1][0], 4, 'triangle_right', str(key_channel - 127), pos) self.control_nodes[num] = cn cn.pen = [color, 1] canvas.AppendShape(cn) else: self.control_nodes[num].visible = True self.control_nodes[num].moveto(coords[0][0], coords[1][0], pos) else: if f is None: print mytime.displayTime() + ' add_spline(%s): invalid lpf data' % num return else: try: color = self.peq_colours[key_channel & 127] except: print mytime.displayTime() + ' Error: Colour index ', key_channel & 127, ' out of range, setting default colour (red)' color = 'red' canvas = self if channel_linked == True: if self.control_nodes.has_key(num): self.control_nodes[num].visible = False return self.splines[num] = (0, 0) pos = (-3, -13) coords = canvas.screen_coord([f], [0]) cn = self.control_nodes.has_key(num) or CenterNode(num, self, coords[0][0], coords[1][0], 4, 'triangle_left', str(key_channel - 127), pos) self.control_nodes[num] = cn cn.pen = [color, 1] canvas.AppendShape(cn) else: self.control_nodes[num].visible = True self.control_nodes[num].moveto(coords[0][0], coords[1][0], pos) return def update_spline(self, num): canvas = self self.remove_spline(num) self.add_spline(num) return def update_all_splines(self): canvas = self try: for num in self.splines: self.remove_spline(num) self.add_spline(num) except: pass return def handle_center_change(self, num, new_x, new_y): self.parent.editing_diagram = True (f, gain) = self.from_screen_coord(new_x, new_y) f = int(f) if f < 19: f = 19 elif f > 20001: f = 20001 hpfkey = None for key in self.freqs: if self.ids[key] == num: hpfkey = key self.freqs[key] = f self.dirty[key] = 1 break self.update_spline(num) try: if hpfkey.struct_id == protocol.STRUCT_ID_LPF: hpfkey = data_model.Key(protocol.STRUCT_ID_HPF, hpfkey.member_id, hpfkey.channel, hpfkey.num) num_hpf = self.ids[hpfkey] self.update_spline(num_hpf) except: print mytime.displayTime() + ' No matching HPF found in XOVER diagram!!' return def get_values(self, changed_only=False): parent = self.GetParent() values = {} for (key, val) in self.links.items() + self.freqs.items() + self.shapes.items() + self.switches.items(): if changed_only and not self.dirty.has_key(key): continue values[key] = val self.dirty = {} return values def set_values(self, values): ids_affected = {} link_changed = 0 for key in values: val = values[key] flex_key = key for test_key in (key, flex_key): if self.links.has_key(test_key): if self.links[test_key] != val: self.links[test_key] = val link_changed = 1 if self.freqs.has_key(test_key): if self.freqs[test_key] != val or link_changed == 1: self.freqs[test_key] = val ids_affected[self.ids[test_key]] = 1 if test_key.struct_id == protocol.STRUCT_ID_LPF: hpf_key = data_model.Key(protocol.STRUCT_ID_HPF, test_key.member_id, test_key.channel, test_key.num) try: ids_affected[self.ids[hpf_key]] = 1 except: pass if self.switches.has_key(test_key): if self.switches[test_key] != val or link_changed == 1: self.switches[test_key] = val lpf_key = data_model.Key(protocol.STRUCT_ID_LPF, protocol.MEMBER_ID_FREQ, test_key.channel, test_key.num) ids_affected[self.ids[lpf_key]] = 1 hpf_key = data_model.Key(protocol.STRUCT_ID_HPF, protocol.MEMBER_ID_FREQ, test_key.channel, test_key.num) ids_affected[self.ids[hpf_key]] = 1 if self.shapes.has_key(test_key): if self.shapes[test_key] != val or link_changed == 1: self.shapes[test_key] = val ids_affected[self.ids[self.freqkeys[key]]] = 1 if test_key.struct_id == protocol.STRUCT_ID_LPF: hpf_key = data_model.Key(protocol.STRUCT_ID_HPF, test_key.member_id, test_key.channel, test_key.num) try: ids_affected[self.ids[self.freqkeys[hpf_key]]] = 1 except: pass if self.dirty.has_key(test_key): del self.dirty[test_key] if link_changed == 1: self.update_all_splines() return for myid in ids_affected: self.update_spline(myid) return class XV_Grid(Grid): pass def gain_level_peq(f0, q, gain, peq_type, f): res = None try: if peq_type == protocol.fAllpass: return 0 else: if peq_type == protocol.fBandPass: df = f / f0 if q > 0.7 and (df > 35 / q or df < q / 35): return -50 q /= 2.0 factor = pow(f0 / f, 2.7 * pow(q, 0.75)) if factor < 1e-10: factor = 1e-10 res = -50 + 551.5 * math.log(1 + factor, 10.0) * math.log(1 + 1.0 / factor, 10.0) return res if peq_type == protocol.fBELL: df = f / f0 if q > 0.7 and (df > 35 / q or df < q / 35): return 0 factor = pow(f0 / f, 2.7 * pow(q, 0.75)) if factor < 1e-10: factor = 1e-10 res = gain * 11.03 * math.log(1 + factor, 10.0) * math.log(1 + 1.0 / factor, 10.0) return res if peq_type == protocol.fNOTCH: if q > 8: q = 8 df = f / f0 dq = 1 - 0.25 / q if df > 1 / dq or df < dq: return 0 factor = pow(f0 / f, q * 50) res = -1103.0 * math.log(1 + factor, 10.0) * math.log(1 + 1.0 / factor, 10.0) return res if peq_type == protocol.fLowShelf: df = f / f0 if q < 12: if df > 300 / q: return 0 if df < q / 300: return gain factor = pow(f / f0, q / 3.33) res = 1.62 * gain * pow(math.log(1 + 1 / (1 + factor)), 1.31) if q > 12: f0 /= 1.3 gain *= (q - 12) / 50 q /= 20 factor = pow(f0 / f, 2.7 * pow(q, 0.75)) if factor < 1e-10: factor = 1e-10 res += gain * 11.03 * math.log(1 + factor, 10.0) * math.log(1 + 1.0 / factor, 10.0) gain = -gain f0 *= 1.69 factor = pow(f0 / f, 2.7 * pow(q, 0.75)) if factor < 1e-10: factor = 1e-10 res += gain * 11.03 * math.log(1 + factor, 10.0) * math.log(1 + 1.0 / factor, 10.0) return res if peq_type == protocol.fHighShelf: df = f / f0 if q < 12: if df > 300 / q: return gain if df < q / 300: return 0 factor = pow(f0 / f, q / 3.33) res = 1.62 * gain * pow(math.log(1 + 1 / (1 + factor)), 1.31) if q > 12: f0 /= 1.3 gain *= (12 - q) / 50 q /= 20 factor = pow(f0 / f, 2.7 * pow(q, 0.75)) if factor < 1e-10: factor = 1e-10 res += gain * 11.03 * math.log(1 + factor, 10.0) * math.log(1 + 1.0 / factor, 10.0) gain = -gain f0 *= 1.69 factor = pow(f0 / f, 2.7 * pow(q, 0.75)) if factor < 1e-10: factor = 1e-10 res += gain * 11.03 * math.log(1 + factor, 10.0) * math.log(1 + 1.0 / factor, 10.0) return res if peq_type == protocol.fHighPass: if q < 5: q = 5 if q > 20: q = 20 res = gain_level_hpf(f0, f, 2, 1 / (q / 5.0 * (q / 5.0))) if q > 7.1: f0 *= 1.068 gain = (q - 7.1) / 2.04 q /= 12 df = f / f0 if q > 0.7 and (df > 35 / q or df < q / 35): return res factor = pow(f0 / f, 2.7 * pow(q, 0.75)) if factor < 1e-10: factor = 1e-10 res += gain * 11.03 * math.log(1 + factor, 10.0) * math.log(1 + 1.0 / factor, 10.0) return res if peq_type == protocol.fLowPass: if q < 5: q = 5 if q > 20: q = 20 res = gain_level_lpf(f0, f, 2, 1 / (q / 5.0 * (q / 5.0))) if q > 7.1: f0 /= 1.068 gain = (q - 7.1) / 2.04 q /= 12 df = f / f0 if q > 0.7 and (df > 35 / q or df < q / 35): return res factor = pow(f0 / f, 2.7 * pow(q, 0.75)) if factor < 1e-10: factor = 1e-10 res += gain * 11.03 * math.log(1 + factor, 10.0) * math.log(1 + 1.0 / factor, 10.0) return res if res == None: print 'd.glp.Unknown PEQ type:', peq_type res = 0 return res except: traceback.print_exc(file=sys.stdout) return 0 return 0 def gain_level_hpf(f0, f, order, q, sw=1): if f0 < 20 or sw == 0: return 0 w = f0 / f if q == 0: print 'd.glh.Error: q=0' return 0 res = 8.7 * math.log(pow(1 / (1 + pow(w, order / q)), q)) return res def gain_level_lpf(f0, f, order, q, sw=1): if f0 > FREQ_MAX or sw == 0: return 0 w = f / f0 if q == 0: print 'd.gll.Error: q=0' return 0 res = 8.7 * math.log(pow(1 / (1 + pow(w, order / q)), q)) return res # okay decompiling pycode/diagram.pyc