Commits

Anonymous committed 16fae0e

add parsing of side info

Comments (0)

Files changed (1)

 #!/usr/bin/env python
+'''
+pyMP3
+
+MP3 decoder
+
+Created on Aug 18, 2010
+ 
+@author: portalfire
+'''
+
 from bitbfr import BitBfr
+from numpy import *
+
+
 
 dbg_output = True
 
                             0b10: "reserved",
                             0b11: "CCIT J.17" }
 
-class mp3_frame:
+class mp3_frame_hdr:
     def __init__(self):
         self.mpeg_version = 0        
         self.layer = 0
         self.copyrighted = False
         self.original = False
         self.emphasis = "unknown"
-        
+        self.n_channels = 0
+
+class mp3_frame_side_info:
+    def __init__(self):
+        self.main_data_begin        = 0
+        self.private_bits           = 0
+        self.scfsi                  = zeros( (2,4), dtype=int32)
+        self.part2_3_length         = zeros( (2,2), dtype=int32)
+        self.big_values             = zeros( (2,2), dtype=int32)
+        self.global_gain            = zeros( (2,2), dtype=int32)
+        self.scalefac_compress      = zeros( (2,2), dtype=int32)
+        self.window_switching_flag  = zeros( (2,2), dtype=int32)
+        self.block_type             = zeros( (2,2), dtype=int32)
+        self.mixed_block_flag       = zeros( (2,2), dtype=int32)
+        self.table_select           = zeros( (2,2,3), dtype=int32)
+        self.subblock_gain          = zeros( (2,2,3), dtype=int32)
+        self.region0_count          = zeros( (2,2), dtype=int32)
+        self.region1_count          = zeros( (2,2), dtype=int32)
+        self.preflag                = zeros( (2,2), dtype=int32)
+        self.scalefac_scale         = zeros( (2,2), dtype=int32)
+        self.count1table_select     = zeros( (2,2), dtype=int32)
+
+class mp3_frame:
+    def __init__(self):
+        self.hdr = mp3_frame_hdr()
+        self.side_info = mp3_frame_side_info()
 
 class pyMP3:
     def __init__(self, filename):
         while( self.bitbfr.bits_left() > 0):        
             self.find_next_syncword()
             self.decode_frame_header()
+
+            if(self.cur_frame.hdr.has_CRC):
+                crc = self.bitbfr.read_bits(16)
+
+            self.decode_side_info()           
+
+            break # stop at first frame for now
+
+    def decode_side_info(self):
+        self.cur_frame.side_info.main_data_begin = self.bitbfr.read_bits(9)
+
+        if(self.cur_frame.hdr.n_channels==1):
+            self.cur_frame.side_info.private_bits = self.bitbfr.read_bits(5)
+        else:
+            self.cur_frame.side_info.private_bits = self.bitbfr.read_bits(3)
+
+        for ch in xrange(self.cur_frame.hdr.n_channels):
+            for i in xrange(4):
+                self.cur_frame.side_info.scfsi[ch][i] = self.bitbfr.read_bits(1)
+
+        for gr in xrange(2):
+             for ch in xrange(self.cur_frame.hdr.n_channels):
+                  self.cur_frame.side_info.part2_3_length[ch][gr] = self.bitbfr.read_bits(12)
+                  self.cur_frame.side_info.big_values[ch][gr] = self.bitbfr.read_bits(9)
+                  self.cur_frame.side_info.global_gain[ch][gr] = self.bitbfr.read_bits(8)
+                  self.cur_frame.side_info.scalefac_compress[ch][gr] = self.bitbfr.read_bits(4)
+                  self.cur_frame.side_info.window_switching_flag[ch][gr] = self.bitbfr.read_bits(1)
+                  if(self.cur_frame.side_info.window_switching_flag[ch][gr]):
+                      self.cur_frame.side_info.block_type[ch][gr] = self.bitbfr.read_bits(2)
+                      self.cur_frame.side_info.mixed_block_flag[ch][gr] = self.bitbfr.read_bits(1)
+                      for i in xrange(2):
+                           self.cur_frame.side_info.table_select[ch][gr][i] = self.bitbfr.read_bits(5)
+                      for i in xrange(3):
+                           self.cur_frame.side_info.subblock_gain[ch][gr][i] = self.bitbfr.read_bits(3)
+                      if(block_type[ch][gr] == 2 and mixed_block_flag[ch][gr] == 0):
+                          self.cur_frame.side_info.region0_count[ch][gr] = 8
+                      else:
+                          self.cur_frame.side_info.region0_count[ch][gr] = 7
+                      self.cur_frame.side_info.region1_count[ch][gr] = 20 - self.cur_frame.side_info.region0_count[ch][gr]
+                  else:
+                       for i in xrange(3):
+                           self.cur_frame.side_info.table_select[ch][gr][i] = self.bitbfr.read_bits(5)
+                       self.cur_frame.side_info.region0_count[ch][gr] = self.bitbfr.read_bits(4)
+                       self.cur_frame.side_info.region1_count[ch][gr] = self.bitbfr.read_bits(3)
+                       self.cur_frame.side_info.block_type[ch][gr] = 0
+                  self.cur_frame.side_info.preflag[ch][gr] = self.bitbfr.read_bits(1)
+                  self.cur_frame.side_info.scalefac_scale[ch][gr] = self.bitbfr.read_bits(1)
+                  self.cur_frame.side_info.count1table_select[ch][gr] = self.bitbfr.read_bits(1)
+
+        if(dbg_output):
+            print "main_data_begin:",  self.cur_frame.side_info.main_data_begin     
+            print "privatebits:", self.cur_frame.side_info.private_bits         
+            print "scale factor select info:", self.cur_frame.side_info.scfsi                 
+            print "part 2_3 len:", self.cur_frame.side_info.part2_3_length        
+            print "big values:", self.cur_frame.side_info.big_values          
+            print "global gain:", self.cur_frame.side_info.global_gain           
+            print "scalefac_compress", self.cur_frame.side_info.scalefac_compress     
+            print "win switch flag:", self.cur_frame.side_info.window_switching_flag 
+            print "block type:", self.cur_frame.side_info.block_type            
+            print "mixed block flag:", self.cur_frame.side_info.mixed_block_flag      
+            print "table select:", self.cur_frame.side_info.table_select          
+            print "subblock gain:", self.cur_frame.side_info.subblock_gain         
+            print "region0_count", self.cur_frame.side_info.region0_count         
+            print "region1_count", self.cur_frame.side_info.region1_count         
+            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    
             
-            break # stop at first frame for now
 
     def decode_frame_header(self):
   
-        self.cur_frame.mpeg_version   = mp3_hdr_ver_tbl[self.bitbfr.read_bits(1)]  
-        self.cur_frame.layer          = mp3_hdr_layer_tbl[self.bitbfr.read_bits(2)]
-        self.cur_frame.has_CRC        = not self.bitbfr.read_bits(1)
-        self.cur_frame.bitrate        = mp3_hdr_bitrate_tbl[self.bitbfr.read_bits(4)]
-        self.cur_frame.smpl_rate      = mp3_hdr_smpl_rate_tbl[self.bitbfr.read_bits(2)]
-        self.cur_frame.padding        = self.bitbfr.read_bits(1)
+        self.cur_frame.hdr.mpeg_version   = mp3_hdr_ver_tbl[self.bitbfr.read_bits(1)]  
+        self.cur_frame.hdr.layer          = mp3_hdr_layer_tbl[self.bitbfr.read_bits(2)]
+        self.cur_frame.hdr.has_CRC        = not self.bitbfr.read_bits(1)
+        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.cur_frame.channel_mode   = mp3_hdr_channel_mode_tbl[self.bitbfr.read_bits(2)]
-        self.cur_frame.mode_extention = self.bitbfr.read_bits(2)
-        self.copyrighted              = self.bitbfr.read_bits(1)
-        self.original                 = self.bitbfr.read_bits(1)  
-        self.emphasis                 = mp3_hdr_emphasis_tbl[self.bitbfr.read_bits(2)]  
+        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)
+        self.cur_frame.hdr.original       = self.bitbfr.read_bits(1)  
+        self.cur_frame.hdr.emphasis       = mp3_hdr_emphasis_tbl[self.bitbfr.read_bits(2)]  
+
+        if(self.cur_frame.hdr.channel_mode == "mono"):         
+            self.cur_frame.hdr.n_channels = 1
+        else:
+            self.cur_frame.hdr.n_channels = 2
 
         if(dbg_output):
             print "frame header info"            
-            print "ver:", self.cur_frame.mpeg_version
-            print "layer:", self.cur_frame.layer
-            print "has CRC:", self.cur_frame.has_CRC
-            print "bitrate(kps):", self.cur_frame.bitrate
-            print "sample rate:", self.cur_frame.smpl_rate      
-            print "padding:", self.cur_frame.padding        
-            print "channel mode:", self.cur_frame.channel_mode   
-            print "mode extention:", self.cur_frame.mode_extention 
-            print "copyrighted:", self.copyrighted              
-            print "original copy:", self.original                
-            print "emphasis:", self.emphasis               
+            print "ver:", self.cur_frame.hdr.mpeg_version
+            print "layer:", self.cur_frame.hdr.layer
+            print "has CRC:", self.cur_frame.hdr.has_CRC
+            print "bitrate(kps):", self.cur_frame.hdr.bitrate
+            print "sample rate:", self.cur_frame.hdr.smpl_rate      
+            print "padding:", self.cur_frame.hdr.padding        
+            print "channel mode:", self.cur_frame.hdr.channel_mode   
+            print "n channels:", self.cur_frame.hdr.n_channels            
+            print "mode extention:", self.cur_frame.hdr.mode_extention 
+            print "copyrighted:", self.cur_frame.hdr.copyrighted              
+            print "original copy:", self.cur_frame.hdr.original                
+            print "emphasis:", self.cur_frame.hdr.emphasis               
 
 
     def find_next_syncword(self):