-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathxi_reader.py
More file actions
90 lines (75 loc) · 2.94 KB
/
xi_reader.py
File metadata and controls
90 lines (75 loc) · 2.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
from ctypes import *
import struct
import sys
f = open(sys.argv[1])
#f = open('/Users/a/Music/Sunvox/Sonatina Symphonic Orchestra/Keys - Grand Piano.xi', 'r')
file = f.read()
pos = 0
xi, instrument, tracker, major_version, minor_version = struct.unpack('21s22sx20s2b', file[pos:(pos + 0x42)])
pos += 0x42
print '/' * 80
print 'Sample info'
print xi, instrument, tracker, major_version, minor_version
note_samples = struct.unpack('96b', file[pos:(pos + 0x60)])
pos += 0x60
print '/' * 80
print 'Samples-notes map'
print note_samples
volume_envelope = struct.unpack('24h', file[pos:(pos + 0x30)])
pos += 0x30
#volume_envelope = dict(volume_envelope[::2], volume_envelope[1::2])
print '/' * 80
print 'Volume envelope:'
print volume_envelope
panning_envelope = struct.unpack('24h', file[pos:(pos + 0x30)])
pos += 0x30
#volume_envelope = dict(volume_envelope[::2], volume_envelope[1::2])
print '/' * 80
print 'Panning envelope:'
print panning_envelope
volume_points_number, panning_points_number, \
volume_sustain_point, volume_loop_start_point, volume_loop_end_point, \
panning_sustain_point, panning_loop_start_point, panning_loop_end_point, \
volume_type, panning_type, \
vibrato_type, vibrato_sweep, vibrato_depth, vibrato_rate \
= struct.unpack('14b', file[pos:(pos + 0xe)])
pos += 0xe
print '/' * 80
print 'Volume and sustain points numbers:', volume_points_number, panning_points_number
print 'Volume sustain point:', volume_sustain_point
print 'Volume loop start and end points:', volume_loop_start_point, volume_loop_end_point
print '/' * 80
print 'Panning sustain point:', panning_sustain_point
print 'Panning loop start and end points:', panning_loop_start_point, panning_loop_end_point
print 'Volume type:', volume_type
print 'Panning type:', panning_type
print 'Vibrato type, weep, depth and rate:', vibrato_type, vibrato_sweep, vibrato_depth, vibrato_rate
volume_fadeout = struct.unpack('h', file[pos:(pos + 0x2)])[0]
pos += 0x2
print 'Volume fadeout:', volume_fadeout
extended_info = struct.unpack('22b', file[pos:(pos + 0x16)])
pos += 0x16
print '/' * 80
print 'Extended info (mostly zeros):'
print extended_info
pos = 0x128
samples_number = struct.unpack('h', file[pos:(pos + 0x2)])[0]
print '/' * 80
print 'Samples count: ', samples_number
print '/' * 80
print 'Sample data:'
pos = 0x12a
samples = range(samples_number)
for i in range(samples_number):
samples[i] = {}
samples[i]['length'], samples[i]['loop_start'], samples[i]['loop_length'], \
samples[i]['volume'], samples[i]['finetune'], samples[i]['type'], \
samples[i]['panning'], samples[i]['transpose'], samples[i]['sample_name_length'], \
samples[i]['sample_name'] = struct.unpack('3i6b22s', file[pos:(pos + 40)])
pos += 40
print samples[i]
# for i in range(samples_number):
# samples[i]['data'] = struct.unpack(str(samples[i]['length']) + 'b', file[pos:(pos + samples[i]['length'])])
# pos += samples[i]['length']
#, volume_envelope_points, \
#panning_envelope_points, volume_points_number, panning_points_number = x