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>
3224 lines
136 KiB
Python
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
|