1*49fe348cSAndroid Build Coastguard Worker# 2*49fe348cSAndroid Build Coastguard Worker# Copyright 2022 Google LLC 3*49fe348cSAndroid Build Coastguard Worker# 4*49fe348cSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 5*49fe348cSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 6*49fe348cSAndroid Build Coastguard Worker# You may obtain a copy of the License at 7*49fe348cSAndroid Build Coastguard Worker# 8*49fe348cSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 9*49fe348cSAndroid Build Coastguard Worker# 10*49fe348cSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 11*49fe348cSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 12*49fe348cSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*49fe348cSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 14*49fe348cSAndroid Build Coastguard Worker# limitations under the License. 15*49fe348cSAndroid Build Coastguard Worker# 16*49fe348cSAndroid Build Coastguard Worker 17*49fe348cSAndroid Build Coastguard Workerimport numpy as np 18*49fe348cSAndroid Build Coastguard Worker 19*49fe348cSAndroid Build Coastguard Workerimport lc3 20*49fe348cSAndroid Build Coastguard Workerimport tables as T, appendix_c as C 21*49fe348cSAndroid Build Coastguard Worker 22*49fe348cSAndroid Build Coastguard Workerimport bwdet as m_bwdet 23*49fe348cSAndroid Build Coastguard Workerimport ltpf as m_ltpf 24*49fe348cSAndroid Build Coastguard Workerimport sns as m_sns 25*49fe348cSAndroid Build Coastguard Workerimport tns as m_tns 26*49fe348cSAndroid Build Coastguard Worker 27*49fe348cSAndroid Build Coastguard Worker### ------------------------------------------------------------------------ ### 28*49fe348cSAndroid Build Coastguard Worker 29*49fe348cSAndroid Build Coastguard Workerclass SpectrumQuantization: 30*49fe348cSAndroid Build Coastguard Worker 31*49fe348cSAndroid Build Coastguard Worker def __init__(self, dt, sr): 32*49fe348cSAndroid Build Coastguard Worker 33*49fe348cSAndroid Build Coastguard Worker self.dt = dt 34*49fe348cSAndroid Build Coastguard Worker self.sr = sr 35*49fe348cSAndroid Build Coastguard Worker 36*49fe348cSAndroid Build Coastguard Worker def get_gain_offset(self, nbytes): 37*49fe348cSAndroid Build Coastguard Worker 38*49fe348cSAndroid Build Coastguard Worker sr_ind = self.sr if self.sr < T.SRATE_48K_HR \ 39*49fe348cSAndroid Build Coastguard Worker else 4 + (self.sr - T.SRATE_48K_HR) 40*49fe348cSAndroid Build Coastguard Worker 41*49fe348cSAndroid Build Coastguard Worker g_off = (nbytes * 8) // (10 * (1 + sr_ind)) 42*49fe348cSAndroid Build Coastguard Worker g_off = -min(115, g_off) - (105 + 5*(1 + sr_ind)) 43*49fe348cSAndroid Build Coastguard Worker if self.sr >= T.SRATE_48K_HR: 44*49fe348cSAndroid Build Coastguard Worker g_off = max(g_off, -181) 45*49fe348cSAndroid Build Coastguard Worker 46*49fe348cSAndroid Build Coastguard Worker return g_off 47*49fe348cSAndroid Build Coastguard Worker 48*49fe348cSAndroid Build Coastguard Worker def get_noise_indices(self, bw, xq, lastnz): 49*49fe348cSAndroid Build Coastguard Worker 50*49fe348cSAndroid Build Coastguard Worker nf_start = [ 6, 12, 18, 24 ][self.dt] 51*49fe348cSAndroid Build Coastguard Worker nf_width = [ 1, 1, 2, 3 ][self.dt] 52*49fe348cSAndroid Build Coastguard Worker 53*49fe348cSAndroid Build Coastguard Worker bw_stop = T.I[self.dt][min(bw, T.SRATE_48K)][-1] 54*49fe348cSAndroid Build Coastguard Worker 55*49fe348cSAndroid Build Coastguard Worker xq = np.append(xq[:lastnz], np.zeros(len(xq) - lastnz)) 56*49fe348cSAndroid Build Coastguard Worker xq[:nf_start-nf_width] = 1 57*49fe348cSAndroid Build Coastguard Worker 58*49fe348cSAndroid Build Coastguard Worker return [ np.all(xq[max(k-nf_width, 0):min(k+nf_width+1, bw_stop)] == 0) 59*49fe348cSAndroid Build Coastguard Worker for k in range(bw_stop) ] 60*49fe348cSAndroid Build Coastguard Worker 61*49fe348cSAndroid Build Coastguard Workerclass SpectrumAnalysis(SpectrumQuantization): 62*49fe348cSAndroid Build Coastguard Worker 63*49fe348cSAndroid Build Coastguard Worker def __init__(self, dt, sr): 64*49fe348cSAndroid Build Coastguard Worker 65*49fe348cSAndroid Build Coastguard Worker super().__init__(dt, sr) 66*49fe348cSAndroid Build Coastguard Worker 67*49fe348cSAndroid Build Coastguard Worker self.reset_off = 0 68*49fe348cSAndroid Build Coastguard Worker self.nbits_off = 0 69*49fe348cSAndroid Build Coastguard Worker self.nbits_spec = 0 70*49fe348cSAndroid Build Coastguard Worker self.nbits_est = 0 71*49fe348cSAndroid Build Coastguard Worker 72*49fe348cSAndroid Build Coastguard Worker (self.g_idx, self.noise_factor, self.xq, self.lastnz, 73*49fe348cSAndroid Build Coastguard Worker self.nbits_residual_max, self.xg) = \ 74*49fe348cSAndroid Build Coastguard Worker (None, None, None, None, None, None) 75*49fe348cSAndroid Build Coastguard Worker 76*49fe348cSAndroid Build Coastguard Worker def estimate_gain(self, x, nbytes, nbits_spec, nbits_off, g_off): 77*49fe348cSAndroid Build Coastguard Worker 78*49fe348cSAndroid Build Coastguard Worker nbits = int(nbits_spec + nbits_off + 0.5) 79*49fe348cSAndroid Build Coastguard Worker 80*49fe348cSAndroid Build Coastguard Worker ### Energy (dB) by 4 MDCT coefficients 81*49fe348cSAndroid Build Coastguard Worker 82*49fe348cSAndroid Build Coastguard Worker hr = (self.sr >= T.SRATE_48K_HR) 83*49fe348cSAndroid Build Coastguard Worker nf = 0 84*49fe348cSAndroid Build Coastguard Worker 85*49fe348cSAndroid Build Coastguard Worker if hr: 86*49fe348cSAndroid Build Coastguard Worker dt = self.dt 87*49fe348cSAndroid Build Coastguard Worker sr = self.sr 88*49fe348cSAndroid Build Coastguard Worker 89*49fe348cSAndroid Build Coastguard Worker dt_ms = T.DT_MS[dt] 90*49fe348cSAndroid Build Coastguard Worker bitrate = (8 * nbytes / (dt_ms * 1e-3)).astype(int) 91*49fe348cSAndroid Build Coastguard Worker 92*49fe348cSAndroid Build Coastguard Worker C = [ [ -6, 0, None, 2 ], [ -6, 0, None, 5 ] ] 93*49fe348cSAndroid Build Coastguard Worker 94*49fe348cSAndroid Build Coastguard Worker reg_bits = np.clip( 95*49fe348cSAndroid Build Coastguard Worker bitrate // 12500 + C[sr - T.SRATE_48K_HR][dt], 6, 23) 96*49fe348cSAndroid Build Coastguard Worker 97*49fe348cSAndroid Build Coastguard Worker M0 = np.sum(np.abs(x)) + 1e-5 98*49fe348cSAndroid Build Coastguard Worker M1 = np.sum(np.arange(len(x)) * np.abs(x)) + 1e-5 99*49fe348cSAndroid Build Coastguard Worker 100*49fe348cSAndroid Build Coastguard Worker low_bits = (4 / dt_ms) * (2*dt_ms - min(M0/M1, 2*dt_ms)) 101*49fe348cSAndroid Build Coastguard Worker 102*49fe348cSAndroid Build Coastguard Worker nf = np.max(np.abs(x)) * np.exp2(-reg_bits - low_bits) 103*49fe348cSAndroid Build Coastguard Worker 104*49fe348cSAndroid Build Coastguard Worker e = [ np.sum(x[4*k:4*(k+1)] ** 2) for k in range(len(x) // 4) ] 105*49fe348cSAndroid Build Coastguard Worker e = 10 * np.log10(2**-31 + np.array(e) + nf) 106*49fe348cSAndroid Build Coastguard Worker 107*49fe348cSAndroid Build Coastguard Worker ### Compute gain index 108*49fe348cSAndroid Build Coastguard Worker 109*49fe348cSAndroid Build Coastguard Worker g_idx = 255 110*49fe348cSAndroid Build Coastguard Worker 111*49fe348cSAndroid Build Coastguard Worker for i in range(8): 112*49fe348cSAndroid Build Coastguard Worker factor = 1 << (7 - i) 113*49fe348cSAndroid Build Coastguard Worker g_idx -= factor 114*49fe348cSAndroid Build Coastguard Worker tmp = 0 115*49fe348cSAndroid Build Coastguard Worker iszero = 1 116*49fe348cSAndroid Build Coastguard Worker 117*49fe348cSAndroid Build Coastguard Worker for ei in e[-1::-1]: 118*49fe348cSAndroid Build Coastguard Worker 119*49fe348cSAndroid Build Coastguard Worker if ei * 28/20 < g_idx + g_off: 120*49fe348cSAndroid Build Coastguard Worker if iszero == 0: 121*49fe348cSAndroid Build Coastguard Worker tmp += 2.7*28/20 122*49fe348cSAndroid Build Coastguard Worker else: 123*49fe348cSAndroid Build Coastguard Worker if g_idx + g_off < (ei - 43) * 28/20: 124*49fe348cSAndroid Build Coastguard Worker tmp += 2*ei*28/20 - 2*(g_idx + g_off) - 36*28/20 125*49fe348cSAndroid Build Coastguard Worker else: 126*49fe348cSAndroid Build Coastguard Worker tmp += ei*28/20 - (g_idx + g_off) + 7*28/20 127*49fe348cSAndroid Build Coastguard Worker iszero = 0 128*49fe348cSAndroid Build Coastguard Worker 129*49fe348cSAndroid Build Coastguard Worker if tmp > nbits * 1.4 * 28/20 and iszero == 0: 130*49fe348cSAndroid Build Coastguard Worker g_idx += factor 131*49fe348cSAndroid Build Coastguard Worker 132*49fe348cSAndroid Build Coastguard Worker ### Limit gain index 133*49fe348cSAndroid Build Coastguard Worker 134*49fe348cSAndroid Build Coastguard Worker x_max = np.amax(np.abs(x)) 135*49fe348cSAndroid Build Coastguard Worker if x_max > 0: 136*49fe348cSAndroid Build Coastguard Worker x_lim = [ 2**15 - 0.375, 2**23 ][hr] 137*49fe348cSAndroid Build Coastguard Worker g_min = 28 * np.log10(x_max / x_lim) 138*49fe348cSAndroid Build Coastguard Worker g_min = np.ceil(g_min).astype(int) - g_off 139*49fe348cSAndroid Build Coastguard Worker reset_off = g_idx < g_min 140*49fe348cSAndroid Build Coastguard Worker else: 141*49fe348cSAndroid Build Coastguard Worker g_min = 0 142*49fe348cSAndroid Build Coastguard Worker reset_off = True 143*49fe348cSAndroid Build Coastguard Worker 144*49fe348cSAndroid Build Coastguard Worker if reset_off: 145*49fe348cSAndroid Build Coastguard Worker g_idx = g_min 146*49fe348cSAndroid Build Coastguard Worker 147*49fe348cSAndroid Build Coastguard Worker return (g_min, g_idx + g_off, reset_off) 148*49fe348cSAndroid Build Coastguard Worker 149*49fe348cSAndroid Build Coastguard Worker def quantize(self, g_int, x): 150*49fe348cSAndroid Build Coastguard Worker 151*49fe348cSAndroid Build Coastguard Worker xg = x / 10 ** (g_int / 28) 152*49fe348cSAndroid Build Coastguard Worker 153*49fe348cSAndroid Build Coastguard Worker hr = (self.sr >= T.SRATE_48K_HR) 154*49fe348cSAndroid Build Coastguard Worker offset = [ 0.375, 0.5 ][hr] 155*49fe348cSAndroid Build Coastguard Worker xq_min = [ -(2**15) , -(2**23) ][hr] 156*49fe348cSAndroid Build Coastguard Worker xq_max = [ (2**15)-1, (2**23)-1 ][hr] 157*49fe348cSAndroid Build Coastguard Worker 158*49fe348cSAndroid Build Coastguard Worker xq = np.where(xg < 0, np.ceil(xg - offset), np.floor(xg + offset)) 159*49fe348cSAndroid Build Coastguard Worker xq = xq.astype(np.int32) 160*49fe348cSAndroid Build Coastguard Worker xq = np.fmin(np.fmax(xq, xq_min), xq_max) 161*49fe348cSAndroid Build Coastguard Worker 162*49fe348cSAndroid Build Coastguard Worker nz_pairs = np.any([ xq[::2] != 0, xq[1::2] != 0 ], axis=0) 163*49fe348cSAndroid Build Coastguard Worker lastnz = len(xq) - 2 * np.argmax(nz_pairs[-1::-1]) 164*49fe348cSAndroid Build Coastguard Worker if not np.any(nz_pairs): 165*49fe348cSAndroid Build Coastguard Worker lastnz = 0 166*49fe348cSAndroid Build Coastguard Worker 167*49fe348cSAndroid Build Coastguard Worker return (xg, xq, lastnz) 168*49fe348cSAndroid Build Coastguard Worker 169*49fe348cSAndroid Build Coastguard Worker def compute_nbits(self, nbytes, x, lastnz, nbits_spec): 170*49fe348cSAndroid Build Coastguard Worker 171*49fe348cSAndroid Build Coastguard Worker mode = [ 0, 1 ][int(self.sr < T.SRATE_96K_HR and \ 172*49fe348cSAndroid Build Coastguard Worker nbytes >= 20 * (3 + min(self.sr, T.SRATE_48K)))] 173*49fe348cSAndroid Build Coastguard Worker rate = [ 0, 512 ][int(self.sr < T.SRATE_96K_HR and \ 174*49fe348cSAndroid Build Coastguard Worker nbytes > 20 * (1 + min(self.sr, T.SRATE_48K)))] 175*49fe348cSAndroid Build Coastguard Worker 176*49fe348cSAndroid Build Coastguard Worker nbits_est = 0 177*49fe348cSAndroid Build Coastguard Worker nbits_trunc = 0 178*49fe348cSAndroid Build Coastguard Worker nbits_lsb = 0 179*49fe348cSAndroid Build Coastguard Worker lastnz_trunc = 2 180*49fe348cSAndroid Build Coastguard Worker c = 0 181*49fe348cSAndroid Build Coastguard Worker 182*49fe348cSAndroid Build Coastguard Worker for n in range(0, lastnz, 2): 183*49fe348cSAndroid Build Coastguard Worker t = c + rate 184*49fe348cSAndroid Build Coastguard Worker if n > len(x) // 2: 185*49fe348cSAndroid Build Coastguard Worker t += 256 186*49fe348cSAndroid Build Coastguard Worker 187*49fe348cSAndroid Build Coastguard Worker a = abs(x[n ]) 188*49fe348cSAndroid Build Coastguard Worker b = abs(x[n+1]) 189*49fe348cSAndroid Build Coastguard Worker lev = 0 190*49fe348cSAndroid Build Coastguard Worker while max(a, b) >= 4: 191*49fe348cSAndroid Build Coastguard Worker nbits_est += \ 192*49fe348cSAndroid Build Coastguard Worker T.AC_SPEC_BITS[T.AC_SPEC_LOOKUP[t + lev*1024]][16]; 193*49fe348cSAndroid Build Coastguard Worker if lev == 0 and mode == 1: 194*49fe348cSAndroid Build Coastguard Worker nbits_lsb += 2 195*49fe348cSAndroid Build Coastguard Worker else: 196*49fe348cSAndroid Build Coastguard Worker nbits_est += 2 * 2048 197*49fe348cSAndroid Build Coastguard Worker 198*49fe348cSAndroid Build Coastguard Worker a >>= 1 199*49fe348cSAndroid Build Coastguard Worker b >>= 1 200*49fe348cSAndroid Build Coastguard Worker lev = min(lev + 1, 3) 201*49fe348cSAndroid Build Coastguard Worker 202*49fe348cSAndroid Build Coastguard Worker nbits_est += \ 203*49fe348cSAndroid Build Coastguard Worker T.AC_SPEC_BITS[T.AC_SPEC_LOOKUP[t + lev*1024]][a + 4*b] 204*49fe348cSAndroid Build Coastguard Worker 205*49fe348cSAndroid Build Coastguard Worker a_lsb = abs(x[n ]) 206*49fe348cSAndroid Build Coastguard Worker b_lsb = abs(x[n+1]) 207*49fe348cSAndroid Build Coastguard Worker nbits_est += (min(a_lsb, 1) + min(b_lsb, 1)) * 2048 208*49fe348cSAndroid Build Coastguard Worker if lev > 0 and mode == 1: 209*49fe348cSAndroid Build Coastguard Worker a_lsb >>= 1; 210*49fe348cSAndroid Build Coastguard Worker b_lsb >>= 1; 211*49fe348cSAndroid Build Coastguard Worker nbits_lsb += int(a_lsb == 0 and x[n ] != 0) 212*49fe348cSAndroid Build Coastguard Worker nbits_lsb += int(b_lsb == 0 and x[n+1] != 0) 213*49fe348cSAndroid Build Coastguard Worker 214*49fe348cSAndroid Build Coastguard Worker if (x[n] != 0 or x[n+1] != 0) and \ 215*49fe348cSAndroid Build Coastguard Worker (nbits_est <= nbits_spec * 2048): 216*49fe348cSAndroid Build Coastguard Worker lastnz_trunc = n + 2; 217*49fe348cSAndroid Build Coastguard Worker nbits_trunc = nbits_est 218*49fe348cSAndroid Build Coastguard Worker 219*49fe348cSAndroid Build Coastguard Worker t = 1 + (a + b) * (lev + 1) if lev <= 1 else 12 + lev; 220*49fe348cSAndroid Build Coastguard Worker c = (c & 15) * 16 + t; 221*49fe348cSAndroid Build Coastguard Worker 222*49fe348cSAndroid Build Coastguard Worker nbits_est = (nbits_est + 2047) // 2048 + nbits_lsb; 223*49fe348cSAndroid Build Coastguard Worker nbits_trunc = (nbits_trunc + 2047) // 2048 224*49fe348cSAndroid Build Coastguard Worker 225*49fe348cSAndroid Build Coastguard Worker self.rate = rate 226*49fe348cSAndroid Build Coastguard Worker self.lsb_mode = mode == 1 and nbits_est > nbits_spec 227*49fe348cSAndroid Build Coastguard Worker 228*49fe348cSAndroid Build Coastguard Worker return (nbits_est, nbits_trunc, lastnz_trunc, self.lsb_mode) 229*49fe348cSAndroid Build Coastguard Worker 230*49fe348cSAndroid Build Coastguard Worker def adjust_gain(self, g_idx, nbits, nbits_spec): 231*49fe348cSAndroid Build Coastguard Worker 232*49fe348cSAndroid Build Coastguard Worker T1 = [ 80, 230, 380, 530, 680, 680, 830 ] 233*49fe348cSAndroid Build Coastguard Worker T2 = [ 500, 1025, 1550, 2075, 2600, 2600, 3125 ] 234*49fe348cSAndroid Build Coastguard Worker T3 = [ 850, 1700, 2550, 3400, 4250, 4250, 5100 ] 235*49fe348cSAndroid Build Coastguard Worker 236*49fe348cSAndroid Build Coastguard Worker dt = self.dt 237*49fe348cSAndroid Build Coastguard Worker sr = self.sr 238*49fe348cSAndroid Build Coastguard Worker 239*49fe348cSAndroid Build Coastguard Worker if nbits < T1[sr]: 240*49fe348cSAndroid Build Coastguard Worker delta = (nbits + 48) / 16 241*49fe348cSAndroid Build Coastguard Worker 242*49fe348cSAndroid Build Coastguard Worker elif nbits < T2[sr]: 243*49fe348cSAndroid Build Coastguard Worker a = T1[sr] / 16 + 3 244*49fe348cSAndroid Build Coastguard Worker b = T2[sr] / 48 245*49fe348cSAndroid Build Coastguard Worker delta = a + (nbits - T1[sr]) * (b - a) / (T2[sr] - T1[sr]) 246*49fe348cSAndroid Build Coastguard Worker 247*49fe348cSAndroid Build Coastguard Worker elif nbits < T3[sr]: 248*49fe348cSAndroid Build Coastguard Worker delta = nbits / 48 249*49fe348cSAndroid Build Coastguard Worker 250*49fe348cSAndroid Build Coastguard Worker else: 251*49fe348cSAndroid Build Coastguard Worker delta = T3[sr] / 48; 252*49fe348cSAndroid Build Coastguard Worker 253*49fe348cSAndroid Build Coastguard Worker delta = np.fix(delta + 0.5).astype(int) 254*49fe348cSAndroid Build Coastguard Worker 255*49fe348cSAndroid Build Coastguard Worker if self.sr >= T.SRATE_48K_HR and \ 256*49fe348cSAndroid Build Coastguard Worker (g_idx < 255 and nbits > nbits_spec): 257*49fe348cSAndroid Build Coastguard Worker 258*49fe348cSAndroid Build Coastguard Worker factor = [ 3 + (nbits >= 520), 2, 0, 1 ][dt] 259*49fe348cSAndroid Build Coastguard Worker g_incr = int(factor * (1 + (nbits - nbits_spec) / delta)) 260*49fe348cSAndroid Build Coastguard Worker return min(g_idx + g_incr, 255) - g_idx; 261*49fe348cSAndroid Build Coastguard Worker 262*49fe348cSAndroid Build Coastguard Worker elif self.sr < T.SRATE_48K_HR and \ 263*49fe348cSAndroid Build Coastguard Worker ( (g_idx < 255 and nbits > nbits_spec) or \ 264*49fe348cSAndroid Build Coastguard Worker (g_idx > 0 and nbits < nbits_spec - (delta + 2)) ): 265*49fe348cSAndroid Build Coastguard Worker 266*49fe348cSAndroid Build Coastguard Worker if nbits < nbits_spec - (delta + 2): 267*49fe348cSAndroid Build Coastguard Worker return -1 268*49fe348cSAndroid Build Coastguard Worker 269*49fe348cSAndroid Build Coastguard Worker if g_idx == 254 or nbits < nbits_spec + delta: 270*49fe348cSAndroid Build Coastguard Worker return 1 271*49fe348cSAndroid Build Coastguard Worker 272*49fe348cSAndroid Build Coastguard Worker else: 273*49fe348cSAndroid Build Coastguard Worker return 2 274*49fe348cSAndroid Build Coastguard Worker 275*49fe348cSAndroid Build Coastguard Worker return 0 276*49fe348cSAndroid Build Coastguard Worker 277*49fe348cSAndroid Build Coastguard Worker def estimate_noise(self, bw, xq, lastnz, x): 278*49fe348cSAndroid Build Coastguard Worker 279*49fe348cSAndroid Build Coastguard Worker i_nf = self.get_noise_indices(bw, xq, lastnz) 280*49fe348cSAndroid Build Coastguard Worker l_nf = sum(abs(x[:len(i_nf)] * i_nf)) / sum(i_nf) \ 281*49fe348cSAndroid Build Coastguard Worker if sum(i_nf) > 0 else 0 282*49fe348cSAndroid Build Coastguard Worker 283*49fe348cSAndroid Build Coastguard Worker return min(max(np.rint(8 - 16 * l_nf).astype(int), 0), 7) 284*49fe348cSAndroid Build Coastguard Worker 285*49fe348cSAndroid Build Coastguard Worker def run(self, bw, nbytes, nbits_bw, nbits_ltpf, nbits_sns, nbits_tns, x): 286*49fe348cSAndroid Build Coastguard Worker 287*49fe348cSAndroid Build Coastguard Worker sr = self.sr 288*49fe348cSAndroid Build Coastguard Worker 289*49fe348cSAndroid Build Coastguard Worker ### Bit budget 290*49fe348cSAndroid Build Coastguard Worker 291*49fe348cSAndroid Build Coastguard Worker hr = self.sr >= T.SRATE_48K_HR 292*49fe348cSAndroid Build Coastguard Worker 293*49fe348cSAndroid Build Coastguard Worker nbits_gain = 8 294*49fe348cSAndroid Build Coastguard Worker nbits_nf = 3 295*49fe348cSAndroid Build Coastguard Worker 296*49fe348cSAndroid Build Coastguard Worker nbits_ari = np.ceil(np.log2(len(x) / 2)).astype(int) 297*49fe348cSAndroid Build Coastguard Worker nbits_ari += 3 + int(hr) + min((8*nbytes - 1) // 1280, 2) 298*49fe348cSAndroid Build Coastguard Worker 299*49fe348cSAndroid Build Coastguard Worker nbits_spec = 8*nbytes - \ 300*49fe348cSAndroid Build Coastguard Worker nbits_bw - nbits_ltpf - nbits_sns - nbits_tns - \ 301*49fe348cSAndroid Build Coastguard Worker nbits_gain - nbits_nf - nbits_ari 302*49fe348cSAndroid Build Coastguard Worker 303*49fe348cSAndroid Build Coastguard Worker ### Global gain estimation 304*49fe348cSAndroid Build Coastguard Worker 305*49fe348cSAndroid Build Coastguard Worker nbits_off = self.nbits_off + self.nbits_spec - self.nbits_est 306*49fe348cSAndroid Build Coastguard Worker nbits_off = min(40, max(-40, nbits_off)) 307*49fe348cSAndroid Build Coastguard Worker 308*49fe348cSAndroid Build Coastguard Worker nbits_off = 0 if self.reset_off else \ 309*49fe348cSAndroid Build Coastguard Worker 0.8 * self.nbits_off + 0.2 * nbits_off 310*49fe348cSAndroid Build Coastguard Worker 311*49fe348cSAndroid Build Coastguard Worker g_off = self.get_gain_offset(nbytes) 312*49fe348cSAndroid Build Coastguard Worker 313*49fe348cSAndroid Build Coastguard Worker (g_min, g_int, self.reset_off) = \ 314*49fe348cSAndroid Build Coastguard Worker self.estimate_gain(x, nbytes, nbits_spec, nbits_off, g_off) 315*49fe348cSAndroid Build Coastguard Worker self.nbits_off = nbits_off 316*49fe348cSAndroid Build Coastguard Worker self.nbits_spec = nbits_spec 317*49fe348cSAndroid Build Coastguard Worker 318*49fe348cSAndroid Build Coastguard Worker ### Quantization 319*49fe348cSAndroid Build Coastguard Worker 320*49fe348cSAndroid Build Coastguard Worker (xg, xq, lastnz) = self.quantize(g_int, x) 321*49fe348cSAndroid Build Coastguard Worker 322*49fe348cSAndroid Build Coastguard Worker (nbits_est, nbits_trunc, lastnz_trunc, _) = \ 323*49fe348cSAndroid Build Coastguard Worker self.compute_nbits(nbytes, xq, lastnz, nbits_spec) 324*49fe348cSAndroid Build Coastguard Worker 325*49fe348cSAndroid Build Coastguard Worker self.nbits_est = nbits_est 326*49fe348cSAndroid Build Coastguard Worker 327*49fe348cSAndroid Build Coastguard Worker ### Adjust gain and requantize 328*49fe348cSAndroid Build Coastguard Worker 329*49fe348cSAndroid Build Coastguard Worker g_adj = self.adjust_gain(g_int - g_off, nbits_est, nbits_spec) 330*49fe348cSAndroid Build Coastguard Worker g_adj = max(g_int + g_adj, g_min + g_off) - g_int 331*49fe348cSAndroid Build Coastguard Worker 332*49fe348cSAndroid Build Coastguard Worker (xg, xq, lastnz) = self.quantize(g_adj, xg) 333*49fe348cSAndroid Build Coastguard Worker 334*49fe348cSAndroid Build Coastguard Worker (nbits_est, nbits_trunc, lastnz_trunc, lsb_mode) = \ 335*49fe348cSAndroid Build Coastguard Worker self.compute_nbits(nbytes, xq, lastnz, nbits_spec) 336*49fe348cSAndroid Build Coastguard Worker 337*49fe348cSAndroid Build Coastguard Worker self.g_idx = g_int + g_adj - g_off 338*49fe348cSAndroid Build Coastguard Worker self.xq = xq 339*49fe348cSAndroid Build Coastguard Worker self.lastnz = lastnz_trunc 340*49fe348cSAndroid Build Coastguard Worker 341*49fe348cSAndroid Build Coastguard Worker self.nbits_residual_max = nbits_spec - nbits_trunc + 4 342*49fe348cSAndroid Build Coastguard Worker self.xg = xg 343*49fe348cSAndroid Build Coastguard Worker 344*49fe348cSAndroid Build Coastguard Worker ### Noise factor 345*49fe348cSAndroid Build Coastguard Worker 346*49fe348cSAndroid Build Coastguard Worker self.noise_factor = self.estimate_noise(bw, xq, lastnz, x) 347*49fe348cSAndroid Build Coastguard Worker 348*49fe348cSAndroid Build Coastguard Worker return (self.xq, self.lastnz, self.xg) 349*49fe348cSAndroid Build Coastguard Worker 350*49fe348cSAndroid Build Coastguard Worker def store(self, b): 351*49fe348cSAndroid Build Coastguard Worker 352*49fe348cSAndroid Build Coastguard Worker ne = T.I[self.dt][self.sr][-1] 353*49fe348cSAndroid Build Coastguard Worker nbits_lastnz = np.ceil(np.log2(ne/2)).astype(int) 354*49fe348cSAndroid Build Coastguard Worker 355*49fe348cSAndroid Build Coastguard Worker b.write_uint((self.lastnz >> 1) - 1, nbits_lastnz) 356*49fe348cSAndroid Build Coastguard Worker b.write_uint(self.lsb_mode, 1) 357*49fe348cSAndroid Build Coastguard Worker b.write_uint(self.g_idx, 8) 358*49fe348cSAndroid Build Coastguard Worker 359*49fe348cSAndroid Build Coastguard Worker def encode(self, bits): 360*49fe348cSAndroid Build Coastguard Worker 361*49fe348cSAndroid Build Coastguard Worker ### Noise factor 362*49fe348cSAndroid Build Coastguard Worker 363*49fe348cSAndroid Build Coastguard Worker bits.write_uint(self.noise_factor, 3) 364*49fe348cSAndroid Build Coastguard Worker 365*49fe348cSAndroid Build Coastguard Worker ### Quantized data 366*49fe348cSAndroid Build Coastguard Worker 367*49fe348cSAndroid Build Coastguard Worker lsbs = [] 368*49fe348cSAndroid Build Coastguard Worker 369*49fe348cSAndroid Build Coastguard Worker x = self.xq 370*49fe348cSAndroid Build Coastguard Worker c = 0 371*49fe348cSAndroid Build Coastguard Worker 372*49fe348cSAndroid Build Coastguard Worker for n in range(0, self.lastnz, 2): 373*49fe348cSAndroid Build Coastguard Worker t = c + self.rate 374*49fe348cSAndroid Build Coastguard Worker if n > len(x) // 2: 375*49fe348cSAndroid Build Coastguard Worker t += 256 376*49fe348cSAndroid Build Coastguard Worker 377*49fe348cSAndroid Build Coastguard Worker a = abs(x[n ]) 378*49fe348cSAndroid Build Coastguard Worker b = abs(x[n+1]) 379*49fe348cSAndroid Build Coastguard Worker lev = 0 380*49fe348cSAndroid Build Coastguard Worker while max(a, b) >= 4: 381*49fe348cSAndroid Build Coastguard Worker 382*49fe348cSAndroid Build Coastguard Worker bits.ac_encode( 383*49fe348cSAndroid Build Coastguard Worker T.AC_SPEC_CUMFREQ[T.AC_SPEC_LOOKUP[t + lev*1024]][16], 384*49fe348cSAndroid Build Coastguard Worker T.AC_SPEC_FREQ[T.AC_SPEC_LOOKUP[t + lev*1024]][16]) 385*49fe348cSAndroid Build Coastguard Worker 386*49fe348cSAndroid Build Coastguard Worker if lev == 0 and self.lsb_mode: 387*49fe348cSAndroid Build Coastguard Worker lsb_0 = a & 1 388*49fe348cSAndroid Build Coastguard Worker lsb_1 = b & 1 389*49fe348cSAndroid Build Coastguard Worker else: 390*49fe348cSAndroid Build Coastguard Worker bits.write_bit(a & 1) 391*49fe348cSAndroid Build Coastguard Worker bits.write_bit(b & 1) 392*49fe348cSAndroid Build Coastguard Worker 393*49fe348cSAndroid Build Coastguard Worker a >>= 1 394*49fe348cSAndroid Build Coastguard Worker b >>= 1 395*49fe348cSAndroid Build Coastguard Worker lev = min(lev + 1, 3) 396*49fe348cSAndroid Build Coastguard Worker 397*49fe348cSAndroid Build Coastguard Worker bits.ac_encode( 398*49fe348cSAndroid Build Coastguard Worker T.AC_SPEC_CUMFREQ[T.AC_SPEC_LOOKUP[t + lev*1024]][a + 4*b], 399*49fe348cSAndroid Build Coastguard Worker T.AC_SPEC_FREQ[T.AC_SPEC_LOOKUP[t + lev*1024]][a + 4*b]) 400*49fe348cSAndroid Build Coastguard Worker 401*49fe348cSAndroid Build Coastguard Worker a_lsb = abs(x[n ]) 402*49fe348cSAndroid Build Coastguard Worker b_lsb = abs(x[n+1]) 403*49fe348cSAndroid Build Coastguard Worker if lev > 0 and self.lsb_mode: 404*49fe348cSAndroid Build Coastguard Worker a_lsb >>= 1 405*49fe348cSAndroid Build Coastguard Worker b_lsb >>= 1 406*49fe348cSAndroid Build Coastguard Worker 407*49fe348cSAndroid Build Coastguard Worker lsbs.append(lsb_0) 408*49fe348cSAndroid Build Coastguard Worker if a_lsb == 0 and x[n+0] != 0: 409*49fe348cSAndroid Build Coastguard Worker lsbs.append(int(x[n+0] < 0)) 410*49fe348cSAndroid Build Coastguard Worker 411*49fe348cSAndroid Build Coastguard Worker lsbs.append(lsb_1) 412*49fe348cSAndroid Build Coastguard Worker if b_lsb == 0 and x[n+1] != 0: 413*49fe348cSAndroid Build Coastguard Worker lsbs.append(int(x[n+1] < 0)) 414*49fe348cSAndroid Build Coastguard Worker 415*49fe348cSAndroid Build Coastguard Worker if a_lsb > 0: 416*49fe348cSAndroid Build Coastguard Worker bits.write_bit(int(x[n+0] < 0)) 417*49fe348cSAndroid Build Coastguard Worker 418*49fe348cSAndroid Build Coastguard Worker if b_lsb > 0: 419*49fe348cSAndroid Build Coastguard Worker bits.write_bit(int(x[n+1] < 0)) 420*49fe348cSAndroid Build Coastguard Worker 421*49fe348cSAndroid Build Coastguard Worker t = 1 + (a + b) * (lev + 1) if lev <= 1 else 12 + lev; 422*49fe348cSAndroid Build Coastguard Worker c = (c & 15) * 16 + t; 423*49fe348cSAndroid Build Coastguard Worker 424*49fe348cSAndroid Build Coastguard Worker ### Residual data 425*49fe348cSAndroid Build Coastguard Worker 426*49fe348cSAndroid Build Coastguard Worker if self.lsb_mode == 0: 427*49fe348cSAndroid Build Coastguard Worker nbits_residual = min(bits.get_bits_left(), self.nbits_residual_max) 428*49fe348cSAndroid Build Coastguard Worker 429*49fe348cSAndroid Build Coastguard Worker for i in range(len(self.xg)): 430*49fe348cSAndroid Build Coastguard Worker 431*49fe348cSAndroid Build Coastguard Worker if self.xq[i] == 0: 432*49fe348cSAndroid Build Coastguard Worker continue 433*49fe348cSAndroid Build Coastguard Worker 434*49fe348cSAndroid Build Coastguard Worker bits.write_bit(self.xg[i] >= self.xq[i]) 435*49fe348cSAndroid Build Coastguard Worker nbits_residual -= 1 436*49fe348cSAndroid Build Coastguard Worker if nbits_residual <= 0: 437*49fe348cSAndroid Build Coastguard Worker break 438*49fe348cSAndroid Build Coastguard Worker 439*49fe348cSAndroid Build Coastguard Worker else: 440*49fe348cSAndroid Build Coastguard Worker nbits_residual = min(bits.get_bits_left(), len(lsbs)) 441*49fe348cSAndroid Build Coastguard Worker for lsb in lsbs[:nbits_residual]: 442*49fe348cSAndroid Build Coastguard Worker bits.write_bit(lsb) 443*49fe348cSAndroid Build Coastguard Worker 444*49fe348cSAndroid Build Coastguard Worker 445*49fe348cSAndroid Build Coastguard Workerclass SpectrumSynthesis(SpectrumQuantization): 446*49fe348cSAndroid Build Coastguard Worker 447*49fe348cSAndroid Build Coastguard Worker def __init__(self, dt, sr): 448*49fe348cSAndroid Build Coastguard Worker 449*49fe348cSAndroid Build Coastguard Worker super().__init__(dt, sr) 450*49fe348cSAndroid Build Coastguard Worker 451*49fe348cSAndroid Build Coastguard Worker (self.lastnz, self.lsb_mode, self.g_idx) = \ 452*49fe348cSAndroid Build Coastguard Worker (None, None, None) 453*49fe348cSAndroid Build Coastguard Worker 454*49fe348cSAndroid Build Coastguard Worker def fill_noise(self, bw, x, lastnz, f_nf, nf_seed): 455*49fe348cSAndroid Build Coastguard Worker 456*49fe348cSAndroid Build Coastguard Worker i_nf = self.get_noise_indices(bw, x, lastnz) 457*49fe348cSAndroid Build Coastguard Worker 458*49fe348cSAndroid Build Coastguard Worker k_nf = np.argwhere(i_nf) 459*49fe348cSAndroid Build Coastguard Worker l_nf = (8 - f_nf)/16 460*49fe348cSAndroid Build Coastguard Worker 461*49fe348cSAndroid Build Coastguard Worker for k in k_nf: 462*49fe348cSAndroid Build Coastguard Worker nf_seed = (13849 + nf_seed * 31821) & 0xffff 463*49fe348cSAndroid Build Coastguard Worker x[k] = [ -l_nf, l_nf ][nf_seed < 0x8000] 464*49fe348cSAndroid Build Coastguard Worker 465*49fe348cSAndroid Build Coastguard Worker return x 466*49fe348cSAndroid Build Coastguard Worker 467*49fe348cSAndroid Build Coastguard Worker def load(self, b): 468*49fe348cSAndroid Build Coastguard Worker 469*49fe348cSAndroid Build Coastguard Worker ne = T.I[self.dt][self.sr][-1] 470*49fe348cSAndroid Build Coastguard Worker nbits_lastnz = np.ceil(np.log2(ne/2)).astype(int) 471*49fe348cSAndroid Build Coastguard Worker 472*49fe348cSAndroid Build Coastguard Worker self.lastnz = (b.read_uint(nbits_lastnz) + 1) << 1 473*49fe348cSAndroid Build Coastguard Worker self.lsb_mode = b.read_uint(1) 474*49fe348cSAndroid Build Coastguard Worker self.g_idx = b.read_uint(8) 475*49fe348cSAndroid Build Coastguard Worker 476*49fe348cSAndroid Build Coastguard Worker if self.lastnz > ne: 477*49fe348cSAndroid Build Coastguard Worker raise ValueError('Invalid count of coded samples') 478*49fe348cSAndroid Build Coastguard Worker 479*49fe348cSAndroid Build Coastguard Worker def decode(self, bits, bw, nbytes): 480*49fe348cSAndroid Build Coastguard Worker 481*49fe348cSAndroid Build Coastguard Worker ### Noise factor 482*49fe348cSAndroid Build Coastguard Worker 483*49fe348cSAndroid Build Coastguard Worker f_nf = bits.read_uint(3) 484*49fe348cSAndroid Build Coastguard Worker 485*49fe348cSAndroid Build Coastguard Worker ### Quantized data 486*49fe348cSAndroid Build Coastguard Worker 487*49fe348cSAndroid Build Coastguard Worker ne = T.I[self.dt][self.sr][-1] 488*49fe348cSAndroid Build Coastguard Worker x = np.zeros(ne) 489*49fe348cSAndroid Build Coastguard Worker rate = [ 0, 512 ][int(self.sr < T.SRATE_96K_HR and \ 490*49fe348cSAndroid Build Coastguard Worker nbytes > 20 * (1 + min(self.sr, T.SRATE_48K)))] 491*49fe348cSAndroid Build Coastguard Worker 492*49fe348cSAndroid Build Coastguard Worker levs = np.zeros(len(x), dtype=np.intc) 493*49fe348cSAndroid Build Coastguard Worker c = 0 494*49fe348cSAndroid Build Coastguard Worker 495*49fe348cSAndroid Build Coastguard Worker for n in range(0, self.lastnz, 2): 496*49fe348cSAndroid Build Coastguard Worker t = c + rate 497*49fe348cSAndroid Build Coastguard Worker if n > len(x) // 2: 498*49fe348cSAndroid Build Coastguard Worker t += 256 499*49fe348cSAndroid Build Coastguard Worker 500*49fe348cSAndroid Build Coastguard Worker for lev in range(14): 501*49fe348cSAndroid Build Coastguard Worker 502*49fe348cSAndroid Build Coastguard Worker s = t + min(lev, 3) * 1024 503*49fe348cSAndroid Build Coastguard Worker 504*49fe348cSAndroid Build Coastguard Worker sym = bits.ac_decode( 505*49fe348cSAndroid Build Coastguard Worker T.AC_SPEC_CUMFREQ[T.AC_SPEC_LOOKUP[s]], 506*49fe348cSAndroid Build Coastguard Worker T.AC_SPEC_FREQ[T.AC_SPEC_LOOKUP[s]]) 507*49fe348cSAndroid Build Coastguard Worker 508*49fe348cSAndroid Build Coastguard Worker if sym < 16: 509*49fe348cSAndroid Build Coastguard Worker break 510*49fe348cSAndroid Build Coastguard Worker 511*49fe348cSAndroid Build Coastguard Worker if self.lsb_mode == 0 or lev > 0: 512*49fe348cSAndroid Build Coastguard Worker x[n ] += bits.read_bit() << lev 513*49fe348cSAndroid Build Coastguard Worker x[n+1] += bits.read_bit() << lev 514*49fe348cSAndroid Build Coastguard Worker 515*49fe348cSAndroid Build Coastguard Worker if lev >= 14: 516*49fe348cSAndroid Build Coastguard Worker raise ValueError('Out of range value') 517*49fe348cSAndroid Build Coastguard Worker 518*49fe348cSAndroid Build Coastguard Worker a = sym % 4 519*49fe348cSAndroid Build Coastguard Worker b = sym // 4 520*49fe348cSAndroid Build Coastguard Worker 521*49fe348cSAndroid Build Coastguard Worker levs[n ] = lev 522*49fe348cSAndroid Build Coastguard Worker levs[n+1] = lev 523*49fe348cSAndroid Build Coastguard Worker 524*49fe348cSAndroid Build Coastguard Worker x[n ] += a << lev 525*49fe348cSAndroid Build Coastguard Worker x[n+1] += b << lev 526*49fe348cSAndroid Build Coastguard Worker 527*49fe348cSAndroid Build Coastguard Worker if x[n] and bits.read_bit(): 528*49fe348cSAndroid Build Coastguard Worker x[n] = -x[n] 529*49fe348cSAndroid Build Coastguard Worker 530*49fe348cSAndroid Build Coastguard Worker if x[n+1] and bits.read_bit(): 531*49fe348cSAndroid Build Coastguard Worker x[n+1] = -x[n+1] 532*49fe348cSAndroid Build Coastguard Worker 533*49fe348cSAndroid Build Coastguard Worker lev = min(lev, 3) 534*49fe348cSAndroid Build Coastguard Worker t = 1 + (a + b) * (lev + 1) if lev <= 1 else 12 + lev; 535*49fe348cSAndroid Build Coastguard Worker c = (c & 15) * 16 + t; 536*49fe348cSAndroid Build Coastguard Worker 537*49fe348cSAndroid Build Coastguard Worker ### Residual data 538*49fe348cSAndroid Build Coastguard Worker 539*49fe348cSAndroid Build Coastguard Worker nbits_residual = bits.get_bits_left() 540*49fe348cSAndroid Build Coastguard Worker if nbits_residual < 0: 541*49fe348cSAndroid Build Coastguard Worker raise ValueError('Out of bitstream') 542*49fe348cSAndroid Build Coastguard Worker 543*49fe348cSAndroid Build Coastguard Worker if self.lsb_mode == 0: 544*49fe348cSAndroid Build Coastguard Worker 545*49fe348cSAndroid Build Coastguard Worker xr = np.zeros(len(x), dtype=np.bool) 546*49fe348cSAndroid Build Coastguard Worker 547*49fe348cSAndroid Build Coastguard Worker for i in range(len(x)): 548*49fe348cSAndroid Build Coastguard Worker 549*49fe348cSAndroid Build Coastguard Worker if nbits_residual <= 0: 550*49fe348cSAndroid Build Coastguard Worker xr.resize(i) 551*49fe348cSAndroid Build Coastguard Worker break 552*49fe348cSAndroid Build Coastguard Worker 553*49fe348cSAndroid Build Coastguard Worker if x[i] == 0: 554*49fe348cSAndroid Build Coastguard Worker continue 555*49fe348cSAndroid Build Coastguard Worker 556*49fe348cSAndroid Build Coastguard Worker xr[i] = bits.read_bit() 557*49fe348cSAndroid Build Coastguard Worker nbits_residual -= 1 558*49fe348cSAndroid Build Coastguard Worker 559*49fe348cSAndroid Build Coastguard Worker else: 560*49fe348cSAndroid Build Coastguard Worker 561*49fe348cSAndroid Build Coastguard Worker for i in range(len(levs)): 562*49fe348cSAndroid Build Coastguard Worker 563*49fe348cSAndroid Build Coastguard Worker if nbits_residual <= 0: 564*49fe348cSAndroid Build Coastguard Worker break 565*49fe348cSAndroid Build Coastguard Worker 566*49fe348cSAndroid Build Coastguard Worker if levs[i] <= 0: 567*49fe348cSAndroid Build Coastguard Worker continue 568*49fe348cSAndroid Build Coastguard Worker 569*49fe348cSAndroid Build Coastguard Worker lsb = bits.read_bit() 570*49fe348cSAndroid Build Coastguard Worker nbits_residual -= 1 571*49fe348cSAndroid Build Coastguard Worker if not lsb: 572*49fe348cSAndroid Build Coastguard Worker continue 573*49fe348cSAndroid Build Coastguard Worker 574*49fe348cSAndroid Build Coastguard Worker sign = int(x[i] < 0) 575*49fe348cSAndroid Build Coastguard Worker 576*49fe348cSAndroid Build Coastguard Worker if x[i] == 0: 577*49fe348cSAndroid Build Coastguard Worker 578*49fe348cSAndroid Build Coastguard Worker if nbits_residual <= 0: 579*49fe348cSAndroid Build Coastguard Worker break 580*49fe348cSAndroid Build Coastguard Worker 581*49fe348cSAndroid Build Coastguard Worker sign = bits.read_bit() 582*49fe348cSAndroid Build Coastguard Worker nbits_residual -= 1 583*49fe348cSAndroid Build Coastguard Worker 584*49fe348cSAndroid Build Coastguard Worker x[i] += [ 1, -1 ][sign] 585*49fe348cSAndroid Build Coastguard Worker 586*49fe348cSAndroid Build Coastguard Worker ### Set residual and noise 587*49fe348cSAndroid Build Coastguard Worker 588*49fe348cSAndroid Build Coastguard Worker nf_seed = sum(abs(x.astype(np.intc)) * range(len(x))) 589*49fe348cSAndroid Build Coastguard Worker 590*49fe348cSAndroid Build Coastguard Worker zero_frame = (self.lastnz <= 2 and x[0] == 0 and x[1] == 0 591*49fe348cSAndroid Build Coastguard Worker and self.g_idx <= 0 and f_nf >= 7) 592*49fe348cSAndroid Build Coastguard Worker 593*49fe348cSAndroid Build Coastguard Worker if self.lsb_mode == 0: 594*49fe348cSAndroid Build Coastguard Worker 595*49fe348cSAndroid Build Coastguard Worker for i in range(len(xr)): 596*49fe348cSAndroid Build Coastguard Worker 597*49fe348cSAndroid Build Coastguard Worker if x[i] and xr[i] == 0: 598*49fe348cSAndroid Build Coastguard Worker x[i] += [ -0.1875, -0.3125 ][x[i] < 0] 599*49fe348cSAndroid Build Coastguard Worker elif x[i]: 600*49fe348cSAndroid Build Coastguard Worker x[i] += [ 0.1875, 0.3125 ][x[i] > 0] 601*49fe348cSAndroid Build Coastguard Worker 602*49fe348cSAndroid Build Coastguard Worker if not zero_frame: 603*49fe348cSAndroid Build Coastguard Worker x = self.fill_noise(bw, x, self.lastnz, f_nf, nf_seed) 604*49fe348cSAndroid Build Coastguard Worker 605*49fe348cSAndroid Build Coastguard Worker ### Rescale coefficients 606*49fe348cSAndroid Build Coastguard Worker 607*49fe348cSAndroid Build Coastguard Worker g_int = self.get_gain_offset(nbytes) + self.g_idx 608*49fe348cSAndroid Build Coastguard Worker x *= 10 ** (g_int / 28) 609*49fe348cSAndroid Build Coastguard Worker 610*49fe348cSAndroid Build Coastguard Worker return x 611*49fe348cSAndroid Build Coastguard Worker 612*49fe348cSAndroid Build Coastguard Worker 613*49fe348cSAndroid Build Coastguard Workerdef initial_state(): 614*49fe348cSAndroid Build Coastguard Worker return { 'nbits_off' : 0.0, 'nbits_spare' : 0 } 615*49fe348cSAndroid Build Coastguard Worker 616*49fe348cSAndroid Build Coastguard Worker 617*49fe348cSAndroid Build Coastguard Worker### ------------------------------------------------------------------------ ### 618*49fe348cSAndroid Build Coastguard Worker 619*49fe348cSAndroid Build Coastguard Workerdef check_estimate_gain(rng, dt, sr): 620*49fe348cSAndroid Build Coastguard Worker 621*49fe348cSAndroid Build Coastguard Worker ok = True 622*49fe348cSAndroid Build Coastguard Worker 623*49fe348cSAndroid Build Coastguard Worker analysis = SpectrumAnalysis(dt, sr) 624*49fe348cSAndroid Build Coastguard Worker 625*49fe348cSAndroid Build Coastguard Worker mismatch_count = 0 626*49fe348cSAndroid Build Coastguard Worker for i in range(10): 627*49fe348cSAndroid Build Coastguard Worker ne = T.I[dt][sr][-1] 628*49fe348cSAndroid Build Coastguard Worker x = rng.random(ne) * i * 1e2 629*49fe348cSAndroid Build Coastguard Worker 630*49fe348cSAndroid Build Coastguard Worker nbytes = 20 + int(rng.random() * 100) 631*49fe348cSAndroid Build Coastguard Worker nbits_budget = 8 * nbytes - int(rng.random() * 100) 632*49fe348cSAndroid Build Coastguard Worker nbits_off = rng.random() * 10 633*49fe348cSAndroid Build Coastguard Worker g_off = 10 - int(rng.random() * 20) 634*49fe348cSAndroid Build Coastguard Worker 635*49fe348cSAndroid Build Coastguard Worker (_, g_int, reset_off) = \ 636*49fe348cSAndroid Build Coastguard Worker analysis.estimate_gain(x, nbytes, nbits_budget, nbits_off, g_off) 637*49fe348cSAndroid Build Coastguard Worker 638*49fe348cSAndroid Build Coastguard Worker (g_int_c, reset_off_c, _) = lc3.spec_estimate_gain( 639*49fe348cSAndroid Build Coastguard Worker dt, sr, x, nbytes, nbits_budget, nbits_off, -g_off) 640*49fe348cSAndroid Build Coastguard Worker 641*49fe348cSAndroid Build Coastguard Worker if g_int_c != g_int: 642*49fe348cSAndroid Build Coastguard Worker mismatch_count += 1 643*49fe348cSAndroid Build Coastguard Worker 644*49fe348cSAndroid Build Coastguard Worker ok = ok and (g_int_c == g_int or mismatch_count <= 1) 645*49fe348cSAndroid Build Coastguard Worker ok = ok and (reset_off_c == reset_off or mismatch_count <= 1) 646*49fe348cSAndroid Build Coastguard Worker 647*49fe348cSAndroid Build Coastguard Worker return ok 648*49fe348cSAndroid Build Coastguard Worker 649*49fe348cSAndroid Build Coastguard Workerdef check_quantization(rng, dt, sr): 650*49fe348cSAndroid Build Coastguard Worker 651*49fe348cSAndroid Build Coastguard Worker ok = True 652*49fe348cSAndroid Build Coastguard Worker 653*49fe348cSAndroid Build Coastguard Worker analysis = SpectrumAnalysis(dt, sr) 654*49fe348cSAndroid Build Coastguard Worker 655*49fe348cSAndroid Build Coastguard Worker for g_int in range(-128, 128): 656*49fe348cSAndroid Build Coastguard Worker 657*49fe348cSAndroid Build Coastguard Worker ne = T.I[dt][sr][-1] 658*49fe348cSAndroid Build Coastguard Worker x = rng.random(ne) * 1e2 659*49fe348cSAndroid Build Coastguard Worker nbytes = 20 + int(rng.random() * 30) 660*49fe348cSAndroid Build Coastguard Worker 661*49fe348cSAndroid Build Coastguard Worker (xg, xq, nq) = analysis.quantize(g_int, x) 662*49fe348cSAndroid Build Coastguard Worker (xg_c, nq_c) = lc3.spec_quantize(dt, sr, g_int, x) 663*49fe348cSAndroid Build Coastguard Worker 664*49fe348cSAndroid Build Coastguard Worker ok = ok and np.amax(np.abs(1 - xg_c/xg)) < 1e-6 665*49fe348cSAndroid Build Coastguard Worker ok = ok and nq_c == nq 666*49fe348cSAndroid Build Coastguard Worker 667*49fe348cSAndroid Build Coastguard Worker return ok 668*49fe348cSAndroid Build Coastguard Worker 669*49fe348cSAndroid Build Coastguard Workerdef check_compute_nbits(rng, dt, sr): 670*49fe348cSAndroid Build Coastguard Worker 671*49fe348cSAndroid Build Coastguard Worker ok = True 672*49fe348cSAndroid Build Coastguard Worker 673*49fe348cSAndroid Build Coastguard Worker analysis = SpectrumAnalysis(dt, sr) 674*49fe348cSAndroid Build Coastguard Worker 675*49fe348cSAndroid Build Coastguard Worker for nbytes in range(20, 150): 676*49fe348cSAndroid Build Coastguard Worker 677*49fe348cSAndroid Build Coastguard Worker nbits_budget = nbytes * 8 - int(rng.random() * 100) 678*49fe348cSAndroid Build Coastguard Worker ne = T.I[dt][sr][-1] 679*49fe348cSAndroid Build Coastguard Worker xq = (rng.random(ne) * 8).astype(int) 680*49fe348cSAndroid Build Coastguard Worker nq = ne // 2 + int(rng.random() * ne // 2) 681*49fe348cSAndroid Build Coastguard Worker 682*49fe348cSAndroid Build Coastguard Worker nq = nq - nq % 2 683*49fe348cSAndroid Build Coastguard Worker if xq[nq-2] == 0 and xq[nq-1] == 0: 684*49fe348cSAndroid Build Coastguard Worker xq[nq-2] = 1 685*49fe348cSAndroid Build Coastguard Worker 686*49fe348cSAndroid Build Coastguard Worker (nbits, nbits_trunc, nq_trunc, lsb_mode) = \ 687*49fe348cSAndroid Build Coastguard Worker analysis.compute_nbits(nbytes, xq, nq, nbits_budget) 688*49fe348cSAndroid Build Coastguard Worker 689*49fe348cSAndroid Build Coastguard Worker (nbits_c, nq_c, _) = \ 690*49fe348cSAndroid Build Coastguard Worker lc3.spec_compute_nbits(dt, sr, nbytes, xq, nq, 0) 691*49fe348cSAndroid Build Coastguard Worker 692*49fe348cSAndroid Build Coastguard Worker (nbits_trunc_c, nq_trunc_c, lsb_mode_c) = \ 693*49fe348cSAndroid Build Coastguard Worker lc3.spec_compute_nbits(dt, sr, nbytes, xq, nq, nbits_budget) 694*49fe348cSAndroid Build Coastguard Worker 695*49fe348cSAndroid Build Coastguard Worker ok = ok and nbits_c == nbits 696*49fe348cSAndroid Build Coastguard Worker ok = ok and nbits_trunc_c == nbits_trunc 697*49fe348cSAndroid Build Coastguard Worker ok = ok and nq_trunc_c == nq_trunc 698*49fe348cSAndroid Build Coastguard Worker ok = ok and lsb_mode_c == lsb_mode 699*49fe348cSAndroid Build Coastguard Worker 700*49fe348cSAndroid Build Coastguard Worker return ok 701*49fe348cSAndroid Build Coastguard Worker 702*49fe348cSAndroid Build Coastguard Workerdef check_adjust_gain(rng, dt, sr): 703*49fe348cSAndroid Build Coastguard Worker 704*49fe348cSAndroid Build Coastguard Worker ok = True 705*49fe348cSAndroid Build Coastguard Worker 706*49fe348cSAndroid Build Coastguard Worker analysis = SpectrumAnalysis(dt, sr) 707*49fe348cSAndroid Build Coastguard Worker 708*49fe348cSAndroid Build Coastguard Worker for g_idx in (0, 128, 254, 255): 709*49fe348cSAndroid Build Coastguard Worker for nbits in range(50, 5000, 5): 710*49fe348cSAndroid Build Coastguard Worker nbits_budget = int(nbits * (0.95 + (rng.random() * 0.1))) 711*49fe348cSAndroid Build Coastguard Worker 712*49fe348cSAndroid Build Coastguard Worker g_adj = analysis.adjust_gain(g_idx, nbits, nbits_budget) 713*49fe348cSAndroid Build Coastguard Worker 714*49fe348cSAndroid Build Coastguard Worker g_adj_c = lc3.spec_adjust_gain( 715*49fe348cSAndroid Build Coastguard Worker dt, sr, g_idx, nbits, nbits_budget, 0) 716*49fe348cSAndroid Build Coastguard Worker 717*49fe348cSAndroid Build Coastguard Worker ok = ok and g_adj_c == g_adj 718*49fe348cSAndroid Build Coastguard Worker 719*49fe348cSAndroid Build Coastguard Worker return ok 720*49fe348cSAndroid Build Coastguard Worker 721*49fe348cSAndroid Build Coastguard Workerdef check_unit(rng, dt, sr): 722*49fe348cSAndroid Build Coastguard Worker 723*49fe348cSAndroid Build Coastguard Worker ok = True 724*49fe348cSAndroid Build Coastguard Worker 725*49fe348cSAndroid Build Coastguard Worker state_c = initial_state() 726*49fe348cSAndroid Build Coastguard Worker 727*49fe348cSAndroid Build Coastguard Worker bwdet = m_bwdet.BandwidthDetector(dt, sr) 728*49fe348cSAndroid Build Coastguard Worker ltpf = m_ltpf.LtpfAnalysis(dt, sr) 729*49fe348cSAndroid Build Coastguard Worker tns = m_tns.TnsAnalysis(dt) 730*49fe348cSAndroid Build Coastguard Worker sns = m_sns.SnsAnalysis(dt, sr) 731*49fe348cSAndroid Build Coastguard Worker analysis = SpectrumAnalysis(dt, sr) 732*49fe348cSAndroid Build Coastguard Worker 733*49fe348cSAndroid Build Coastguard Worker nbytes = 100 734*49fe348cSAndroid Build Coastguard Worker 735*49fe348cSAndroid Build Coastguard Worker for i in range(10): 736*49fe348cSAndroid Build Coastguard Worker ns = T.NS[dt][sr] 737*49fe348cSAndroid Build Coastguard Worker ne = T.I[dt][sr][-1] 738*49fe348cSAndroid Build Coastguard Worker 739*49fe348cSAndroid Build Coastguard Worker x = rng.random(ns) * 1e4 740*49fe348cSAndroid Build Coastguard Worker e = rng.random(min(len(x), 64)) * 1e10 741*49fe348cSAndroid Build Coastguard Worker 742*49fe348cSAndroid Build Coastguard Worker if sr < T.SRATE_48K_HR: 743*49fe348cSAndroid Build Coastguard Worker bwdet.run(e) 744*49fe348cSAndroid Build Coastguard Worker pitch_present = ltpf.run(x) 745*49fe348cSAndroid Build Coastguard Worker tns.run(x[:ne], sr, False, nbytes) 746*49fe348cSAndroid Build Coastguard Worker sns.run(e, False, 0, x) 747*49fe348cSAndroid Build Coastguard Worker 748*49fe348cSAndroid Build Coastguard Worker (xq, nq, xg) = analysis.run(sr, nbytes, 749*49fe348cSAndroid Build Coastguard Worker 0 if sr >= T.SRATE_48K_HR else bwdet.get_nbits(), 750*49fe348cSAndroid Build Coastguard Worker ltpf.get_nbits(), sns.get_nbits(), tns.get_nbits(), x[:ne]) 751*49fe348cSAndroid Build Coastguard Worker 752*49fe348cSAndroid Build Coastguard Worker (xg_c, side_c) = lc3.spec_analyze(dt, sr, 753*49fe348cSAndroid Build Coastguard Worker nbytes, pitch_present, tns.get_data(), state_c, x[:ne]) 754*49fe348cSAndroid Build Coastguard Worker 755*49fe348cSAndroid Build Coastguard Worker ok = ok and side_c['g_idx'] == analysis.g_idx 756*49fe348cSAndroid Build Coastguard Worker ok = ok and side_c['nq'] == nq 757*49fe348cSAndroid Build Coastguard Worker ok = ok and np.amax(np.abs(1 - xg_c/xg)) < 1e-6 758*49fe348cSAndroid Build Coastguard Worker 759*49fe348cSAndroid Build Coastguard Worker return ok 760*49fe348cSAndroid Build Coastguard Worker 761*49fe348cSAndroid Build Coastguard Workerdef check_noise(rng, dt, bw, hrmode = False): 762*49fe348cSAndroid Build Coastguard Worker 763*49fe348cSAndroid Build Coastguard Worker ok = True 764*49fe348cSAndroid Build Coastguard Worker 765*49fe348cSAndroid Build Coastguard Worker analysis = SpectrumAnalysis(dt, bw) 766*49fe348cSAndroid Build Coastguard Worker 767*49fe348cSAndroid Build Coastguard Worker xq_off = [ 0.375, 0.5 ][hrmode] 768*49fe348cSAndroid Build Coastguard Worker 769*49fe348cSAndroid Build Coastguard Worker for i in range(10): 770*49fe348cSAndroid Build Coastguard Worker ne = T.I[dt][bw][-1] 771*49fe348cSAndroid Build Coastguard Worker xq = ((rng.random(ne) - 0.5) * 10 ** (0.5)).astype(int) 772*49fe348cSAndroid Build Coastguard Worker nq = ne - int(rng.random() * 5) 773*49fe348cSAndroid Build Coastguard Worker x = xq - np.select([xq < 0, xq > 0], np.array([ xq_off, -xq_off ])) 774*49fe348cSAndroid Build Coastguard Worker 775*49fe348cSAndroid Build Coastguard Worker nf = analysis.estimate_noise(bw, xq, nq, x) 776*49fe348cSAndroid Build Coastguard Worker nf_c = lc3.spec_estimate_noise(dt, bw, hrmode, x, nq) 777*49fe348cSAndroid Build Coastguard Worker 778*49fe348cSAndroid Build Coastguard Worker ok = ok and nf_c == nf 779*49fe348cSAndroid Build Coastguard Worker 780*49fe348cSAndroid Build Coastguard Worker return ok 781*49fe348cSAndroid Build Coastguard Worker 782*49fe348cSAndroid Build Coastguard Workerdef check_appendix_c(dt): 783*49fe348cSAndroid Build Coastguard Worker 784*49fe348cSAndroid Build Coastguard Worker i0 = dt - T.DT_7M5 785*49fe348cSAndroid Build Coastguard Worker sr = T.SRATE_16K 786*49fe348cSAndroid Build Coastguard Worker 787*49fe348cSAndroid Build Coastguard Worker ok = True 788*49fe348cSAndroid Build Coastguard Worker 789*49fe348cSAndroid Build Coastguard Worker state_c = initial_state() 790*49fe348cSAndroid Build Coastguard Worker 791*49fe348cSAndroid Build Coastguard Worker for i in range(len(C.X_F[i0])): 792*49fe348cSAndroid Build Coastguard Worker 793*49fe348cSAndroid Build Coastguard Worker ne = T.I[dt][sr][-1] 794*49fe348cSAndroid Build Coastguard Worker 795*49fe348cSAndroid Build Coastguard Worker g_int = lc3.spec_estimate_gain(dt, sr, C.X_F[i0][i], 796*49fe348cSAndroid Build Coastguard Worker 0, C.NBITS_SPEC[i0][i], C.NBITS_OFFSET[i0][i], -C.GG_OFF[i0][i])[0] 797*49fe348cSAndroid Build Coastguard Worker ok = ok and g_int == C.GG_IND[i0][i] + C.GG_OFF[i0][i] 798*49fe348cSAndroid Build Coastguard Worker 799*49fe348cSAndroid Build Coastguard Worker (x, nq) = lc3.spec_quantize(dt, sr, 800*49fe348cSAndroid Build Coastguard Worker C.GG_IND[i0][i] + C.GG_OFF[i0][i], C.X_F[i0][i]) 801*49fe348cSAndroid Build Coastguard Worker x += np.select([x < 0, x > 0], np.array([ 0.375, -0.375 ])) 802*49fe348cSAndroid Build Coastguard Worker ok = ok and np.any((np.trunc(x) - C.X_Q[i0][i]) == 0) 803*49fe348cSAndroid Build Coastguard Worker ok = ok and nq == C.LASTNZ[i0][i] 804*49fe348cSAndroid Build Coastguard Worker nbits = lc3.spec_compute_nbits(dt, sr, 805*49fe348cSAndroid Build Coastguard Worker C.NBYTES[i0], C.X_Q[i0][i], C.LASTNZ[i0][i], 0)[0] 806*49fe348cSAndroid Build Coastguard Worker ok = ok and nbits == C.NBITS_EST[i0][i] 807*49fe348cSAndroid Build Coastguard Worker 808*49fe348cSAndroid Build Coastguard Worker g_adj = lc3.spec_adjust_gain(dt, sr, 809*49fe348cSAndroid Build Coastguard Worker C.GG_IND[i0][i], C.NBITS_EST[i0][i], C.NBITS_SPEC[i0][i], 0) 810*49fe348cSAndroid Build Coastguard Worker ok = ok and g_adj == C.GG_IND_ADJ[i0][i] - C.GG_IND[i0][i] 811*49fe348cSAndroid Build Coastguard Worker 812*49fe348cSAndroid Build Coastguard Worker if C.GG_IND_ADJ[i0][i] != C.GG_IND[i0][i]: 813*49fe348cSAndroid Build Coastguard Worker 814*49fe348cSAndroid Build Coastguard Worker (x, nq) = lc3.spec_quantize(dt, sr, 815*49fe348cSAndroid Build Coastguard Worker C.GG_IND_ADJ[i0][i] + C.GG_OFF[i0][i], C.X_F[i0][i]) 816*49fe348cSAndroid Build Coastguard Worker lastnz = C.LASTNZ_REQ[i0][i] 817*49fe348cSAndroid Build Coastguard Worker x += np.select([x < 0, x > 0], np.array([ 0.375, -0.375 ])) 818*49fe348cSAndroid Build Coastguard Worker ok = ok and np.any(((np.trunc(x) - C.X_Q_REQ[i0][i])[:lastnz]) == 0) 819*49fe348cSAndroid Build Coastguard Worker 820*49fe348cSAndroid Build Coastguard Worker tns_data = { 821*49fe348cSAndroid Build Coastguard Worker 'nfilters' : C.NUM_TNS_FILTERS[i0][i], 822*49fe348cSAndroid Build Coastguard Worker 'lpc_weighting' : [ True, True ], 823*49fe348cSAndroid Build Coastguard Worker 'rc_order' : [ C.RC_ORDER[i0][i][0], 0 ], 824*49fe348cSAndroid Build Coastguard Worker 'rc' : [ C.RC_I_1[i0][i] - 8, np.zeros(8, dtype = np.intc) ] 825*49fe348cSAndroid Build Coastguard Worker } 826*49fe348cSAndroid Build Coastguard Worker 827*49fe348cSAndroid Build Coastguard Worker (x, side) = lc3.spec_analyze(dt, sr, C.NBYTES[i0], 828*49fe348cSAndroid Build Coastguard Worker C.PITCH_PRESENT[i0][i], tns_data, state_c, C.X_F[i0][i]) 829*49fe348cSAndroid Build Coastguard Worker 830*49fe348cSAndroid Build Coastguard Worker xq = x + np.select([x < 0, x > 0], np.array([ 0.375, -0.375 ])) 831*49fe348cSAndroid Build Coastguard Worker xq = np.trunc(xq) 832*49fe348cSAndroid Build Coastguard Worker 833*49fe348cSAndroid Build Coastguard Worker ok = ok and np.abs(state_c['nbits_off'] - C.NBITS_OFFSET[i0][i]) < 1e-5 834*49fe348cSAndroid Build Coastguard Worker if C.GG_IND_ADJ[i0][i] != C.GG_IND[i0][i]: 835*49fe348cSAndroid Build Coastguard Worker xq = C.X_Q_REQ[i0][i] 836*49fe348cSAndroid Build Coastguard Worker nq = C.LASTNZ_REQ[i0][i] 837*49fe348cSAndroid Build Coastguard Worker ok = ok and side['g_idx'] == C.GG_IND_ADJ[i0][i] 838*49fe348cSAndroid Build Coastguard Worker ok = ok and side['nq'] == nq 839*49fe348cSAndroid Build Coastguard Worker ok = ok and np.any(((xq[:nq] - xq[:nq])) == 0) 840*49fe348cSAndroid Build Coastguard Worker else: 841*49fe348cSAndroid Build Coastguard Worker xq = C.X_Q[i0][i] 842*49fe348cSAndroid Build Coastguard Worker nq = C.LASTNZ[i0][i] 843*49fe348cSAndroid Build Coastguard Worker ok = ok and side['g_idx'] == C.GG_IND[i0][i] 844*49fe348cSAndroid Build Coastguard Worker ok = ok and side['nq'] == nq 845*49fe348cSAndroid Build Coastguard Worker ok = ok and np.any((xq[:nq] - C.X_Q[i0][i][:nq]) == 0) 846*49fe348cSAndroid Build Coastguard Worker ok = ok and side['lsb_mode'] == C.LSB_MODE[i0][i] 847*49fe348cSAndroid Build Coastguard Worker 848*49fe348cSAndroid Build Coastguard Worker gg = C.GG[i0][i] if C.GG_IND_ADJ[i0][i] == C.GG_IND[i0][i] \ 849*49fe348cSAndroid Build Coastguard Worker else C.GG_ADJ[i0][i] 850*49fe348cSAndroid Build Coastguard Worker 851*49fe348cSAndroid Build Coastguard Worker nf = lc3.spec_estimate_noise( 852*49fe348cSAndroid Build Coastguard Worker dt, C.P_BW[i0][i], False, C.X_F[i0][i] / gg, nq) 853*49fe348cSAndroid Build Coastguard Worker ok = ok and nf == C.F_NF[i0][i] 854*49fe348cSAndroid Build Coastguard Worker 855*49fe348cSAndroid Build Coastguard Worker return ok 856*49fe348cSAndroid Build Coastguard Worker 857*49fe348cSAndroid Build Coastguard Workerdef check(): 858*49fe348cSAndroid Build Coastguard Worker 859*49fe348cSAndroid Build Coastguard Worker rng = np.random.default_rng(1234) 860*49fe348cSAndroid Build Coastguard Worker ok = True 861*49fe348cSAndroid Build Coastguard Worker 862*49fe348cSAndroid Build Coastguard Worker for dt in range(T.NUM_DT): 863*49fe348cSAndroid Build Coastguard Worker for sr in range(T.SRATE_8K, T.SRATE_48K + 1): 864*49fe348cSAndroid Build Coastguard Worker ok = ok and check_estimate_gain(rng, dt, sr) 865*49fe348cSAndroid Build Coastguard Worker ok = ok and check_quantization(rng, dt, sr) 866*49fe348cSAndroid Build Coastguard Worker ok = ok and check_compute_nbits(rng, dt, sr) 867*49fe348cSAndroid Build Coastguard Worker ok = ok and check_adjust_gain(rng, dt, sr) 868*49fe348cSAndroid Build Coastguard Worker ok = ok and check_unit(rng, dt, sr) 869*49fe348cSAndroid Build Coastguard Worker ok = ok and check_noise(rng, dt, sr) 870*49fe348cSAndroid Build Coastguard Worker 871*49fe348cSAndroid Build Coastguard Worker for dt in ( T.DT_2M5, T.DT_5M, T.DT_10M ): 872*49fe348cSAndroid Build Coastguard Worker for sr in ( T.SRATE_48K_HR, T.SRATE_96K_HR ): 873*49fe348cSAndroid Build Coastguard Worker ok = ok and check_estimate_gain(rng, dt, sr) 874*49fe348cSAndroid Build Coastguard Worker ok = ok and check_quantization(rng, dt, sr) 875*49fe348cSAndroid Build Coastguard Worker ok = ok and check_compute_nbits(rng, dt, sr) 876*49fe348cSAndroid Build Coastguard Worker ok = ok and check_adjust_gain(rng, dt, sr) 877*49fe348cSAndroid Build Coastguard Worker ok = ok and check_unit(rng, dt, sr) 878*49fe348cSAndroid Build Coastguard Worker ok = ok and check_noise(rng, dt, sr, True) 879*49fe348cSAndroid Build Coastguard Worker 880*49fe348cSAndroid Build Coastguard Worker for dt in ( T.DT_7M5, T.DT_10M ): 881*49fe348cSAndroid Build Coastguard Worker ok = ok and check_appendix_c(dt) 882*49fe348cSAndroid Build Coastguard Worker 883*49fe348cSAndroid Build Coastguard Worker return ok 884*49fe348cSAndroid Build Coastguard Worker 885*49fe348cSAndroid Build Coastguard Worker### ------------------------------------------------------------------------ ### 886