diff options
-rw-r--r-- | utilities/blinkenrocket.py | 176 | ||||
-rw-r--r-- | utilities/hammington2416.py | 31 | ||||
-rw-r--r-- | utilities/modem.py | 111 |
3 files changed, 176 insertions, 142 deletions
diff --git a/utilities/blinkenrocket.py b/utilities/blinkenrocket.py new file mode 100644 index 0000000..6dc3ea6 --- /dev/null +++ b/utilities/blinkenrocket.py @@ -0,0 +1,176 @@ +#!/usr/bin/env python + +import sys, wave + +class modem: + + # Modem specific constants + bits = [[3 * chr(0), 5 * chr(0)], [3 * chr(255), 5 * chr(255)]] + sync = [17 * chr(0), 17 * chr(255)] + # Variable to alternate high and low + hilo = 0 + supportedFrequencies = [16000,22050,24000,32000,44100,48000] + cnt = 0 + # Data variables + data = [] + parity = True + frequency = 48000 + + # Hamming code translation table + _hammingCalculateParityLowNibble = [0, 3, 5, 6, 6, 5, 3, 0, 7, 4, 2, 1, 1, 2, 4, 7] + _hammingCalculateParityHighNibble = [0, 9, 10, 3, 11, 2, 1, 8, 12, 5, 6, 15, 7, 14, 13, 4] + + # Almost nothing here + def __init__(self, data=[], parity=True, frequency=48000): + self.data = data + self.parity = parity + self.frequency = frequency if frequency in self.supportedFrequencies else 48000 + + # Calculate Hamming parity for 12,8 code (12 bit of which 8bit data) + def hammingCalculateParity128(self, byte): + return self._hammingCalculateParityLowNibble[byte&0x0F] ^ self._hammingCalculateParityHighNibble[byte >> 4] + + # Calculate Hamming parity for 24,16 code (24 bit of which 16 bit are data) + def hammingCalculateParity2416(self, first, second): + return self.hammingCalculateParity128(second) << 4 | self.hammingCalculateParity128(first) + + # Generate one sync-pulse + def syncsignal(self): + self.hilo ^= 1 + return self.sync[self.hilo] + + # Generate a number of sync signals + def generateSyncSignal(self, number): + sound = "" + for i in xrange(number): + sound += self.syncsignal() + return sound + + # Decode bits to modem signals + def modemcode(self, byte): + bleep = "" + for x in xrange(8): + self.hilo ^= 1 + bleep += self.bits[self.hilo][byte & 0x01] + byte >>= 1 + return bleep + + # Return <length> samples of silence + def silence(self, length): + return chr(127) * length + + # Set data for modem code + def setData(self, data): + self.data = data + + # Set whether to use parity or not + def setParity(self, parity): + self.parity = parity + + # Set the frequency for the audio + def setFrequency(self, frequency): + self.frequency = frequency if frequency in self.supportedFrequencies else 48000 + + # Generates the audio frames based on the data + def generateAudioFrames(self): + if self.parity: + tmpdata = [] + # for uneven length data, we have to append a null byte + if not len(self.data) % 2 == 0: + self.data.append(ord(0)) + # insert the parity information every two bytes, sorry for the heavy casting + for index in range(0, len(self.data), 2): + tmpdata.extend(self.data[index:index+2]) + tmpdata.append(chr(self.hammingCalculateParity2416(ord(self.data[index]),ord(self.data[index+1])))) + self.data = tmpdata + # generate the audio itself + # add some sync signal in front + sound = self.generateSyncSignal(4) + # process the data and insert sync signal every 10 bytes + for byte in self.data: + sound += self.modemcode(ord(byte)) + self.cnt += 1 + if self.cnt == 10: + sound += m.generateSyncSignal(2) + self.cnt = 0 + # add some sync signals in the end + sound += m.generateSyncSignal(4) + return sound + + def saveAudio(self,filename): + wav = wave.open(filename, 'wb') + wav.setparams((1, 1, self.frequency, 0, "NONE", None)) + wav.writeframes(self.generateAudioFrames()) + wav.close() + +class textFrame(): + text = "" + speed = 0 + delay = 0 + direction = 0 + + def __init__(self,text,speed=1,delay=0,direction=0): + self.text = text + self.setSpeed(speed) + self.setDelay(delay) + self.setDirection(direction) + + def setSpeed(self,speed): + self.speed = speed if speed < 16 else 1 + + def setDelay(self,delay): + self.delay = delay if delay < 16 else 0 + + def setDirection(self,direction): + self.direction = direction if direction in [0,1] else 0 + + # Header -> 4bit speed, 4 bit delay, 4 bit direction, 4 bit zero + def getHeader(self): + return [chr(self.speed << 4 | self.delay), chr(self.direction << 4 | 0x00)] + + def getRepresentation(self): + return self.getHeader().append(list(self.text)) + +class animationFrame(): + animation = [] + speed = 0 + delay = 0 + + def __init__(self,animation,speed=1,delay=0): + self.setAnimation(animation) + self.setSpeed(speed) + self.setDelay(delay) + + def setAnimation(self,animation): + if len(animation) % 8 is not 0: + raise Exception + else: + self.animation = animation + + def setSpeed(self,speed): + self.speed = speed if speed < 16 else 1 + + def setDelay(self,delay): + self.delay = delay if delay < 16 else 0 + + # Header -> 4bit zero, 4bit speed, 4 bit zero, 4 bit direction + def getHeader(self): + return [self.speed, self.delay] + + def getRepresentation(self): + return self.getHeader().extend(self.animation) + +class blinkenrocket(): + + eeprom_size = 65536 + + def __init__(self,eeprom_size=65536): + pass + + +if __name__ == '__main__': + m = modem() + m.setData(['M','U','Z','Y']) + print m.generateAudioFrames() + + diff --git a/utilities/hammington2416.py b/utilities/hammington2416.py deleted file mode 100644 index 8e60a33..0000000 --- a/utilities/hammington2416.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/python - -import sys - -_hammingCalculateParityLowNibble = [0, 3, 5, 6, 6, 5, 3, 0, 7, 4, 2, 1, 1, 2, 4, 7] -_hammingCalculateParityHighNibble = [0, 9, 10, 3, 11, 2, 1, 8, 12, 5, 6, 15, 7, 14, 13, 4] - -def HammingCalculateParity128(byte): - return _hammingCalculateParityLowNibble[byte&0x0F] ^ _hammingCalculateParityHighNibble[byte >> 4] - -def HammingCalculateParity2416(first, second): - return HammingCalculateParity128(second) << 4 | HammingCalculateParity128(first) - -output = "" -bytepos = 0 -oldbyte = None - -# Read bytewise -f = open(sys.argv[1]) -for byte in f.read(): - output += byte - oldbyte = byte - bytepos += 1 - if bytepos == 2: - bytepos = 0 - output += str(HammingCalculateParity2416(ord(oldbyte), ord(byte))) -if bytepos == 1: - output += "\x00" - output += str(HammingCalculateParity2416(ord(oldbyte), ord("\x00"))) - -print output
\ No newline at end of file diff --git a/utilities/modem.py b/utilities/modem.py deleted file mode 100644 index f2e2b1b..0000000 --- a/utilities/modem.py +++ /dev/null @@ -1,111 +0,0 @@ -#!/usr/bin/env python - -import sys, wave - -# -# "Modem" wav creator for "Next Gen" Tagsu Modem :) -# -# Author: Jari Tulilahti -# Copyright: 2014 Rakettitiede Oy -# License: LGPLv3, see COPYING and COPYING.LESSER -files for more info -# -# Usage: -# python modem.py <input_filename> [output_wav_filename] [samplerate] -# -# Default sample rate is 48000 -# Default output to stdout if no wav filename given -# -# Working sample rates are between 16000 - 48000: -# -# 16000 (~4000 bps) -# 22050 (~5500 bps) -# 24000 (~6000 bps) -# 32000 (~8000 bps) -# 44100 (~11025 bps) -# 48000 (~12000 bps) -# -# NOTICE: -# -# Actual speed depends of the data, as zeroes and ones take -# different amount of samples, the more zeros, the faster the speed. -# Average bps has been calculated using data "0101010101..." -# - -class modem: - - bits = [[3 * chr(0), 5 * chr(0)], [3 * chr(255), 5 * chr(255)]] - sync = [17 * chr(0), 17 * chr(255)] - hilo = 0 - - # Nothing here - def __init__(self): - pass - - # Generate one sync-pulse - def syncsignal(self): - self.hilo ^= 1 - return self.sync[self.hilo] - - # Decode bits to modem signals - def modemcode(self, byte): - bleep = "" - for x in xrange(8): - self.hilo ^= 1 - bleep += self.bits[self.hilo][byte & 0x01] - byte >>= 1 - return bleep - - # Return <length> samples of silence - def silence(self, length): - return chr(127) * length - - -if len(sys.argv) < 2: - print """Usage: {0} <input_filename> [output_wav_filename] [samplerate] - - input_filename Data file as input to modem. - output_wav_filename Write output-wav to this file. If empty, output to STDOUT. - samplerate Sample rate between 16000 - 48000. Default is 48000. - """.format(sys.argv[0]) - sys.exit() - -sound = "" - -m = modem() -cnt = 0 - -# Add silence -# sound += m.silence(24000) - -# Add 4 sync signals to start -for x in xrange(4): - sound += m.syncsignal() - -# Send Actual data -f = open(sys.argv[1]) -for byte in f.read(): - sound += m.modemcode(ord(byte)) - - # Add counter - cnt += 1 - - # After every 10 bytes, send 2 sync signals - if cnt == 10: - for x in xrange(2): - sound += m.syncsignal() - cnt = 0 - -# End transmission with few sync-signals -for x in xrange(4): - sound += m.syncsignal() - -# Output the generated sound (no wav headers) -if len(sys.argv) <= 2: - print sound -else: - freq = int(sys.argv[3]) if len(sys.argv) > 3 else 48000 - wav = wave.open(sys.argv[2], 'wb') - wav.setparams((1, 1, freq, 0, "NONE", None)) - wav.writeframes(sound) - wav.close() - |