Initial Commit
This commit is contained in:
commit
971e0b8038
|
@ -0,0 +1,366 @@
|
|||
from tkinter import *
|
||||
from tkinter import filedialog
|
||||
from random import *
|
||||
from scipy.io import wavfile #pip install scipy
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
import os
|
||||
|
||||
|
||||
PlotErrors = False
|
||||
|
||||
def wavfile_to_examples(wav_file):
|
||||
"""Convenience wrapper around waveform_to_examples() for a common WAV format.
|
||||
|
||||
Args:
|
||||
wav_file: String path to a file, or a file-like object. The file
|
||||
is assumed to contain WAV audio data with signed 16-bit PCM samples.
|
||||
|
||||
Returns:
|
||||
See waveform_to_examples.
|
||||
"""
|
||||
try:
|
||||
sr, wav_data = wavfile.read(wav_file)
|
||||
except IOError:
|
||||
print("Error reading WAV file!")
|
||||
print("The specified WAV file type is not supported by scipy.io.wavfile.read()")
|
||||
sys.exit(1)
|
||||
|
||||
#if wav_data.dtype != np.int16:
|
||||
# raise TypeError('Bad sample type: %r' % wav_data.dtype)
|
||||
samples = wav_data / 32768.0 # Convert to [-1.0, +1.0]
|
||||
return samples, sr
|
||||
|
||||
|
||||
def DecodeTime(aT):
|
||||
if aT > (1/250): # Silent
|
||||
Bit = 'S'
|
||||
else:
|
||||
if aT > (1/800):
|
||||
Bit = 'T'
|
||||
else:
|
||||
if aT > (1/1500):
|
||||
Bit = '1'
|
||||
else:
|
||||
if aT > (1/3000):
|
||||
Bit = '0'
|
||||
else:
|
||||
Bit = 'E'
|
||||
return Bit
|
||||
|
||||
def GetName(aBlock):
|
||||
if aBlock[0] == 1:
|
||||
NameBlock = []
|
||||
if aBlock[1] == 0xD3: # BASIC
|
||||
for Byte in aBlock[4:12]:
|
||||
if Byte != 0:
|
||||
NameBlock.append(Byte)
|
||||
else: # CHAOS
|
||||
for Byte in aBlock[1:9]:
|
||||
if Byte != 0:
|
||||
NameBlock.append(Byte)
|
||||
Name = ''.join([''.join(chr(ch)) for ch in NameBlock])
|
||||
Name.replace('&','n')
|
||||
else:
|
||||
Name = ''
|
||||
print(Name)
|
||||
return Name.strip()
|
||||
|
||||
def WriteTAB(aBlocks, aFilename):
|
||||
with open(aFilename,'wb') as TAB_file:
|
||||
TAB_file.write(b'\xC3KC-TAPE by AF. ') # C3 4B 43 2D 54 41 50 45 20 62 79 20 41 46 2E 20
|
||||
#Block = [b''.join(ch) for ch in aBlocks[0]]
|
||||
for Block in aBlocks:
|
||||
Bytes = bytes(Block[0:-1])
|
||||
TAB_file.write(Bytes)
|
||||
|
||||
def WriteTABs(aBlocks, aPath):
|
||||
Index = 1
|
||||
NewFile = False
|
||||
Filename = 'Errors.TAP'
|
||||
TAB_file = open(Filename,"wb")
|
||||
TAB_file.close()
|
||||
for Block in aBlocks:
|
||||
if not (len(Block) == 130):
|
||||
print('Bad Block')
|
||||
if Block[0] == 1:
|
||||
Filename = os.path.join(aPath,str(Index).zfill(3) + '_' + GetName(Block) + '.TAP')
|
||||
Index = Index + 1
|
||||
NewFile = True
|
||||
if NewFile:
|
||||
if TAB_file.closed:
|
||||
TAB_file = open(Filename,"wb")
|
||||
else:
|
||||
TAB_file.close()
|
||||
TAB_file = open(Filename,"wb")
|
||||
NewFile = False
|
||||
if not TAB_file.closed:
|
||||
Bytes = bytes(Block)
|
||||
TAB_file.write(Bytes)
|
||||
if Block[0] == 0xFF:
|
||||
TAB_file.close()
|
||||
|
||||
|
||||
|
||||
def WriteRAW(aBlocks, aFilename):
|
||||
with open(aFilename,'wb') as RAW_file:
|
||||
for Block in aBlocks:
|
||||
try:
|
||||
Bytes = bytes(Block)
|
||||
except:
|
||||
print(Block)
|
||||
RAW_file.write(Bytes)
|
||||
|
||||
|
||||
#Block = [1, 211, 211, 211, 72]
|
||||
#Block2 = bytes(Block) #[b''.join(bytes(abyte)) for abyte in Block]
|
||||
|
||||
fenster = Tk()
|
||||
fenster.filename = ""
|
||||
fenster.filename = filedialog.askopenfilename(initialdir = "", title = "Select file", filetypes =(("wav files","*.wav"),("all files","*")))
|
||||
print(fenster.filename)
|
||||
filename = fenster.filename
|
||||
fenster.destroy()
|
||||
|
||||
if os.path.exists(filename) and not (os.path.isdir(filename)):
|
||||
File = os.path.splitext(filename)[0]
|
||||
Ext = os.path.splitext(filename)[1]
|
||||
OutputFile = File + ".TAP"
|
||||
RawFile = File + ".RAW"
|
||||
|
||||
Samples, Rate = wavfile_to_examples(filename)
|
||||
#print(Samples[1:1000,0])
|
||||
|
||||
|
||||
print('Samplerate: ',Rate)
|
||||
AmplitudeL = 0;
|
||||
BestChannel = 0;
|
||||
for data in Samples[0:4410000]: #100s
|
||||
if abs(data[0]) > AmplitudeL:
|
||||
AmplitudeL = abs(data[0]);
|
||||
print('Amplitude Links:',AmplitudeL)
|
||||
AmplitudeR = 0;
|
||||
for data in Samples[0:4410000]: #100s
|
||||
if abs(data[1]) > AmplitudeR:
|
||||
AmplitudeR = abs(data[1]);
|
||||
print('Amplitude Rechts:',AmplitudeR)
|
||||
if AmplitudeR > AmplitudeL:
|
||||
BestChannel = 1;
|
||||
|
||||
Bitstream = []
|
||||
Periode1 = 0
|
||||
Periode2 = 0
|
||||
LastData1 = 0
|
||||
LastData2 = 0
|
||||
LastData3 = 0
|
||||
LastData4 = 0
|
||||
LastData5 = 0
|
||||
LastData = 0
|
||||
NextData = 0
|
||||
Min1 = 1.0
|
||||
Max1 = -1.0
|
||||
|
||||
Min2 = 1.0
|
||||
Max2 = -1.0
|
||||
|
||||
CalcSpeedError = True;
|
||||
Speedfaktor = 1.0
|
||||
|
||||
EinsCount = 0
|
||||
EinsTime = 0.0
|
||||
|
||||
UseDecoder = 0
|
||||
EnableDecoder1 = True # Damit er nicht 2x bei der steigenden Flanke auslöst
|
||||
EnableDecoder2 = True
|
||||
|
||||
|
||||
SampeNr = -1
|
||||
for data in Samples:
|
||||
SampeNr = SampeNr + 1
|
||||
Periode1 = Periode1 + 1
|
||||
Periode2 = Periode2 + 1
|
||||
Ellongation = data[BestChannel]
|
||||
if Min1 > Ellongation:
|
||||
Min1 = Ellongation
|
||||
if Max1 < Ellongation:
|
||||
Max1 = Ellongation
|
||||
Zero1 = Min1 + ((Max1 - Min1) / 2)
|
||||
|
||||
if Min2 > Ellongation:
|
||||
Min2 = Ellongation
|
||||
if Max2 < Ellongation:
|
||||
Max2 = Ellongation
|
||||
Zero2 = Min2 + ((Max2 - Min2) / 2)
|
||||
|
||||
LastData = (LastData3 + LastData4 + LastData5) / 3
|
||||
NextData = (Ellongation + LastData1 + LastData2) /3
|
||||
|
||||
if (Periode2 > 8) and (Zero2 > LastData) and (Zero2 < NextData):
|
||||
EnableDecoder2 = True
|
||||
if (EnableDecoder2) and (Periode2 > 8) and (Zero2 < LastData) and (Zero2 > NextData):
|
||||
T = (Periode2 / Rate) * Speedfaktor
|
||||
Periode2 = 0
|
||||
EnableDecoder2 = False
|
||||
EnableDecoder1 = True
|
||||
Min2 = Ellongation
|
||||
Max2 = Ellongation
|
||||
Bit = DecodeTime(T);
|
||||
if (UseDecoder == 0) and (Bit == 'T'):
|
||||
UseDecoder = 2
|
||||
#print('Decoder 2')
|
||||
if UseDecoder == 2:
|
||||
Bitstream.append([Bit,SampeNr-2]) # Nullstelle Speichern
|
||||
|
||||
if (Periode1 > 8) and (Zero1 < LastData) and (Zero1 > NextData):
|
||||
EnableDecoder1 = True
|
||||
if (EnableDecoder1) and (Periode1 > 8) and (Zero1 > LastData) and (Zero1 < NextData):
|
||||
T = (Periode1 / Rate) * Speedfaktor
|
||||
#print(Periode, Min, Max, Zero, LastData1, Ellongation )
|
||||
Periode1 = 0
|
||||
EnableDecoder1 = False
|
||||
EnableDecoder2 = True
|
||||
Min1 = Ellongation
|
||||
Max1 = Ellongation
|
||||
Bit = DecodeTime(T);
|
||||
if (UseDecoder == 0) and (Bit == 'T'):
|
||||
UseDecoder = 1
|
||||
#print('Decoder 1')
|
||||
if UseDecoder <= 1:
|
||||
Bitstream.append([Bit,SampeNr-2]) # Nullstelle Speichern
|
||||
if Bit == '1':
|
||||
EinsCount = EinsCount + 1
|
||||
EinsTime = EinsTime + T
|
||||
if (EinsCount == 50):
|
||||
UseDecoder = 0
|
||||
EnableDecoder1 = True
|
||||
EnableDecoder2 = True
|
||||
if (CalcSpeedError):
|
||||
Speedfaktor = (1/1200) / (EinsTime / EinsCount)
|
||||
CalcSpeedError = False
|
||||
else:
|
||||
EinsCount = 0
|
||||
EinsTime = 0.0
|
||||
|
||||
LastData5 = LastData4
|
||||
LastData4 = LastData3
|
||||
LastData3 = LastData2
|
||||
LastData2 = LastData1
|
||||
LastData1 = Ellongation
|
||||
|
||||
print('Speedfaktor = ', Speedfaktor)
|
||||
#print(Bitstream[0:100])
|
||||
|
||||
EinsCount = 0;
|
||||
FileFound = False
|
||||
Blocknummer = 1
|
||||
Bytenummer = 0
|
||||
Block = []
|
||||
Blocks = []
|
||||
Byte = 0
|
||||
Bitcounter = 0;
|
||||
BlockFound = False;
|
||||
BitstreamIndex = -1;
|
||||
for Bit in Bitstream:
|
||||
BitstreamIndex = BitstreamIndex + 1
|
||||
if (Bit[0] == '1') :
|
||||
EinsCount = EinsCount + 1
|
||||
if (Bitcounter < 8):
|
||||
#Byte = Byte | (1 << Bitcounter) # hier stehen die ersten bits richtig wenn nur 7bit
|
||||
Byte = (Byte >> 1) | 0x80 # hier stehen die letzten bits richtig wenn nur 7bit
|
||||
Bitcounter = Bitcounter + 1
|
||||
else:
|
||||
if (Bit[0] != 'T'):
|
||||
EinsCount = 0
|
||||
if Bit[0] == '0':
|
||||
Byte = (Byte >> 1) # hier stehen die letzten bits richtig wenn nur 7bit
|
||||
Bitcounter = Bitcounter + 1
|
||||
#if Bit[0] == 'E':
|
||||
# print('Fehlerhaftes Bit')
|
||||
#if Bit[0] == 'S':
|
||||
# print('Stille')
|
||||
|
||||
|
||||
if (EinsCount > 300) and (Bit[0] == 'T'): #Newfile
|
||||
FileFound = True;
|
||||
print('File Found')
|
||||
File = []
|
||||
Block = []
|
||||
BlockFound = False
|
||||
Blocknummer = 1
|
||||
Bytenummer = 0
|
||||
IndexFehlerhaft = 0
|
||||
if FileFound:
|
||||
if ((Bytenummer == 130)):
|
||||
if (Blocknummer == 1):
|
||||
Name = [''.join(chr(ch)) for ch in Block[1:12]]
|
||||
print(''.join(Name))
|
||||
#print(chr(Block[1]))
|
||||
Blocks.append(Block)
|
||||
summe = 0
|
||||
for byte in Block[1:-1]:
|
||||
summe = summe + byte
|
||||
summe = summe & 0xFF
|
||||
if summe != Block [-1]:
|
||||
print('%d Summe %d NOK Read %d' % (Block [0], summe, Block [-1]))
|
||||
print(Block)
|
||||
if (IndexFehlerhaft > 0) and (IndexFehlerhaft < 129):
|
||||
print('Fehlerhaftes Byte konnte identifiziert werden', IndexFehlerhaft)
|
||||
print('Gelesen wurde: ', Block[IndexFehlerhaft-1])
|
||||
Block[IndexFehlerhaft-1] = (Block[IndexFehlerhaft-1] + ((Block[-1] - summe) & 0xFF)) & 0xFF
|
||||
print('Sollte laut Summe sein: ', Block[IndexFehlerhaft-1])
|
||||
summe = 0
|
||||
for byte in Block[1:-1]:
|
||||
summe = summe + byte
|
||||
summe = summe & 0xFF
|
||||
if summe == Block [-1]:
|
||||
print('Korrigiert!')
|
||||
else:
|
||||
print('Mehr als einn Byte Fehlerhaft')
|
||||
|
||||
else:
|
||||
print('%d OK' % Block [0])
|
||||
#Name = [''.join(chr(ch)) for ch in Block[1:-1]]
|
||||
#print(''.join(Name))
|
||||
if Block[0] == 0xFF:
|
||||
FileFound = False
|
||||
Block = []
|
||||
Blocknummer = Blocknummer + 1;
|
||||
Bytenummer = 0
|
||||
IndexFehlerhaft = 0
|
||||
BlockFound = False
|
||||
#print('Block ',Blocknummer)
|
||||
if (not BlockFound) and (EinsCount > 50) and (Bit[0] == 'T'): # neuer Block
|
||||
Bitcounter = 0
|
||||
Bytenummer = 0
|
||||
Byte = 0
|
||||
BlockFound = True
|
||||
else:
|
||||
if Bit[0] == 'T' and BlockFound:
|
||||
Block.append(Byte & 0xFF)
|
||||
Bytenummer = Bytenummer + 1;
|
||||
Byte = 0
|
||||
if Bitcounter != 8:
|
||||
print('Fehlerhafte Bytelänge %d im Block %d und Byte %d' % (Bitcounter,Blocknummer,Bytenummer))
|
||||
if IndexFehlerhaft == 0:
|
||||
IndexFehlerhaft = Bytenummer
|
||||
else:
|
||||
IndexFehlerhaft = -1
|
||||
Bytelaenge = round(11*Rate/1200)
|
||||
Stuetzstellen = [Bitstream[X][1] for X in range(BitstreamIndex-11, BitstreamIndex+1)]
|
||||
Stuetzbits = ''.join([Bitstream[X][0] for X in range(BitstreamIndex-11, BitstreamIndex+1)])
|
||||
#print(Stuetzstellen)
|
||||
if PlotErrors:
|
||||
plt.plot([X for X in range((Bit[1]-Bytelaenge),(Bit[1]))],Samples[(Bit[1]-Bytelaenge):(Bit[1]),BestChannel], "-b" , label=(('1/%d' % round(1200*Speedfaktor))+ Stuetzbits))
|
||||
plt.plot(Stuetzstellen, [Samples[X,BestChannel] for X in Stuetzstellen], "or")# [Samples[Y,BestChannel] for Y in Bitstream[BitstreamIndex-11: BitstreamIndex+1][1]], "or")
|
||||
plt.legend(loc='upper right')
|
||||
plt.show()
|
||||
Bitcounter = 0
|
||||
#if Bit[0] == 'S':
|
||||
# FileFound = False;
|
||||
#print(Blocks)
|
||||
#WriteTAB(Blocks, OutputFile)
|
||||
WriteRAW(Blocks, RawFile)
|
||||
WriteTABs(Blocks, os.path.dirname(os.path.abspath(OutputFile)))
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue