Skip to content

Instantly share code, notes, and snippets.

@jangler
Created October 4, 2012 19:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jangler/3836002 to your computer and use it in GitHub Desktop.
Save jangler/3836002 to your computer and use it in GitHub Desktop.
Amiga module reader
#!/usr/bin/env python
periods = (
1712,1616,1525,1440,1357,1281,1209,1141,1077,1017, 961, 907,
856, 808, 762, 720, 678, 640, 604, 570, 538, 508, 480, 453,
428, 404, 381, 360, 339, 320, 302, 285, 269, 254, 240, 226,
214, 202, 190, 180, 170, 160, 151, 143, 135, 127, 120, 113,
107, 101, 95, 90, 85, 80, 76, 71, 67, 64, 60, 57
)
def sum_bytes(b):
result = 0
for i in range(len(b)):
result += b[i] << (8 * i)
return result
def null_bytes(n):
result = []
for i in range(0, n):
result.append(0)
return bytes(result)
class Sample:
def __init__(self):
pass
def read_header(self, f):
self.name = f.read(22)
self.length = f.read(2)
self.finetune = f.read(1)
self.volume = f.read(1)
self.offset = f.read(2)
self.repeat = f.read(2)
def read_data(self, f):
self.data = f.read(sum_bytes(self.length))
def create_new(self):
self.name = null_bytes(22)
self.length = null_bytes(2)
self.finetune = null_bytes(1)
self.volume = null_bytes(1)
self.offset = null_bytes(2)
self.repeat = null_bytes(2)
self.data = null_bytes(0)
def write_header(self, f):
f.write(self.name)
f.write(self.length)
f.write(self.finetune)
f.write(self.volume)
f.write(self.offset)
f.write(self.repeat)
def write_data(self, f):
f.write(self.data)
class Division:
def __init__(self):
pass
def read(self, f):
data = f.read(4)
self.sample = (data[0] & 0xf0) | ((data[2] & 0xf0) >> 4)
self.period = ((data[0] & 0x0f) << 8) | data[1]
self.effect = ((data[2] & 0x0f) << 8) | data[3]
def create_new(self):
self.sample = 0
self.period = 0
self.effect = 0
def write(self, f):
b0 = (self.sample & 0xf0) | ((self.period & 0xf00) >> 8)
b1 = self.period & 0xff
b2 = ((self.sample & 0x0f) << 4) | ((self.effect & 0xf00) >> 8)
b3 = self.effect & 0xff
f.write(bytes((b0, b1, b2, b3)))
class Pattern:
def __init__(self):
pass
def read(self, f):
self.divisions = []
for d in range(0, 64):
self.divisions.append([])
for c in range(0, 4):
div = Division()
div.read(f)
self.divisions[d].append(div)
def create_new(self):
self.divisions = []
for d in range(0, 64):
self.divisions.append([])
for c in range(0, 4):
div = Division()
div.create_new()
self.divisions[d].append(div)
def write(self, f):
for d in range(0, 64):
for c in range(0, 4):
self.divisions[d][c].write(f)
class Module:
def __init__(self):
pass
def read(self, f):
self.title = f.read(20)
self.samples = []
for i in range(0, 31):
sample = Sample()
sample.read_header(f)
self.samples.append(sample)
self.num_positions = f.read(1)
self.restart_pos = f.read(1)
self.pattern_table = bytearray(f.read(128))
self.num_patterns = 0
for i in range(0, 128):
if self.pattern_table[i] > self.num_patterns:
self.num_patterns = self.pattern_table[i]
self.num_patterns += 1
self.initials = f.read(4)
self.patterns = []
for i in range(0, self.num_patterns):
pattern = Pattern()
pattern.read(f)
self.patterns.append(pattern)
for i in range(0, 31):
self.samples[i].read_data(f)
def create_new(self):
self.title = null_bytes(20)
self.samples = []
for i in range(0, 31):
sample = Sample()
sample.create_new()
self.samples.append(sample)
self.num_positions = bytes([1])
self.restart_pos = null_bytes(1)
self.pattern_table = bytearray(null_bytes(128))
self.num_patterns = 1
self.initials = bytes('M.K.', 'utf-8')
self.patterns = []
for i in range(0, self.num_patterns):
pattern = Pattern()
pattern.create_new()
self.patterns.append(pattern)
def write(self, f):
f.write(self.title)
for i in range(0, 31):
self.samples[i].write_header(f)
f.write(self.num_positions)
f.write(self.restart_pos)
f.write(bytes(self.pattern_table))
f.write(self.initials)
for i in range(0, self.num_patterns):
self.patterns[i].write(f)
for i in range(0, 31):
self.samples[i].write_data(f)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment