Files
maikandClaude Opus 4.8 a7c93fa266 Erster Commit: nativer Linux-Port aus macOS-Bytecode
Läuft die Voice Acoustic VA-Remotecontrol (AllDSP AllControl) nativ unter Linux
auf echtem wxGTK 3.0 — ohne Wine und ohne dekompilierten App-Code. Ausgeführt wird
das unveränderte Python-2.7-Bytecode aus dem macOS-.app; C-Extensions (wxGTK/numpy/
scipy/PortAudio) kommen nativ aus Debian stretch.

Enthält: va/ (Original-.pyc + pure-Python-Libs + Assets + launch.py mit den drei
Linux-Fixes), Dockerfile/run.sh/entrypoint.sh, reference/ (dekompilierter Quellcode
zum Debuggen) und README/STATUS. img.cache (378 MB, regenerierbar) ist per
.gitignore ausgeschlossen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-20 19:57:01 +02:00

3224 lines
136 KiB
Python

# 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