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