Commits

Anonymous committed fd7aca2

added dequantizer and stubs for remaining blocks

Comments (0)

Files changed (2)

     def __init__(self):
         self.scalefac_s    = zeros( (2,3,13), dtype=int32)
         self.scalefac_l    = zeros( (2,23), dtype=int32)
-        self.vals          = zeros( (32,18), dtype=int32)
+        self.q_vals        = zeros( (2,2,32,18), dtype=int32)
 
+class mp3_frame_decoded_data:
+    def __init__(self):
+        self.dq_vals       = zeros( (2,2,32,18), dtype=float)
 
 class mp3_frame:
     def __init__(self):
-        self.hdr        = mp3_frame_hdr()
-        self.side_info  = mp3_frame_side_info()
-        self.main_data  = mp3_frame_main_data()
+        self.hdr          = mp3_frame_hdr()
+        self.side_info    = mp3_frame_side_info()
+        self.main_data    = mp3_frame_main_data()
+        self.decoded_data = mp3_frame_decoded_data()
 
 class pyMP3:
     def __init__(self, filename):
             print "Starting Decode"        
         frame_cnt = 0
         while( self.bitbfr.bits_left() > 0):        
-            #print "frame #%d" % (frame_cnt+1)
+            print "frame #%d" % (frame_cnt+1)
+
+            #Decode the data            
             self.find_next_syncword()
             self.decode_frame_header()
-
-            if(self.cur_frame.hdr.has_CRC):
-                crc = self.bitbfr.read_bits(16)
-
+            self.decode_CRC()
             self.decode_side_info()           
             self.decode_main_info()
+            
+            #Process the Data
+            self.dequantize_samples()
+            self.process_stereo()
+            self.reorder_samples()
+            self.antialias_samples()
+            self.hybrid_synthesis()
+            self.polyphase_synthesis()
+            
             frame_cnt+=1
 
             if(frame_cnt == 2 ):
                 break
 
+    def dequantize_samples(self):
+        for gr in xrange(2):        
+            for ch in xrange(self.cur_frame.hdr.n_channels):        
+                cb = 0                 
+                #get initial boundary        
+                if (self.cur_frame.side_info.window_switching_flag[ch][gr] and (self.cur_frame.side_info.block_type[ch][gr] == 2) ):
+                    if (self.cur_frame.side_info.mixed_block_flag[ch][gr]): 
+                        #mixed (long first)                
+                        next_cb_boundary = sfBandIndex_[self.cur_frame.hdr.smpl_rate][1]
+                    else: 
+                        #pure short                
+                        next_cb_boundary = sfBandIndex_s[self.cur_frame.hdr.smpl_rate][1]*3
+                        cb_width         = sfBandIndex_s[self.cur_frame.hdr.smpl_rate][1]
+                        cb_begin         = 0;
+                else: 
+                    #long blocks             
+                    next_cb_boundary = sfBandIndex_l[self.cur_frame.hdr.smpl_rate][1]
+
+                #apply formula per block type */    
+                for sb in xrange(SBLIMIT):
+                    for ss in xrange(SSLIMIT): 
+                        if ( (sb*18)+ss == next_cb_boundary):  
+                            if (self.cur_frame.side_info.window_switching_flag[ch][gr] and (self.cur_frame.side_info.block_type[ch][gr] == 2)): 
+                                if (self.cur_frame.side_info.mixed_block_flag[ch][gr]):  
+                                    if (((sb*18)+ss) == sfBandIndex_l[self.cur_frame.hdr.smpl_rate][8]):  
+                                        next_cb_boundary = sfBandIndex_s[self.cur_frame.hdr.smpl_rate][4]*3 
+                                        cb               = 3
+                                        cb_width         = sfBandIndex_s[self.cur_frame.hdr.smpl_rate][cb+1] - sfBandIndex_s[self.cur_frame.hdr.smpl_rate][cb]
+                                        cb_begin         = sfBandIndex_s[self.cur_frame.hdr.smpl_rate][cb]*3      
+                                    elif (((sb*18)+ss) < sfBandIndex_l[self.cur_frame.hdr.smpl_rate][8]):
+                                        cb += 1 
+                                        next_cb_boundary = sfBandIndex_l[self.cur_frame.hdr.smpl_rate][cb+1]
+                                    else: 
+                                        cb += 1 
+                                        next_cb_boundary = sfBandIndex_s[self.cur_frame.hdr.smpl_rate][cb+1]*3
+                                        cb_width         = sfBandIndex_s[self.cur_frame.hdr.smpl_rate][cb+1] - sfBandIndex_s[self.cur_frame.hdr.smpl_rate][cb]
+                                        cb_begin         = sfBandIndex_s[self.cur_frame.hdr.smpl_rate][cb]*3                                       
+                                else:  
+                                    cb += 1
+                                    next_cb_boundary = sfBandIndex_s[self.cur_frame.hdr.smpl_rate][cb+1]*3
+                                    cb_width = sfBandIndex_s[self.cur_frame.hdr.smpl_rate][cb+1] -sfBandIndex_s[self.cur_frame.hdr.smpl_rate][cb];
+                                    cb_begin = sfBandIndex_s[self.cur_frame.hdr.smpl_rate][cb]*3;                                  
+                            else: 
+                                cb += 1
+                                next_cb_boundary = sfBandIndex_l[self.cur_frame.hdr.smpl_rate][cb+1]
+                 
+                        #Compute global scaling
+                        self.cur_frame.decoded_data.dq_vals[gr][ch][sb][ss] = pow( 2.0 , (0.25 * (self.cur_frame.side_info.global_gain[ch][gr] - 210.0)))
+
+                        #Compute block dependent scaling
+                        if (self.cur_frame.side_info.window_switching_flag[ch][gr] and (
+                            ((self.cur_frame.side_info.block_type[ch][gr] == 2) and (self.cur_frame.side_info.mixed_block_flag[ch][gr] == 0)) or
+                            ((self.cur_frame.side_info.block_type[ch][gr] == 2) and self.cur_frame.side_info.mixed_block_flag[ch][gr] and (sb >= 2)) )): 
+                            #SHORT
+                            self.cur_frame.decoded_data.dq_vals[gr][ch][sb][ss] *= pow(2.0, 0.25 * -8.0 * self.cur_frame.side_info.subblock_gain[ch][gr][(((sb*18)+ss) - cb_begin)/cb_width])
+                            self.cur_frame.decoded_data.dq_vals[gr][ch][sb][ss] *= pow(2.0, 0.25 * -2.0 * 
+                                (1.0+self.cur_frame.side_info.scalefac_scale[ch][gr]) * self.cur_frame.main_data.scalefac_s[ch][(((sb*18)+ss) - cb_begin)/cb_width][cb])
+                        else:    
+                            #LONG block types 0,1,3 & 1st 2 subbands of switched blocks 
+                            self.cur_frame.decoded_data.dq_vals[gr][ch][sb][ss] *= pow(2.0, -0.5 * 
+                                (1.0+self.cur_frame.side_info.scalefac_scale[ch][gr]) * (self.cur_frame.main_data.scalefac_l[ch][cb] + self.cur_frame.side_info.preflag[ch][gr] * pretab[cb]))
+
+                        #Scale quantized value        
+                        self.cur_frame.decoded_data.dq_vals[gr][ch][sb][ss] *= pow( abs(self.cur_frame.main_data.q_vals[gr][ch][sb][ss]), (4.0/3.0) )
+                        if (self.cur_frame.main_data.q_vals[gr][ch][sb][ss]<0):
+                            self.cur_frame.decoded_data.dq_vals[gr][ch][sb][ss] = -self.cur_frame.decoded_data.dq_vals[gr][ch][sb][ss]
+        
+
+    def process_stereo(self):
+        pass
+    
+    def reorder_samples(self):
+        pass
+
+    def antialias_samples(self):
+        pass
+
+    def hybrid_synthesis(self):
+        pass
+
+    def polyphase_synthesis(self):
+        pass
+
     def decode_main_info(self):
         for gr in xrange(2):
             for ch in xrange(self.cur_frame.hdr.n_channels):
                 if(self.cur_frame.side_info.window_switching_flag[ch][gr] == 1 and 
                    self.cur_frame.side_info.block_type[ch][gr] == 2):
                     if(self.cur_frame.side_info.mixed_block_flag[ch][gr]):
-                        #mixed
+                        #mixed blocks
                         print "mixed scale blocks not supported yet"
                         pass
                     else:
-                        #short
+                        #short blocks
                         for i in xrange(2):
                             for sfb in xrange(sfbtable_s[i], sfbtable_s[i+1]):
                                 for window in xrange(3):
                             self.cur_frame.main_data.scalefac_s[ch][window][sfb] = 0;  
   
                 else:
-                    #long                    
+                    #long blocks                   
                     for i in xrange(4):
                         if ((self.cur_frame.side_info.scfsi[ch][i] == 0) or (gr == 0)):
                             for sfb in xrange( sfbtable_l[i], sfbtable_l[i+1]):
             ht = ht_list[ht_idx]
             v, w, x, y = self.huffman_decoder(ht)
             #print "huff bv:%d t:%d v:%d %d" % (i, ht_idx, x, y)            
-            self.cur_frame.main_data.vals[i/SSLIMIT][i%SSLIMIT]           = x
-            self.cur_frame.main_data.vals[(i+1)/SSLIMIT][(i+1)%SSLIMIT]   = y
+            self.cur_frame.main_data.q_vals[gr][ch][i/SSLIMIT][i%SSLIMIT]           = x
+            self.cur_frame.main_data.q_vals[gr][ch][(i+1)/SSLIMIT][(i+1)%SSLIMIT]   = y
 
         #read count1 area
         idx = self.cur_frame.side_info.big_values[ch][gr]*2        
         while( (self.bitbfr.get_pos() < (part2_start + self.cur_frame.side_info.part2_3_length[ch][gr]) ) and (idx<SBLIMIT*SSLIMIT) ):
             v, w, x, y = self.huffman_decoder(ht)
             #print "huff ct1:%d t:%d v:%d %d %d %d" % (idx, self.cur_frame.side_info.count1table_select[ch][gr] + 32, x, y, v, w)            
-            self.cur_frame.main_data.vals[idx/SSLIMIT][idx%SSLIMIT] = v;
-            self.cur_frame.main_data.vals[(idx+1)/SSLIMIT][(idx+1)%SSLIMIT] = w
-            self.cur_frame.main_data.vals[(idx+2)/SSLIMIT][(idx+2)%SSLIMIT] = x
-            self.cur_frame.main_data.vals[(idx+3)/SSLIMIT][(idx+3)%SSLIMIT] = y
+            self.cur_frame.main_data.q_vals[gr][ch][idx/SSLIMIT][idx%SSLIMIT] = v;
+            self.cur_frame.main_data.q_vals[gr][ch][(idx+1)/SSLIMIT][(idx+1)%SSLIMIT] = w
+            self.cur_frame.main_data.q_vals[gr][ch][(idx+2)/SSLIMIT][(idx+2)%SSLIMIT] = x
+            self.cur_frame.main_data.q_vals[gr][ch][(idx+3)/SSLIMIT][(idx+3)%SSLIMIT] = y
             idx += 4
 
         #the rest are zeros 
         
-        #print "coefficents"        
-        #print self.cur_frame.main_data.vals        
-
 
     def huffman_decoder(self, ht):                
         MXOFF = 250         
             print "preflag", self.cur_frame.side_info.preflag               
             print "scalefac_scale", self.cur_frame.side_info.scalefac_scale        
             print "count1table select:", self.cur_frame.side_info.count1table_select    
-            
+
+    def decode_CRC(self):
+         if(self.cur_frame.hdr.has_CRC):
+            crc = self.bitbfr.read_bits(16)
 
     def decode_frame_header(self):
   
         self.cur_frame.hdr.bitrate        = mp3_hdr_bitrate_tbl[self.bitbfr.read_bits(4)]
         self.cur_frame.hdr.smpl_rate      = mp3_hdr_smpl_rate_tbl[self.bitbfr.read_bits(2)]
         self.cur_frame.hdr.padding        = self.bitbfr.read_bits(1)
-        self.bitbfr.read_bits(1)      #private bit
+        self.bitbfr.read_bits(1)          #private bit
         self.cur_frame.hdr.channel_mode   = mp3_hdr_channel_mode_tbl[self.bitbfr.read_bits(2)]
         self.cur_frame.hdr.mode_extention = self.bitbfr.read_bits(2)
         self.cur_frame.hdr.copyrighted    = self.bitbfr.read_bits(1)
                   48000 : [0,4,8,12,16,22,28,38,50,64,80,100,126,192],
                   32000 : [0,4,8,12,16,22,30,42,58,78,104,138,180,192] }
 
+pretab = [0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,2,2,3,3,3,2,0]
+
 class huffman_table:
     def __init__(self, tbl_type, tbl_idx, treelen, xlen, ylen, linbits, values):
         self.tbl_type = tbl_type