Advertisement
Guest User

dedenc.py

a guest
Feb 17th, 2017
241
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.09 KB | None | 0 0
  1. # ported from my own shining.py
  2. rate = 10485.76
  3. vol = 3.2
  4.  
  5. import argparse, math, wave, random
  6.  
  7. # tree building
  8. class HuffTree:
  9.     def __init__(self,a,b,c):
  10.         self.val = a
  11.         self.left = b
  12.         self.right = c
  13.  
  14. class HuffLeaf:
  15.     def __init__(self,a,b):
  16.         self.val = a
  17.         self.id = b
  18.  
  19. def readsamp(src,pos,size,chs): # returns a value between -0.5 and 0.5
  20.     t = 0
  21.     for i in range(chs):
  22.         tt = 0
  23.         for j in range(size):
  24.             tt = tt + (ord(src[pos+i*size+j]) << (j * 8))
  25.         if size == 1: # 8-bit samples are usually unsigned
  26.             tt = tt - 128 # negative
  27.         elif tt > 256**size/2-1: tt = tt - 256**size # negative
  28.         t = t + tt
  29.     return t / chs / 256.0**size
  30.  
  31. # cubic spline interpolation
  32. def cuinterpo(s,n):
  33.     nn = int(n)
  34.     p0 = s[nn]
  35.     p1 = s[nn+1]
  36.     m0 = (s[nn+1]-s[nn-1])/2
  37.     m1 = (s[nn+2]-s[nn])/2
  38.     t1 = math.modf(n)[0]
  39.     t2 = math.pow(t1,2)
  40.     t3 = math.pow(t1,3)
  41.     return (2*t3-3*t2+1)*p0+(t3-2*t2+t1)*m0+(-2*t3+3*t2)*p1+(t3-t2)*m1
  42.    
  43. def writetree(tree,jrcnt,bits,dict):
  44.     le = tree.left
  45.     ri = tree.right
  46.     if isinstance(le,HuffTree) and isinstance(ri,HuffTree):
  47.         jrcnt = jrcnt+9
  48.         res,jrcnt2 = writetree(le,jrcnt,bits+"0",dict)
  49.         res2,jrcnt3 = writetree(ri,0,bits+"1",dict)
  50.         if(jrcnt2-jrcnt > 127):
  51.             outs = chr(0xe0+((jrcnt2-jrcnt)>>8))+chr((jrcnt2-jrcnt)%0x100)+res+res2
  52.             jrcnt = jrcnt+1
  53.         else: outs = chr(jrcnt2-jrcnt)+res+res2
  54.         jrcnt = jrcnt2+jrcnt3
  55.     elif isinstance(le,HuffTree) and isinstance(ri,HuffLeaf):
  56.         jrcnt = jrcnt+10
  57.         dict[ri.id] = bits+"1"
  58.         res,jrcnt = writetree(le,jrcnt,bits+"0",dict)
  59.         outs = chr(0x80+ri.id)+res
  60.     else:
  61.         jrcnt = jrcnt+13
  62.         dict[le.id] = bits+"0"
  63.         dict[ri.id] = bits+"1"
  64.         outs = chr(0xc0+ri.id)+chr(le.id)
  65.     return (outs,jrcnt)
  66.  
  67. def wavtoded(fd,ra,ch,wi):
  68.     fdd = []
  69.     fdl = []
  70.  
  71.     for i in range(0,len(fd),wi*ch): # amplify
  72.         t = readsamp(fd, i, wi, ch)
  73.         fdd.append(t * vol)
  74.     fdd = fdd + [0.0]*2
  75.  
  76.     if abs(ra-rate)/rate > 0.05:
  77.         for i in range(0,int((len(fdd)-2)*rate/ra)): # stretch
  78.             fdl.append(cuinterpo(fdd,i*ra/rate))
  79.     else: fdl = fdd
  80.  
  81.     for i in range(0,len(fdl)): # convert
  82.         fdl[i] = min(max(fdl[i]+(8.0/15.0),0),1.0)
  83.  
  84.     # TPDF dither
  85.     last = 8
  86.     tp = []
  87.     freq = {}
  88.     random.seed(3490487757541254948)
  89.     for i in fdl:
  90.         ev = int(i*15)
  91.         er = i*15.0 - ev
  92.         eo = 0.0
  93.         if er < 0.5: eo = 2.0*er*er
  94.         else: eo = 1.0-(2.0*(1.0-er)*(1.0-er))
  95.         if eo > random.random(): ev = ev+1
  96.         ew = (ev-last)%16
  97.         tp.append(ew)
  98.         if ew not in freq: freq[ew] = 0
  99.         freq[ew] = freq[ew] + 1
  100.         last = ev
  101.     while len(tp) % 32 != 0: tp.append(0)
  102.  
  103.     qu = []
  104.     for i in freq.keys(): qu.append(HuffLeaf(freq[i],i))
  105.     while len(qu) > 1:
  106.         qu = sorted(qu, lambda x,y: cmp(x.val,y.val))
  107.         le = qu.pop(0)
  108.         ri = qu.pop(0)
  109.         if isinstance(le,HuffLeaf) and isinstance(ri,HuffTree):
  110.             tmp = ri
  111.             ri = le
  112.             le = tmp
  113.         qu.append(HuffTree(le.val+ri.val,le,ri))
  114.  
  115.     # tree writing
  116.     code = {}
  117.     ls = writetree(qu[0],0,"",code)[0] + chr(0xff)
  118.  
  119.     # compression
  120.     ou = ""
  121.     for i in range(len(tp)): ou = ou + code[tp[i]]
  122.     while len(ou) % 8 != 0: ou = ou + "1"
  123.  
  124.     ls = ls + chr((len(tp)/32)%256) + chr((len(tp)/32)>>8)
  125.     for i in range(0,len(ou),8): ls = ls + chr(int(ou[i:i+8],2))
  126.     return ls
  127.  
  128. if __name__ == "__main__":
  129.     parser = argparse.ArgumentParser()
  130.     parser.add_argument('fi', metavar='in', type=argparse.FileType('rb'), help='Input file name')
  131.     parser.add_argument('fo', metavar='out', type=argparse.FileType('wb'), help='Output file name')
  132.     nsp = parser.parse_args()
  133.  
  134.     fl = wave.open(nsp.fi,"rb")
  135.     nf = fl.getnframes()
  136.     ous = wavtoded(fl.readframes(nf), fl.getframerate(), fl.getnchannels(), fl.getsampwidth())
  137.     fl.close()
  138.     nsp.fo.write(ous)
  139.     nsp.fo.close()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement