+++ /dev/null
-# -*- coding: ISO-8859-1 -*-\r
-\r
-from struct import pack, unpack\r
-\r
-"""\r
-This module contains functions for reading and writing the special data types\r
-that a midi file contains.\r
-"""\r
-\r
-"""\r
-nibbles are four bits. A byte consists of two nibles.\r
-hiBits==0xF0, loBits==0x0F Especially used for setting\r
-channel and event in 1. byte of musical midi events\r
-"""\r
-\r
-\r
-\r
-def getNibbles(byte):\r
- """\r
- Returns hi and lo bits in a byte as a tuple\r
- >>> getNibbles(142)\r
- (8, 14)\r
- \r
- Asserts byte value in byte range\r
- >>> getNibbles(256)\r
- Traceback (most recent call last):\r
- ...\r
- ValueError: Byte value out of range 0-255: 256\r
- """\r
- if not 0 <= byte <= 255:\r
- raise ValueError('Byte value out of range 0-255: %s' % byte)\r
- return (byte >> 4 & 0xF, byte & 0xF)\r
-\r
-\r
-def setNibbles(hiNibble, loNibble):\r
- """\r
- Returns byte with value set according to hi and lo bits\r
- Asserts hiNibble and loNibble in range(16)\r
- >>> setNibbles(8, 14)\r
- 142\r
- \r
- >>> setNibbles(8, 16)\r
- Traceback (most recent call last):\r
- ...\r
- ValueError: Nible value out of range 0-15: (8, 16)\r
- """\r
- if not (0 <= hiNibble <= 15) or not (0 <= loNibble <= 15):\r
- raise ValueError('Nible value out of range 0-15: (%s, %s)' % (hiNibble, loNibble))\r
- return (hiNibble << 4) + loNibble\r
-\r
-\r
-\r
-def readBew(value):\r
- """\r
- Reads string as big endian word, (asserts len(value) in [1,2,4])\r
- >>> readBew('aáâã')\r
- 1642193635L\r
- >>> readBew('aá')\r
- 25057\r
- """\r
- return unpack('>%s' % {1:'B', 2:'H', 4:'L'}[len(value)], value)[0]\r
-\r
-\r
-def writeBew(value, length):\r
- """\r
- Write int as big endian formatted string, (asserts length in [1,2,4])\r
- Difficult to print the result in doctest, so I do a simple roundabout test.\r
- >>> readBew(writeBew(25057, 2))\r
- 25057\r
- >>> readBew(writeBew(1642193635L, 4))\r
- 1642193635L\r
- """\r
- return pack('>%s' % {1:'B', 2:'H', 4:'L'}[length], value)\r
-\r
-\r
-\r
-"""\r
-Variable Length Data (varlen) is a data format sprayed liberally throughout\r
-a midi file. It can be anywhere from 1 to 4 bytes long.\r
-If the 8'th bit is set in a byte another byte follows. The value is stored\r
-in the lowest 7 bits of each byte. So max value is 4x7 bits = 28 bits.\r
-"""\r
-\r
-\r
-def readVar(value):\r
- """\r
- Converts varlength format to integer. Just pass it 0 or more chars that\r
- might be a varlen and it will only use the relevant chars.\r
- use varLen(readVar(value)) to see how many bytes the integer value takes.\r
- asserts len(value) >= 0\r
- >>> readVar('\80@')\r
- 64\r
- >>> readVar('áâãa')\r
- 205042145\r
- """\r
- sum = 0\r
- for byte in unpack('%sB' % len(value), value):\r
- sum = (sum << 7) + (byte & 0x7F)\r
- if not 0x80 & byte: break # stop after last byte\r
- return sum\r
-\r
-\r
-\r
-def varLen(value):\r
- """\r
- Returns the the number of bytes an integer will be when\r
- converted to varlength\r
- """\r
- if value <= 127:\r
- return 1\r
- elif value <= 16383:\r
- return 2\r
- elif value <= 2097151:\r
- return 3\r
- else:\r
- return 4\r
-\r
-\r
-def writeVar(value):\r
- "Converts an integer to varlength format"\r
- sevens = to_n_bits(value, varLen(value))\r
- for i in range(len(sevens)-1):\r
- sevens[i] = sevens[i] | 0x80\r
- return fromBytes(sevens)\r
-\r
-\r
-def to_n_bits(value, length=1, nbits=7):\r
- "returns the integer value as a sequence of nbits bytes"\r
- bytes = [(value >> (i*nbits)) & 0x7F for i in range(length)]\r
- bytes.reverse()\r
- return bytes\r
-\r
-\r
-def toBytes(value):\r
- "Turns a string into a list of byte values"\r
- return unpack('%sB' % len(value), value)\r
-\r
-\r
-def fromBytes(value):\r
- "Turns a list of bytes into a string"\r
- if not value:\r
- return ''\r
- return pack('%sB' % len(value), *value)\r
-\r
-\r
-\r
-if __name__ == '__main__':\r
-\r
-# print to7bits(0, 3)\r
-# print to7bits(127, 3)\r
-# print to7bits(255, 3)\r
-# print to7bits(65536, 3)\r
-\r
- # simple test cases\r
- \r
-# print 'getHiLoHex', getNibbles(16)\r
-# print 'setHiLoHex', setNibbles(1,0)\r
-# \r
-# print 'readBew', readBew('aáâã')\r
-# print 'writeBew', writeBew(1642193635, 4)\r
-#\r
-# print 'varLen', varLen(1)\r
-#\r
- print 'readVar', readVar('\80@')\r
- print 'writeVar', writeVar(8192)\r
- \r
- print 'readVar', readVar('áâãa')\r
- print 'writeVar', writeVar(205058401)\r
-# \r
-# vartest = '\x82\xF7\x80\x00'\r
-# print 'toBytes', toBytes(vartest)\r
-# print 'fromBytes', fromBytes([48, 49, 50,])\r
- \r
- \r
-# instr = '\xFF\xFF\xFF\x00'\r
-# print 'readVar', readVar(instr)\r
-# inst2 = 268435455\r
-# print inst2\r
-# print writeVar(inst2)\r
-# print writeVar(readVar(instr))\r
-\r
- s1 = 0x00000000\r
- print '%08X -' % s1, '00', writeVar(s1)\r
- s2 = 0x00000040\r
- print '%08X -' % s2, '40', writeVar(s2)\r
- s3 = 0x0000007F\r
- print '%08X -' % s3, '7F', writeVar(s3)\r
- s4 = 0x00000080\r
- print '%08X -' % s4, '81 00', writeVar(s4)\r
- s5 = 0x00002000\r
- print '%08X -' % s5, 'C0 00', writeVar(s5)\r
- s6 = 0x00003FFF\r
- print '%08X -' % s6, 'FF 7F', writeVar(s6)\r
- s7 = 0x00004000\r
- print '%08X -' % s7, '81 80 00', writeVar(s7)\r
- s8 = 0x00100000\r
- print '%08X -' % s8, 'C0 80 00', writeVar(s8)\r
- s9 = 0x001FFFFF\r
- print '%08X -' % s9, 'FF FF 7F', writeVar(s9)\r
- s10 = 0x00200000\r
- print '%08X -' % s10, '81 80 80 00', writeVar(s10)\r
- s11 = 0x08000000\r
- print '%08X -' % s11, 'C0 80 80 00', writeVar(s11)\r
- s12 = 0x0FFFFFFF\r
- print '%08X -' % s12, 'FF FF FF 7F', writeVar(s12)\r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
- \r
-
\ No newline at end of file