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 12ad470863SMilanka Ringwaldchannel_modes = ["MONO", "DUAL CHANNEL", "STEREO", "JOINT STEREO"] 13c21a9c2fSMilanka Ringwald 14c21a9c2fSMilanka Ringwald# allocation method 15c21a9c2fSMilanka RingwaldLOUDNESS = 0 16c21a9c2fSMilanka RingwaldSNR = 1 17ad470863SMilanka Ringwaldallocation_methods = ["LOUDNESS", "SNR"] 18ad470863SMilanka Ringwald 19ad470863SMilanka Ringwaldsampling_frequencies = [16000, 32000, 44100, 48000] 20ad470863SMilanka Ringwaldnr_blocks = [4, 8, 12, 16] 21ad470863SMilanka Ringwaldnr_subbands = [4, 8] 22ad470863SMilanka Ringwald 23ad470863SMilanka Ringwald 24ad470863SMilanka Ringwalddef allocation_method_to_str(allocation_method): 25ad470863SMilanka Ringwald global allocation_methods 26ad470863SMilanka Ringwald return allocation_methods[allocation_method] 27ad470863SMilanka Ringwald 28ad470863SMilanka Ringwalddef channel_mode_to_str(channel_mode): 29ad470863SMilanka Ringwald global channel_modes 30ad470863SMilanka Ringwald return channel_modes[channel_mode] 31ad470863SMilanka Ringwald 32ad470863SMilanka Ringwalddef sampling_frequency_to_str(sampling_frequency): 33ad470863SMilanka Ringwald global sampling_frequencies 34ad470863SMilanka Ringwald return sampling_frequencies[sampling_frequency] 35ad470863SMilanka Ringwald 36ad470863SMilanka Ringwalddef sampling_frequency_index(sampling_frequency): 37ad470863SMilanka Ringwald global sampling_frequencies 38ad470863SMilanka Ringwald for index, value in enumerate(sampling_frequencies): 39ad470863SMilanka Ringwald if value == sampling_frequency: 40ad470863SMilanka Ringwald return index 41ad470863SMilanka 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 127*1522543dSMilanka Ringwalddef calculate_scalefactor(max_subbandsample): 128*1522543dSMilanka Ringwald x = 0 129*1522543dSMilanka Ringwald while True: 130*1522543dSMilanka Ringwald y = 1 << x + 1 131*1522543dSMilanka Ringwald if y > max_subbandsample: 132*1522543dSMilanka Ringwald break 133*1522543dSMilanka Ringwald x += 1 134*1522543dSMilanka Ringwald return (x,y) 135*1522543dSMilanka Ringwald 136*1522543dSMilanka Ringwald 137*1522543dSMilanka Ringwalddef calculate_max_subbandsample(nr_blocks, nr_channels, nr_subbands, sb_sample): 138*1522543dSMilanka Ringwald max_subbandsample = np.zeros(shape = (nr_channels, nr_subbands)) 139*1522543dSMilanka Ringwald 140*1522543dSMilanka Ringwald for blk in range(nr_blocks): 141*1522543dSMilanka Ringwald for ch in range(nr_channels): 142*1522543dSMilanka Ringwald for sb in range(nr_subbands): 143*1522543dSMilanka Ringwald m = abs(sb_sample[blk][ch][sb]) 144*1522543dSMilanka Ringwald if max_subbandsample[ch][sb] < m: 145*1522543dSMilanka Ringwald max_subbandsample[ch][sb] = m 146*1522543dSMilanka Ringwald return max_subbandsample 147*1522543dSMilanka Ringwald 148*1522543dSMilanka Ringwalddef calculate_scalefactors(nr_blocks, nr_channels, nr_subbands, sb_sample): 149*1522543dSMilanka Ringwald scale_factor = np.zeros(shape=(nr_channels, nr_subbands), dtype = np.int32) 150*1522543dSMilanka Ringwald scalefactor = np.zeros(shape=(nr_channels, nr_subbands), dtype = np.int32) 151*1522543dSMilanka Ringwald 152*1522543dSMilanka Ringwald # max_subbandsample = calculate_max_subbandsample(nr_blocks, nr_channels, nr_subbands, sb_sample) 153*1522543dSMilanka Ringwald # for ch in range(nr_channels): 154*1522543dSMilanka Ringwald # for sb in range(nr_subbands): 155*1522543dSMilanka Ringwald # (scale_factor[ch][sb], scalefactor[ch][sb]) = calculate_scalefactor(max_subbandsample[ch][sb]) 156*1522543dSMilanka Ringwald 157*1522543dSMilanka Ringwald for ch in range(nr_channels): 158*1522543dSMilanka Ringwald for sb in range(nr_subbands): 159*1522543dSMilanka Ringwald scale_factor[ch][sb] = 0 160*1522543dSMilanka Ringwald scalefactor[ch][sb] = 2 161*1522543dSMilanka Ringwald for blk in range(nr_blocks): 162*1522543dSMilanka Ringwald while scalefactor[ch][sb] < abs(sb_sample[blk][ch][sb]): 163*1522543dSMilanka Ringwald scale_factor[ch][sb]+=1 164*1522543dSMilanka Ringwald scalefactor[ch][sb] *= 2 165*1522543dSMilanka Ringwald 166*1522543dSMilanka Ringwald return scale_factor, scalefactor 167*1522543dSMilanka Ringwald 168*1522543dSMilanka Ringwalddef calculate_scalefactors_and_channel_mode(frame): 169*1522543dSMilanka Ringwald frame.scale_factor, frame.scalefactor = calculate_scalefactors(frame.nr_blocks, frame.nr_channels, frame.nr_subbands, frame.sb_sample) 170*1522543dSMilanka Ringwald #print "calculate_scalefactors_and_channel_mode1 ", frame.scale_factor 171*1522543dSMilanka Ringwald 172*1522543dSMilanka Ringwald if frame.nr_channels == 1: 173*1522543dSMilanka Ringwald frame.channel_mode = MONO 174*1522543dSMilanka Ringwald else: 175*1522543dSMilanka Ringwald sb_sample1 = np.zeros(shape = (frame.nr_blocks,2,frame.nr_subbands), dtype = np.uint16) 176*1522543dSMilanka Ringwald 177*1522543dSMilanka Ringwald for blk in range(frame.nr_blocks): 178*1522543dSMilanka Ringwald for sb in range(frame.nr_subbands): 179*1522543dSMilanka Ringwald sb_sample1[blk][0][sb] = frame.sb_sample[blk][0][sb] + frame.sb_sample[blk][1][sb] 180*1522543dSMilanka Ringwald sb_sample1[blk][1][sb] = frame.sb_sample[blk][0][sb] - frame.sb_sample[blk][1][sb] 181*1522543dSMilanka Ringwald 182*1522543dSMilanka Ringwald scale_factor, scalefactor = calculate_scalefactors(frame.nr_blocks, frame.nr_channels, frame.nr_subbands, sb_sample1) 183*1522543dSMilanka Ringwald #print "calculate_scalefactors_and_channel_mode 2", scale_factor 184*1522543dSMilanka Ringwald sumb = 0 185*1522543dSMilanka Ringwald suma = 0 186*1522543dSMilanka Ringwald for sb in range(frame.nr_subbands): 187*1522543dSMilanka Ringwald suma += frame.scale_factor[0][sb] + frame.scale_factor[1][sb] 188*1522543dSMilanka Ringwald sumb += scale_factor[0][sb] + scale_factor[1][sb] 189*1522543dSMilanka Ringwald 190*1522543dSMilanka Ringwald #print "calculate_scalefactors_and_channel_mode 3", suma, sumb 191*1522543dSMilanka Ringwald if suma > sumb: 192*1522543dSMilanka Ringwald frame.channel_mode = JOINT_STEREO 193*1522543dSMilanka Ringwald else: 194*1522543dSMilanka Ringwald frame.channel_mode = STEREO 195*1522543dSMilanka Ringwald 196*1522543dSMilanka Ringwald 197c21a9c2fSMilanka Ringwaldclass SBCFrame: 198c21a9c2fSMilanka Ringwald syncword = 0 199c21a9c2fSMilanka Ringwald sampling_frequency = 0 200c21a9c2fSMilanka Ringwald nr_blocks = 0 201c21a9c2fSMilanka Ringwald channel_mode = 0 202c21a9c2fSMilanka Ringwald nr_channels = 0 203c21a9c2fSMilanka Ringwald allocation_method = 0 204c21a9c2fSMilanka Ringwald nr_subbands = 0 205c21a9c2fSMilanka Ringwald bitpool = 0 206c21a9c2fSMilanka Ringwald crc_check = 0 207c21a9c2fSMilanka Ringwald # pro subband - 1 208c21a9c2fSMilanka Ringwald join = np.zeros(8, dtype = np.uint8) 209c21a9c2fSMilanka Ringwald scale_factor = np.zeros(shape=(2, 8), dtype = np.int32) 210c21a9c2fSMilanka Ringwald scalefactor = np.zeros(shape=(2, 8), dtype = np.int32) 211c21a9c2fSMilanka Ringwald audio_sample = np.zeros(shape = (16,2,8), dtype = np.uint16) 212c21a9c2fSMilanka Ringwald sb_sample = np.zeros(shape = (16,2,8), dtype = np.uint16) 213c21a9c2fSMilanka Ringwald X = np.zeros(8, dtype = np.int16) 214c21a9c2fSMilanka Ringwald EX = np.zeros(8) 215*1522543dSMilanka Ringwald pcm = np.zeros(shape=(2, 8*16), dtype = np.int16) 216c21a9c2fSMilanka Ringwald bits = np.zeros(shape=(2, 8)) 217c21a9c2fSMilanka Ringwald levels = np.zeros(shape=(2, 8), dtype = np.int32) 218c21a9c2fSMilanka Ringwald 219ad470863SMilanka Ringwald 2205665ea35SMilanka Ringwald def __init__(self, nr_blocks=16, nr_subbands=4, nr_channels=1, bitpool=31, sampling_frequency=44100, allocation_method = 0): 221c21a9c2fSMilanka Ringwald self.nr_blocks = nr_blocks 222c21a9c2fSMilanka Ringwald self.nr_subbands = nr_subbands 223c21a9c2fSMilanka Ringwald self.nr_channels = nr_channels 224ad470863SMilanka Ringwald self.sampling_frequency = sampling_frequency_index(sampling_frequency) 225c21a9c2fSMilanka Ringwald self.bitpool = bitpool 2265665ea35SMilanka Ringwald self.allocation_method = allocation_method 227c21a9c2fSMilanka Ringwald self.scale_factor = np.zeros(shape=(nr_channels, nr_subbands), dtype = np.int32) 228c21a9c2fSMilanka Ringwald self.scalefactor = np.zeros(shape=(nr_channels, nr_subbands), dtype = np.int32) 229c21a9c2fSMilanka Ringwald self.audio_sample = np.zeros(shape=(nr_blocks, nr_channels, nr_subbands), dtype = np.uint16) 230c21a9c2fSMilanka Ringwald self.sb_sample = np.zeros(shape=(nr_blocks, nr_channels, nr_subbands), dtype = np.uint16) 231c21a9c2fSMilanka Ringwald self.levels = np.zeros(shape=(nr_channels, nr_subbands), dtype = np.int32) 232c21a9c2fSMilanka Ringwald self.EX = np.zeros(nr_subbands) 233c21a9c2fSMilanka Ringwald return 234c21a9c2fSMilanka Ringwald 235ad470863SMilanka Ringwald def dump_audio_samples(self, blk, ch): 236ad470863SMilanka Ringwald print self.audio_sample[blk][ch] 237ad470863SMilanka Ringwald 238ad470863SMilanka Ringwald def dump_subband_samples(self, blk, ch): 239ad470863SMilanka Ringwald print self.sb_sample[blk][ch] 240ad470863SMilanka Ringwald 241ad470863SMilanka Ringwald def dump_state(self): 242ad470863SMilanka Ringwald res = "SBCFrameHeader state:" 243ad470863SMilanka Ringwald res += "\n - nr channels %d" % self.nr_channels 244ad470863SMilanka Ringwald res += "\n - nr blocks %d" % self.nr_blocks 245ad470863SMilanka Ringwald res += "\n - nr subbands %d" % self.nr_subbands 246ad470863SMilanka Ringwald res += "\n - scale factors: %s" % self.scale_factor 247ad470863SMilanka Ringwald res += "\n - levels: %s" % self.levels 248ad470863SMilanka Ringwald res += "\n - join: %s" % self.join 249ad470863SMilanka Ringwald res += "\n - bits: %s" % self.bits 250ad470863SMilanka Ringwald print res 251ad470863SMilanka Ringwald 252c21a9c2fSMilanka Ringwald def __str__(self): 253c21a9c2fSMilanka Ringwald res = "SBCFrameHeader:" 254ad470863SMilanka Ringwald res += "\n - syncword %d" % self.syncword 255ad470863SMilanka Ringwald res += "\n - sampling frequency %d Hz" % sampling_frequency_to_str(self.sampling_frequency) 256c21a9c2fSMilanka Ringwald 257ad470863SMilanka Ringwald res += "\n - nr channels %d" % self.nr_channels 258ad470863SMilanka Ringwald res += "\n - nr blocks %d" % self.nr_blocks 259ad470863SMilanka Ringwald res += "\n - nr subbands %d" % self.nr_subbands 260c21a9c2fSMilanka Ringwald 261ad470863SMilanka Ringwald res += "\n - channel mode %s" % channel_mode_to_str(self.channel_mode) 262ad470863SMilanka Ringwald res += "\n - allocation method %s" % allocation_method_to_str(self.allocation_method) 263c21a9c2fSMilanka Ringwald 264ad470863SMilanka Ringwald res += "\n - bitpool %d" % self.bitpool 265ad470863SMilanka Ringwald res += "\n - crc check %d" % self.crc_check 266c21a9c2fSMilanka Ringwald return res 267c21a9c2fSMilanka Ringwald 268c21a9c2fSMilanka Ringwald 269*1522543dSMilanka Ringwalddef sbc_bit_allocation_stereo_joint(frame): 270*1522543dSMilanka Ringwald bitneed = np.zeros(shape=(frame.nr_channels, frame.nr_subbands), dtype = np.int32) 271*1522543dSMilanka Ringwald bits = np.zeros(shape=(frame.nr_channels, frame.nr_subbands), dtype = np.int32) 272*1522543dSMilanka Ringwald 273c21a9c2fSMilanka Ringwald loudness = 0 274c21a9c2fSMilanka Ringwald 275c21a9c2fSMilanka Ringwald if frame.allocation_method == SNR: 276c21a9c2fSMilanka Ringwald for ch in range(frame.nr_channels): 277c21a9c2fSMilanka Ringwald for sb in range(frame.nr_subbands): 278c21a9c2fSMilanka Ringwald bitneed[ch][sb] = frame.scale_factor[ch][sb] 279c21a9c2fSMilanka Ringwald else: 280c21a9c2fSMilanka Ringwald for ch in range(frame.nr_channels): 281c21a9c2fSMilanka Ringwald for sb in range(frame.nr_subbands): 282c21a9c2fSMilanka Ringwald if frame.scale_factor[ch][sb] == 0: 283c21a9c2fSMilanka Ringwald bitneed[ch][sb] = -5 284c21a9c2fSMilanka Ringwald else: 285c21a9c2fSMilanka Ringwald if frame.nr_subbands == 4: 286c21a9c2fSMilanka Ringwald loudness = scale_factor[ch][sb] - offset4[frame.sampling_frequency][sb] 287c21a9c2fSMilanka Ringwald else: 288c21a9c2fSMilanka Ringwald loudness = frame.scale_factor[ch][sb] - offset8[frame.sampling_frequency][sb] 289*1522543dSMilanka Ringwald 290c21a9c2fSMilanka Ringwald if loudness > 0: 291c21a9c2fSMilanka Ringwald bitneed[ch][sb] = loudness/2 292c21a9c2fSMilanka Ringwald else: 293c21a9c2fSMilanka Ringwald bitneed[ch][sb] = loudness 294c21a9c2fSMilanka Ringwald 295c21a9c2fSMilanka Ringwald # search the maximum bitneed index 296c21a9c2fSMilanka Ringwald max_bitneed = 0 297c21a9c2fSMilanka Ringwald for ch in range(frame.nr_channels): 298c21a9c2fSMilanka Ringwald for sb in range(frame.nr_subbands): 299c21a9c2fSMilanka Ringwald if bitneed[ch][sb] > max_bitneed: 300c21a9c2fSMilanka Ringwald max_bitneed = bitneed[ch][sb] 301c21a9c2fSMilanka Ringwald 302c21a9c2fSMilanka Ringwald # calculate how many bitslices fit into the bitpool 303c21a9c2fSMilanka Ringwald bitcount = 0 304c21a9c2fSMilanka Ringwald slicecount = 0 305c21a9c2fSMilanka Ringwald bitslice = max_bitneed + 1 #/* init just above the largest sf */ 306c21a9c2fSMilanka Ringwald 307c21a9c2fSMilanka Ringwald while True: 308*1522543dSMilanka Ringwald bitslice -= 1 309*1522543dSMilanka Ringwald bitcount += slicecount 310c21a9c2fSMilanka Ringwald slicecount = 0 311c21a9c2fSMilanka Ringwald for ch in range(frame.nr_channels): 312c21a9c2fSMilanka Ringwald for sb in range(frame.nr_subbands): 313c21a9c2fSMilanka Ringwald if (bitneed[ch][sb] > bitslice+1) and (bitneed[ch][sb] < bitslice+16): 314*1522543dSMilanka Ringwald slicecount += 1 315c21a9c2fSMilanka Ringwald elif bitneed[ch][sb] == bitslice + 1: 316*1522543dSMilanka Ringwald slicecount += 2 317c21a9c2fSMilanka Ringwald if bitcount + slicecount >= frame.bitpool: 318c21a9c2fSMilanka Ringwald break 319c21a9c2fSMilanka Ringwald 320c21a9c2fSMilanka Ringwald if bitcount + slicecount == frame.bitpool: 321*1522543dSMilanka Ringwald bitcount += slicecount 322*1522543dSMilanka Ringwald bitslice -= 1 323c21a9c2fSMilanka Ringwald 324c21a9c2fSMilanka Ringwald # bits are distributed until the last bitslice is reached 325c21a9c2fSMilanka Ringwald for ch in range(frame.nr_channels): 326c21a9c2fSMilanka Ringwald for sb in range(frame.nr_subbands): 327c21a9c2fSMilanka Ringwald if bitneed[ch][sb] < bitslice+2 : 328c21a9c2fSMilanka Ringwald bits[ch][sb]=0; 329c21a9c2fSMilanka Ringwald else: 330c21a9c2fSMilanka Ringwald bits[ch][sb] = min(bitneed[ch][sb]-bitslice,16) 331c21a9c2fSMilanka Ringwald 332c21a9c2fSMilanka Ringwald ch = 0 333c21a9c2fSMilanka Ringwald sb = 0 334c21a9c2fSMilanka Ringwald while bitcount < frame.bitpool and sb < frame.nr_subbands: 335c21a9c2fSMilanka Ringwald if bits[ch][sb] >= 2 and bits[ch][sb] < 16: 336*1522543dSMilanka Ringwald bits[ch][sb] += 1 337*1522543dSMilanka Ringwald bitcount += 1 338c21a9c2fSMilanka Ringwald elif (bitneed[ch][sb] == bitslice+1) and (frame.bitpool > bitcount+1): 339c21a9c2fSMilanka Ringwald bits[ch][sb] = 2 340c21a9c2fSMilanka Ringwald bitcount += 2 341c21a9c2fSMilanka Ringwald 342c21a9c2fSMilanka Ringwald if ch == 1: 343c21a9c2fSMilanka Ringwald ch = 0 344*1522543dSMilanka Ringwald sb += 1 345c21a9c2fSMilanka Ringwald else: 346c21a9c2fSMilanka Ringwald ch = 1 347c21a9c2fSMilanka Ringwald 348c21a9c2fSMilanka Ringwald return bits 349c21a9c2fSMilanka Ringwald 350c21a9c2fSMilanka Ringwald 351c21a9c2fSMilanka Ringwalddef sbc_bit_allocation_mono_dual(frame): 352c21a9c2fSMilanka Ringwald #print "Bit allocation for mono/dual channel" 353c21a9c2fSMilanka Ringwald bitneed = np.zeros(shape=(frame.nr_channels, frame.nr_subbands), dtype = np.int32) 354c21a9c2fSMilanka Ringwald bits = np.zeros(shape=(frame.nr_channels, frame.nr_subbands), dtype = np.int32) 355c21a9c2fSMilanka Ringwald loudness = 0 356c21a9c2fSMilanka Ringwald 357c21a9c2fSMilanka Ringwald for ch in range(frame.nr_channels): 358c21a9c2fSMilanka Ringwald # bitneed values are derived from the scale factors 359c21a9c2fSMilanka Ringwald if frame.allocation_method == SNR: 360c21a9c2fSMilanka Ringwald for sb in range(frame.nr_subbands): 361c21a9c2fSMilanka Ringwald bitneed[ch][sb] = frame.scale_factor[ch][sb] 362c21a9c2fSMilanka Ringwald else: 363c21a9c2fSMilanka Ringwald for sb in range(frame.nr_subbands): 364c21a9c2fSMilanka Ringwald if frame.scale_factor[ch][sb] == 0: 365c21a9c2fSMilanka Ringwald bitneed[ch][sb] = -5 366c21a9c2fSMilanka Ringwald else: 367c21a9c2fSMilanka Ringwald if frame.nr_subbands == 4: 368c21a9c2fSMilanka Ringwald loudness = frame.scale_factor[ch][sb] - offset4[frame.sampling_frequency][sb] 369c21a9c2fSMilanka Ringwald else: 370c21a9c2fSMilanka Ringwald loudness = frame.scale_factor[ch][sb] - offset8[frame.sampling_frequency][sb] 371c21a9c2fSMilanka Ringwald if loudness > 0: 372c21a9c2fSMilanka Ringwald bitneed[ch][sb] = loudness/2 373c21a9c2fSMilanka Ringwald else: 374c21a9c2fSMilanka Ringwald bitneed[ch][sb] = loudness 375c21a9c2fSMilanka Ringwald 376c21a9c2fSMilanka Ringwald # search the maximum bitneed index 377c21a9c2fSMilanka Ringwald max_bitneed = 0 378c21a9c2fSMilanka Ringwald for sb in range(frame.nr_subbands): 379c21a9c2fSMilanka Ringwald if bitneed[ch][sb] > max_bitneed: 380c21a9c2fSMilanka Ringwald max_bitneed = bitneed[ch][sb] 381c21a9c2fSMilanka Ringwald 382c21a9c2fSMilanka Ringwald # calculate how many bitslices fit into the bitpool 383c21a9c2fSMilanka Ringwald bitcount = 0 384c21a9c2fSMilanka Ringwald slicecount = 0 38541a4a18dSMilanka Ringwald bitslice = max_bitneed + 1 386c21a9c2fSMilanka Ringwald 387c21a9c2fSMilanka Ringwald while True: 388c21a9c2fSMilanka Ringwald bitslice = bitslice - 1 389c21a9c2fSMilanka Ringwald bitcount = bitcount + slicecount 390c21a9c2fSMilanka Ringwald slicecount = 0 391c21a9c2fSMilanka Ringwald for sb in range(frame.nr_subbands): 392c21a9c2fSMilanka Ringwald if (bitneed[ch][sb] > bitslice+1) and (bitneed[ch][sb] < bitslice+16): 393c21a9c2fSMilanka Ringwald slicecount = slicecount + 1 394c21a9c2fSMilanka Ringwald elif bitneed[ch][sb] == bitslice + 1: 395c21a9c2fSMilanka Ringwald slicecount = slicecount + 2 396c21a9c2fSMilanka Ringwald if bitcount + slicecount >= frame.bitpool: 397c21a9c2fSMilanka Ringwald break 398c21a9c2fSMilanka Ringwald 399c21a9c2fSMilanka Ringwald if bitcount + slicecount == frame.bitpool: 400c21a9c2fSMilanka Ringwald bitcount = bitcount + slicecount 401c21a9c2fSMilanka Ringwald bitslice = bitslice - 1 402c21a9c2fSMilanka Ringwald 403c21a9c2fSMilanka Ringwald for sb in range(frame.nr_subbands): 404c21a9c2fSMilanka Ringwald if bitneed[ch][sb] < bitslice+2 : 405c21a9c2fSMilanka Ringwald bits[ch][sb]=0; 406c21a9c2fSMilanka Ringwald else: 407c21a9c2fSMilanka Ringwald bits[ch][sb] = min(bitneed[ch][sb]-bitslice,16) 408c21a9c2fSMilanka Ringwald 409c21a9c2fSMilanka Ringwald sb = 0 410c21a9c2fSMilanka Ringwald while bitcount < frame.bitpool and sb < frame.nr_subbands: 411c21a9c2fSMilanka Ringwald if bits[ch][sb] >= 2 and bits[ch][sb] < 16: 412c21a9c2fSMilanka Ringwald bits[ch][sb] = bits[ch][sb] + 1 413c21a9c2fSMilanka Ringwald bitcount = bitcount + 1 414c21a9c2fSMilanka Ringwald 415c21a9c2fSMilanka Ringwald elif (bitneed[ch][sb] == bitslice+1) and (frame.bitpool > bitcount+1): 416c21a9c2fSMilanka Ringwald bits[ch][sb] = 2 417c21a9c2fSMilanka Ringwald bitcount += 2 418c21a9c2fSMilanka Ringwald 419c21a9c2fSMilanka Ringwald sb = sb + 1 420c21a9c2fSMilanka Ringwald 421c21a9c2fSMilanka Ringwald 422c21a9c2fSMilanka Ringwald sb = 0 423c21a9c2fSMilanka Ringwald while bitcount < frame.bitpool and sb < frame.nr_subbands: 424c21a9c2fSMilanka Ringwald if bits[ch][sb] < 16: 425c21a9c2fSMilanka Ringwald bits[ch][sb] = bits[ch][sb] + 1 426c21a9c2fSMilanka Ringwald bitcount = bitcount + 1 427c21a9c2fSMilanka Ringwald sb = sb + 1 428c21a9c2fSMilanka Ringwald 429c21a9c2fSMilanka Ringwald return bits 430c21a9c2fSMilanka Ringwald 431c21a9c2fSMilanka Ringwalddef sbc_bit_allocation(frame): 432c21a9c2fSMilanka Ringwald if frame.channel_mode == MONO or frame.channel_mode == DUAL_CHANNEL: 433c21a9c2fSMilanka Ringwald return sbc_bit_allocation_mono_dual(frame) 434c21a9c2fSMilanka Ringwald elif frame.channel_mode == STEREO or frame.channel_mode == JOINT_STEREO: 435c21a9c2fSMilanka Ringwald return sbc_bit_allocation_stereo_joint(frame) 436c21a9c2fSMilanka Ringwald else: 437c21a9c2fSMilanka Ringwald print "Wrong channel mode ", frame.channel_mode 438c21a9c2fSMilanka Ringwald return -1 439c21a9c2fSMilanka Ringwald 440c21a9c2fSMilanka Ringwalddef sbc_sampling_frequency_index(sample_rate): 441c21a9c2fSMilanka Ringwald sbc_sampling_frequency_index = 0 442c21a9c2fSMilanka Ringwald for i in range(len(sampling_frequency)): 443c21a9c2fSMilanka Ringwald if sample_rate == sampling_frequency[i]: 444c21a9c2fSMilanka Ringwald sbc_sampling_frequency_index = i 445c21a9c2fSMilanka Ringwald break 446c21a9c2fSMilanka Ringwald return sbc_sampling_frequency_index 447c21a9c2fSMilanka Ringwald 448c21a9c2fSMilanka Ringwald 449c21a9c2fSMilanka Ringwalddef sbc_crc8(data, data_len): 450c21a9c2fSMilanka Ringwald crc = 0x0f 451c21a9c2fSMilanka Ringwald j = 0 452c21a9c2fSMilanka Ringwald for i in range(data_len / 8): 453c21a9c2fSMilanka Ringwald crc = crc_table[crc ^ data[i]] 454c21a9c2fSMilanka Ringwald j = i + 1 455c21a9c2fSMilanka Ringwald 456c21a9c2fSMilanka Ringwald bits_left = data_len%8 457c21a9c2fSMilanka Ringwald if bits_left: 458c21a9c2fSMilanka Ringwald octet = data[j] 459c21a9c2fSMilanka Ringwald for i in range(data_len%8): 460c21a9c2fSMilanka Ringwald bit = ((octet ^ crc) & 0x80) >> 7 461c21a9c2fSMilanka Ringwald if bit: 462c21a9c2fSMilanka Ringwald bit = 0x1d 463c21a9c2fSMilanka Ringwald crc = ((crc & 0x7f) << 1) ^ bit 464c21a9c2fSMilanka Ringwald octet = octet << 1 465c21a9c2fSMilanka Ringwald return crc 466c21a9c2fSMilanka Ringwald 467c21a9c2fSMilanka Ringwald 468ad470863SMilanka Ringwaldbitstream = None 469c21a9c2fSMilanka Ringwaldbitstream_index = -1 470c21a9c2fSMilanka Ringwaldbitstream_bits_available = 0 471c21a9c2fSMilanka Ringwald 472c21a9c2fSMilanka Ringwalddef init_bitstream(): 473c21a9c2fSMilanka Ringwald global bitstream, bitstream_bits_available, bitstream_index 474c21a9c2fSMilanka Ringwald bitstream = [] 475c21a9c2fSMilanka Ringwald bitstream_index = -1 476c21a9c2fSMilanka Ringwald bitstream_bits_available = 0 477c21a9c2fSMilanka Ringwald 478c21a9c2fSMilanka Ringwalddef add_bit(bit): 479c21a9c2fSMilanka Ringwald global bitstream, bitstream_bits_available, bitstream_index 480c21a9c2fSMilanka Ringwald if bitstream_bits_available == 0: 481c21a9c2fSMilanka Ringwald bitstream.append(0) 482c21a9c2fSMilanka Ringwald bitstream_bits_available = 8 483c21a9c2fSMilanka Ringwald bitstream_index += 1 484c21a9c2fSMilanka Ringwald 485c21a9c2fSMilanka Ringwald bitstream[bitstream_index] |= bit << (bitstream_bits_available - 1) 486c21a9c2fSMilanka Ringwald bitstream_bits_available -= 1 487c21a9c2fSMilanka Ringwald 488c21a9c2fSMilanka Ringwald 489c21a9c2fSMilanka Ringwalddef add_bits(bits, len): 490c21a9c2fSMilanka Ringwald global bitstream, bitstream_bits_available 491c21a9c2fSMilanka Ringwald for i in range(len): 492c21a9c2fSMilanka Ringwald add_bit((bits >> (len-1-i)) & 1) 493c21a9c2fSMilanka Ringwald 494ad470863SMilanka Ringwaldibuffer = None 495ad470863SMilanka Ringwaldibuffer_count = 0 496ad470863SMilanka Ringwald 497ad470863SMilanka Ringwalddef get_bit(fin): 498ad470863SMilanka Ringwald global ibuffer, ibuffer_count 499ad470863SMilanka Ringwald if ibuffer_count == 0: 500ad470863SMilanka Ringwald ibuffer = ord(fin.read(1)) 501ad470863SMilanka Ringwald ibuffer_count = 8 502ad470863SMilanka Ringwald 503ad470863SMilanka Ringwald bit = (ibuffer >> 7) & 1 504ad470863SMilanka Ringwald ibuffer = ibuffer << 1 505ad470863SMilanka Ringwald ibuffer_count = ibuffer_count - 1 506ad470863SMilanka Ringwald return bit 507ad470863SMilanka Ringwald 508ad470863SMilanka Ringwalddef drop_remaining_bits(): 509ad470863SMilanka Ringwald global ibuffer_count 510ad470863SMilanka Ringwald ibuffer_count = 0 511ad470863SMilanka Ringwald 512ad470863SMilanka Ringwalddef get_bits(fin, bit_count): 513ad470863SMilanka Ringwald bits = 0 514ad470863SMilanka Ringwald for i in range(bit_count): 515ad470863SMilanka Ringwald bits = (bits << 1) | get_bit(fin) 516ad470863SMilanka Ringwald return bits 517ad470863SMilanka Ringwald 518c21a9c2fSMilanka Ringwald 519c21a9c2fSMilanka Ringwalddef calculate_crc(frame): 520c21a9c2fSMilanka Ringwald global bitstream, bitstream_bits_available, bitstream_index 521c21a9c2fSMilanka Ringwald init_bitstream() 522c21a9c2fSMilanka Ringwald 523c21a9c2fSMilanka Ringwald add_bits(frame.sampling_frequency, 2) 524c21a9c2fSMilanka Ringwald add_bits(frame.nr_blocks/4-1, 2) 525c21a9c2fSMilanka Ringwald add_bits(frame.channel_mode, 2) 526c21a9c2fSMilanka Ringwald add_bits(frame.allocation_method, 1) 527c21a9c2fSMilanka Ringwald add_bits(frame.nr_subbands/4-1, 1) 528c21a9c2fSMilanka Ringwald add_bits(frame.bitpool, 8) 529c21a9c2fSMilanka Ringwald 530c21a9c2fSMilanka Ringwald if frame.channel_mode == JOINT_STEREO: 531c21a9c2fSMilanka Ringwald for sb in range(frame.nr_subbands): 532c21a9c2fSMilanka Ringwald add_bits(frame.join[sb],1) 533c21a9c2fSMilanka Ringwald 534c21a9c2fSMilanka Ringwald for ch in range(frame.nr_channels): 535c21a9c2fSMilanka Ringwald for sb in range(frame.nr_subbands): 536c21a9c2fSMilanka Ringwald add_bits(frame.scale_factor[ch][sb], 4) 53741a4a18dSMilanka Ringwald 538c21a9c2fSMilanka Ringwald bitstream_len = (bitstream_index + 1) * 8 539c21a9c2fSMilanka Ringwald if bitstream_bits_available: 540c21a9c2fSMilanka Ringwald bitstream_len += (8-bitstream_bits_available) 541c21a9c2fSMilanka Ringwald return sbc_crc8(bitstream, bitstream_len) 542c21a9c2fSMilanka Ringwald 543c21a9c2fSMilanka Ringwald 544c21a9c2fSMilanka Ringwald 545ad470863SMilanka Ringwalddef frame_to_bitstream(frame): 546ad470863SMilanka Ringwald global bitstream, bitstream_bits_available, bitstream_index 547ad470863SMilanka Ringwald init_bitstream() 548c21a9c2fSMilanka Ringwald 549ad470863SMilanka Ringwald add_bits(frame.syncword, 8) 550ad470863SMilanka Ringwald add_bits(frame.sampling_frequency, 2) 551ad470863SMilanka Ringwald add_bits(frame.nr_blocks/4-1, 2) 552ad470863SMilanka Ringwald add_bits(frame.channel_mode, 2) 553ad470863SMilanka Ringwald add_bits(frame.allocation_method, 1) 554ad470863SMilanka Ringwald add_bits(frame.nr_subbands/4-1, 1) 555ad470863SMilanka Ringwald add_bits(frame.bitpool, 8) 556ad470863SMilanka Ringwald add_bits(frame.crc_check, 8) 557c21a9c2fSMilanka Ringwald 558ad470863SMilanka Ringwald if frame.channel_mode == JOINT_STEREO: 559ad470863SMilanka Ringwald for sb in range(frame.nr_subbands-1): 560ad470863SMilanka Ringwald add_bits(frame.join[sb],1) 561ad470863SMilanka Ringwald add_bits(0,1) 562ad470863SMilanka Ringwald 563ad470863SMilanka Ringwald for ch in range(frame.nr_channels): 564ad470863SMilanka Ringwald for sb in range(frame.nr_subbands): 565ad470863SMilanka Ringwald add_bits(frame.scale_factor[ch][sb], 4) 566ad470863SMilanka Ringwald 567ad470863SMilanka Ringwald for blk in range(frame.nr_blocks): 568ad470863SMilanka Ringwald for ch in range(frame.nr_channels): 569ad470863SMilanka Ringwald for sb in range(frame.nr_subbands): 570ad470863SMilanka Ringwald add_bits(frame.audio_sample[blk][ch][sb], frame.bits[ch][sb]) 571ad470863SMilanka Ringwald 572ad470863SMilanka Ringwald bitstream_bits_available = 0 573ad470863SMilanka Ringwald return bitstream 574ad470863SMilanka Ringwald 575ad470863SMilanka Ringwalddef mse(a,b): 576ad470863SMilanka Ringwald count = 1 577ad470863SMilanka Ringwald for i in a.shape: 578ad470863SMilanka Ringwald count *= i 579ad470863SMilanka Ringwald delta = a - b 580ad470863SMilanka Ringwald sqr = delta ** 2 581ad470863SMilanka Ringwald res = sqr.sum()*1.0/count 582ad470863SMilanka Ringwald # res = ((a - b) ** 2).mean() 583ad470863SMilanka Ringwald return res 584