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>
181 lines
5.5 KiB
Python
181 lines
5.5 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: cleanImage.pyc
|
|
# Compiled at: 2022-10-28 07:19:25
|
|
import mytime, struct
|
|
|
|
def findDataSize(data):
|
|
i = len(data) - 1
|
|
while i > 0:
|
|
if ord(data[i]) != 255:
|
|
return i + 1
|
|
i -= 1
|
|
|
|
return
|
|
|
|
|
|
def verifyChecksum(data):
|
|
if ord(data[0]) == 251:
|
|
return True
|
|
else:
|
|
dataSize = findDataSize(data)
|
|
Checksum = 1454917101
|
|
i = 0
|
|
while i < (dataSize - 4) / 4:
|
|
Checksum = Checksum ^ ord(data[i])
|
|
i += 1
|
|
|
|
while i < (dataSize - 4) / 2:
|
|
Checksum = Checksum ^ ord(data[i]) << 8 & 65280
|
|
i += 1
|
|
|
|
while i < dataSize - 4:
|
|
Checksum = Checksum ^ ord(data[i]) << 16 & 16711680
|
|
i += 1
|
|
|
|
try:
|
|
storedChecksum = struct.unpack('<L', data[dataSize - 4:dataSize])[0]
|
|
except:
|
|
return False
|
|
|
|
if storedChecksum == Checksum:
|
|
return True
|
|
print 'Checksum FAILED, calculated', hex(Checksum), ' but file says', hex(storedChecksum), 'preset corrupt?'
|
|
return False
|
|
return
|
|
|
|
|
|
updateImageStartAddress = 0
|
|
|
|
def verifySectorsperSlot(srcPath, sectorsPerSlot, flashDiskStart, sectorSize):
|
|
f = open(srcPath, 'rb')
|
|
data = f.read()
|
|
f.close()
|
|
mytime.sleep(0.1)
|
|
slots = {}
|
|
txt = 'Verifying slot size for ' + srcPath + ' with slot size ' + str(sectorsPerSlot) + ', data length ' + str(len(data)) + ' bytes, sector size ' + str(sectorSize) + ' bytes'
|
|
slotSize = sectorsPerSlot * sectorSize
|
|
data = data[flashDiskStart - updateImageStartAddress:]
|
|
address = flashDiskStart
|
|
verified = True
|
|
foundGlobal = False
|
|
foundLastPreset = False
|
|
while len(data) >= sectorSize:
|
|
slot = data[:slotSize]
|
|
if ord(slot[0]) == 251:
|
|
foundGlobal = True
|
|
if ord(slot[0]) == 252:
|
|
foundLastPreset = True
|
|
if ord(slot[0]) != 0 and ord(slot[0]) != 251 and ord(slot[0]) != 255:
|
|
checksum = verifyChecksum(slot)
|
|
print 'verified slot', ord(slot[0]), 'naam:', slot[65:81], 'resultaat:', checksum, 'for', sectorsPerSlot, 'sectors per slot'
|
|
if checksum == False:
|
|
verified = False
|
|
break
|
|
data = data[slotSize:]
|
|
address += slotSize
|
|
|
|
if foundGlobal == False or foundLastPreset == False:
|
|
verified = False
|
|
if verified == True:
|
|
txt += ': PASS'
|
|
try:
|
|
print txt
|
|
except:
|
|
pass
|
|
|
|
else:
|
|
try:
|
|
txt += ': FAIL'
|
|
print txt
|
|
except:
|
|
pass
|
|
|
|
return verified
|
|
|
|
|
|
def getSectorsPerSlot(srcPath, sectorsPerSlot, flashDiskStart, sectorSize, limit):
|
|
res = 0
|
|
aantalGevonden = 0
|
|
while True:
|
|
if verifySectorsperSlot(srcPath, sectorsPerSlot, flashDiskStart, sectorSize):
|
|
res = sectorsPerSlot
|
|
return res
|
|
aantalGevonden += 1
|
|
sectorsPerSlot += 1
|
|
if sectorsPerSlot > limit:
|
|
break
|
|
|
|
if aantalGevonden != 1:
|
|
print 'ERROR -> niet 1 flash disk size gevonden', res, aantalGevonden
|
|
return None
|
|
else:
|
|
return res
|
|
|
|
|
|
def cleanImage(srcPath, targetPath, sectorsPerSlot, flashDiskStart, sectorSize, limit):
|
|
sectorsPerSlot = getSectorsPerSlot(srcPath, sectorsPerSlot, flashDiskStart, sectorSize, limit)
|
|
print 'FFI slot size:', sectorsPerSlot
|
|
if sectorsPerSlot == None:
|
|
print 'Failed to verify slot size! Image unchanged'
|
|
f = open(srcPath, 'rb')
|
|
data = f.read()
|
|
f.close()
|
|
mytime.sleep(0.5)
|
|
f = open(targetPath, 'wb')
|
|
f.write(data)
|
|
f.close()
|
|
return
|
|
else:
|
|
f = open(srcPath, 'rb')
|
|
data = f.read()
|
|
f.close()
|
|
mytime.sleep(0.1)
|
|
slots = {}
|
|
try:
|
|
txt = mytime.displayTime() + ' Cleaning ' + srcPath
|
|
print txt
|
|
except:
|
|
pass
|
|
|
|
slotSize = sectorsPerSlot * sectorSize
|
|
outData = data[:flashDiskStart]
|
|
data = data[flashDiskStart:]
|
|
address = flashDiskStart
|
|
print 'd_p.Flash info: Slot size:', slotSize, 'sector size:', sectorSize, 'data length:', len(data), 'flash disk start address:', flashDiskStart
|
|
while len(data) >= sectorSize:
|
|
slot = data[:slotSize]
|
|
if ord(slot[0]) != 0 and ord(slot[0]) != 255:
|
|
checksum = verifyChecksum(slot)
|
|
slots[ord(slot[0])] = slot
|
|
data = data[slotSize:]
|
|
address += slotSize
|
|
|
|
for slotNumber in sorted(slots.keys()):
|
|
slotData = slots[slotNumber]
|
|
if slotNumber == 251:
|
|
slotName = 'Global: ' + slotData[1:17]
|
|
elif slotNumber == 252:
|
|
slotName = 'Last Setting: ' + slotData[67:83]
|
|
elif slotNumber < 10:
|
|
slotName = 'Preset: ' + slotData[67:83]
|
|
else:
|
|
slotName = 'Preset: ' + slotData[67:83]
|
|
txt = mytime.displayTime() + ' Appending slot ' + str(slotNumber) + ': ' + slotName
|
|
print txt
|
|
outData += slotData
|
|
|
|
f = open(targetPath, 'wb')
|
|
f.write(outData)
|
|
f.close()
|
|
mytime.sleep(0.1)
|
|
return
|
|
|
|
|
|
if __name__ == '__main__':
|
|
cleanImage('presets/NAW/99_mac.ffi', 'presets/NAW/99_mac.ffi_compacted', 4, 196608, 4096, 16)
|
|
|
|
# okay decompiling pycode/cleanImage.pyc
|