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