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)))