xref: /btstack/test/sbc/sbc.py (revision ad4708631f2e55d80402f366e09c0f0768618f79)
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