Erster Commit: nativer Linux-Port aus macOS-Bytecode
Läuft die Voice Acoustic VA-Remotecontrol (AllDSP AllControl) nativ unter Linux auf echtem wxGTK 3.0 — ohne Wine und ohne dekompilierten App-Code. Ausgeführt wird das unveränderte Python-2.7-Bytecode aus dem macOS-.app; C-Extensions (wxGTK/numpy/ scipy/PortAudio) kommen nativ aus Debian stretch. Enthält: va/ (Original-.pyc + pure-Python-Libs + Assets + launch.py mit den drei Linux-Fixes), Dockerfile/run.sh/entrypoint.sh, reference/ (dekompilierter Quellcode zum Debuggen) und README/STATUS. img.cache (378 MB, regenerierbar) ist per .gitignore ausgeschlossen. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,394 @@
|
||||
# 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: fir_dialog.pyc
|
||||
# Compiled at: 2022-04-20 07:08:28
|
||||
import mytime, wx, os, data_model, traceback, one_unit, sys, math, dialog
|
||||
mac_names = 'posix'
|
||||
accepted = '+-.0123456789Ee'
|
||||
|
||||
def safeNumber(text):
|
||||
res = ''
|
||||
for c in text:
|
||||
if c in accepted:
|
||||
res += c
|
||||
|
||||
return res
|
||||
|
||||
|
||||
def getString(strID):
|
||||
return one_unit.getString(strID)
|
||||
|
||||
|
||||
class Dialog(wx.Dialog):
|
||||
|
||||
def __init__(self, parent, id, title, infotext='', optkey=None, optmask=0, opttext={}, bgcolour=(220, 220, 220), fgcolour=(70, 70, 70), OK_Only=False, textkey=None, default_text=None, IsPassword=False, Set=True, Wrap=400, size=(250, 10), bg=None, choices={}, value_mask=None, selectkey=None, default_choice=0, OK_Enable=True, OKtext='Ok', Canceltext='Cancel', OK_Show=True, max=None, default_options=0, numtaps=0, maxnumtaps=0, Fs=48828):
|
||||
wx.Dialog.__init__(self, None, wx.ID_ANY, title, size=size, style=wx.CAPTION | wx.DEFAULT_DIALOG_STYLE)
|
||||
self.parent = parent
|
||||
if bg != None:
|
||||
self.bg = bg
|
||||
self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
|
||||
self.value_mask = value_mask
|
||||
self.optkey = optkey
|
||||
self.numtaps = numtaps
|
||||
self.textkey = textkey
|
||||
self.selectkey = selectkey
|
||||
self.options = default_options
|
||||
self.choices = choices
|
||||
self.default_options = default_options
|
||||
self.max = max
|
||||
self.maxnumtaps = maxnumtaps
|
||||
self.Fs = Fs
|
||||
self.optmask = optmask
|
||||
self.frame_height = 2 * wx.SystemSettings.GetMetric(wx.SYS_CAPTION_Y) + wx.SystemSettings.GetMetric(wx.SYS_BORDER_Y)
|
||||
if os.name in mac_names:
|
||||
self.frame_height = 24
|
||||
self.chkboxes = {}
|
||||
self.Set = Set
|
||||
self.infotext = None
|
||||
textpanel = wx.Panel(self, -1)
|
||||
textvbox = wx.BoxSizer(wx.VERTICAL)
|
||||
textfieldpanel = wx.Panel(self, -1)
|
||||
textfieldvbox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
loadbuttonpanel = wx.Panel(self, -1)
|
||||
loadbuttonvbox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
selectfieldpanel = wx.Panel(self, -1)
|
||||
selectfieldvbox = wx.BoxSizer(wx.VERTICAL)
|
||||
optionspanel = wx.Panel(self, -1)
|
||||
optionsvbox = wx.BoxSizer(wx.VERTICAL)
|
||||
buttonspanel = wx.Panel(self, -1)
|
||||
buttonshbox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
mainvbox = wx.BoxSizer(wx.VERTICAL)
|
||||
if infotext != '':
|
||||
textstring = wx.StaticText(textpanel, -1, infotext, style=wx.ALIGN_LEFT | wx.ST_NO_AUTORESIZE)
|
||||
textstring.Wrap(Wrap)
|
||||
textstring.SetForegroundColour(fgcolour)
|
||||
textvbox.Add(textstring, 1, wx.EXPAND)
|
||||
textpanel.SetSizer(textvbox)
|
||||
if Wrap > 0:
|
||||
textvbox.SetMinSize((Wrap, 10))
|
||||
else:
|
||||
textvbox.SetMinSize(size)
|
||||
mainvbox.Add(textpanel, 0, border=10, flag=wx.ALL)
|
||||
self.infotext = textstring
|
||||
self.infostring = infotext
|
||||
self.wrap = Wrap
|
||||
self.Bind(wx.EVT_BUTTON, self.OnLoad, id=3)
|
||||
if numtaps > 0:
|
||||
numtapstring = wx.StaticText(textfieldpanel, -1, 'Number of Taps:', style=wx.ALIGN_LEFT | wx.ST_NO_AUTORESIZE, pos=(0,
|
||||
30))
|
||||
textfieldvbox.Add(numtapstring, 1, border=5, flag=wx.ALIGN_LEFT | wx.ALL)
|
||||
textval = str(numtaps)
|
||||
textfield = wx.TextCtrl(textfieldpanel, 3, unicode(textval), style=wx.TE_PROCESS_ENTER, pos=(100,
|
||||
30))
|
||||
textfieldvbox.Add(textfield, 1, border=5, flag=wx.ALIGN_LEFT | wx.ALL)
|
||||
self.textfield = textfield
|
||||
textfield.Bind(wx.EVT_TEXT_ENTER, self.OnTextEnter, textfield)
|
||||
sample_time = 1.0 / self.Fs
|
||||
latency = str(round(numtaps * sample_time * 500, 2)) + 'ms'
|
||||
self.latencyfield = wx.StaticText(textfieldpanel, -1, '(' + latency + ' latency)', style=wx.ALIGN_LEFT | wx.ST_NO_AUTORESIZE)
|
||||
textfieldvbox.Add(self.latencyfield, 1, border=5, flag=wx.ALIGN_LEFT | wx.ALL)
|
||||
textfieldpanel.SetSizer(textfieldvbox)
|
||||
mainvbox.Add(textfieldpanel, 0, border=10, flag=wx.LEFT | wx.RIGHT)
|
||||
if selectkey != None:
|
||||
selectval = None
|
||||
try:
|
||||
selectval = self.parent.model.get(selectkey)
|
||||
if value_mask != None:
|
||||
selectval = int(int(selectval) & value_mask)
|
||||
except:
|
||||
traceback.print_exc(file=sys.stdout)
|
||||
else:
|
||||
if selectval == None:
|
||||
selectval = default_choice
|
||||
if selectval not in self.choices.keys():
|
||||
selectval = default_choice
|
||||
style = wx.BORDER_NONE | wx.CB_READONLY
|
||||
mychoices = []
|
||||
for i in sorted(choices.keys()):
|
||||
mychoices.append(choices[i])
|
||||
|
||||
selectfield = wx.ComboBox(selectfieldpanel, 30, choices=mychoices, style=style)
|
||||
selectfield.SetStringSelection(self.choices[selectval])
|
||||
selectfieldvbox.Add(selectfield, 1, border=5, flag=wx.ALIGN_LEFT | wx.ALL)
|
||||
selectfieldpanel.SetSizer(selectfieldvbox)
|
||||
mainvbox.Add(selectfieldpanel, 0, border=10, flag=wx.LEFT | wx.RIGHT)
|
||||
self.selectfield = selectfield
|
||||
if optkey != None and optmask != 0:
|
||||
try:
|
||||
options = int(self.parent.model.get(optkey))
|
||||
except:
|
||||
options = default_options
|
||||
else:
|
||||
chkboxes = {}
|
||||
for i in range(0, 31):
|
||||
optnr = optmask & 1 << i
|
||||
val = options & 1 << i
|
||||
if optnr > 0:
|
||||
try:
|
||||
this_opttext = opttext[optnr]
|
||||
except:
|
||||
this_opttext = 'Unlisted Option: ' + hex(optnr)
|
||||
else:
|
||||
chkboxes[i] = wx.CheckBox(optionspanel, i, this_opttext)
|
||||
chkboxes[i].SetForegroundColour(fgcolour)
|
||||
optionsvbox.Add(chkboxes[i], 1, border=5, flag=wx.ALIGN_LEFT | wx.ALL)
|
||||
if val > 0:
|
||||
chkboxes[i].SetValue(1)
|
||||
if optnr == 32768:
|
||||
if self.parent.fir_file != '':
|
||||
chkboxes[i].SetLabel(self.parent.fir_file)
|
||||
chkboxes[i].SetSize((100, 150))
|
||||
if self.parent.parent.fir_taps_from_file == None:
|
||||
chkboxes[i].Enable(False)
|
||||
self.file_chkbox = chkboxes[i]
|
||||
self.load_button = wx.Button(optionspanel, 3, 'Load File')
|
||||
self.load_button.Enable(True)
|
||||
self.load_button.Show(True)
|
||||
optionsvbox.Add(self.load_button, 1, border=5, flag=wx.ALIGN_RIGHT | wx.ALL)
|
||||
self.Bind(wx.EVT_CHECKBOX, self.OnEnabled, id=i)
|
||||
|
||||
optionspanel.SetSizer(optionsvbox)
|
||||
optionsvbox.SetMinSize((250, 10))
|
||||
mainvbox.Add(optionspanel, 0, border=10, flag=wx.LEFT | wx.RIGHT)
|
||||
self.chkboxes = chkboxes
|
||||
self.OK_button = wx.Button(buttonspanel, 1, OKtext)
|
||||
self.OK_button.Enable(OK_Enable)
|
||||
self.OK_button.Show(OK_Show)
|
||||
buttonshbox.Add(self.OK_button, 1, border=3, flag=wx.ALL)
|
||||
if OK_Only == False:
|
||||
buttonshbox.Add(wx.Button(buttonspanel, 2, Canceltext), 1, border=3, flag=wx.ALL)
|
||||
buttonspanel.SetSizer(buttonshbox)
|
||||
if OK_Only == True:
|
||||
buttonshbox.SetMinSize((75, self.frame_height))
|
||||
else:
|
||||
buttonshbox.SetMinSize((150, self.frame_height))
|
||||
mainvbox.Add(buttonspanel, 0, border=5, flag=wx.ALL)
|
||||
self.SetSizerAndFit(mainvbox)
|
||||
self.Centre()
|
||||
self.textvbox = textvbox
|
||||
self.SetBackgroundColour(bgcolour)
|
||||
self.Bind(wx.EVT_TEXT_ENTER, self.OnOK, id=3)
|
||||
self.Bind(wx.EVT_BUTTON, self.OnOK, id=1)
|
||||
self.Bind(wx.EVT_BUTTON, self.OnCancel, id=2)
|
||||
self.CenterOnScreen()
|
||||
self.mainvbox = mainvbox
|
||||
self.response = None
|
||||
return
|
||||
|
||||
def OnEnabled(self, e):
|
||||
id = e.GetId()
|
||||
try:
|
||||
if self.chkboxes[id].GetValue() == 1:
|
||||
if id == 15:
|
||||
for i in range(15):
|
||||
self.chkboxes[i].SetValue(0)
|
||||
|
||||
else:
|
||||
self.chkboxes[15].SetValue(0)
|
||||
except:
|
||||
pass
|
||||
|
||||
return
|
||||
|
||||
def OnTextEnter(self, e):
|
||||
try:
|
||||
numtaps = int(self.textfield.GetValue())
|
||||
except:
|
||||
self.textfield.SetValue(str(self.numtaps))
|
||||
numtaps = self.numtaps
|
||||
|
||||
if numtaps > self.maxnumtaps:
|
||||
self.textfield.SetValue(str(self.maxnumtaps))
|
||||
numtaps = self.maxnumtaps
|
||||
sample_time = 1.0 / self.Fs
|
||||
latency = str(round(numtaps * sample_time * 500, 2)) + 'ms'
|
||||
self.latencyfield.SetLabel('(' + latency + ' latency)')
|
||||
return
|
||||
|
||||
def OnEraseBackground(self, evt):
|
||||
"""
|
||||
Add a picture to the background
|
||||
"""
|
||||
dc = evt.GetDC()
|
||||
if not dc:
|
||||
dc = wx.ClientDC(self)
|
||||
rect = self.GetUpdateRegion().GetBox()
|
||||
dc.SetClippingRect(rect)
|
||||
dc.Clear()
|
||||
bmp = wx.Bitmap(self.bg)
|
||||
dc.DrawBitmap(bmp, 0, 0)
|
||||
return
|
||||
|
||||
def OnLoad(self, e):
|
||||
wildcard = 'Text File (*.txt)|*.txt|Comma Separated Values File (*.csv)|*.csv'
|
||||
path = None
|
||||
dlg = wx.FileDialog(self, message='Select File....', defaultDir=one_unit.app.library_path, defaultFile='', wildcard=wildcard, style=wx.OPEN | wx.CHANGE_DIR)
|
||||
answer = dlg.Show()
|
||||
dlg.Destroy()
|
||||
dlg = wx.FileDialog(self, message='Select File....', defaultDir=one_unit.app.library_path, defaultFile='', wildcard=wildcard, style=wx.OPEN | wx.CHANGE_DIR)
|
||||
answer = dlg.ShowModal()
|
||||
if answer == wx.ID_OK:
|
||||
path = dlg.GetPath()
|
||||
else:
|
||||
path = None
|
||||
dlg.Destroy()
|
||||
if path:
|
||||
one_unit.app.library_path = os.path.split(path)[0]
|
||||
print mytime.displayTime() + ' Loading FIR file:', path
|
||||
f = open(path, 'r')
|
||||
content = f.readlines()
|
||||
f.close()
|
||||
if path.endswith('.csv'):
|
||||
split_content = []
|
||||
for line in content:
|
||||
split_content += line.split(',')
|
||||
|
||||
content = split_content
|
||||
coefs_raw = []
|
||||
coefs_float = []
|
||||
scaled_coefs = []
|
||||
max_val = 0
|
||||
floating_point = False
|
||||
checked_content = []
|
||||
q = 0
|
||||
for value in content:
|
||||
try:
|
||||
checked_content.append(float(safeNumber(value)))
|
||||
q += 1
|
||||
if str(value).find('.') > 0:
|
||||
floating_point = True
|
||||
except:
|
||||
pass
|
||||
|
||||
content = checked_content
|
||||
if floating_point:
|
||||
for coef in content:
|
||||
scaled_coefs.append(coef)
|
||||
|
||||
else:
|
||||
for raw_coef in content:
|
||||
coef = int(raw_coef)
|
||||
coefs_raw.append(coef)
|
||||
if abs(coef) > max_val:
|
||||
max_val = abs(coef)
|
||||
|
||||
scale = 8388607
|
||||
if max_val >= 16777215:
|
||||
scale = 2147483647
|
||||
scale = scale * 1.0
|
||||
for coef in coefs_raw:
|
||||
coef = coef / scale
|
||||
scaled_coefs.append(coef)
|
||||
|
||||
if len(scaled_coefs) > self.parent.maxnumtaps + 1:
|
||||
print mytime.displayTime() + ' Filter too long:', len(scaled_coefs)
|
||||
dlgMessage = getString('lffmt1') + ' ' + str(len(scaled_coefs)) + ' ' + getString('lffmt2') + ' ' + str(self.parent.maxnumtaps) + ' ' + getString('lffmt3')
|
||||
dlgTitle = getString('lff')
|
||||
res = wx.MessageBox(dlgMessage, dlgTitle, wx.OK | wx.CANCEL)
|
||||
if res != wx.OK:
|
||||
print 'fd.ol.Customer declined filter resampling'
|
||||
return
|
||||
taps = self.parent.RecalculateFIR(scaled_coefs, int(self.parent.maxnumtaps))
|
||||
print mytime.displayTime() + ' Resampled to ', len(taps), 'taps'
|
||||
else:
|
||||
taps = scaled_coefs
|
||||
self.textfield.SetValue(str(len(taps)))
|
||||
self.parent.parent.numtaps = len(taps)
|
||||
self.parent.parent.fir_taps_from_file = taps
|
||||
self.parent.calc_fir_options |= 32768
|
||||
self.file_chkbox.Enable(True)
|
||||
self.file_chkbox.SetValue(1)
|
||||
self.parent.fir_file = os.path.split(path)[1]
|
||||
self.chkboxes[15].SetLabel(self.parent.fir_file)
|
||||
font = self.chkboxes[15].GetFont()
|
||||
dc = wx.ScreenDC()
|
||||
dc.SetFont(font)
|
||||
(w, h) = dc.GetTextExtent(self.parent.fir_file)
|
||||
print 'Size:', w, h
|
||||
self.chkboxes[15].SetSize((w + 50, h + 10))
|
||||
if w + 100 > self.GetSize()[0]:
|
||||
self.SetSize((w + 100, self.GetSize()[1]))
|
||||
for i in range(15):
|
||||
try:
|
||||
self.chkboxes[i].SetValue(0)
|
||||
except:
|
||||
pass
|
||||
|
||||
self.chkboxes[15].SetValue(1)
|
||||
return
|
||||
|
||||
def OnOK(self, evt):
|
||||
self.response = 'OK'
|
||||
try:
|
||||
self.numtaps = self.textfield.GetValue()
|
||||
if self.optkey != None and self.optmask != 0:
|
||||
try:
|
||||
options = int(self.parent.model.get(self.optkey))
|
||||
except:
|
||||
options = self.default_options
|
||||
else:
|
||||
for i in range(0, 31):
|
||||
optnr = self.optmask & 1 << i
|
||||
val = 1 << i
|
||||
if optnr > 0:
|
||||
if self.chkboxes[i].GetValue() == True:
|
||||
options |= val
|
||||
else:
|
||||
options &= 4294967295L - val
|
||||
|
||||
if self.Set == True:
|
||||
self.parent.set_value(self.optkey, options)
|
||||
self.options = options
|
||||
if self.selectkey != None and self.Set == True:
|
||||
s = self.selectfield.GetStringSelection()
|
||||
for (k, v) in self.choices.items():
|
||||
if v == s:
|
||||
v = k
|
||||
if self.value_mask != None:
|
||||
val = int(self.parent.model.get(self.selectkey)) & (4294967295L ^ self.value_mask)
|
||||
val |= int(v)
|
||||
v = val
|
||||
self.parent.set_value(self.selectkey, v)
|
||||
|
||||
except:
|
||||
traceback.print_exc(file=sys.stdout)
|
||||
|
||||
if self.IsModal() == False:
|
||||
self.Destroy()
|
||||
else:
|
||||
self.Close()
|
||||
return
|
||||
|
||||
def OnCancel(self, evt):
|
||||
self.response = 'Cancel'
|
||||
if self.IsModal == False:
|
||||
self.Destroy()
|
||||
else:
|
||||
self.Close()
|
||||
return
|
||||
|
||||
def Update(self, text):
|
||||
if self.infotext == None:
|
||||
return
|
||||
else:
|
||||
if unicode(text) != self.infostring:
|
||||
self.infostring = unicode(text)
|
||||
self.infotext.SetLabel(self.infostring)
|
||||
self.infotext.Wrap(self.wrap)
|
||||
self.Layout()
|
||||
self.SetSizerAndFit(self.mainvbox)
|
||||
return
|
||||
|
||||
def EnableOK(self, OK_Enable):
|
||||
self.OK_button.Enable(OK_Enable)
|
||||
return
|
||||
|
||||
def ShowOK(self, OK_Enable):
|
||||
self.OK_button.Show(OK_Enable)
|
||||
return
|
||||
|
||||
|
||||
|
||||
# okay decompiling pycode/fir_dialog.pyc
|
||||
Reference in New Issue
Block a user