1c21a9c2fSMilanka Ringwald#!/usr/bin/env python 2c21a9c2fSMilanka Ringwaldimport numpy as np 3c21a9c2fSMilanka Ringwaldimport wave 4c21a9c2fSMilanka Ringwaldimport struct 5c21a9c2fSMilanka Ringwaldimport sys 6c21a9c2fSMilanka Ringwald 7c21a9c2fSMilanka Ringwald# channel mode 8c21a9c2fSMilanka RingwaldMONO = 0 9c21a9c2fSMilanka RingwaldDUAL_CHANNEL = 1 10c21a9c2fSMilanka RingwaldSTEREO = 2 11c21a9c2fSMilanka RingwaldJOINT_STEREO = 3 12*ad470863SMilanka Ringwaldchannel_modes = ["MONO", "DUAL CHANNEL", "STEREO", "JOINT STEREO"] 13c21a9c2fSMilanka Ringwald 14c21a9c2fSMilanka Ringwald# allocation method 15c21a9c2fSMilanka RingwaldLOUDNESS = 0 16c21a9c2fSMilanka RingwaldSNR = 1 17*ad470863SMilanka Ringwaldallocation_methods = ["LOUDNESS", "SNR"] 18*ad470863SMilanka Ringwald 19*ad470863SMilanka Ringwaldsampling_frequencies = [16000, 32000, 44100, 48000] 20*ad470863SMilanka Ringwaldnr_blocks = [4, 8, 12, 16] 21*ad470863SMilanka Ringwaldnr_subbands = [4, 8] 22*ad470863SMilanka Ringwald 23*ad470863SMilanka Ringwald 24*ad470863SMilanka Ringwalddef allocation_method_to_str(allocation_method): 25*ad470863SMilanka Ringwald global allocation_methods 26*ad470863SMilanka Ringwald return allocation_methods[allocation_method] 27*ad470863SMilanka Ringwald 28*ad470863SMilanka Ringwalddef channel_mode_to_str(channel_mode): 29*ad470863SMilanka Ringwald global channel_modes 30*ad470863SMilanka Ringwald return channel_modes[channel_mode] 31*ad470863SMilanka Ringwald 32*ad470863SMilanka Ringwalddef sampling_frequency_to_str(sampling_frequency): 33*ad470863SMilanka Ringwald global sampling_frequencies 34*ad470863SMilanka Ringwald return sampling_frequencies[sampling_frequency] 35*ad470863SMilanka Ringwald 36*ad470863SMilanka Ringwalddef sampling_frequency_index(sampling_frequency): 37*ad470863SMilanka Ringwald global sampling_frequencies 38*ad470863SMilanka Ringwald for index, value in enumerate(sampling_frequencies): 39*ad470863SMilanka Ringwald if value == sampling_frequency: 40*ad470863SMilanka Ringwald return index 41*ad470863SMilanka Ringwald return -1 42c21a9c2fSMilanka Ringwald 43c21a9c2fSMilanka RingwaldProto_4_40 = [ 44c21a9c2fSMilanka Ringwald 0.00000000E+00, 5.36548976E-04, 1.49188357E-03, 2.73370904E-03, 45c21a9c2fSMilanka Ringwald 3.83720193E-03, 3.89205149E-03, 1.86581691E-03, -3.06012286E-03, 46c21a9c2fSMilanka Ringwald 1.09137620E-02, 2.04385087E-02, 2.88757392E-02, 3.21939290E-02, 47c21a9c2fSMilanka Ringwald 2.58767811E-02, 6.13245186E-03, -2.88217274E-02, -7.76463494E-02, 48c21a9c2fSMilanka Ringwald 1.35593274E-01, 1.94987841E-01, 2.46636662E-01, 2.81828203E-01, 49c21a9c2fSMilanka Ringwald 2.94315332E-01, 2.81828203E-01, 2.46636662E-01, 1.94987841E-01, 50c21a9c2fSMilanka Ringwald -1.35593274E-01, -7.76463494E-02, -2.88217274E-02, 6.13245186E-03, 51c21a9c2fSMilanka Ringwald 2.58767811E-02, 3.21939290E-02, 2.88757392E-02, 2.04385087E-02, 52c21a9c2fSMilanka Ringwald -1.09137620E-02, -3.06012286E-03, 1.86581691E-03, 3.89205149E-03, 53c21a9c2fSMilanka Ringwald 3.83720193E-03, 2.73370904E-03, 1.49188357E-03, 5.36548976E-04 54c21a9c2fSMilanka Ringwald] 55c21a9c2fSMilanka Ringwald 56c21a9c2fSMilanka RingwaldProto_8_80 = [ 57c21a9c2fSMilanka Ringwald 0.00000000E+00, 1.56575398E-04, 3.43256425E-04, 5.54620202E-04, 58c21a9c2fSMilanka Ringwald 8.23919506E-04, 1.13992507E-03, 1.47640169E-03, 1.78371725E-03, 59c21a9c2fSMilanka Ringwald 2.01182542E-03, 2.10371989E-03, 1.99454554E-03, 1.61656283E-03, 60c21a9c2fSMilanka Ringwald 9.02154502E-04, -1.78805361E-04, -1.64973098E-03, -3.49717454E-03, 61c21a9c2fSMilanka Ringwald 5.65949473E-03, 8.02941163E-03, 1.04584443E-02, 1.27472335E-02, 62c21a9c2fSMilanka Ringwald 1.46525263E-02, 1.59045603E-02, 1.62208471E-02, 1.53184106E-02, 63c21a9c2fSMilanka Ringwald 1.29371806E-02, 8.85757540E-03, 2.92408442E-03, -4.91578024E-03, 64c21a9c2fSMilanka Ringwald -1.46404076E-02, -2.61098752E-02, -3.90751381E-02, -5.31873032E-02, 65c21a9c2fSMilanka Ringwald 6.79989431E-02, 8.29847578E-02, 9.75753918E-02, 1.11196689E-01, 66c21a9c2fSMilanka Ringwald 1.23264548E-01, 1.33264415E-01, 1.40753505E-01, 1.45389847E-01, 67c21a9c2fSMilanka Ringwald 1.46955068E-01, 1.45389847E-01, 1.40753505E-01, 1.33264415E-01, 68c21a9c2fSMilanka Ringwald 1.23264548E-01, 1.11196689E-01, 9.75753918E-02, 8.29847578E-02, 69c21a9c2fSMilanka Ringwald -6.79989431E-02, -5.31873032E-02, -3.90751381E-02, -2.61098752E-02, 70c21a9c2fSMilanka Ringwald -1.46404076E-02, -4.91578024E-03, 2.92408442E-03, 8.85757540E-03, 71c21a9c2fSMilanka Ringwald 1.29371806E-02, 1.53184106E-02, 1.62208471E-02, 1.59045603E-02, 72c21a9c2fSMilanka Ringwald 1.46525263E-02, 1.27472335E-02, 1.04584443E-02, 8.02941163E-03, 73c21a9c2fSMilanka Ringwald -5.65949473E-03, -3.49717454E-03, -1.64973098E-03, -1.78805361E-04, 74c21a9c2fSMilanka Ringwald 9.02154502E-04, 1.61656283E-03, 1.99454554E-03, 2.10371989E-03, 75c21a9c2fSMilanka Ringwald 2.01182542E-03, 1.78371725E-03, 1.47640169E-03, 1.13992507E-03, 76c21a9c2fSMilanka Ringwald 8.23919506E-04, 5.54620202E-04, 3.43256425E-04, 1.56575398E-04 77c21a9c2fSMilanka Ringwald] 78c21a9c2fSMilanka Ringwald 79c21a9c2fSMilanka Ringwaldcrc_table = [ 80c21a9c2fSMilanka Ringwald 0x00, 0x1D, 0x3A, 0x27, 0x74, 0x69, 0x4E, 0x53, 81c21a9c2fSMilanka Ringwald 0xE8, 0xF5, 0xD2, 0xCF, 0x9C, 0x81, 0xA6, 0xBB, 82c21a9c2fSMilanka Ringwald 0xCD, 0xD0, 0xF7, 0xEA, 0xB9, 0xA4, 0x83, 0x9E, 83c21a9c2fSMilanka Ringwald 0x25, 0x38, 0x1F, 0x02, 0x51, 0x4C, 0x6B, 0x76, 84c21a9c2fSMilanka Ringwald 0x87, 0x9A, 0xBD, 0xA0, 0xF3, 0xEE, 0xC9, 0xD4, 85c21a9c2fSMilanka Ringwald 0x6F, 0x72, 0x55, 0x48, 0x1B, 0x06, 0x21, 0x3C, 86c21a9c2fSMilanka Ringwald 0x4A, 0x57, 0x70, 0x6D, 0x3E, 0x23, 0x04, 0x19, 87c21a9c2fSMilanka Ringwald 0xA2, 0xBF, 0x98, 0x85, 0xD6, 0xCB, 0xEC, 0xF1, 88c21a9c2fSMilanka Ringwald 0x13, 0x0E, 0x29, 0x34, 0x67, 0x7A, 0x5D, 0x40, 89c21a9c2fSMilanka Ringwald 0xFB, 0xE6, 0xC1, 0xDC, 0x8F, 0x92, 0xB5, 0xA8, 90c21a9c2fSMilanka Ringwald 0xDE, 0xC3, 0xE4, 0xF9, 0xAA, 0xB7, 0x90, 0x8D, 91c21a9c2fSMilanka Ringwald 0x36, 0x2B, 0x0C, 0x11, 0x42, 0x5F, 0x78, 0x65, 92c21a9c2fSMilanka Ringwald 0x94, 0x89, 0xAE, 0xB3, 0xE0, 0xFD, 0xDA, 0xC7, 93c21a9c2fSMilanka Ringwald 0x7C, 0x61, 0x46, 0x5B, 0x08, 0x15, 0x32, 0x2F, 94c21a9c2fSMilanka Ringwald 0x59, 0x44, 0x63, 0x7E, 0x2D, 0x30, 0x17, 0x0A, 95c21a9c2fSMilanka Ringwald 0xB1, 0xAC, 0x8B, 0x96, 0xC5, 0xD8, 0xFF, 0xE2, 96c21a9c2fSMilanka Ringwald 0x26, 0x3B, 0x1C, 0x01, 0x52, 0x4F, 0x68, 0x75, 97c21a9c2fSMilanka Ringwald 0xCE, 0xD3, 0xF4, 0xE9, 0xBA, 0xA7, 0x80, 0x9D, 98c21a9c2fSMilanka Ringwald 0xEB, 0xF6, 0xD1, 0xCC, 0x9F, 0x82, 0xA5, 0xB8, 99c21a9c2fSMilanka Ringwald 0x03, 0x1E, 0x39, 0x24, 0x77, 0x6A, 0x4D, 0x50, 100c21a9c2fSMilanka Ringwald 0xA1, 0xBC, 0x9B, 0x86, 0xD5, 0xC8, 0xEF, 0xF2, 101c21a9c2fSMilanka Ringwald 0x49, 0x54, 0x73, 0x6E, 0x3D, 0x20, 0x07, 0x1A, 102c21a9c2fSMilanka Ringwald 0x6C, 0x71, 0x56, 0x4B, 0x18, 0x05, 0x22, 0x3F, 103c21a9c2fSMilanka Ringwald 0x84, 0x99, 0xBE, 0xA3, 0xF0, 0xED, 0xCA, 0xD7, 104c21a9c2fSMilanka Ringwald 0x35, 0x28, 0x0F, 0x12, 0x41, 0x5C, 0x7B, 0x66, 105c21a9c2fSMilanka Ringwald 0xDD, 0xC0, 0xE7, 0xFA, 0xA9, 0xB4, 0x93, 0x8E, 106c21a9c2fSMilanka Ringwald 0xF8, 0xE5, 0xC2, 0xDF, 0x8C, 0x91, 0xB6, 0xAB, 107c21a9c2fSMilanka Ringwald 0x10, 0x0D, 0x2A, 0x37, 0x64, 0x79, 0x5E, 0x43, 108c21a9c2fSMilanka Ringwald 0xB2, 0xAF, 0x88, 0x95, 0xC6, 0xDB, 0xFC, 0xE1, 109c21a9c2fSMilanka Ringwald 0x5A, 0x47, 0x60, 0x7D, 0x2E, 0x33, 0x14, 0x09, 110c21a9c2fSMilanka Ringwald 0x7F, 0x62, 0x45, 0x58, 0x0B, 0x16, 0x31, 0x2C, 111c21a9c2fSMilanka Ringwald 0x97, 0x8A, 0xAD, 0xB0, 0xE3, 0xFE, 0xD9, 0xC4 112c21a9c2fSMilanka Ringwald] 113c21a9c2fSMilanka Ringwald# offset table for 4-subbands 114c21a9c2fSMilanka Ringwaldoffset4 = np.array([[ -1, 0, 0, 0 ], 115c21a9c2fSMilanka Ringwald [ -2, 0, 0, 1 ], 116c21a9c2fSMilanka Ringwald [ -2, 0, 0, 1 ], 117c21a9c2fSMilanka Ringwald [ -2, 0, 0, 1 ] 118c21a9c2fSMilanka Ringwald ]) 119c21a9c2fSMilanka Ringwald 120c21a9c2fSMilanka Ringwald# offset tables for 8-subbands 121c21a9c2fSMilanka Ringwaldoffset8 = np.array([[ -2, 0, 0, 0, 0, 0, 0, 1 ], 122c21a9c2fSMilanka Ringwald [ -3, 0, 0, 0, 0, 0, 1, 2 ], 123c21a9c2fSMilanka Ringwald [ -4, 0, 0, 0, 0, 0, 1, 2 ], 124c21a9c2fSMilanka Ringwald [ -4, 0, 0, 0, 0, 0, 1, 2 ] 125c21a9c2fSMilanka Ringwald ]) 126c21a9c2fSMilanka Ringwald 127c21a9c2fSMilanka Ringwaldclass SBCFrame: 128c21a9c2fSMilanka Ringwald syncword = 0 129c21a9c2fSMilanka Ringwald sampling_frequency = 0 130c21a9c2fSMilanka Ringwald nr_blocks = 0 131c21a9c2fSMilanka Ringwald channel_mode = 0 132c21a9c2fSMilanka Ringwald nr_channels = 0 133c21a9c2fSMilanka Ringwald allocation_method = 0 134c21a9c2fSMilanka Ringwald nr_subbands = 0 135c21a9c2fSMilanka Ringwald bitpool = 0 136c21a9c2fSMilanka Ringwald crc_check = 0 137c21a9c2fSMilanka Ringwald # pro subband - 1 138c21a9c2fSMilanka Ringwald join = np.zeros(8, dtype = np.uint8) 139c21a9c2fSMilanka Ringwald scale_factor = np.zeros(shape=(2, 8), dtype = np.int32) 140c21a9c2fSMilanka Ringwald scalefactor = np.zeros(shape=(2, 8), dtype = np.int32) 141c21a9c2fSMilanka Ringwald audio_sample = np.zeros(shape = (16,2,8), dtype = np.uint16) 142c21a9c2fSMilanka Ringwald sb_sample = np.zeros(shape = (16,2,8), dtype = np.uint16) 143c21a9c2fSMilanka Ringwald X = np.zeros(8, dtype = np.int16) 144c21a9c2fSMilanka Ringwald EX = np.zeros(8) 145c21a9c2fSMilanka Ringwald pcm = np.array([], dtype = np.int16) 146c21a9c2fSMilanka Ringwald bits = np.zeros(shape=(2, 8)) 147c21a9c2fSMilanka Ringwald levels = np.zeros(shape=(2, 8), dtype = np.int32) 148c21a9c2fSMilanka Ringwald 149*ad470863SMilanka Ringwald 150*ad470863SMilanka Ringwald def __init__(self, nr_blocks=16, nr_subbands=4, nr_channels=1, bitpool=31, sampling_frequency=44100): 151c21a9c2fSMilanka Ringwald self.nr_blocks = nr_blocks 152c21a9c2fSMilanka Ringwald self.nr_subbands = nr_subbands 153c21a9c2fSMilanka Ringwald self.nr_channels = nr_channels 154*ad470863SMilanka Ringwald self.sampling_frequency = sampling_frequency_index(sampling_frequency) 155c21a9c2fSMilanka Ringwald self.bitpool = bitpool 156c21a9c2fSMilanka Ringwald self.scale_factor = np.zeros(shape=(nr_channels, nr_subbands), dtype = np.int32) 157c21a9c2fSMilanka Ringwald self.scalefactor = np.zeros(shape=(nr_channels, nr_subbands), dtype = np.int32) 158c21a9c2fSMilanka Ringwald self.audio_sample = np.zeros(shape=(nr_blocks, nr_channels, nr_subbands), dtype = np.uint16) 159c21a9c2fSMilanka Ringwald self.sb_sample = np.zeros(shape=(nr_blocks, nr_channels, nr_subbands), dtype = np.uint16) 160c21a9c2fSMilanka Ringwald self.levels = np.zeros(shape=(nr_channels, nr_subbands), dtype = np.int32) 161c21a9c2fSMilanka Ringwald self.EX = np.zeros(nr_subbands) 162c21a9c2fSMilanka Ringwald return 163c21a9c2fSMilanka Ringwald 164*ad470863SMilanka Ringwald def dump_audio_samples(self, blk, ch): 165*ad470863SMilanka Ringwald print self.audio_sample[blk][ch] 166*ad470863SMilanka Ringwald 167*ad470863SMilanka Ringwald def dump_subband_samples(self, blk, ch): 168*ad470863SMilanka Ringwald print self.sb_sample[blk][ch] 169*ad470863SMilanka Ringwald 170*ad470863SMilanka Ringwald def dump_state(self): 171*ad470863SMilanka Ringwald res = "SBCFrameHeader state:" 172*ad470863SMilanka Ringwald res += "\n - nr channels %d" % self.nr_channels 173*ad470863SMilanka Ringwald res += "\n - nr blocks %d" % self.nr_blocks 174*ad470863SMilanka Ringwald res += "\n - nr subbands %d" % self.nr_subbands 175*ad470863SMilanka Ringwald res += "\n - scale factors: %s" % self.scale_factor 176*ad470863SMilanka Ringwald res += "\n - levels: %s" % self.levels 177*ad470863SMilanka Ringwald res += "\n - join: %s" % self.join 178*ad470863SMilanka Ringwald res += "\n - bits: %s" % self.bits 179*ad470863SMilanka Ringwald print res 180*ad470863SMilanka Ringwald 181c21a9c2fSMilanka Ringwald def __str__(self): 182c21a9c2fSMilanka Ringwald res = "SBCFrameHeader:" 183*ad470863SMilanka Ringwald res += "\n - syncword %d" % self.syncword 184*ad470863SMilanka Ringwald res += "\n - sampling frequency %d Hz" % sampling_frequency_to_str(self.sampling_frequency) 185c21a9c2fSMilanka Ringwald 186*ad470863SMilanka Ringwald res += "\n - nr channels %d" % self.nr_channels 187*ad470863SMilanka Ringwald res += "\n - nr blocks %d" % self.nr_blocks 188*ad470863SMilanka Ringwald res += "\n - nr subbands %d" % self.nr_subbands 189c21a9c2fSMilanka Ringwald 190*ad470863SMilanka Ringwald res += "\n - channel mode %s" % channel_mode_to_str(self.channel_mode) 191*ad470863SMilanka Ringwald res += "\n - allocation method %s" % allocation_method_to_str(self.allocation_method) 192c21a9c2fSMilanka Ringwald 193*ad470863SMilanka Ringwald res += "\n - bitpool %d" % self.bitpool 194*ad470863SMilanka Ringwald res += "\n - crc check %d" % self.crc_check 195c21a9c2fSMilanka Ringwald return res 196c21a9c2fSMilanka Ringwald 197c21a9c2fSMilanka Ringwald 198c21a9c2fSMilanka Ringwalddef sbc_bit_allocation_stereo_joint(frame, ch): 199c21a9c2fSMilanka Ringwald bitneed = np.zeros(shape=(frame.nr_channels, frame.nr_subbands)) 200c21a9c2fSMilanka Ringwald bits = np.zeros(shape=(frame.nr_channels, frame.nr_subbands)) 201c21a9c2fSMilanka Ringwald loudness = 0 202c21a9c2fSMilanka Ringwald 203c21a9c2fSMilanka Ringwald if frame.allocation_method == SNR: 204c21a9c2fSMilanka Ringwald for ch in range(frame.nr_channels): 205c21a9c2fSMilanka Ringwald for sb in range(frame.nr_subbands): 206c21a9c2fSMilanka Ringwald bitneed[ch][sb] = frame.scale_factor[ch][sb] 207c21a9c2fSMilanka Ringwald else: 208c21a9c2fSMilanka Ringwald for ch in range(frame.nr_channels): 209c21a9c2fSMilanka Ringwald for sb in range(frame.nr_subbands): 210c21a9c2fSMilanka Ringwald if frame.scale_factor[ch][sb] == 0: 211c21a9c2fSMilanka Ringwald bitneed[ch][sb] = -5 212c21a9c2fSMilanka Ringwald else: 213c21a9c2fSMilanka Ringwald if frame.nr_subbands == 4: 214c21a9c2fSMilanka Ringwald loudness = scale_factor[ch][sb] - offset4[frame.sampling_frequency][sb] 215c21a9c2fSMilanka Ringwald else: 216c21a9c2fSMilanka Ringwald if frame.nr_subbands == 4: 217c21a9c2fSMilanka Ringwald loudness = frame.scale_factor[ch][sb] - offset4[frame.sampling_frequency][sb] 218c21a9c2fSMilanka Ringwald else: 219c21a9c2fSMilanka Ringwald loudness = frame.scale_factor[ch][sb] - offset8[frame.sampling_frequency][sb] 220c21a9c2fSMilanka Ringwald if loudness > 0: 221c21a9c2fSMilanka Ringwald bitneed[ch][sb] = loudness/2 222c21a9c2fSMilanka Ringwald else: 223c21a9c2fSMilanka Ringwald bitneed[ch][sb] = loudness 224c21a9c2fSMilanka Ringwald 225c21a9c2fSMilanka Ringwald # search the maximum bitneed index 226c21a9c2fSMilanka Ringwald max_bitneed = 0 227c21a9c2fSMilanka Ringwald for ch in range(frame.nr_channels): 228c21a9c2fSMilanka Ringwald for sb in range(frame.nr_subbands): 229c21a9c2fSMilanka Ringwald if bitneed[ch][sb] > max_bitneed: 230c21a9c2fSMilanka Ringwald max_bitneed = bitneed[ch][sb] 231c21a9c2fSMilanka Ringwald 232c21a9c2fSMilanka Ringwald # calculate how many bitslices fit into the bitpool 233c21a9c2fSMilanka Ringwald bitcount = 0 234c21a9c2fSMilanka Ringwald slicecount = 0 235c21a9c2fSMilanka Ringwald bitslice = max_bitneed + 1 #/* init just above the largest sf */ 236c21a9c2fSMilanka Ringwald 237c21a9c2fSMilanka Ringwald while True: 238c21a9c2fSMilanka Ringwald bitslice = bitslice - 1 239c21a9c2fSMilanka Ringwald bitcount = bitcount + slicecount 240c21a9c2fSMilanka Ringwald slicecount = 0 241c21a9c2fSMilanka Ringwald for ch in range(frame.nr_channels): 242c21a9c2fSMilanka Ringwald for sb in range(frame.nr_subbands): 243c21a9c2fSMilanka Ringwald if (bitneed[ch][sb] > bitslice+1) and (bitneed[ch][sb] < bitslice+16): 244c21a9c2fSMilanka Ringwald slicecount = slicecount + 1 245c21a9c2fSMilanka Ringwald elif bitneed[ch][sb] == bitslice + 1: 246c21a9c2fSMilanka Ringwald slicecount = slicecount + 2 247c21a9c2fSMilanka Ringwald if bitcount + slicecount >= frame.bitpool: 248c21a9c2fSMilanka Ringwald break 249c21a9c2fSMilanka Ringwald 250c21a9c2fSMilanka Ringwald if bitcount + slicecount == frame.bitpool: 251c21a9c2fSMilanka Ringwald bitcount = bitcount + slicecount 252c21a9c2fSMilanka Ringwald bitslice = bitslice - 1 253c21a9c2fSMilanka Ringwald 254c21a9c2fSMilanka Ringwald # bits are distributed until the last bitslice is reached 255c21a9c2fSMilanka Ringwald for ch in range(frame.nr_channels): 256c21a9c2fSMilanka Ringwald for sb in range(frame.nr_subbands): 257c21a9c2fSMilanka Ringwald if bitneed[ch][sb] < bitslice+2 : 258c21a9c2fSMilanka Ringwald bits[ch][sb]=0; 259c21a9c2fSMilanka Ringwald else: 260c21a9c2fSMilanka Ringwald bits[ch][sb] = min(bitneed[ch][sb]-bitslice,16) 261c21a9c2fSMilanka Ringwald 262c21a9c2fSMilanka Ringwald ch = 0 263c21a9c2fSMilanka Ringwald sb = 0 264c21a9c2fSMilanka Ringwald while bitcount < frame.bitpool and sb < frame.nr_subbands: 265c21a9c2fSMilanka Ringwald if bits[ch][sb] >= 2 and bits[ch][sb] < 16: 266c21a9c2fSMilanka Ringwald bits[ch][sb] = bits[ch][sb] + 1 267c21a9c2fSMilanka Ringwald bitcount = bitcount + 1 268c21a9c2fSMilanka Ringwald 269c21a9c2fSMilanka Ringwald elif (bitneed[ch][sb] == bitslice+1) and (frame.bitpool > bitcount+1): 270c21a9c2fSMilanka Ringwald bits[ch][sb] = 2 271c21a9c2fSMilanka Ringwald bitcount += 2 272c21a9c2fSMilanka Ringwald 273c21a9c2fSMilanka Ringwald if ch == 1: 274c21a9c2fSMilanka Ringwald ch = 0 275c21a9c2fSMilanka Ringwald sb = sb + 1 276c21a9c2fSMilanka Ringwald else: 277c21a9c2fSMilanka Ringwald ch = 1 278c21a9c2fSMilanka Ringwald 279c21a9c2fSMilanka Ringwald ch = 0 280c21a9c2fSMilanka Ringwald sb = 0 281c21a9c2fSMilanka Ringwald while bitcount < frame.bitpool and sb < frame.nr_subbands: 282c21a9c2fSMilanka Ringwald if bits[ch][sb] < 16: 283c21a9c2fSMilanka Ringwald bits[ch][sb] = bits[ch][sb] + 1 284c21a9c2fSMilanka Ringwald bitcount = bitcount + 1 285c21a9c2fSMilanka Ringwald if ch == 1: 286c21a9c2fSMilanka Ringwald ch = 0 287c21a9c2fSMilanka Ringwald sb = sb + 1 288c21a9c2fSMilanka Ringwald else: 289c21a9c2fSMilanka Ringwald ch = 1 290c21a9c2fSMilanka Ringwald 291c21a9c2fSMilanka Ringwald return bits 292c21a9c2fSMilanka Ringwald 293c21a9c2fSMilanka Ringwald 294c21a9c2fSMilanka Ringwalddef sbc_bit_allocation_mono_dual(frame): 295c21a9c2fSMilanka Ringwald #print "Bit allocation for mono/dual channel" 296c21a9c2fSMilanka Ringwald bitneed = np.zeros(shape=(frame.nr_channels, frame.nr_subbands), dtype = np.int32) 297c21a9c2fSMilanka Ringwald bits = np.zeros(shape=(frame.nr_channels, frame.nr_subbands), dtype = np.int32) 298c21a9c2fSMilanka Ringwald loudness = 0 299c21a9c2fSMilanka Ringwald 300c21a9c2fSMilanka Ringwald for ch in range(frame.nr_channels): 301c21a9c2fSMilanka Ringwald # bitneed values are derived from the scale factors 302c21a9c2fSMilanka Ringwald if frame.allocation_method == SNR: 303c21a9c2fSMilanka Ringwald for sb in range(frame.nr_subbands): 304c21a9c2fSMilanka Ringwald bitneed[ch][sb] = frame.scale_factor[ch][sb] 305c21a9c2fSMilanka Ringwald else: 306c21a9c2fSMilanka Ringwald for sb in range(frame.nr_subbands): 307c21a9c2fSMilanka Ringwald if frame.scale_factor[ch][sb] == 0: 308c21a9c2fSMilanka Ringwald bitneed[ch][sb] = -5 309c21a9c2fSMilanka Ringwald else: 310c21a9c2fSMilanka Ringwald if frame.nr_subbands == 4: 311c21a9c2fSMilanka Ringwald loudness = frame.scale_factor[ch][sb] - offset4[frame.sampling_frequency][sb] 312c21a9c2fSMilanka Ringwald else: 313c21a9c2fSMilanka Ringwald loudness = frame.scale_factor[ch][sb] - offset8[frame.sampling_frequency][sb] 314c21a9c2fSMilanka Ringwald if loudness > 0: 315c21a9c2fSMilanka Ringwald bitneed[ch][sb] = loudness/2 316c21a9c2fSMilanka Ringwald else: 317c21a9c2fSMilanka Ringwald bitneed[ch][sb] = loudness 318c21a9c2fSMilanka Ringwald 319c21a9c2fSMilanka Ringwald # search the maximum bitneed index 320c21a9c2fSMilanka Ringwald max_bitneed = 0 321c21a9c2fSMilanka Ringwald for sb in range(frame.nr_subbands): 322c21a9c2fSMilanka Ringwald if bitneed[ch][sb] > max_bitneed: 323c21a9c2fSMilanka Ringwald max_bitneed = bitneed[ch][sb] 324c21a9c2fSMilanka Ringwald 325c21a9c2fSMilanka Ringwald # calculate how many bitslices fit into the bitpool 326c21a9c2fSMilanka Ringwald bitcount = 0 327c21a9c2fSMilanka Ringwald slicecount = 0 32841a4a18dSMilanka Ringwald bitslice = max_bitneed + 1 329c21a9c2fSMilanka Ringwald 330c21a9c2fSMilanka Ringwald while True: 331c21a9c2fSMilanka Ringwald bitslice = bitslice - 1 332c21a9c2fSMilanka Ringwald bitcount = bitcount + slicecount 333c21a9c2fSMilanka Ringwald slicecount = 0 334c21a9c2fSMilanka Ringwald for sb in range(frame.nr_subbands): 335c21a9c2fSMilanka Ringwald if (bitneed[ch][sb] > bitslice+1) and (bitneed[ch][sb] < bitslice+16): 336c21a9c2fSMilanka Ringwald slicecount = slicecount + 1 337c21a9c2fSMilanka Ringwald elif bitneed[ch][sb] == bitslice + 1: 338c21a9c2fSMilanka Ringwald slicecount = slicecount + 2 339c21a9c2fSMilanka Ringwald if bitcount + slicecount >= frame.bitpool: 340c21a9c2fSMilanka Ringwald break 341c21a9c2fSMilanka Ringwald 342c21a9c2fSMilanka Ringwald if bitcount + slicecount == frame.bitpool: 343c21a9c2fSMilanka Ringwald bitcount = bitcount + slicecount 344c21a9c2fSMilanka Ringwald bitslice = bitslice - 1 345c21a9c2fSMilanka Ringwald 346c21a9c2fSMilanka Ringwald for sb in range(frame.nr_subbands): 347c21a9c2fSMilanka Ringwald if bitneed[ch][sb] < bitslice+2 : 348c21a9c2fSMilanka Ringwald bits[ch][sb]=0; 349c21a9c2fSMilanka Ringwald else: 350c21a9c2fSMilanka Ringwald bits[ch][sb] = min(bitneed[ch][sb]-bitslice,16) 351c21a9c2fSMilanka Ringwald 352c21a9c2fSMilanka Ringwald sb = 0 353c21a9c2fSMilanka Ringwald while bitcount < frame.bitpool and sb < frame.nr_subbands: 354c21a9c2fSMilanka Ringwald if bits[ch][sb] >= 2 and bits[ch][sb] < 16: 355c21a9c2fSMilanka Ringwald bits[ch][sb] = bits[ch][sb] + 1 356c21a9c2fSMilanka Ringwald bitcount = bitcount + 1 357c21a9c2fSMilanka Ringwald 358c21a9c2fSMilanka Ringwald elif (bitneed[ch][sb] == bitslice+1) and (frame.bitpool > bitcount+1): 359c21a9c2fSMilanka Ringwald bits[ch][sb] = 2 360c21a9c2fSMilanka Ringwald bitcount += 2 361c21a9c2fSMilanka Ringwald 362c21a9c2fSMilanka Ringwald sb = sb + 1 363c21a9c2fSMilanka Ringwald 364c21a9c2fSMilanka Ringwald 365c21a9c2fSMilanka Ringwald sb = 0 366c21a9c2fSMilanka Ringwald while bitcount < frame.bitpool and sb < frame.nr_subbands: 367c21a9c2fSMilanka Ringwald if bits[ch][sb] < 16: 368c21a9c2fSMilanka Ringwald bits[ch][sb] = bits[ch][sb] + 1 369c21a9c2fSMilanka Ringwald bitcount = bitcount + 1 370c21a9c2fSMilanka Ringwald sb = sb + 1 371c21a9c2fSMilanka Ringwald 372c21a9c2fSMilanka Ringwald return bits 373c21a9c2fSMilanka Ringwald 374c21a9c2fSMilanka Ringwalddef sbc_bit_allocation(frame): 375c21a9c2fSMilanka Ringwald if frame.channel_mode == MONO or frame.channel_mode == DUAL_CHANNEL: 376c21a9c2fSMilanka Ringwald return sbc_bit_allocation_mono_dual(frame) 377c21a9c2fSMilanka Ringwald elif frame.channel_mode == STEREO or frame.channel_mode == JOINT_STEREO: 378c21a9c2fSMilanka Ringwald return sbc_bit_allocation_stereo_joint(frame) 379c21a9c2fSMilanka Ringwald else: 380c21a9c2fSMilanka Ringwald print "Wrong channel mode ", frame.channel_mode 381c21a9c2fSMilanka Ringwald return -1 382c21a9c2fSMilanka Ringwald 383c21a9c2fSMilanka Ringwalddef sbc_sampling_frequency_index(sample_rate): 384c21a9c2fSMilanka Ringwald sbc_sampling_frequency_index = 0 385c21a9c2fSMilanka Ringwald for i in range(len(sampling_frequency)): 386c21a9c2fSMilanka Ringwald if sample_rate == sampling_frequency[i]: 387c21a9c2fSMilanka Ringwald sbc_sampling_frequency_index = i 388c21a9c2fSMilanka Ringwald break 389c21a9c2fSMilanka Ringwald return sbc_sampling_frequency_index 390c21a9c2fSMilanka Ringwald 391c21a9c2fSMilanka Ringwald 392c21a9c2fSMilanka Ringwalddef sbc_crc8(data, data_len): 393c21a9c2fSMilanka Ringwald crc = 0x0f 394c21a9c2fSMilanka Ringwald j = 0 395c21a9c2fSMilanka Ringwald for i in range(data_len / 8): 396c21a9c2fSMilanka Ringwald crc = crc_table[crc ^ data[i]] 397c21a9c2fSMilanka Ringwald j = i + 1 398c21a9c2fSMilanka Ringwald 399c21a9c2fSMilanka Ringwald bits_left = data_len%8 400c21a9c2fSMilanka Ringwald if bits_left: 401c21a9c2fSMilanka Ringwald octet = data[j] 402c21a9c2fSMilanka Ringwald for i in range(data_len%8): 403c21a9c2fSMilanka Ringwald bit = ((octet ^ crc) & 0x80) >> 7 404c21a9c2fSMilanka Ringwald if bit: 405c21a9c2fSMilanka Ringwald bit = 0x1d 406c21a9c2fSMilanka Ringwald crc = ((crc & 0x7f) << 1) ^ bit 407c21a9c2fSMilanka Ringwald octet = octet << 1 408c21a9c2fSMilanka Ringwald return crc 409c21a9c2fSMilanka Ringwald 410c21a9c2fSMilanka Ringwald 411*ad470863SMilanka Ringwaldbitstream = None 412c21a9c2fSMilanka Ringwaldbitstream_index = -1 413c21a9c2fSMilanka Ringwaldbitstream_bits_available = 0 414c21a9c2fSMilanka Ringwald 415c21a9c2fSMilanka Ringwalddef init_bitstream(): 416c21a9c2fSMilanka Ringwald global bitstream, bitstream_bits_available, bitstream_index 417c21a9c2fSMilanka Ringwald bitstream = [] 418c21a9c2fSMilanka Ringwald bitstream_index = -1 419c21a9c2fSMilanka Ringwald bitstream_bits_available = 0 420c21a9c2fSMilanka Ringwald 421c21a9c2fSMilanka Ringwalddef add_bit(bit): 422c21a9c2fSMilanka Ringwald global bitstream, bitstream_bits_available, bitstream_index 423c21a9c2fSMilanka Ringwald if bitstream_bits_available == 0: 424c21a9c2fSMilanka Ringwald bitstream.append(0) 425c21a9c2fSMilanka Ringwald bitstream_bits_available = 8 426c21a9c2fSMilanka Ringwald bitstream_index += 1 427c21a9c2fSMilanka Ringwald 428c21a9c2fSMilanka Ringwald bitstream[bitstream_index] |= bit << (bitstream_bits_available - 1) 429c21a9c2fSMilanka Ringwald bitstream_bits_available -= 1 430c21a9c2fSMilanka Ringwald 431c21a9c2fSMilanka Ringwald 432c21a9c2fSMilanka Ringwalddef add_bits(bits, len): 433c21a9c2fSMilanka Ringwald global bitstream, bitstream_bits_available 434c21a9c2fSMilanka Ringwald for i in range(len): 435c21a9c2fSMilanka Ringwald add_bit((bits >> (len-1-i)) & 1) 436c21a9c2fSMilanka Ringwald 437*ad470863SMilanka Ringwaldibuffer = None 438*ad470863SMilanka Ringwaldibuffer_count = 0 439*ad470863SMilanka Ringwald 440*ad470863SMilanka Ringwalddef get_bit(fin): 441*ad470863SMilanka Ringwald global ibuffer, ibuffer_count 442*ad470863SMilanka Ringwald if ibuffer_count == 0: 443*ad470863SMilanka Ringwald ibuffer = ord(fin.read(1)) 444*ad470863SMilanka Ringwald ibuffer_count = 8 445*ad470863SMilanka Ringwald 446*ad470863SMilanka Ringwald bit = (ibuffer >> 7) & 1 447*ad470863SMilanka Ringwald ibuffer = ibuffer << 1 448*ad470863SMilanka Ringwald ibuffer_count = ibuffer_count - 1 449*ad470863SMilanka Ringwald return bit 450*ad470863SMilanka Ringwald 451*ad470863SMilanka Ringwalddef drop_remaining_bits(): 452*ad470863SMilanka Ringwald global ibuffer_count 453*ad470863SMilanka Ringwald ibuffer_count = 0 454*ad470863SMilanka Ringwald 455*ad470863SMilanka Ringwalddef get_bits(fin, bit_count): 456*ad470863SMilanka Ringwald bits = 0 457*ad470863SMilanka Ringwald for i in range(bit_count): 458*ad470863SMilanka Ringwald bits = (bits << 1) | get_bit(fin) 459*ad470863SMilanka Ringwald return bits 460*ad470863SMilanka Ringwald 461c21a9c2fSMilanka Ringwald 462c21a9c2fSMilanka Ringwalddef calculate_crc(frame): 463c21a9c2fSMilanka Ringwald global bitstream, bitstream_bits_available, bitstream_index 464c21a9c2fSMilanka Ringwald init_bitstream() 465c21a9c2fSMilanka Ringwald 466c21a9c2fSMilanka Ringwald add_bits(frame.sampling_frequency, 2) 467c21a9c2fSMilanka Ringwald add_bits(frame.nr_blocks/4-1, 2) 468c21a9c2fSMilanka Ringwald add_bits(frame.channel_mode, 2) 469c21a9c2fSMilanka Ringwald add_bits(frame.allocation_method, 1) 470c21a9c2fSMilanka Ringwald add_bits(frame.nr_subbands/4-1, 1) 471c21a9c2fSMilanka Ringwald add_bits(frame.bitpool, 8) 472c21a9c2fSMilanka Ringwald 473c21a9c2fSMilanka Ringwald if frame.channel_mode == JOINT_STEREO: 474c21a9c2fSMilanka Ringwald for sb in range(frame.nr_subbands): 475c21a9c2fSMilanka Ringwald add_bits(frame.join[sb],1) 476c21a9c2fSMilanka Ringwald 477c21a9c2fSMilanka Ringwald for ch in range(frame.nr_channels): 478c21a9c2fSMilanka Ringwald for sb in range(frame.nr_subbands): 479c21a9c2fSMilanka Ringwald add_bits(frame.scale_factor[ch][sb], 4) 48041a4a18dSMilanka Ringwald 481c21a9c2fSMilanka Ringwald bitstream_len = (bitstream_index + 1) * 8 482c21a9c2fSMilanka Ringwald if bitstream_bits_available: 483c21a9c2fSMilanka Ringwald bitstream_len += (8-bitstream_bits_available) 484c21a9c2fSMilanka Ringwald return sbc_crc8(bitstream, bitstream_len) 485c21a9c2fSMilanka Ringwald 486c21a9c2fSMilanka Ringwald 487c21a9c2fSMilanka Ringwald 488*ad470863SMilanka Ringwalddef frame_to_bitstream(frame): 489*ad470863SMilanka Ringwald global bitstream, bitstream_bits_available, bitstream_index 490*ad470863SMilanka Ringwald init_bitstream() 491c21a9c2fSMilanka Ringwald 492*ad470863SMilanka Ringwald add_bits(frame.syncword, 8) 493*ad470863SMilanka Ringwald add_bits(frame.sampling_frequency, 2) 494*ad470863SMilanka Ringwald add_bits(frame.nr_blocks/4-1, 2) 495*ad470863SMilanka Ringwald add_bits(frame.channel_mode, 2) 496*ad470863SMilanka Ringwald add_bits(frame.allocation_method, 1) 497*ad470863SMilanka Ringwald add_bits(frame.nr_subbands/4-1, 1) 498*ad470863SMilanka Ringwald add_bits(frame.bitpool, 8) 499*ad470863SMilanka Ringwald add_bits(frame.crc_check, 8) 500c21a9c2fSMilanka Ringwald 501*ad470863SMilanka Ringwald if frame.channel_mode == JOINT_STEREO: 502*ad470863SMilanka Ringwald for sb in range(frame.nr_subbands-1): 503*ad470863SMilanka Ringwald add_bits(frame.join[sb],1) 504*ad470863SMilanka Ringwald add_bits(0,1) 505*ad470863SMilanka Ringwald 506*ad470863SMilanka Ringwald for ch in range(frame.nr_channels): 507*ad470863SMilanka Ringwald for sb in range(frame.nr_subbands): 508*ad470863SMilanka Ringwald add_bits(frame.scale_factor[ch][sb], 4) 509*ad470863SMilanka Ringwald 510*ad470863SMilanka Ringwald for blk in range(frame.nr_blocks): 511*ad470863SMilanka Ringwald for ch in range(frame.nr_channels): 512*ad470863SMilanka Ringwald for sb in range(frame.nr_subbands): 513*ad470863SMilanka Ringwald add_bits(frame.audio_sample[blk][ch][sb], frame.bits[ch][sb]) 514*ad470863SMilanka Ringwald 515*ad470863SMilanka Ringwald bitstream_bits_available = 0 516*ad470863SMilanka Ringwald return bitstream 517*ad470863SMilanka Ringwald 518*ad470863SMilanka Ringwalddef mse(a,b): 519*ad470863SMilanka Ringwald count = 1 520*ad470863SMilanka Ringwald for i in a.shape: 521*ad470863SMilanka Ringwald count *= i 522*ad470863SMilanka Ringwald delta = a - b 523*ad470863SMilanka Ringwald sqr = delta ** 2 524*ad470863SMilanka Ringwald res = sqr.sum()*1.0/count 525*ad470863SMilanka Ringwald # res = ((a - b) ** 2).mean() 526*ad470863SMilanka Ringwald return res 527c21a9c2fSMilanka Ringwald