xref: /btstack/test/sbc/sbc.py (revision 5c9bef5ba273d4d18de0f76f9370002de99dfae4)
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
1271522543dSMilanka Ringwalddef calculate_scalefactor(max_subbandsample):
1281522543dSMilanka Ringwald    x = 0
1291522543dSMilanka Ringwald    while True:
1301522543dSMilanka Ringwald        y = 1 << x + 1
1311522543dSMilanka Ringwald        if y > max_subbandsample:
1321522543dSMilanka Ringwald            break
1331522543dSMilanka Ringwald        x += 1
1341522543dSMilanka Ringwald    return (x,y)
1351522543dSMilanka Ringwald
1361522543dSMilanka Ringwald
1371522543dSMilanka Ringwalddef calculate_max_subbandsample(nr_blocks, nr_channels, nr_subbands, sb_sample):
1381522543dSMilanka Ringwald    max_subbandsample = np.zeros(shape = (nr_channels, nr_subbands))
1391522543dSMilanka Ringwald
1401522543dSMilanka Ringwald    for blk in range(nr_blocks):
1411522543dSMilanka Ringwald        for ch in range(nr_channels):
1421522543dSMilanka Ringwald            for sb in range(nr_subbands):
1431522543dSMilanka Ringwald                m = abs(sb_sample[blk][ch][sb])
1441522543dSMilanka Ringwald                if max_subbandsample[ch][sb] < m:
1451522543dSMilanka Ringwald                    max_subbandsample[ch][sb] = m
1461522543dSMilanka Ringwald    return max_subbandsample
1471522543dSMilanka Ringwald
1481522543dSMilanka Ringwalddef calculate_scalefactors(nr_blocks, nr_channels, nr_subbands, sb_sample):
1491522543dSMilanka Ringwald    scale_factor =  np.zeros(shape=(nr_channels, nr_subbands), dtype = np.int32)
1501522543dSMilanka Ringwald    scalefactor =  np.zeros(shape=(nr_channels, nr_subbands), dtype = np.int32)
1511522543dSMilanka Ringwald
152*5c9bef5bSMilanka Ringwald    max_subbandsample = calculate_max_subbandsample(nr_blocks, nr_channels, nr_subbands, sb_sample)
1531522543dSMilanka Ringwald    for ch in range(nr_channels):
1541522543dSMilanka Ringwald        for sb in range(nr_subbands):
155*5c9bef5bSMilanka Ringwald            (scale_factor[ch][sb], scalefactor[ch][sb]) = calculate_scalefactor(max_subbandsample[ch][sb])
1561522543dSMilanka Ringwald    return scale_factor, scalefactor
1571522543dSMilanka Ringwald
158*5c9bef5bSMilanka Ringwalddef calculate_channel_mode(frame):
1591522543dSMilanka Ringwald    if frame.nr_channels == 1:
1601522543dSMilanka Ringwald        frame.channel_mode = MONO
1611522543dSMilanka Ringwald    else:
162*5c9bef5bSMilanka Ringwald        frame.channel_mode = STEREO
163*5c9bef5bSMilanka Ringwald        frame.join = np.zeros(frame.nr_subbands, dtype = np.uint8)
164*5c9bef5bSMilanka Ringwald        return
1651522543dSMilanka Ringwald        sb_sample1 = np.zeros(shape = (frame.nr_blocks,2,frame.nr_subbands), dtype = np.uint16)
1661522543dSMilanka Ringwald
1671522543dSMilanka Ringwald        for blk in range(frame.nr_blocks):
1681522543dSMilanka Ringwald            for sb in range(frame.nr_subbands):
169*5c9bef5bSMilanka Ringwald                sb_sample1[blk][0][sb] = (frame.sb_sample[blk][0][sb] + frame.sb_sample[blk][1][sb])/2
170*5c9bef5bSMilanka Ringwald                sb_sample1[blk][1][sb] = (frame.sb_sample[blk][0][sb] - frame.sb_sample[blk][1][sb])/2
1711522543dSMilanka Ringwald
1721522543dSMilanka Ringwald        scale_factor, scalefactor = calculate_scalefactors(frame.nr_blocks, frame.nr_channels, frame.nr_subbands, sb_sample1)
1731522543dSMilanka Ringwald
174*5c9bef5bSMilanka Ringwald
175*5c9bef5bSMilanka Ringwald        for sb in range(frame.nr_subbands):
176*5c9bef5bSMilanka Ringwald            suma = frame.scale_factor[0][sb] + frame.scale_factor[1][sb]
177*5c9bef5bSMilanka Ringwald            sumb = scale_factor[0][sb] + scale_factor[1][sb]
178*5c9bef5bSMilanka Ringwald
1791522543dSMilanka Ringwald            if suma > sumb:
1801522543dSMilanka Ringwald                frame.channel_mode = JOINT_STEREO
181*5c9bef5bSMilanka Ringwald                frame.join[sb] = 1
182*5c9bef5bSMilanka Ringwald
183*5c9bef5bSMilanka Ringwald                frame.scale_factor[0][sb] = scale_factor[0][sb]
184*5c9bef5bSMilanka Ringwald                frame.scale_factor[1][sb] = scale_factor[1][sb]
185*5c9bef5bSMilanka Ringwald                frame.scalefactor[0][sb]  = scalefactor[0][sb]
186*5c9bef5bSMilanka Ringwald                frame.scalefactor[1][sb]  = scalefactor[1][sb]
187*5c9bef5bSMilanka Ringwald
188*5c9bef5bSMilanka Ringwald                for blk in range(frame.nr_blocks):
189*5c9bef5bSMilanka Ringwald                    frame.sb_sample[blk][0][sb] = sb_sample1[blk][0][sb]
190*5c9bef5bSMilanka Ringwald                    frame.sb_sample[blk][1][sb] = sb_sample1[blk][1][sb]
191*5c9bef5bSMilanka Ringwald
192*5c9bef5bSMilanka Ringwald                print " channel_mode = JOINT_STEREO"
1931522543dSMilanka Ringwald
1941522543dSMilanka Ringwald
195c21a9c2fSMilanka Ringwaldclass SBCFrame:
196c21a9c2fSMilanka Ringwald    syncword = 0
197c21a9c2fSMilanka Ringwald    sampling_frequency = 0
198c21a9c2fSMilanka Ringwald    nr_blocks = 0
199c21a9c2fSMilanka Ringwald    channel_mode = 0
200c21a9c2fSMilanka Ringwald    nr_channels = 0
201c21a9c2fSMilanka Ringwald    allocation_method = 0
202c21a9c2fSMilanka Ringwald    nr_subbands = 0
203c21a9c2fSMilanka Ringwald    bitpool = 0
204c21a9c2fSMilanka Ringwald    crc_check = 0
205c21a9c2fSMilanka Ringwald    # pro subband - 1
206c21a9c2fSMilanka Ringwald    join = np.zeros(8, dtype = np.uint8)
207c21a9c2fSMilanka Ringwald    scale_factor =  np.zeros(shape=(2, 8), dtype = np.int32)
208c21a9c2fSMilanka Ringwald    scalefactor =  np.zeros(shape=(2, 8), dtype = np.int32)
209c21a9c2fSMilanka Ringwald    audio_sample = np.zeros(shape = (16,2,8), dtype = np.uint16)
210c21a9c2fSMilanka Ringwald    sb_sample = np.zeros(shape = (16,2,8), dtype = np.uint16)
211c21a9c2fSMilanka Ringwald    X = np.zeros(8, dtype = np.int16)
212c21a9c2fSMilanka Ringwald    EX = np.zeros(8)
2131522543dSMilanka Ringwald    pcm = np.zeros(shape=(2, 8*16), dtype = np.int16)
214c21a9c2fSMilanka Ringwald    bits    = np.zeros(shape=(2, 8))
215c21a9c2fSMilanka Ringwald    levels = np.zeros(shape=(2, 8), dtype = np.int32)
216c21a9c2fSMilanka Ringwald
217ad470863SMilanka Ringwald
2185665ea35SMilanka Ringwald    def __init__(self, nr_blocks=16, nr_subbands=4, nr_channels=1, bitpool=31, sampling_frequency=44100, allocation_method = 0):
219c21a9c2fSMilanka Ringwald        self.nr_blocks = nr_blocks
220c21a9c2fSMilanka Ringwald        self.nr_subbands = nr_subbands
221c21a9c2fSMilanka Ringwald        self.nr_channels = nr_channels
222ad470863SMilanka Ringwald        self.sampling_frequency = sampling_frequency_index(sampling_frequency)
223c21a9c2fSMilanka Ringwald        self.bitpool = bitpool
2245665ea35SMilanka Ringwald        self.allocation_method = allocation_method
225*5c9bef5bSMilanka Ringwald        self.init(nr_blocks, nr_subbands, nr_channels)
226*5c9bef5bSMilanka Ringwald        return
227*5c9bef5bSMilanka Ringwald
228*5c9bef5bSMilanka Ringwald    def init(self, nr_blocks, nr_subbands, nr_channels):
229c21a9c2fSMilanka Ringwald        self.scale_factor = np.zeros(shape=(nr_channels, nr_subbands), dtype = np.int32)
230c21a9c2fSMilanka Ringwald        self.scalefactor = np.zeros(shape=(nr_channels, nr_subbands), dtype = np.int32)
231c21a9c2fSMilanka Ringwald        self.audio_sample = np.zeros(shape=(nr_blocks, nr_channels, nr_subbands), dtype = np.uint16)
232c21a9c2fSMilanka Ringwald        self.sb_sample = np.zeros(shape=(nr_blocks, nr_channels, nr_subbands), dtype = np.uint16)
233c21a9c2fSMilanka Ringwald        self.levels = np.zeros(shape=(nr_channels, nr_subbands), dtype = np.int32)
234*5c9bef5bSMilanka Ringwald        self.pcm = np.zeros(shape=(nr_channels, nr_subbands*nr_blocks), dtype = np.int16)
235*5c9bef5bSMilanka Ringwald        self.join = np.zeros(nr_subbands, dtype = np.uint8)
236*5c9bef5bSMilanka Ringwald        self.X = np.zeros(nr_subbands, dtype = np.int16)
237c21a9c2fSMilanka Ringwald        self.EX = np.zeros(nr_subbands)
238c21a9c2fSMilanka Ringwald
239ad470863SMilanka Ringwald    def dump_audio_samples(self, blk, ch):
240ad470863SMilanka Ringwald        print self.audio_sample[blk][ch]
241ad470863SMilanka Ringwald
242ad470863SMilanka Ringwald    def dump_subband_samples(self, blk, ch):
243ad470863SMilanka Ringwald        print self.sb_sample[blk][ch]
244ad470863SMilanka Ringwald
245ad470863SMilanka Ringwald    def dump_state(self):
246ad470863SMilanka Ringwald        res =  "SBCFrameHeader state:"
247ad470863SMilanka Ringwald        res += "\n - nr channels %d" % self.nr_channels
248ad470863SMilanka Ringwald        res += "\n - nr blocks %d" % self.nr_blocks
249ad470863SMilanka Ringwald        res += "\n - nr subbands %d" % self.nr_subbands
250ad470863SMilanka Ringwald        res += "\n - scale factors: %s" % self.scale_factor
251ad470863SMilanka Ringwald        res += "\n - levels: %s" % self.levels
252ad470863SMilanka Ringwald        res += "\n - join: %s" % self.join
253ad470863SMilanka Ringwald        res += "\n - bits: %s" % self.bits
254ad470863SMilanka Ringwald        print res
255ad470863SMilanka Ringwald
256c21a9c2fSMilanka Ringwald    def __str__(self):
257c21a9c2fSMilanka Ringwald        res =  "SBCFrameHeader:"
258ad470863SMilanka Ringwald        res += "\n - syncword %d" % self.syncword
259ad470863SMilanka Ringwald        res += "\n - sampling frequency %d Hz" % sampling_frequency_to_str(self.sampling_frequency)
260c21a9c2fSMilanka Ringwald
261ad470863SMilanka Ringwald        res += "\n - nr channels %d" % self.nr_channels
262ad470863SMilanka Ringwald        res += "\n - nr blocks %d" % self.nr_blocks
263ad470863SMilanka Ringwald        res += "\n - nr subbands %d" % self.nr_subbands
264c21a9c2fSMilanka Ringwald
265ad470863SMilanka Ringwald        res += "\n - channel mode %s" % channel_mode_to_str(self.channel_mode)
266ad470863SMilanka Ringwald        res += "\n - allocation method %s" % allocation_method_to_str(self.allocation_method)
267c21a9c2fSMilanka Ringwald
268ad470863SMilanka Ringwald        res += "\n - bitpool %d" % self.bitpool
269ad470863SMilanka Ringwald        res += "\n - crc check %d" % self.crc_check
270c21a9c2fSMilanka Ringwald        return res
271c21a9c2fSMilanka Ringwald
272c21a9c2fSMilanka Ringwald
2731522543dSMilanka Ringwalddef sbc_bit_allocation_stereo_joint(frame):
2741522543dSMilanka Ringwald    bitneed = np.zeros(shape=(frame.nr_channels, frame.nr_subbands), dtype = np.int32)
2751522543dSMilanka Ringwald    bits    = np.zeros(shape=(frame.nr_channels, frame.nr_subbands), dtype = np.int32)
2761522543dSMilanka Ringwald
277c21a9c2fSMilanka Ringwald    loudness = 0
278c21a9c2fSMilanka Ringwald
279c21a9c2fSMilanka Ringwald    if frame.allocation_method == SNR:
280c21a9c2fSMilanka Ringwald        for ch in range(frame.nr_channels):
281c21a9c2fSMilanka Ringwald            for sb in range(frame.nr_subbands):
282c21a9c2fSMilanka Ringwald                bitneed[ch][sb] = frame.scale_factor[ch][sb]
283c21a9c2fSMilanka Ringwald    else:
284c21a9c2fSMilanka Ringwald        for ch in range(frame.nr_channels):
285c21a9c2fSMilanka Ringwald            for sb in range(frame.nr_subbands):
286c21a9c2fSMilanka Ringwald                if frame.scale_factor[ch][sb] == 0:
287c21a9c2fSMilanka Ringwald                    bitneed[ch][sb] = -5
288c21a9c2fSMilanka Ringwald                else:
289c21a9c2fSMilanka Ringwald                    if frame.nr_subbands == 4:
290c21a9c2fSMilanka Ringwald                        loudness = scale_factor[ch][sb] - offset4[frame.sampling_frequency][sb]
291c21a9c2fSMilanka Ringwald                    else:
292c21a9c2fSMilanka Ringwald                        loudness = frame.scale_factor[ch][sb] - offset8[frame.sampling_frequency][sb]
2931522543dSMilanka Ringwald
294c21a9c2fSMilanka Ringwald                    if loudness > 0:
295c21a9c2fSMilanka Ringwald                        bitneed[ch][sb] = loudness/2
296c21a9c2fSMilanka Ringwald                    else:
297c21a9c2fSMilanka Ringwald                        bitneed[ch][sb] = loudness
298c21a9c2fSMilanka Ringwald
299c21a9c2fSMilanka Ringwald    # search the maximum bitneed index
300c21a9c2fSMilanka Ringwald    max_bitneed = 0
301c21a9c2fSMilanka Ringwald    for ch in range(frame.nr_channels):
302c21a9c2fSMilanka Ringwald        for sb in range(frame.nr_subbands):
303c21a9c2fSMilanka Ringwald            if bitneed[ch][sb] > max_bitneed:
304c21a9c2fSMilanka Ringwald                max_bitneed = bitneed[ch][sb]
305c21a9c2fSMilanka Ringwald
306c21a9c2fSMilanka Ringwald    # calculate how many bitslices fit into the bitpool
307c21a9c2fSMilanka Ringwald    bitcount = 0
308c21a9c2fSMilanka Ringwald    slicecount = 0
309c21a9c2fSMilanka Ringwald    bitslice = max_bitneed + 1 #/* init just above the largest sf */
310c21a9c2fSMilanka Ringwald
311c21a9c2fSMilanka Ringwald    while True:
3121522543dSMilanka Ringwald        bitslice -= 1
3131522543dSMilanka Ringwald        bitcount += slicecount
314c21a9c2fSMilanka Ringwald        slicecount = 0
315c21a9c2fSMilanka Ringwald        for ch in range(frame.nr_channels):
316c21a9c2fSMilanka Ringwald            for sb in range(frame.nr_subbands):
317c21a9c2fSMilanka Ringwald                if (bitneed[ch][sb] > bitslice+1) and (bitneed[ch][sb] < bitslice+16):
3181522543dSMilanka Ringwald                    slicecount += 1
319c21a9c2fSMilanka Ringwald                elif bitneed[ch][sb] == bitslice + 1:
3201522543dSMilanka Ringwald                    slicecount += 2
321c21a9c2fSMilanka Ringwald        if bitcount + slicecount >= frame.bitpool:
322c21a9c2fSMilanka Ringwald            break
323c21a9c2fSMilanka Ringwald
324c21a9c2fSMilanka Ringwald    if bitcount + slicecount == frame.bitpool:
3251522543dSMilanka Ringwald        bitcount += slicecount
3261522543dSMilanka Ringwald        bitslice -= 1
327c21a9c2fSMilanka Ringwald
328c21a9c2fSMilanka Ringwald    # bits are distributed until the last bitslice is reached
329c21a9c2fSMilanka Ringwald    for ch in range(frame.nr_channels):
330c21a9c2fSMilanka Ringwald        for sb in range(frame.nr_subbands):
331c21a9c2fSMilanka Ringwald            if bitneed[ch][sb] < bitslice+2 :
332c21a9c2fSMilanka Ringwald               bits[ch][sb]=0;
333c21a9c2fSMilanka Ringwald            else:
334c21a9c2fSMilanka Ringwald                bits[ch][sb] = min(bitneed[ch][sb]-bitslice,16)
335c21a9c2fSMilanka Ringwald
336c21a9c2fSMilanka Ringwald    ch = 0
337c21a9c2fSMilanka Ringwald    sb = 0
338c21a9c2fSMilanka Ringwald    while bitcount < frame.bitpool and sb < frame.nr_subbands:
339c21a9c2fSMilanka Ringwald        if bits[ch][sb] >= 2 and bits[ch][sb] < 16:
3401522543dSMilanka Ringwald            bits[ch][sb] += 1
3411522543dSMilanka Ringwald            bitcount += 1
342c21a9c2fSMilanka Ringwald        elif (bitneed[ch][sb] == bitslice+1) and (frame.bitpool > bitcount+1):
343c21a9c2fSMilanka Ringwald            bits[ch][sb] = 2
344c21a9c2fSMilanka Ringwald            bitcount += 2
345c21a9c2fSMilanka Ringwald        if ch == 1:
346c21a9c2fSMilanka Ringwald            ch = 0
3471522543dSMilanka Ringwald            sb += 1
348c21a9c2fSMilanka Ringwald        else:
349c21a9c2fSMilanka Ringwald            ch = 1
350c21a9c2fSMilanka Ringwald
351f08a674bSMilanka Ringwald
352f08a674bSMilanka Ringwald    ch = 0
353f08a674bSMilanka Ringwald    sb = 0
354f08a674bSMilanka Ringwald    while bitcount < frame.bitpool and sb < frame.nr_subbands:
355f08a674bSMilanka Ringwald        if bits[ch][sb] < 16:
356f08a674bSMilanka Ringwald            bits[ch][sb]+=1
357f08a674bSMilanka Ringwald            bitcount+=1
358f08a674bSMilanka Ringwald        if ch == 1:
359f08a674bSMilanka Ringwald            ch = 0
360f08a674bSMilanka Ringwald            sb += 1
361f08a674bSMilanka Ringwald        else:
362f08a674bSMilanka Ringwald            ch = 1
363f08a674bSMilanka Ringwald
364f08a674bSMilanka Ringwald    if bits.sum() != frame.bitpool:
365f08a674bSMilanka Ringwald        print "bit allocation failed, bitpool %d, allocated %d" % (bits.sum() , frame.bitpool)
366f08a674bSMilanka Ringwald        exit(1)
367c21a9c2fSMilanka Ringwald    return bits
368c21a9c2fSMilanka Ringwald
369c21a9c2fSMilanka Ringwald
370c21a9c2fSMilanka Ringwalddef sbc_bit_allocation_mono_dual(frame):
371c21a9c2fSMilanka Ringwald    #print "Bit allocation for mono/dual channel"
372c21a9c2fSMilanka Ringwald    bitneed = np.zeros(shape=(frame.nr_channels, frame.nr_subbands), dtype = np.int32)
373c21a9c2fSMilanka Ringwald    bits    = np.zeros(shape=(frame.nr_channels, frame.nr_subbands), dtype = np.int32)
374c21a9c2fSMilanka Ringwald    loudness = 0
375c21a9c2fSMilanka Ringwald
376c21a9c2fSMilanka Ringwald    for ch in range(frame.nr_channels):
377c21a9c2fSMilanka Ringwald        # bitneed values are derived from the scale factors
378c21a9c2fSMilanka Ringwald        if frame.allocation_method == SNR:
379c21a9c2fSMilanka Ringwald            for sb in range(frame.nr_subbands):
380c21a9c2fSMilanka Ringwald                bitneed[ch][sb] = frame.scale_factor[ch][sb]
381c21a9c2fSMilanka Ringwald        else:
382c21a9c2fSMilanka Ringwald            for sb in range(frame.nr_subbands):
383c21a9c2fSMilanka Ringwald                if frame.scale_factor[ch][sb] == 0:
384c21a9c2fSMilanka Ringwald                    bitneed[ch][sb] = -5
385c21a9c2fSMilanka Ringwald                else:
386c21a9c2fSMilanka Ringwald                    if frame.nr_subbands == 4:
387c21a9c2fSMilanka Ringwald                        loudness = frame.scale_factor[ch][sb] - offset4[frame.sampling_frequency][sb]
388c21a9c2fSMilanka Ringwald                    else:
389c21a9c2fSMilanka Ringwald                        loudness = frame.scale_factor[ch][sb] - offset8[frame.sampling_frequency][sb]
390c21a9c2fSMilanka Ringwald                    if loudness > 0:
391c21a9c2fSMilanka Ringwald                        bitneed[ch][sb] = loudness/2
392c21a9c2fSMilanka Ringwald                    else:
393c21a9c2fSMilanka Ringwald                        bitneed[ch][sb] = loudness
394c21a9c2fSMilanka Ringwald
395c21a9c2fSMilanka Ringwald        # search the maximum bitneed index
396c21a9c2fSMilanka Ringwald        max_bitneed = 0
397c21a9c2fSMilanka Ringwald        for sb in range(frame.nr_subbands):
398c21a9c2fSMilanka Ringwald            if bitneed[ch][sb] > max_bitneed:
399c21a9c2fSMilanka Ringwald                max_bitneed = bitneed[ch][sb]
400c21a9c2fSMilanka Ringwald
401c21a9c2fSMilanka Ringwald        # calculate how many bitslices fit into the bitpool
402c21a9c2fSMilanka Ringwald        bitcount = 0
403c21a9c2fSMilanka Ringwald        slicecount = 0
40441a4a18dSMilanka Ringwald        bitslice = max_bitneed + 1
405c21a9c2fSMilanka Ringwald
406c21a9c2fSMilanka Ringwald        while True:
407c21a9c2fSMilanka Ringwald            bitslice = bitslice - 1
408c21a9c2fSMilanka Ringwald            bitcount = bitcount + slicecount
409c21a9c2fSMilanka Ringwald            slicecount = 0
410c21a9c2fSMilanka Ringwald            for sb in range(frame.nr_subbands):
411c21a9c2fSMilanka Ringwald                if (bitneed[ch][sb] > bitslice+1) and (bitneed[ch][sb] < bitslice+16):
412c21a9c2fSMilanka Ringwald                    slicecount = slicecount + 1
413c21a9c2fSMilanka Ringwald                elif bitneed[ch][sb] == bitslice + 1:
414c21a9c2fSMilanka Ringwald                    slicecount = slicecount + 2
415c21a9c2fSMilanka Ringwald            if bitcount + slicecount >= frame.bitpool:
416c21a9c2fSMilanka Ringwald                break
417c21a9c2fSMilanka Ringwald
418c21a9c2fSMilanka Ringwald        if bitcount + slicecount == frame.bitpool:
419c21a9c2fSMilanka Ringwald            bitcount = bitcount + slicecount
420c21a9c2fSMilanka Ringwald            bitslice = bitslice - 1
421c21a9c2fSMilanka Ringwald
422c21a9c2fSMilanka Ringwald        for sb in range(frame.nr_subbands):
423c21a9c2fSMilanka Ringwald            if bitneed[ch][sb] < bitslice+2 :
424c21a9c2fSMilanka Ringwald               bits[ch][sb]=0;
425c21a9c2fSMilanka Ringwald            else:
426c21a9c2fSMilanka Ringwald                bits[ch][sb] = min(bitneed[ch][sb]-bitslice,16)
427c21a9c2fSMilanka Ringwald
428c21a9c2fSMilanka Ringwald        sb = 0
429c21a9c2fSMilanka Ringwald        while bitcount < frame.bitpool and sb < frame.nr_subbands:
430c21a9c2fSMilanka Ringwald            if bits[ch][sb] >= 2 and bits[ch][sb] < 16:
431c21a9c2fSMilanka Ringwald                   bits[ch][sb] = bits[ch][sb] + 1
432c21a9c2fSMilanka Ringwald                   bitcount = bitcount + 1
433c21a9c2fSMilanka Ringwald
434c21a9c2fSMilanka Ringwald            elif (bitneed[ch][sb] == bitslice+1) and (frame.bitpool > bitcount+1):
435c21a9c2fSMilanka Ringwald                bits[ch][sb] = 2
436c21a9c2fSMilanka Ringwald                bitcount += 2
437c21a9c2fSMilanka Ringwald
438c21a9c2fSMilanka Ringwald            sb = sb + 1
439c21a9c2fSMilanka Ringwald
440c21a9c2fSMilanka Ringwald
441c21a9c2fSMilanka Ringwald        sb = 0
442c21a9c2fSMilanka Ringwald        while bitcount < frame.bitpool and sb < frame.nr_subbands:
443c21a9c2fSMilanka Ringwald            if bits[ch][sb] < 16:
444c21a9c2fSMilanka Ringwald                bits[ch][sb] = bits[ch][sb] + 1
445c21a9c2fSMilanka Ringwald                bitcount = bitcount + 1
446c21a9c2fSMilanka Ringwald            sb = sb + 1
447c21a9c2fSMilanka Ringwald
448c21a9c2fSMilanka Ringwald    return bits
449c21a9c2fSMilanka Ringwald
450c21a9c2fSMilanka Ringwalddef sbc_bit_allocation(frame):
451c21a9c2fSMilanka Ringwald    if frame.channel_mode == MONO or frame.channel_mode == DUAL_CHANNEL:
452c21a9c2fSMilanka Ringwald        return sbc_bit_allocation_mono_dual(frame)
453c21a9c2fSMilanka Ringwald    elif frame.channel_mode == STEREO or frame.channel_mode == JOINT_STEREO:
454c21a9c2fSMilanka Ringwald        return sbc_bit_allocation_stereo_joint(frame)
455c21a9c2fSMilanka Ringwald    else:
456c21a9c2fSMilanka Ringwald        print "Wrong channel mode ", frame.channel_mode
457c21a9c2fSMilanka Ringwald        return -1
458c21a9c2fSMilanka Ringwald
459c21a9c2fSMilanka Ringwalddef sbc_sampling_frequency_index(sample_rate):
460c21a9c2fSMilanka Ringwald    sbc_sampling_frequency_index = 0
461c21a9c2fSMilanka Ringwald    for i in range(len(sampling_frequency)):
462c21a9c2fSMilanka Ringwald        if sample_rate == sampling_frequency[i]:
463c21a9c2fSMilanka Ringwald            sbc_sampling_frequency_index = i
464c21a9c2fSMilanka Ringwald            break
465c21a9c2fSMilanka Ringwald    return sbc_sampling_frequency_index
466c21a9c2fSMilanka Ringwald
467c21a9c2fSMilanka Ringwald
468c21a9c2fSMilanka Ringwalddef sbc_crc8(data, data_len):
469c21a9c2fSMilanka Ringwald    crc = 0x0f
470c21a9c2fSMilanka Ringwald    j = 0
471c21a9c2fSMilanka Ringwald    for i in range(data_len / 8):
472c21a9c2fSMilanka Ringwald        crc = crc_table[crc ^ data[i]]
473c21a9c2fSMilanka Ringwald        j = i + 1
474c21a9c2fSMilanka Ringwald
475c21a9c2fSMilanka Ringwald    bits_left = data_len%8
476c21a9c2fSMilanka Ringwald    if bits_left:
477c21a9c2fSMilanka Ringwald        octet = data[j]
478c21a9c2fSMilanka Ringwald        for i in range(data_len%8):
479c21a9c2fSMilanka Ringwald            bit = ((octet ^ crc) & 0x80) >> 7
480c21a9c2fSMilanka Ringwald            if bit:
481c21a9c2fSMilanka Ringwald                bit = 0x1d
482c21a9c2fSMilanka Ringwald            crc = ((crc & 0x7f) << 1) ^ bit
483c21a9c2fSMilanka Ringwald            octet = octet << 1
484c21a9c2fSMilanka Ringwald    return crc
485c21a9c2fSMilanka Ringwald
486c21a9c2fSMilanka Ringwald
487ad470863SMilanka Ringwaldbitstream = None
488c21a9c2fSMilanka Ringwaldbitstream_index = -1
489c21a9c2fSMilanka Ringwaldbitstream_bits_available = 0
490c21a9c2fSMilanka Ringwald
491c21a9c2fSMilanka Ringwalddef init_bitstream():
492c21a9c2fSMilanka Ringwald    global bitstream, bitstream_bits_available, bitstream_index
493c21a9c2fSMilanka Ringwald    bitstream = []
494c21a9c2fSMilanka Ringwald    bitstream_index = -1
495c21a9c2fSMilanka Ringwald    bitstream_bits_available = 0
496c21a9c2fSMilanka Ringwald
497c21a9c2fSMilanka Ringwalddef add_bit(bit):
498c21a9c2fSMilanka Ringwald    global bitstream, bitstream_bits_available, bitstream_index
499c21a9c2fSMilanka Ringwald    if bitstream_bits_available == 0:
500c21a9c2fSMilanka Ringwald        bitstream.append(0)
501c21a9c2fSMilanka Ringwald        bitstream_bits_available = 8
502c21a9c2fSMilanka Ringwald        bitstream_index += 1
503c21a9c2fSMilanka Ringwald
504c21a9c2fSMilanka Ringwald    bitstream[bitstream_index] |= bit << (bitstream_bits_available - 1)
505c21a9c2fSMilanka Ringwald    bitstream_bits_available -= 1
506c21a9c2fSMilanka Ringwald
507c21a9c2fSMilanka Ringwald
508c21a9c2fSMilanka Ringwalddef add_bits(bits, len):
509c21a9c2fSMilanka Ringwald    global bitstream, bitstream_bits_available
510c21a9c2fSMilanka Ringwald    for i in range(len):
511c21a9c2fSMilanka Ringwald        add_bit((bits >> (len-1-i)) & 1)
512c21a9c2fSMilanka Ringwald
513ad470863SMilanka Ringwaldibuffer = None
514ad470863SMilanka Ringwaldibuffer_count = 0
515ad470863SMilanka Ringwald
516ad470863SMilanka Ringwalddef get_bit(fin):
517ad470863SMilanka Ringwald    global ibuffer, ibuffer_count
518ad470863SMilanka Ringwald    if ibuffer_count == 0:
519ad470863SMilanka Ringwald        ibuffer = ord(fin.read(1))
520ad470863SMilanka Ringwald        ibuffer_count = 8
521ad470863SMilanka Ringwald
522ad470863SMilanka Ringwald    bit = (ibuffer >> 7) & 1
523ad470863SMilanka Ringwald    ibuffer = ibuffer << 1
524ad470863SMilanka Ringwald    ibuffer_count = ibuffer_count - 1
525ad470863SMilanka Ringwald    return bit
526ad470863SMilanka Ringwald
527ad470863SMilanka Ringwalddef drop_remaining_bits():
528ad470863SMilanka Ringwald    global ibuffer_count
529f08a674bSMilanka Ringwald    #print "dropping %d bits" % ibuffer_count
530ad470863SMilanka Ringwald    ibuffer_count = 0
531ad470863SMilanka Ringwald
532ad470863SMilanka Ringwalddef get_bits(fin, bit_count):
533ad470863SMilanka Ringwald    bits = 0
534ad470863SMilanka Ringwald    for i in range(bit_count):
535ad470863SMilanka Ringwald        bits = (bits << 1) | get_bit(fin)
536f08a674bSMilanka Ringwald    # print "get bits: %d -> %02x" %(bit_count, bits)
537ad470863SMilanka Ringwald    return bits
538ad470863SMilanka Ringwald
539c21a9c2fSMilanka Ringwald
540c21a9c2fSMilanka Ringwalddef calculate_crc(frame):
541c21a9c2fSMilanka Ringwald    global bitstream, bitstream_bits_available, bitstream_index
542c21a9c2fSMilanka Ringwald    init_bitstream()
543c21a9c2fSMilanka Ringwald
544c21a9c2fSMilanka Ringwald    add_bits(frame.sampling_frequency, 2)
545c21a9c2fSMilanka Ringwald    add_bits(frame.nr_blocks/4-1, 2)
546c21a9c2fSMilanka Ringwald    add_bits(frame.channel_mode, 2)
547c21a9c2fSMilanka Ringwald    add_bits(frame.allocation_method, 1)
548c21a9c2fSMilanka Ringwald    add_bits(frame.nr_subbands/4-1, 1)
549c21a9c2fSMilanka Ringwald    add_bits(frame.bitpool, 8)
550c21a9c2fSMilanka Ringwald
551c21a9c2fSMilanka Ringwald    if frame.channel_mode == JOINT_STEREO:
552*5c9bef5bSMilanka Ringwald        #print ("Joint Stereo!")
553c21a9c2fSMilanka Ringwald        for sb in range(frame.nr_subbands):
554c21a9c2fSMilanka Ringwald            add_bits(frame.join[sb],1)
555c21a9c2fSMilanka Ringwald
556c21a9c2fSMilanka Ringwald    for ch in range(frame.nr_channels):
557c21a9c2fSMilanka Ringwald        for sb in range(frame.nr_subbands):
558c21a9c2fSMilanka Ringwald            add_bits(frame.scale_factor[ch][sb], 4)
55941a4a18dSMilanka Ringwald
560c21a9c2fSMilanka Ringwald    bitstream_len = (bitstream_index + 1) * 8
561c21a9c2fSMilanka Ringwald    if bitstream_bits_available:
562*5c9bef5bSMilanka Ringwald        bitstream_len -= bitstream_bits_available
563*5c9bef5bSMilanka Ringwald
564c21a9c2fSMilanka Ringwald    return sbc_crc8(bitstream, bitstream_len)
565c21a9c2fSMilanka Ringwald
566c21a9c2fSMilanka Ringwald
567c21a9c2fSMilanka Ringwald
568ad470863SMilanka Ringwalddef frame_to_bitstream(frame):
569ad470863SMilanka Ringwald    global bitstream, bitstream_bits_available, bitstream_index
570ad470863SMilanka Ringwald    init_bitstream()
571c21a9c2fSMilanka Ringwald
572ad470863SMilanka Ringwald    add_bits(frame.syncword, 8)
573ad470863SMilanka Ringwald    add_bits(frame.sampling_frequency, 2)
574ad470863SMilanka Ringwald    add_bits(frame.nr_blocks/4-1, 2)
575ad470863SMilanka Ringwald    add_bits(frame.channel_mode, 2)
576ad470863SMilanka Ringwald    add_bits(frame.allocation_method, 1)
577ad470863SMilanka Ringwald    add_bits(frame.nr_subbands/4-1, 1)
578ad470863SMilanka Ringwald    add_bits(frame.bitpool, 8)
579ad470863SMilanka Ringwald    add_bits(frame.crc_check, 8)
580c21a9c2fSMilanka Ringwald
581ad470863SMilanka Ringwald    if frame.channel_mode == JOINT_STEREO:
582ad470863SMilanka Ringwald        for sb in range(frame.nr_subbands-1):
583ad470863SMilanka Ringwald            add_bits(frame.join[sb],1)
584ad470863SMilanka Ringwald        add_bits(0,1)
585ad470863SMilanka Ringwald
586ad470863SMilanka Ringwald    for ch in range(frame.nr_channels):
587ad470863SMilanka Ringwald        for sb in range(frame.nr_subbands):
588ad470863SMilanka Ringwald            add_bits(frame.scale_factor[ch][sb], 4)
589ad470863SMilanka Ringwald
590ad470863SMilanka Ringwald    for blk in range(frame.nr_blocks):
591ad470863SMilanka Ringwald        for ch in range(frame.nr_channels):
592ad470863SMilanka Ringwald            for sb in range(frame.nr_subbands):
593ad470863SMilanka Ringwald                add_bits(frame.audio_sample[blk][ch][sb], frame.bits[ch][sb])
594ad470863SMilanka Ringwald
595ad470863SMilanka Ringwald    bitstream_bits_available = 0
596ad470863SMilanka Ringwald    return bitstream
597ad470863SMilanka Ringwald
598ad470863SMilanka Ringwalddef mse(a,b):
599ad470863SMilanka Ringwald    count = 1
600ad470863SMilanka Ringwald    for i in a.shape:
601ad470863SMilanka Ringwald        count *= i
602ad470863SMilanka Ringwald    delta = a - b
603ad470863SMilanka Ringwald    sqr = delta ** 2
604ad470863SMilanka Ringwald    res = sqr.sum()*1.0/count
605ad470863SMilanka Ringwald    # res = ((a - b) ** 2).mean()
606ad470863SMilanka Ringwald    return res
607