def __init__(self, filename): # read entire file into memory f = open(filename, "rb") file_data = f.read() f.close() self.bitbfr = BitBfr(file_data) # info needed block to block self.hybrid_prevblck = zeros((2, 32, 18), dtype=double) self.sbs_bufOffset = [64, 64] self.sbs_buf = zeros((2, 1024), dtype=double) self.sbs_filter = zeros((64, 32), dtype=double) self.pcm = [[], []] self.first_frame = True self.init_tables()
class pyMP3: def __init__(self, filename): # read entire file into memory f = open(filename, "rb") file_data = f.read() f.close() self.bitbfr = BitBfr(file_data) # info needed block to block self.hybrid_prevblck = zeros((2, 32, 18), dtype=double) self.sbs_bufOffset = [64, 64] self.sbs_buf = zeros((2, 1024), dtype=double) self.sbs_filter = zeros((64, 32), dtype=double) self.pcm = [[], []] self.first_frame = True self.init_tables() def init_tables(self): #=======MDCT====== self.mdct_win = zeros((4, 36), dtype=double) self.mdct_cos_tbl = zeros((4 * 36), dtype=double) self.mdct_cos_tbl_2 = zeros((36, 18), dtype=double) # block type 0 for i in range(36): self.mdct_win[0][i] = sin(PI / 36 * (i + 0.5)) # block type 1 for i in range(18): self.mdct_win[1][i] = sin(PI / 36 * (i + 0.5)) for i in range(18, 24): self.mdct_win[1][i] = 1.0 for i in range(24, 30): self.mdct_win[1][i] = sin(PI / 12 * (i + 0.5 - 18)) for i in range(30, 36): self.mdct_win[1][i] = 0.0 # block type 2 for i in range(12): self.mdct_win[2][i] = sin(PI / 12 * (i + 0.5)) for i in range(12, 36): self.mdct_win[2][i] = 0.0 # block type 3 for i in range(6): self.mdct_win[3][i] = 0.0 for i in range(6, 12): self.mdct_win[3][i] = sin(PI / 12 * (i + 0.5 - 6)) for i in range(12, 18): self.mdct_win[3][i] = 1.0 for i in range(18, 36): self.mdct_win[3][i] = sin(PI / 36 * (i + 0.5)) for i in range(4 * 36): self.mdct_cos_tbl[i] = cos(PI / (2 * 36) * i) N = 36 for p in range(N): for m in range(N // 2): self.mdct_cos_tbl_2[p][m] = self.mdct_cos_tbl[( (2 * p + 1 + N / 2) * (2 * m + 1)) % (4 * 36)] #======SUB BAND SYNTHESIS=== # create filter for i in range(64): for k in range(32): self.sbs_filter[i][k] = 1e9 * \ cos(((PI / 64 * i + PI / 4) * (2 * k + 1))) if (self.sbs_filter[i][k] >= 0): dummy, self.sbs_filter[i][k] = modf(self.sbs_filter[i][k] + 0.5) else: dummy, self.sbs_filter[i][k] = modf(self.sbs_filter[i][k] - 0.5) self.sbs_filter[i][k] *= 1e-9 def decode(self, filename): print("Starting Decode") self.frame_num = 0 while (self.bitbfr.bits_left() > 0): self.cur_frame = mp3_frame() st = time.time() # Decode the data self.find_next_syncword() self.decode_frame_header() self.decode_CRC() self.decode_side_info() self.decode_main_info() # Process the Data self.dequantize_samples() self.process_stereo() self.reorder_samples() self.antialias_samples() self.hybrid_synthesis() self.polyphase_synthesis() # timing tt = (time.time() - st) * 1000 if (tt == 0): tt = 1 print("frame #%d - %.1f %.3fx" % (self.frame_num + 1, tt, 26 / tt)) self.frame_num += 1 if (self.frame_num == frame_cnt_limit): break self.write_wav(filename) def write_wav(self, filename): file_sz = len(self.pcm[0]) * 2 + 36 n_channels = 1 smpl_rate = 44100 f = open(filename, "wb") f.write("RIFF") f.write(pack("<i", file_sz)) f.write("WAVE") f.write("fmt ") f.write(pack("<i", 16)) f.write(pack("<h", 1)) f.write(pack("<h", n_channels)) f.write(pack("<i", smpl_rate)) f.write(pack("<i", smpl_rate * n_channels * 2)) f.write(pack("<h", n_channels * 2)) f.write(pack("<h", 16)) f.write("data") f.write(pack("<i", file_sz - 36)) for x in self.pcm[0]: f.write(pack("<h", x)) f.close() def dequantize_samples(self): if (dbg_output and False): for gr in range(2): for sb in range(SBLIMIT): for ss in range(SSLIMIT): print("dq", self.frame_num, gr, sb, ss, self.cur_frame.main_data.q_vals[gr][0][sb][ss]) for gr in range(2): for ch in range(self.cur_frame.hdr.n_channels): cb = 0 # get initial boundary if (self.cur_frame.side_info.window_switching_flag[ch][gr] and (self.cur_frame.side_info.block_type[ch][gr] == 2)): if (self.cur_frame.side_info.mixed_block_flag[ch][gr]): # mixed (long first) next_cb_boundary = sfBandIndex_l[ self.cur_frame.hdr.smpl_rate][1] else: # pure short next_cb_boundary = sfBandIndex_s[ self.cur_frame.hdr.smpl_rate][1] * 3 cb_width = sfBandIndex_s[ self.cur_frame.hdr.smpl_rate][1] cb_begin = 0 else: # long blocks next_cb_boundary = sfBandIndex_l[ self.cur_frame.hdr.smpl_rate][1] # apply formula per block type */ for sb in range(SBLIMIT): for ss in range(SSLIMIT): if ((sb * 18) + ss == next_cb_boundary): if (self.cur_frame.side_info. window_switching_flag[ch][gr] and (self.cur_frame.side_info.block_type[ch][gr] == 2)): if (self.cur_frame.side_info. mixed_block_flag[ch][gr]): if (((sb * 18) + ss) == sfBandIndex_l[ self.cur_frame.hdr.smpl_rate][8]): next_cb_boundary = sfBandIndex_s[ self.cur_frame.hdr. smpl_rate][4] * 3 cb = 3 cb_width = sfBandIndex_s[ self.cur_frame.hdr.smpl_rate][ cb + 1] - sfBandIndex_s[ self.cur_frame.hdr. smpl_rate][cb] cb_begin = sfBandIndex_s[ self.cur_frame.hdr. smpl_rate][cb] * 3 elif (((sb * 18) + ss) < sfBandIndex_l[ self.cur_frame.hdr.smpl_rate][8]): cb += 1 next_cb_boundary = sfBandIndex_l[ self.cur_frame.hdr.smpl_rate][cb + 1] else: cb += 1 next_cb_boundary = sfBandIndex_s[ self.cur_frame.hdr.smpl_rate][ cb + 1] * 3 cb_width = sfBandIndex_s[ self.cur_frame.hdr.smpl_rate][ cb + 1] - sfBandIndex_s[ self.cur_frame.hdr. smpl_rate][cb] cb_begin = sfBandIndex_s[ self.cur_frame.hdr. smpl_rate][cb] * 3 else: cb += 1 next_cb_boundary = sfBandIndex_s[ self.cur_frame.hdr.smpl_rate][cb + 1] * 3 cb_width = sfBandIndex_s[ self.cur_frame.hdr. smpl_rate][cb + 1] - sfBandIndex_s[ self.cur_frame.hdr.smpl_rate][cb] cb_begin = sfBandIndex_s[ self.cur_frame.hdr.smpl_rate][cb] * 3 else: cb += 1 next_cb_boundary = sfBandIndex_l[ self.cur_frame.hdr.smpl_rate][cb + 1] # Compute global scaling self.cur_frame.decoded_data.dq_vals[gr][ch][sb][ ss] = pow(2.0, ( 0.25 * (self.cur_frame.side_info.global_gain[ch][gr] - 210.0))) val_a = self.cur_frame.decoded_data.dq_vals[gr][ch][ sb][ss] # Compute block dependent scaling if (self.cur_frame.side_info.window_switching_flag[ch] [gr] and (((self.cur_frame.side_info.block_type[ch][gr] == 2) and (self.cur_frame.side_info.mixed_block_flag[ch] [gr] == 0)) or ((self.cur_frame.side_info.block_type[ch][gr] == 2) and self.cur_frame.side_info.mixed_block_flag[ch][gr] and (sb >= 2)))): # SHORT self.cur_frame.decoded_data.dq_vals[gr][ch][sb][ ss] *= pow( 2.0, 0.25 * -8.0 * self.cur_frame.side_info.subblock_gain[ch] [gr][(((sb * 18) + ss) - cb_begin) / cb_width]) val_a2 = self.cur_frame.decoded_data.dq_vals[gr][ ch][sb][ss] self.cur_frame.decoded_data.dq_vals[gr][ch][sb][ ss] *= pow( 2.0, 0.25 * -2.0 * (1.0 + self.cur_frame.side_info. scalefac_scale[ch][gr]) * self.cur_frame.main_data.scalefac_s[ch][gr] [(((sb * 18) + ss) - cb_begin) / cb_width][cb]) val_a3 = self.cur_frame.decoded_data.dq_vals[gr][ ch][sb][ss] else: # LONG block types 0,1,3 & 1st 2 subbands of # switched blocks self.cur_frame.decoded_data.dq_vals[gr][ch][sb][ ss] *= pow( 2.0, -0.5 * (1.0 + self.cur_frame.side_info. scalefac_scale[ch][gr]) * (self.cur_frame.main_data.scalefac_l[ch] [gr][cb] + self.cur_frame.side_info.preflag[ch][gr] * pretab[cb])) val_b = self.cur_frame.decoded_data.dq_vals[gr][ch][ sb][ss] val_b2 = self.cur_frame.side_info.scalefac_scale[ch][ gr] val_b3 = self.cur_frame.main_data.scalefac_l[ch][gr][ cb] # Scale quantized value self.cur_frame.decoded_data.dq_vals[gr][ch][sb][ ss] *= pow( abs(self.cur_frame.main_data.q_vals[gr][ch][sb] [ss]), (4.0 / 3.0)) if (self.cur_frame.main_data.q_vals[gr][ch][sb][ss] < 0): self.cur_frame.decoded_data.dq_vals[gr][ch][sb][ ss] = -self.cur_frame.decoded_data.dq_vals[gr][ ch][sb][ss] val_c = self.cur_frame.decoded_data.dq_vals[gr][ch][ sb][ss] def process_stereo(self): has_intensity_stereo = (self.cur_frame.hdr.mode_extention & INTENSITY_STEREO_BIT) has_mid_side_stereo = (self.cur_frame.hdr.mode_extention & MID_SIDE_STEREO_BIT) lr = self.cur_frame.decoded_data.lr_vals dq_vals = self.cur_frame.decoded_data.dq_vals if (dbg_output and False): for gr in range(2): for sb in range(SBLIMIT): for ss in range(SSLIMIT): print("s", self.frame_num, gr, sb, ss, dq_vals[gr][0][sb][ss]) for gr in range(2): if (self.cur_frame.hdr.n_channels == 2): is_pos = [7 for dummy in range(576)] if (has_intensity_stereo): is_ratio = self.process_intensity_stereo(gr, is_pos) for sb in range(SBLIMIT): for ss in range(SSLIMIT): i = (sb * 18) + ss if (is_pos[i] == 7): if (has_mid_side_stereo): lr[gr][0][sb][ss] = ( dq_vals[gr][0][sb][ss] + dq_vals[gr][1][sb][ss]) / 1.41421356 lr[gr][1][sb][ss] = ( dq_vals[gr][0][sb][ss] - dq_vals[gr][1][sb][ss]) / 1.41421356 else: lr[gr][0][sb][ss] = dq_vals[gr][0][sb][ss] lr[gr][1][sb][ss] = dq_vals[gr][1][sb][ss] elif (has_intensity_stereo): lr[gr][0][sb][ss] = dq_vals[gr][0][sb][ss] * ( is_ratio[i] / (1 + is_ratio[i])) lr[gr][1][sb][ss] = dq_vals[gr][0][sb][ss] * ( 1 / (1 + is_ratio[i])) else: print("Stereo - Error") else: for sb in range(SBLIMIT): for ss in range(SSLIMIT): lr[gr][0][sb][ss] = dq_vals[gr][0][sb][ss] def process_intensity_stereo(self, gr, is_pos): ch = 0 if (self.cur_frame.side_info.window_switching_flag[ch][gr] and (self.cur_frame.side_info.block_type[ch][gr] == 2)): is_ratio = self.process_intensity_stereo__non_standard_window( gr, is_pos) else: is_ratio = self.process_intensity_stereo__standard_window( gr, is_pos) return is_ratio def process_intensity_stereo__standard_window(self, gr, is_pos): smpl_rate = self.cur_frame.hdr.smpl_rate i = 31 ss = 17 sb = 0 while (i >= 0): if (self.decoded_data.dq_vals[1][i][ss] != 0.0): sb = i * 18 + ss i = -1 else: ss -= 1 if (ss < 0): i -= 1 ss = 17 i = 0 while (sfBandIndex_l[smpl_rate][i] <= sb): i += 1 sfb = i i = sfBandIndex_l[smpl_rate][i] for sfb in range(sfb, 21): sb = sfBandIndex_l[smpl_rate][sfb + 1] - sfBandIndex_l[smpl_rate][sfb] for sb in range(sb, 0, -1): is_pos[i] = self.cur_frame.main_data.scalefac_l[1][gr][sfb] if (is_pos[i] != 7): is_ratio[i] = tan(is_pos[i] * (PI / 12)) i += 1 sfb = sfBandIndex_l[smpl_rate][20] for sb in range(576 - sfBandIndex_l[smpl_rate][21], 0, -1): is_pos[i] = is_pos[sfb] is_ratio[i] = is_ratio[sfb] i += 1 return is_ratio def process_intensity_stereo__non_standard_window(self, gr, is_pos): ch = 0 smpl_rate = self.cur_frame.hdr.smpl_rate if (self.cur_frame.side_info.mixed_block_flag[ch][gr]): max_sfb = 0 for j in range(3): sfbcnt = 2 for sfb in range(12, 2, -1): lines = sfBandIndex_s[smpl_rate][ sfb + 1] - sfBandIndex_s[smpl_rate][sfb] i = 3 * sfBandIndex_s[sfreq][sfb] + (j + 1) * lines - 1 while (lines > 0): if (self.decoded_data.dq_vals[1][i / SSLIMIT][i % SSLIMIT] != 0.0): sfbcnt = sfb sfb = -10 lines = -10 lines -= 1 i -= 1 sfb = sfbcnt + 1 if (sfb > max_sfb): max_sfb = sfb while (sfb < 12): sb = sfBandIndex_s[smpl_rate][ sfb + 1] - sfBandIndex_s[sfreq][sfb] i = 3 * sfBandIndex_s[smpl_rate][sfb] + j * sb for sb in range(sb, 0, -1): is_pos[i] = self.cur_frame.main_data.scalefac_s[1][gr][ j][sfb] if (is_pos[i] != 7): is_ratio[i] = tan(is_pos[i] * (PI / 12)) i += 1 sfb += 1 sb = sfBandIndex_s[smpl_rate][11] - sfBandIndex_s[smpl_rate][10] sfb = 3 * sfBandIndex_s[smpl_rate].s[10] + j * sb sb = sfBandIndex_s[smpl_rate][12] - sfBandIndex_s[smpl_rate][11] i = 3 * sfBandIndex_s[smpl_rate][11] + j * sb for sb in range(sb, 0, -1): is_pos[i] = is_pos[sfb] is_ratio[i] = is_ratio[sfb] i += 1 if (max_sfb <= 3): i = 2 ss = 17 sb = -1 while (i >= 0): if (self.decoded_data.dq_vals[1][i][ss] != 0.0): sb = i * 18 + ss i = -1 else: ss -= 1 if (ss < 0): i -= 1 ss = 17 i = 0 while (sfBandIndex_l[smpl_rate][i] <= sb): i += 1 sfb = i i = sfBandIndex_l[smpl_rate][i] for sfb in range(sfb, 8): sb = sfBandIndex_l[smpl_rate][ sfb + 1] - sfBandIndex_l[sfreq][sfb] for sb in range(sb, 0, -1): is_pos[i] = self.cur_frame.main_data.scalefac_l[1][gr][ sfb] if (is_pos[i] != 7): is_ratio[i] = tan(is_pos[i] * (PI / 12)) i += 1 else: for j in range(3): sfbcnt = -1 for sfb in range(12, -1, -1): lines = sfBandIndex_s[smpl_rate][ sfb + 1] - sfBandIndex_s[smpl_rate][sfb] i = 3 * sfBandIndex_s[smpl_rate][sfb] + (j + 1) * lines - 1 while (lines > 0): if (self.decoded_data.dq_vals[1][i / SSLIMIT][i % SSLIMIT] != 0.0): sfbcnt = sfb sfb = -10 lines = -10 lines -= 1 i -= 1 sfb = sfbcnt + 1 while (sfb < 12): sb = sfBandIndex_s[smpl_rate][ sfb + 1] - sfBandIndex_s[smpl_rate][sfb] i = 3 * sfBandIndex_s[smpl_rate][sfb] + j * sb for sb in range(sb, 0, -1): is_pos[i] = self.cur_frame.main_data.scalefac_s[1][gr][j][ sfb] if (is_pos[i] != 7): is_ratio[i] = tan(is_pos[i] * (PI / 12)) i += 1 sfb += 1 sb = sfBandIndex_s[smpl_rate][11] - sfBandIndex_s[sfreq][10] sfb = 3 * sfBandIndex_s[smpl_rate][10] + j * sb sb = sfBandIndex_s[smpl_rate][12] - sfBandIndex_s[sfreq][11] i = 3 * sfBandIndex_s[smpl_rate][11] + j * sb for sb in range(sb, -1, -1): is_pos[i] = is_pos[sfb] is_ratio[i] = is_ratio[sfb] i += 1 return is_ratio def reorder_samples(self): smpl_rate = self.cur_frame.hdr.smpl_rate lr = self.cur_frame.decoded_data.lr_vals ro = self.cur_frame.decoded_data.reordered_vals if (dbg_output and False): for gr in range(2): for sb in range(SBLIMIT): for ss in range(SSLIMIT): print("ro", self.frame_num, gr, sb, ss, lr[gr][0][sb][ss]) for gr in range(2): for ch in range(self.cur_frame.hdr.n_channels): if (self.cur_frame.side_info.window_switching_flag[ch][gr] and (self.cur_frame.side_info.block_type[ch][gr] == 2)): if (self.cur_frame.side_info.mixed_block_flag[ch][gr]): # NO REORDER FOR LOW 2 SUBBANDS for sb in range(2): for ss in range(SSLIMIT): ro[gr][ch][sb][ss] = lr[gr][ch][sb][ss] # REORDERING FOR REST SWITCHED SHORT sfb_start = sfBandIndex_s[smpl_rate][3] sfb_lines = sfBandIndex_s[smpl_rate][4] - sfb_start for sfb in range(3, 13): for window in range(3): for freq in range(sfb_lines): src_line = sfb_start * 3 + \ window * sfb_lines + freq des_line = (sfb_start * 3) + window + (freq * 3) ro[gr][ch][des_line / SSLIMIT][des_line % SSLIMIT] = lr[gr][ch][ src_line / SSLIMIT][src_line % SSLIMIT] sfb_start = sfBandIndex_s[smpl_rate][sfb] sfb_lines = sfBandIndex_s[smpl_rate][sfb + 1] - sfb_start else: # pure short sfb_start = 0 sfb_lines = sfBandIndex_s[smpl_rate][1] for sfb in range(13): for window in range(3): for freq in range(sfb_lines): src_line = sfb_start * 3 + \ window * sfb_lines + freq des_line = (sfb_start * 3) + window + (freq * 3) ro[gr][ch][des_line / SSLIMIT][des_line % SSLIMIT] = lr[gr][ch][ src_line / SSLIMIT][src_line % SSLIMIT] sfb_start = sfBandIndex_s[smpl_rate][sfb] sfb_lines = sfBandIndex_s[smpl_rate][sfb + 1] - sfb_start else: # long blocks */ for sb in range(SBLIMIT): for ss in range(SSLIMIT): ro[gr][ch][sb][ss] = lr[gr][ch][sb][ss] def antialias_samples(self): cs = [1.0 / sqrt(1.0 + ci * ci) for ci in antialias_Ci] ca = [ci / sqrt(1.0 + ci * ci) for ci in antialias_Ci] ro = self.cur_frame.decoded_data.reordered_vals aa = self.cur_frame.decoded_data.antialiased_vals if (dbg_output and False): for gr in range(2): for sb in range(SBLIMIT): for ss in range(SSLIMIT): print("aa", self.frame_num, gr, sb, ss, ro[gr][0][sb][ss]) for gr in range(2): for ch in range(self.cur_frame.hdr.n_channels): for sb in range(SBLIMIT): for ss in range(SSLIMIT): aa[gr][ch][sb][ss] = ro[gr][ch][sb][ss] if ((self.cur_frame.side_info.window_switching_flag[ch][gr] and (self.cur_frame.side_info.block_type[ch][gr] == 2)) and (not self.cur_frame.side_info.mixed_block_flag[ch][gr])): continue if (self.cur_frame.side_info.window_switching_flag[ch][gr] and self.cur_frame.side_info.mixed_block_flag[ch][gr] and (self.cur_frame.side_info.block_type[ch][gr] == 2)): sblim = 1 else: sblim = SBLIMIT - 1 # 31 alias-reduction operations between each pair of sub-bands # with 8 butterflies between each pair for sb in range(sblim): for ss in range(8): bu = ro[gr][ch][sb][17 - ss] bd = ro[gr][ch][sb + 1][ss] aa[gr][ch][sb][17 - ss] = (bu * cs[ss]) - (bd * ca[ss]) aa[gr][ch][sb + 1][ss] = (bd * cs[ss]) + (bu * ca[ss]) def hybrid_synthesis(self): data_in = self.cur_frame.decoded_data.antialiased_vals data_out = self.cur_frame.decoded_data.hybrid_vals if (dbg_output and False): for gr in range(2): for sb in range(SBLIMIT): for ss in range(SSLIMIT): print( "hs", self.frame_num, gr, sb, ss, self.cur_frame.decoded_data.antialiased_vals[gr][0] [sb][ss]) for gr in range(2): for ch in range(self.cur_frame.hdr.n_channels): for sb in range(SBLIMIT): if (self.cur_frame.side_info.window_switching_flag[ch][gr] and self.cur_frame.side_info.mixed_block_flag[ch][gr] and sb < 2): blk_type = 0 else: blk_type = self.cur_frame.side_info.block_type[ch][gr] rawout = self.inv_mdct(data_in[gr][ch][sb], blk_type) # overlap addition for ss in range(SSLIMIT): data_out[gr][ch][sb][ ss] = rawout[ss] + self.hybrid_prevblck[ch][sb][ss] self.hybrid_prevblck[ch][sb][ss] = rawout[ss + 18] def inv_mdct(self, data_in, blk_type): out = zeros((36), dtype=double) if (blk_type == 2): tmp = zeros((12), dtype=double) N = 12 for i in range(3): for p in range(N): total = 0.0 for m in range(N / 2): total += data_in[i + 3 * m] * \ cos(PI / (2 * N) * (2 * p + 1 + N / 2) * (2 * m + 1)) tmp[p] = total * self.mdct_win[blk_type][p] for p in range(N): out[6 * i + p + 6] += tmp[p] else: cos_tbl = self.mdct_cos_tbl_2 win = self.mdct_win[blk_type] for p in range(36): out[p] = sum(data_in * cos_tbl[p]) * win[p] return out def polyphase_synthesis(self): data_in = self.cur_frame.decoded_data.hybrid_vals data_out = self.pcm bfr = zeros((SBLIMIT), dtype=double) if (dbg_output and False): for gr in range(2): for sb in range(SBLIMIT): for ss in range(SSLIMIT): print("pps %d %d %d %d %.3e" % (self.frame_num, gr, sb, ss, self.cur_frame. decoded_data.hybrid_vals[gr][0][sb][ss])) for gr in range(2): for ch in range(self.cur_frame.hdr.n_channels): # frequency inversion for ss in range(18): for sb in range(SBLIMIT): if ((ss % 2) and (sb % 2)): self.cur_frame.decoded_data.hybrid_vals[gr][ch][sb][ ss] = -self.cur_frame.decoded_data.hybrid_vals[ gr][ch][sb][ss] # subBand synthesis for ss in range(18): for sb in range(SBLIMIT): bfr[sb] = data_in[gr][ch][sb][ss] pcm_bfr = self.subBandSynthesis(bfr, ch) # copy to final output data_out[ch].extend(pcm_bfr) def subBandSynthesis(self, data_in, ch): pcm = zeros((32), dtype=int32) self.sbs_buf[ch] = roll(self.sbs_buf[ch], 64) # init bfr = self.sbs_buf[ch] # fir filter for i in range(64): bfr[i] = sum(data_in * self.sbs_filter[i]) # window output for j in range(32): total = 0 for i in range(16): k = j + i * 32 idx = (k + (((i + 1) >> 1) * 64)) total += sbs_window[k] * bfr[idx] # clip pcm[j] = min(max(total * SCALE, -SCALE), SCALE - 1) return pcm def decode_main_info(self): for gr in range(2): for ch in range(self.cur_frame.hdr.n_channels): # Get scale factors part2_start = self.bitbfr.get_pos() if (self.cur_frame.side_info.window_switching_flag[ch][gr] == 1 and self.cur_frame.side_info.block_type[ch][gr] == 2): if (self.cur_frame.side_info.mixed_block_flag[ch][gr]): # mixed blocks print("mixed scale blocks not supported yet") else: # short blocks for i in range(2): for sfb in range(sfbtable_s[i], sfbtable_s[i + 1]): for window in range(3): self.cur_frame.main_data.scalefac_s[ch][gr][ window][sfb] = self.bitbfr.read_bits( slen[i][self.cur_frame.side_info. scalefac_compress[ch][gr]]) sfb = 12 for window in range(3): self.cur_frame.main_data.scalefac_s[ch][gr][ window][sfb] = 0 else: # long blocks for i in range(4): if ((self.cur_frame.side_info.scfsi[ch][i] == 0) or (gr == 0)): for sfb in range(sfbtable_l[i], sfbtable_l[i + 1]): if (i < 2): k = 0 else: k = 1 self.cur_frame.main_data.scalefac_l[ch][gr][ sfb] = self.bitbfr.read_bits( slen[k][self.cur_frame.side_info. scalefac_compress[ch][gr]]) self.cur_frame.main_data.scalefac_l[ch][gr][22] = 0 self.decode_main_data_huffman(ch, gr, part2_start) def decode_main_data_huffman(self, ch, gr, part2_start): # calculate region boundries if (self.cur_frame.side_info.window_switching_flag[ch][gr] == 1 and self.cur_frame.side_info.block_type[ch][gr] == 2): # short block region1Start = 36 region2Start = 576 else: # long block region1Start = sfBandIndex_l[self.cur_frame.hdr.smpl_rate][ self.cur_frame.side_info.region0_count[ch][gr] + 1] region2Start = sfBandIndex_l[self.cur_frame.hdr.smpl_rate][ self.cur_frame.side_info.region0_count[ch][gr] + self.cur_frame.side_info.region1_count[ch][gr] + 2] # read big value area for i in range(0, self.cur_frame.side_info.big_values[ch][gr] * 2, 2): if (i < region1Start): ht_idx = self.cur_frame.side_info.table_select[ch][gr][0] elif (i < region2Start): ht_idx = self.cur_frame.side_info.table_select[ch][gr][1] else: ht_idx = self.cur_frame.side_info.table_select[ch][gr][2] ht = ht_list[ht_idx] v, w, x, y = self.huffman_decoder(ht) self.cur_frame.main_data.q_vals[gr][ch][i / SSLIMIT][i % SSLIMIT] = x self.cur_frame.main_data.q_vals[gr][ch][(i + 1) / SSLIMIT][(i + 1) % SSLIMIT] = y # read count1 area idx = self.cur_frame.side_info.big_values[ch][gr] * 2 # 32 is offset to count1 tables ht = ht_list[self.cur_frame.side_info.count1table_select[ch][gr] + 32] while ( (self.bitbfr.get_pos() < (part2_start + self.cur_frame.side_info.part2_3_length[ch][gr])) and (idx < SBLIMIT * SSLIMIT)): v, w, x, y = self.huffman_decoder(ht) self.cur_frame.main_data.q_vals[gr][ch][idx / SSLIMIT][idx % SSLIMIT] = v self.cur_frame.main_data.q_vals[gr][ch][(idx + 1) / SSLIMIT][(idx + 1) % SSLIMIT] = w self.cur_frame.main_data.q_vals[gr][ch][(idx + 2) / SSLIMIT][(idx + 2) % SSLIMIT] = x self.cur_frame.main_data.q_vals[gr][ch][(idx + 3) / SSLIMIT][(idx + 3) % SSLIMIT] = y idx += 4 # the rest are zeros def huffman_decoder(self, ht): MXOFF = 250 v = w = x = y = 0 # check for empty tree if (ht.treelen == 0): return (0, 0, 0, 0) # run through huffman tree success = False pos = 0 nbits = 0 while (pos < ht.treelen and nbits < 32): # check for end of tree if (ht.values[pos][0] == 0): x = ht.values[pos][1] >> 4 y = ht.values[pos][1] & 0xf success = True break # get more bits to transverse tree bit = self.bitbfr.read_bits(1) while (ht.values[pos][bit] >= MXOFF): pos += ht.values[pos][bit] pos += ht.values[pos][bit] nbits += 1 if (not success): print("Failure during huffman decode") return (0, 0, 0, 0) # read sign bits if (ht.tbl_type == "quad"): v = (y >> 3) & 1 w = (y >> 2) & 1 x = (y >> 1) & 1 y = y & 1 if (v != 0): if (self.bitbfr.read_bits(1)): v = -v if (w != 0): if (self.bitbfr.read_bits(1)): w = -w if (x != 0): if (self.bitbfr.read_bits(1)): x = -x if (y != 0): if (self.bitbfr.read_bits(1)): y = -y else: # process escape encodings if (ht.linbits > 0): if ((ht.xlen - 1) == x): x += self.bitbfr.read_bits(ht.linbits) if (x != 0): if (self.bitbfr.read_bits(1)): x = -x if (ht.linbits > 0): if ((ht.ylen - 1) == y): y += self.bitbfr.read_bits(ht.linbits) if (y != 0): if (self.bitbfr.read_bits(1)): y = -y return (v, w, x, y) def decode_side_info(self): self.cur_frame.side_info.main_data_begin = self.bitbfr.read_bits(9) if (self.cur_frame.side_info.main_data_begin != 0): print("Error - dont support bitreservoir yet") if (self.cur_frame.hdr.n_channels == 1): self.cur_frame.side_info.private_bits = self.bitbfr.read_bits(5) else: self.cur_frame.side_info.private_bits = self.bitbfr.read_bits(3) for ch in range(self.cur_frame.hdr.n_channels): for i in range(4): self.cur_frame.side_info.scfsi[ch][i] = self.bitbfr.read_bits( 1) for gr in range(2): for ch in range(self.cur_frame.hdr.n_channels): self.cur_frame.side_info.part2_3_length[ch][ gr] = self.bitbfr.read_bits(12) self.cur_frame.side_info.big_values[ch][ gr] = self.bitbfr.read_bits(9) self.cur_frame.side_info.global_gain[ch][ gr] = self.bitbfr.read_bits(8) self.cur_frame.side_info.scalefac_compress[ch][ gr] = self.bitbfr.read_bits(4) self.cur_frame.side_info.window_switching_flag[ch][ gr] = self.bitbfr.read_bits(1) if (self.cur_frame.side_info.window_switching_flag[ch][gr]): self.cur_frame.side_info.block_type[ch][ gr] = self.bitbfr.read_bits(2) self.cur_frame.side_info.mixed_block_flag[ch][ gr] = self.bitbfr.read_bits(1) for i in range(2): self.cur_frame.side_info.table_select[ch][gr][ i] = self.bitbfr.read_bits(5) for i in range(3): self.cur_frame.side_info.subblock_gain[ch][gr][ i] = self.bitbfr.read_bits(3) if (self.cur_frame.side_info.block_type[ch][gr] == 2 and self.cur_frame.side_info.mixed_block_flag[ch][gr] == 0): self.cur_frame.side_info.region0_count[ch][gr] = 8 else: self.cur_frame.side_info.region0_count[ch][gr] = 7 self.cur_frame.side_info.region1_count[ch][ gr] = 20 - self.cur_frame.side_info.region0_count[ch][ gr] else: for i in range(3): self.cur_frame.side_info.table_select[ch][gr][ i] = self.bitbfr.read_bits(5) self.cur_frame.side_info.region0_count[ch][ gr] = self.bitbfr.read_bits(4) self.cur_frame.side_info.region1_count[ch][ gr] = self.bitbfr.read_bits(3) self.cur_frame.side_info.block_type[ch][gr] = 0 self.cur_frame.side_info.preflag[ch][ gr] = self.bitbfr.read_bits(1) self.cur_frame.side_info.scalefac_scale[ch][ gr] = self.bitbfr.read_bits(1) self.cur_frame.side_info.count1table_select[ch][ gr] = self.bitbfr.read_bits(1) if (dbg_output): print("main_data_begin:", self.cur_frame.side_info.main_data_begin) print("privatebits:", self.cur_frame.side_info.private_bits) print("scale factor select info:", self.cur_frame.side_info.scfsi) print("part 2_3 len:", self.cur_frame.side_info.part2_3_length) print("big values:", self.cur_frame.side_info.big_values) print("global gain:", self.cur_frame.side_info.global_gain) print("scalefac_compress", self.cur_frame.side_info.scalefac_compress) print("win switch flag:", self.cur_frame.side_info.window_switching_flag) print("block type:", self.cur_frame.side_info.block_type) print("mixed block flag:", self.cur_frame.side_info.mixed_block_flag) print("table select:", self.cur_frame.side_info.table_select) print("subblock gain:", self.cur_frame.side_info.subblock_gain) print("region0_count", self.cur_frame.side_info.region0_count) print("region1_count", self.cur_frame.side_info.region1_count) print("preflag", self.cur_frame.side_info.preflag) print("scalefac_scale", self.cur_frame.side_info.scalefac_scale) print("count1table select:", self.cur_frame.side_info.count1table_select) def decode_CRC(self): if (self.cur_frame.hdr.has_CRC): crc = self.bitbfr.read_bits(16) def decode_frame_header(self): self.cur_frame.hdr.mpeg_version = mp3_hdr_ver_tbl[ self.bitbfr.read_bits(1)] self.cur_frame.hdr.layer = mp3_hdr_layer_tbl[self.bitbfr.read_bits(2)] self.cur_frame.hdr.has_CRC = not self.bitbfr.read_bits(1) self.cur_frame.hdr.bitrate = mp3_hdr_bitrate_tbl[self.bitbfr.read_bits( 4)] self.cur_frame.hdr.smpl_rate = mp3_hdr_smpl_rate_tbl[ self.bitbfr.read_bits(2)] self.cur_frame.hdr.padding = self.bitbfr.read_bits(1) self.bitbfr.read_bits(1) # private bit self.cur_frame.hdr.channel_mode = mp3_hdr_channel_mode_tbl[ self.bitbfr.read_bits(2)] self.cur_frame.hdr.mode_extention = self.bitbfr.read_bits(2) self.cur_frame.hdr.copyrighted = self.bitbfr.read_bits(1) self.cur_frame.hdr.original = self.bitbfr.read_bits(1) self.cur_frame.hdr.emphasis = mp3_hdr_emphasis_tbl[ self.bitbfr.read_bits(2)] if (self.cur_frame.hdr.channel_mode == "mono"): self.cur_frame.hdr.n_channels = 1 else: self.cur_frame.hdr.n_channels = 2 if (dbg_output): print("frame header info") print("ver:", self.cur_frame.hdr.mpeg_version) print("layer:", self.cur_frame.hdr.layer) print("has CRC:", self.cur_frame.hdr.has_CRC) print("bitrate(kps):", self.cur_frame.hdr.bitrate) print("sample rate:", self.cur_frame.hdr.smpl_rate) print("padding:", self.cur_frame.hdr.padding) print("channel mode:", self.cur_frame.hdr.channel_mode) print("n channels:", self.cur_frame.hdr.n_channels) print("mode extention:", self.cur_frame.hdr.mode_extention) print("copyrighted:", self.cur_frame.hdr.copyrighted) print("original copy:", self.cur_frame.hdr.original) print("emphasis:", self.cur_frame.hdr.emphasis) if (self.first_frame): print("bitrate(kps):", self.cur_frame.hdr.bitrate) print("sample rate:", self.cur_frame.hdr.smpl_rate) print("channel mode:", self.cur_frame.hdr.channel_mode) self.first_frame = False def find_next_syncword(self): # align to byte boundry align = self.bitbfr.get_pos() % 8 if (align != 0): self.bitbfr.read_bits(8 - align) cnt = 0 while (self.bitbfr.bits_left() > 0): b = self.bitbfr.read_bits(4) if (b == 0xf): cnt += 1 if (cnt == 3): break else: cnt = 0 if (dbg_output): print("sync found at %d" % (self.bitbfr.get_pos()))
class pyMP3: def __init__(self, filename): # read entire file into memory f = open(filename, "rb") file_data = f.read() f.close() self.bitbfr = BitBfr(file_data) # info needed block to block self.hybrid_prevblck = zeros((2, 32, 18), dtype=double) self.sbs_bufOffset = [64, 64] self.sbs_buf = zeros((2, 1024), dtype=double) self.sbs_filter = zeros((64, 32), dtype=double) self.pcm = [[], []] self.first_frame = True self.init_tables() def init_tables(self): #=======MDCT====== self.mdct_win = zeros((4, 36), dtype=double) self.mdct_cos_tbl = zeros((4 * 36), dtype=double) self.mdct_cos_tbl_2 = zeros((36, 18), dtype=double) # block type 0 for i in range(36): self.mdct_win[0][i] = sin(PI / 36 * (i + 0.5)) # block type 1 for i in range(18): self.mdct_win[1][i] = sin(PI / 36 * (i + 0.5)) for i in range(18, 24): self.mdct_win[1][i] = 1.0 for i in range(24, 30): self.mdct_win[1][i] = sin(PI / 12 * (i + 0.5 - 18)) for i in range(30, 36): self.mdct_win[1][i] = 0.0 # block type 2 for i in range(12): self.mdct_win[2][i] = sin(PI / 12 * (i + 0.5)) for i in range(12, 36): self.mdct_win[2][i] = 0.0 # block type 3 for i in range(6): self.mdct_win[3][i] = 0.0 for i in range(6, 12): self.mdct_win[3][i] = sin(PI / 12 * (i + 0.5 - 6)) for i in range(12, 18): self.mdct_win[3][i] = 1.0 for i in range(18, 36): self.mdct_win[3][i] = sin(PI / 36 * (i + 0.5)) for i in range(4 * 36): self.mdct_cos_tbl[i] = cos(PI / (2 * 36) * i) N = 36 for p in range(N): for m in range(N // 2): self.mdct_cos_tbl_2[p][m] = self.mdct_cos_tbl[ ((2 * p + 1 + N / 2) * (2 * m + 1)) % (4 * 36)] #======SUB BAND SYNTHESIS=== # create filter for i in range(64): for k in range(32): self.sbs_filter[i][k] = 1e9 * \ cos(((PI / 64 * i + PI / 4) * (2 * k + 1))) if (self.sbs_filter[i][k] >= 0): dummy, self.sbs_filter[i][k] = modf( self.sbs_filter[i][k] + 0.5) else: dummy, self.sbs_filter[i][k] = modf( self.sbs_filter[i][k] - 0.5) self.sbs_filter[i][k] *= 1e-9 def decode(self, filename): print("Starting Decode") self.frame_num = 0 while(self.bitbfr.bits_left() > 0): self.cur_frame = mp3_frame() st = time.time() # Decode the data self.find_next_syncword() self.decode_frame_header() self.decode_CRC() self.decode_side_info() self.decode_main_info() # Process the Data self.dequantize_samples() self.process_stereo() self.reorder_samples() self.antialias_samples() self.hybrid_synthesis() self.polyphase_synthesis() # timing tt = (time.time() - st) * 1000 if(tt == 0): tt = 1 print("frame #%d - %.1f %.3fx" % (self.frame_num + 1, tt, 26 / tt)) self.frame_num += 1 if(self.frame_num == frame_cnt_limit): break self.write_wav(filename) def write_wav(self, filename): file_sz = len(self.pcm[0]) * 2 + 36 n_channels = 1 smpl_rate = 44100 f = open(filename, "wb") f.write("RIFF") f.write(pack("<i", file_sz)) f.write("WAVE") f.write("fmt ") f.write(pack("<i", 16)) f.write(pack("<h", 1)) f.write(pack("<h", n_channels)) f.write(pack("<i", smpl_rate)) f.write(pack("<i", smpl_rate * n_channels * 2)) f.write(pack("<h", n_channels * 2)) f.write(pack("<h", 16)) f.write("data") f.write(pack("<i", file_sz - 36)) for x in self.pcm[0]: f.write(pack("<h", x)) f.close() def dequantize_samples(self): if(dbg_output and False): for gr in range(2): for sb in range(SBLIMIT): for ss in range(SSLIMIT): print("dq", self.frame_num, gr, sb, ss, self.cur_frame.main_data.q_vals[gr][0][sb][ss]) for gr in range(2): for ch in range(self.cur_frame.hdr.n_channels): cb = 0 # get initial boundary if (self.cur_frame.side_info.window_switching_flag[ch][gr] and (self.cur_frame.side_info.block_type[ch][gr] == 2)): if (self.cur_frame.side_info.mixed_block_flag[ch][gr]): # mixed (long first) next_cb_boundary = sfBandIndex_l[ self.cur_frame.hdr.smpl_rate][1] else: # pure short next_cb_boundary = sfBandIndex_s[ self.cur_frame.hdr.smpl_rate][1] * 3 cb_width = sfBandIndex_s[ self.cur_frame.hdr.smpl_rate][1] cb_begin = 0 else: # long blocks next_cb_boundary = sfBandIndex_l[ self.cur_frame.hdr.smpl_rate][1] # apply formula per block type */ for sb in range(SBLIMIT): for ss in range(SSLIMIT): if ((sb * 18) + ss == next_cb_boundary): if (self.cur_frame.side_info.window_switching_flag[ch][gr] and (self.cur_frame.side_info.block_type[ch][gr] == 2)): if (self.cur_frame.side_info.mixed_block_flag[ch][gr]): if (((sb * 18) + ss) == sfBandIndex_l[self.cur_frame.hdr.smpl_rate][8]): next_cb_boundary = sfBandIndex_s[ self.cur_frame.hdr.smpl_rate][4] * 3 cb = 3 cb_width = sfBandIndex_s[self.cur_frame.hdr.smpl_rate][ cb + 1] - sfBandIndex_s[self.cur_frame.hdr.smpl_rate][cb] cb_begin = sfBandIndex_s[ self.cur_frame.hdr.smpl_rate][cb] * 3 elif (((sb * 18) + ss) < sfBandIndex_l[self.cur_frame.hdr.smpl_rate][8]): cb += 1 next_cb_boundary = sfBandIndex_l[ self.cur_frame.hdr.smpl_rate][cb + 1] else: cb += 1 next_cb_boundary = sfBandIndex_s[ self.cur_frame.hdr.smpl_rate][cb + 1] * 3 cb_width = sfBandIndex_s[self.cur_frame.hdr.smpl_rate][ cb + 1] - sfBandIndex_s[self.cur_frame.hdr.smpl_rate][cb] cb_begin = sfBandIndex_s[ self.cur_frame.hdr.smpl_rate][cb] * 3 else: cb += 1 next_cb_boundary = sfBandIndex_s[ self.cur_frame.hdr.smpl_rate][cb + 1] * 3 cb_width = sfBandIndex_s[self.cur_frame.hdr.smpl_rate][ cb + 1] - sfBandIndex_s[self.cur_frame.hdr.smpl_rate][cb] cb_begin = sfBandIndex_s[ self.cur_frame.hdr.smpl_rate][cb] * 3 else: cb += 1 next_cb_boundary = sfBandIndex_l[ self.cur_frame.hdr.smpl_rate][cb + 1] # Compute global scaling self.cur_frame.decoded_data.dq_vals[gr][ch][sb][ss] = pow( 2.0, (0.25 * (self.cur_frame.side_info.global_gain[ch][gr] - 210.0))) val_a = self.cur_frame.decoded_data.dq_vals[ gr][ch][sb][ss] # Compute block dependent scaling if (self.cur_frame.side_info.window_switching_flag[ch][gr] and ( ((self.cur_frame.side_info.block_type[ch][gr] == 2) and (self.cur_frame.side_info.mixed_block_flag[ch][gr] == 0)) or ((self.cur_frame.side_info.block_type[ch][gr] == 2) and self.cur_frame.side_info.mixed_block_flag[ch][gr] and (sb >= 2)))): # SHORT self.cur_frame.decoded_data.dq_vals[gr][ch][sb][ ss] *= pow(2.0, 0.25 * -8.0 * self.cur_frame.side_info.subblock_gain[ch][gr][(((sb * 18) + ss) - cb_begin) / cb_width]) val_a2 = self.cur_frame.decoded_data.dq_vals[ gr][ch][sb][ss] self.cur_frame.decoded_data.dq_vals[gr][ch][sb][ss] *= pow(2.0, 0.25 * -2.0 * (1.0 + self.cur_frame.side_info.scalefac_scale[ch][gr]) * self.cur_frame.main_data.scalefac_s[ch][gr][(((sb * 18) + ss) - cb_begin) / cb_width][cb]) val_a3 = self.cur_frame.decoded_data.dq_vals[ gr][ch][sb][ss] else: # LONG block types 0,1,3 & 1st 2 subbands of # switched blocks self.cur_frame.decoded_data.dq_vals[gr][ch][sb][ss] *= pow(2.0, -0.5 * (1.0 + self.cur_frame.side_info.scalefac_scale[ch][gr]) * (self.cur_frame.main_data.scalefac_l[ch][gr][cb] + self.cur_frame.side_info.preflag[ch][gr] * pretab[cb])) val_b = self.cur_frame.decoded_data.dq_vals[ gr][ch][sb][ss] val_b2 = self.cur_frame.side_info.scalefac_scale[ ch][gr] val_b3 = self.cur_frame.main_data.scalefac_l[ ch][gr][cb] # Scale quantized value self.cur_frame.decoded_data.dq_vals[gr][ch][sb][ ss] *= pow(abs(self.cur_frame.main_data.q_vals[gr][ch][sb][ss]), (4.0 / 3.0)) if (self.cur_frame.main_data.q_vals[gr][ch][sb][ss] < 0): self.cur_frame.decoded_data.dq_vals[gr][ch][sb][ ss] = -self.cur_frame.decoded_data.dq_vals[gr][ch][sb][ss] val_c = self.cur_frame.decoded_data.dq_vals[ gr][ch][sb][ss] def process_stereo(self): has_intensity_stereo = ( self.cur_frame.hdr.mode_extention & INTENSITY_STEREO_BIT) has_mid_side_stereo = ( self.cur_frame.hdr.mode_extention & MID_SIDE_STEREO_BIT) lr = self.cur_frame.decoded_data.lr_vals dq_vals = self.cur_frame.decoded_data.dq_vals if(dbg_output and False): for gr in range(2): for sb in range(SBLIMIT): for ss in range(SSLIMIT): print( "s", self.frame_num, gr, sb, ss, dq_vals[gr][0][sb][ss]) for gr in range(2): if (self.cur_frame.hdr.n_channels == 2): is_pos = [7 for dummy in range(576)] if(has_intensity_stereo): is_ratio = self.process_intensity_stereo(gr, is_pos) for sb in range(SBLIMIT): for ss in range(SSLIMIT): i = (sb * 18) + ss if (is_pos[i] == 7): if (has_mid_side_stereo): lr[gr][0][sb][ss] = ( dq_vals[gr][0][sb][ss] + dq_vals[gr][1][sb][ss]) / 1.41421356 lr[gr][1][sb][ss] = ( dq_vals[gr][0][sb][ss] - dq_vals[gr][1][sb][ss]) / 1.41421356 else: lr[gr][0][sb][ss] = dq_vals[gr][0][sb][ss] lr[gr][1][sb][ss] = dq_vals[gr][1][sb][ss] elif (has_intensity_stereo): lr[gr][0][sb][ss] = dq_vals[gr][0][sb][ ss] * (is_ratio[i] / (1 + is_ratio[i])) lr[gr][1][sb][ss] = dq_vals[gr][0][ sb][ss] * (1 / (1 + is_ratio[i])) else: print("Stereo - Error") else: for sb in range(SBLIMIT): for ss in range(SSLIMIT): lr[gr][0][sb][ss] = dq_vals[gr][0][sb][ss] def process_intensity_stereo(self, gr, is_pos): ch = 0 if (self.cur_frame.side_info.window_switching_flag[ch][gr] and (self.cur_frame.side_info.block_type[ch][gr] == 2)): is_ratio = self.process_intensity_stereo__non_standard_window( gr, is_pos) else: is_ratio = self.process_intensity_stereo__standard_window( gr, is_pos) return is_ratio def process_intensity_stereo__standard_window(self, gr, is_pos): smpl_rate = self.cur_frame.hdr.smpl_rate i = 31 ss = 17 sb = 0 while (i >= 0): if (self.decoded_data.dq_vals[1][i][ss] != 0.0): sb = i * 18 + ss i = -1 else: ss -= 1 if (ss < 0): i -= 1 ss = 17 i = 0 while (sfBandIndex_l[smpl_rate][i] <= sb): i += 1 sfb = i i = sfBandIndex_l[smpl_rate][i] for sfb in range(sfb, 21): sb = sfBandIndex_l[smpl_rate][ sfb + 1] - sfBandIndex_l[smpl_rate][sfb] for sb in range(sb, 0, -1): is_pos[i] = self.cur_frame.main_data.scalefac_l[1][gr][sfb] if (is_pos[i] != 7): is_ratio[i] = tan(is_pos[i] * (PI / 12)) i += 1 sfb = sfBandIndex_l[smpl_rate][20] for sb in range(576 - sfBandIndex_l[smpl_rate][21], 0, -1): is_pos[i] = is_pos[sfb] is_ratio[i] = is_ratio[sfb] i += 1 return is_ratio def process_intensity_stereo__non_standard_window(self, gr, is_pos): ch = 0 smpl_rate = self.cur_frame.hdr.smpl_rate if (self.cur_frame.side_info.mixed_block_flag[ch][gr]): max_sfb = 0 for j in range(3): sfbcnt = 2 for sfb in range(12, 2, -1): lines = sfBandIndex_s[smpl_rate][ sfb + 1] - sfBandIndex_s[smpl_rate][sfb] i = 3 * sfBandIndex_s[sfreq][sfb] + (j + 1) * lines - 1 while (lines > 0): if (self.decoded_data.dq_vals[1][i / SSLIMIT][i % SSLIMIT] != 0.0): sfbcnt = sfb sfb = -10 lines = -10 lines -= 1 i -= 1 sfb = sfbcnt + 1 if (sfb > max_sfb): max_sfb = sfb while(sfb < 12): sb = sfBandIndex_s[smpl_rate][ sfb + 1] - sfBandIndex_s[sfreq][sfb] i = 3 * sfBandIndex_s[smpl_rate][sfb] + j * sb for sb in range(sb, 0, -1): is_pos[i] = self.cur_frame.main_data.scalefac_s[ 1][gr][j][sfb] if (is_pos[i] != 7): is_ratio[i] = tan(is_pos[i] * (PI / 12)) i += 1 sfb += 1 sb = sfBandIndex_s[smpl_rate][ 11] - sfBandIndex_s[smpl_rate][10] sfb = 3 * sfBandIndex_s[smpl_rate].s[10] + j * sb sb = sfBandIndex_s[smpl_rate][ 12] - sfBandIndex_s[smpl_rate][11] i = 3 * sfBandIndex_s[smpl_rate][11] + j * sb for sb in range(sb, 0, -1): is_pos[i] = is_pos[sfb] is_ratio[i] = is_ratio[sfb] i += 1 if (max_sfb <= 3): i = 2 ss = 17 sb = -1 while (i >= 0): if (self.decoded_data.dq_vals[1][i][ss] != 0.0): sb = i * 18 + ss i = -1 else: ss -= 1 if (ss < 0): i -= 1 ss = 17 i = 0 while (sfBandIndex_l[smpl_rate][i] <= sb): i += 1 sfb = i i = sfBandIndex_l[smpl_rate][i] for sfb in range(sfb, 8): sb = sfBandIndex_l[smpl_rate][ sfb + 1] - sfBandIndex_l[sfreq][sfb] for sb in range(sb, 0, -1): is_pos[i] = self.cur_frame.main_data.scalefac_l[ 1][gr][sfb] if (is_pos[i] != 7): is_ratio[i] = tan(is_pos[i] * (PI / 12)) i += 1 else: for j in range(3): sfbcnt = -1 for sfb in range(12, -1, -1): lines = sfBandIndex_s[smpl_rate][ sfb + 1] - sfBandIndex_s[smpl_rate][sfb] i = 3 * sfBandIndex_s[smpl_rate][sfb] + (j + 1) * lines - 1 while (lines > 0): if (self.decoded_data.dq_vals[1][i / SSLIMIT][i % SSLIMIT] != 0.0): sfbcnt = sfb sfb = -10 lines = -10 lines -= 1 i -= 1 sfb = sfbcnt + 1 while(sfb < 12): sb = sfBandIndex_s[smpl_rate][ sfb + 1] - sfBandIndex_s[smpl_rate][sfb] i = 3 * sfBandIndex_s[smpl_rate][sfb] + j * sb for sb in range(sb, 0, -1): is_pos[i] = self.cur_frame.main_data.scalefac_s[ 1][gr][j][sfb] if (is_pos[i] != 7): is_ratio[i] = tan(is_pos[i] * (PI / 12)) i += 1 sfb += 1 sb = sfBandIndex_s[smpl_rate][11] - sfBandIndex_s[sfreq][10] sfb = 3 * sfBandIndex_s[smpl_rate][10] + j * sb sb = sfBandIndex_s[smpl_rate][12] - sfBandIndex_s[sfreq][11] i = 3 * sfBandIndex_s[smpl_rate][11] + j * sb for sb in range(sb, -1, -1): is_pos[i] = is_pos[sfb] is_ratio[i] = is_ratio[sfb] i += 1 return is_ratio def reorder_samples(self): smpl_rate = self.cur_frame.hdr.smpl_rate lr = self.cur_frame.decoded_data.lr_vals ro = self.cur_frame.decoded_data.reordered_vals if(dbg_output and False): for gr in range(2): for sb in range(SBLIMIT): for ss in range(SSLIMIT): print( "ro", self.frame_num, gr, sb, ss, lr[gr][0][sb][ss]) for gr in range(2): for ch in range(self.cur_frame.hdr.n_channels): if (self.cur_frame.side_info.window_switching_flag[ch][gr] and (self.cur_frame.side_info.block_type[ch][gr] == 2)): if (self.cur_frame.side_info.mixed_block_flag[ch][gr]): # NO REORDER FOR LOW 2 SUBBANDS for sb in range(2): for ss in range(SSLIMIT): ro[gr][ch][sb][ss] = lr[gr][ch][sb][ss] # REORDERING FOR REST SWITCHED SHORT sfb_start = sfBandIndex_s[smpl_rate][3] sfb_lines = sfBandIndex_s[smpl_rate][4] - sfb_start for sfb in range(3, 13): for window in range(3): for freq in range(sfb_lines): src_line = sfb_start * 3 + \ window * sfb_lines + freq des_line = ( sfb_start * 3) + window + (freq * 3) ro[gr][ch][ des_line / SSLIMIT][des_line % SSLIMIT] = lr[gr][ch][src_line / SSLIMIT][src_line % SSLIMIT] sfb_start = sfBandIndex_s[smpl_rate][sfb] sfb_lines = sfBandIndex_s[ smpl_rate][sfb + 1] - sfb_start else: # pure short sfb_start = 0 sfb_lines = sfBandIndex_s[smpl_rate][1] for sfb in range(13): for window in range(3): for freq in range(sfb_lines): src_line = sfb_start * 3 + \ window * sfb_lines + freq des_line = ( sfb_start * 3) + window + (freq * 3) ro[gr][ch][ des_line / SSLIMIT][des_line % SSLIMIT] = lr[gr][ch][src_line / SSLIMIT][src_line % SSLIMIT] sfb_start = sfBandIndex_s[smpl_rate][sfb] sfb_lines = sfBandIndex_s[ smpl_rate][sfb + 1] - sfb_start else: # long blocks */ for sb in range(SBLIMIT): for ss in range(SSLIMIT): ro[gr][ch][sb][ss] = lr[gr][ch][sb][ss] def antialias_samples(self): cs = [1.0 / sqrt(1.0 + ci * ci) for ci in antialias_Ci] ca = [ci / sqrt(1.0 + ci * ci) for ci in antialias_Ci] ro = self.cur_frame.decoded_data.reordered_vals aa = self.cur_frame.decoded_data.antialiased_vals if(dbg_output and False): for gr in range(2): for sb in range(SBLIMIT): for ss in range(SSLIMIT): print( "aa", self.frame_num, gr, sb, ss, ro[gr][0][sb][ss]) for gr in range(2): for ch in range(self.cur_frame.hdr.n_channels): for sb in range(SBLIMIT): for ss in range(SSLIMIT): aa[gr][ch][sb][ss] = ro[gr][ch][sb][ss] if ((self.cur_frame.side_info.window_switching_flag[ch][gr] and (self.cur_frame.side_info.block_type[ch][gr] == 2)) and (not self.cur_frame.side_info.mixed_block_flag[ch][gr])): continue if (self.cur_frame.side_info.window_switching_flag[ch][gr] and self.cur_frame.side_info.mixed_block_flag[ch][gr] and (self.cur_frame.side_info.block_type[ch][gr] == 2)): sblim = 1 else: sblim = SBLIMIT - 1 # 31 alias-reduction operations between each pair of sub-bands # with 8 butterflies between each pair for sb in range(sblim): for ss in range(8): bu = ro[gr][ch][sb][17 - ss] bd = ro[gr][ch][sb + 1][ss] aa[gr][ch][sb][17 - ss] = (bu * cs[ss]) - (bd * ca[ss]) aa[gr][ch][sb + 1][ss] = (bd * cs[ss]) + (bu * ca[ss]) def hybrid_synthesis(self): data_in = self.cur_frame.decoded_data.antialiased_vals data_out = self.cur_frame.decoded_data.hybrid_vals if(dbg_output and False): for gr in range(2): for sb in range(SBLIMIT): for ss in range(SSLIMIT): print("hs", self.frame_num, gr, sb, ss, self.cur_frame.decoded_data.antialiased_vals[ gr][0][sb][ss]) for gr in range(2): for ch in range(self.cur_frame.hdr.n_channels): for sb in range(SBLIMIT): if(self.cur_frame.side_info.window_switching_flag[ch][gr] and self.cur_frame.side_info.mixed_block_flag[ch][gr] and sb < 2): blk_type = 0 else: blk_type = self.cur_frame.side_info.block_type[ch][gr] rawout = self.inv_mdct(data_in[gr][ch][sb], blk_type) # overlap addition for ss in range(SSLIMIT): data_out[gr][ch][sb][ss] = rawout[ ss] + self.hybrid_prevblck[ch][sb][ss] self.hybrid_prevblck[ch][sb][ss] = rawout[ss + 18] def inv_mdct(self, data_in, blk_type): out = zeros((36), dtype=double) if(blk_type == 2): tmp = zeros((12), dtype=double) N = 12 for i in range(3): for p in range(N): total = 0.0 for m in range(N / 2): total += data_in[i + 3 * m] * \ cos(PI / (2 * N) * (2 * p + 1 + N / 2) * (2 * m + 1)) tmp[p] = total * self.mdct_win[blk_type][p] for p in range(N): out[6 * i + p + 6] += tmp[p] else: cos_tbl = self.mdct_cos_tbl_2 win = self.mdct_win[blk_type] for p in range(36): out[p] = sum(data_in * cos_tbl[p]) * win[p] return out def polyphase_synthesis(self): data_in = self.cur_frame.decoded_data.hybrid_vals data_out = self.pcm bfr = zeros((SBLIMIT), dtype=double) if(dbg_output and False): for gr in range(2): for sb in range(SBLIMIT): for ss in range(SSLIMIT): print("pps %d %d %d %d %.3e" % ( self.frame_num, gr, sb, ss, self.cur_frame.decoded_data.hybrid_vals[gr][0][sb][ss])) for gr in range(2): for ch in range(self.cur_frame.hdr.n_channels): # frequency inversion for ss in range(18): for sb in range(SBLIMIT): if ((ss % 2) and (sb % 2)): self.cur_frame.decoded_data.hybrid_vals[gr][ch][sb][ ss] = -self.cur_frame.decoded_data.hybrid_vals[gr][ch][sb][ss] # subBand synthesis for ss in range(18): for sb in range(SBLIMIT): bfr[sb] = data_in[gr][ch][sb][ss] pcm_bfr = self.subBandSynthesis(bfr, ch) # copy to final output data_out[ch].extend(pcm_bfr) def subBandSynthesis(self, data_in, ch): pcm = zeros((32), dtype=int32) self.sbs_buf[ch] = roll(self.sbs_buf[ch], 64) # init bfr = self.sbs_buf[ch] # fir filter for i in range(64): bfr[i] = sum(data_in * self.sbs_filter[i]) # window output for j in range(32): total = 0 for i in range(16): k = j + i * 32 idx = (k + (((i + 1) >> 1) * 64)) total += sbs_window[k] * bfr[idx] # clip pcm[j] = min(max(total * SCALE, -SCALE), SCALE - 1) return pcm def decode_main_info(self): for gr in range(2): for ch in range(self.cur_frame.hdr.n_channels): # Get scale factors part2_start = self.bitbfr.get_pos() if(self.cur_frame.side_info.window_switching_flag[ch][gr] == 1 and self.cur_frame.side_info.block_type[ch][gr] == 2): if(self.cur_frame.side_info.mixed_block_flag[ch][gr]): # mixed blocks print("mixed scale blocks not supported yet") else: # short blocks for i in range(2): for sfb in range(sfbtable_s[i], sfbtable_s[i + 1]): for window in range(3): self.cur_frame.main_data.scalefac_s[ch][gr][window][sfb] = self.bitbfr.read_bits( slen[i][self.cur_frame.side_info.scalefac_compress[ch][gr]]) sfb = 12 for window in range(3): self.cur_frame.main_data.scalefac_s[ ch][gr][window][sfb] = 0 else: # long blocks for i in range(4): if ((self.cur_frame.side_info.scfsi[ch][i] == 0) or (gr == 0)): for sfb in range(sfbtable_l[i], sfbtable_l[i + 1]): if(i < 2): k = 0 else: k = 1 self.cur_frame.main_data.scalefac_l[ch][gr][sfb] = self.bitbfr.read_bits( slen[k][self.cur_frame.side_info.scalefac_compress[ch][gr]]) self.cur_frame.main_data.scalefac_l[ch][gr][22] = 0 self.decode_main_data_huffman(ch, gr, part2_start) def decode_main_data_huffman(self, ch, gr, part2_start): # calculate region boundries if(self.cur_frame.side_info.window_switching_flag[ch][gr] == 1 and self.cur_frame.side_info.block_type[ch][gr] == 2): # short block region1Start = 36 region2Start = 576 else: # long block region1Start = sfBandIndex_l[self.cur_frame.hdr.smpl_rate][ self.cur_frame.side_info.region0_count[ch][gr] + 1] region2Start = sfBandIndex_l[self.cur_frame.hdr.smpl_rate][ self.cur_frame.side_info.region0_count[ch][gr] + self.cur_frame.side_info.region1_count[ch][gr] + 2] # read big value area for i in range(0, self.cur_frame.side_info.big_values[ch][gr] * 2, 2): if (i < region1Start): ht_idx = self.cur_frame.side_info.table_select[ch][gr][0] elif (i < region2Start): ht_idx = self.cur_frame.side_info.table_select[ch][gr][1] else: ht_idx = self.cur_frame.side_info.table_select[ch][gr][2] ht = ht_list[ht_idx] v, w, x, y = self.huffman_decoder(ht) self.cur_frame.main_data.q_vals[gr][ ch][i / SSLIMIT][i % SSLIMIT] = x self.cur_frame.main_data.q_vals[gr][ch][ (i + 1) / SSLIMIT][(i + 1) % SSLIMIT] = y # read count1 area idx = self.cur_frame.side_info.big_values[ch][gr] * 2 # 32 is offset to count1 tables ht = ht_list[self.cur_frame.side_info.count1table_select[ch][gr] + 32] while((self.bitbfr.get_pos() < (part2_start + self.cur_frame.side_info.part2_3_length[ch][gr])) and (idx < SBLIMIT * SSLIMIT)): v, w, x, y = self.huffman_decoder(ht) self.cur_frame.main_data.q_vals[gr][ch][ idx / SSLIMIT][idx % SSLIMIT] = v self.cur_frame.main_data.q_vals[gr][ch][ (idx + 1) / SSLIMIT][(idx + 1) % SSLIMIT] = w self.cur_frame.main_data.q_vals[gr][ch][ (idx + 2) / SSLIMIT][(idx + 2) % SSLIMIT] = x self.cur_frame.main_data.q_vals[gr][ch][ (idx + 3) / SSLIMIT][(idx + 3) % SSLIMIT] = y idx += 4 # the rest are zeros def huffman_decoder(self, ht): MXOFF = 250 v = w = x = y = 0 # check for empty tree if(ht.treelen == 0): return (0, 0, 0, 0) # run through huffman tree success = False pos = 0 nbits = 0 while(pos < ht.treelen and nbits < 32): # check for end of tree if(ht.values[pos][0] == 0): x = ht.values[pos][1] >> 4 y = ht.values[pos][1] & 0xf success = True break # get more bits to transverse tree bit = self.bitbfr.read_bits(1) while(ht.values[pos][bit] >= MXOFF): pos += ht.values[pos][bit] pos += ht.values[pos][bit] nbits += 1 if(not success): print("Failure during huffman decode") return (0, 0, 0, 0) # read sign bits if(ht.tbl_type == "quad"): v = (y >> 3) & 1 w = (y >> 2) & 1 x = (y >> 1) & 1 y = y & 1 if(v != 0): if(self.bitbfr.read_bits(1)): v = -v if(w != 0): if(self.bitbfr.read_bits(1)): w = -w if(x != 0): if(self.bitbfr.read_bits(1)): x = -x if(y != 0): if(self.bitbfr.read_bits(1)): y = -y else: # process escape encodings if(ht.linbits > 0): if((ht.xlen - 1) == x): x += self.bitbfr.read_bits(ht.linbits) if(x != 0): if(self.bitbfr.read_bits(1)): x = -x if(ht.linbits > 0): if((ht.ylen - 1) == y): y += self.bitbfr.read_bits(ht.linbits) if(y != 0): if(self.bitbfr.read_bits(1)): y = -y return (v, w, x, y) def decode_side_info(self): self.cur_frame.side_info.main_data_begin = self.bitbfr.read_bits(9) if(self.cur_frame.side_info.main_data_begin != 0): print("Error - dont support bitreservoir yet") if(self.cur_frame.hdr.n_channels == 1): self.cur_frame.side_info.private_bits = self.bitbfr.read_bits(5) else: self.cur_frame.side_info.private_bits = self.bitbfr.read_bits(3) for ch in range(self.cur_frame.hdr.n_channels): for i in range(4): self.cur_frame.side_info.scfsi[ch][ i] = self.bitbfr.read_bits(1) for gr in range(2): for ch in range(self.cur_frame.hdr.n_channels): self.cur_frame.side_info.part2_3_length[ ch][gr] = self.bitbfr.read_bits(12) self.cur_frame.side_info.big_values[ ch][gr] = self.bitbfr.read_bits(9) self.cur_frame.side_info.global_gain[ ch][gr] = self.bitbfr.read_bits(8) self.cur_frame.side_info.scalefac_compress[ ch][gr] = self.bitbfr.read_bits(4) self.cur_frame.side_info.window_switching_flag[ ch][gr] = self.bitbfr.read_bits(1) if(self.cur_frame.side_info.window_switching_flag[ch][gr]): self.cur_frame.side_info.block_type[ ch][gr] = self.bitbfr.read_bits(2) self.cur_frame.side_info.mixed_block_flag[ ch][gr] = self.bitbfr.read_bits(1) for i in range(2): self.cur_frame.side_info.table_select[ ch][gr][i] = self.bitbfr.read_bits(5) for i in range(3): self.cur_frame.side_info.subblock_gain[ ch][gr][i] = self.bitbfr.read_bits(3) if(self.cur_frame.side_info.block_type[ch][gr] == 2 and self.cur_frame.side_info.mixed_block_flag[ch][gr] == 0): self.cur_frame.side_info.region0_count[ch][gr] = 8 else: self.cur_frame.side_info.region0_count[ch][gr] = 7 self.cur_frame.side_info.region1_count[ch][ gr] = 20 - self.cur_frame.side_info.region0_count[ch][gr] else: for i in range(3): self.cur_frame.side_info.table_select[ ch][gr][i] = self.bitbfr.read_bits(5) self.cur_frame.side_info.region0_count[ ch][gr] = self.bitbfr.read_bits(4) self.cur_frame.side_info.region1_count[ ch][gr] = self.bitbfr.read_bits(3) self.cur_frame.side_info.block_type[ch][gr] = 0 self.cur_frame.side_info.preflag[ch][ gr] = self.bitbfr.read_bits(1) self.cur_frame.side_info.scalefac_scale[ ch][gr] = self.bitbfr.read_bits(1) self.cur_frame.side_info.count1table_select[ ch][gr] = self.bitbfr.read_bits(1) if(dbg_output): print( "main_data_begin:", self.cur_frame.side_info.main_data_begin) print("privatebits:", self.cur_frame.side_info.private_bits) print("scale factor select info:", self.cur_frame.side_info.scfsi) print("part 2_3 len:", self.cur_frame.side_info.part2_3_length) print("big values:", self.cur_frame.side_info.big_values) print("global gain:", self.cur_frame.side_info.global_gain) print( "scalefac_compress", self.cur_frame.side_info.scalefac_compress) print( "win switch flag:", self.cur_frame.side_info.window_switching_flag) print("block type:", self.cur_frame.side_info.block_type) print( "mixed block flag:", self.cur_frame.side_info.mixed_block_flag) print("table select:", self.cur_frame.side_info.table_select) print("subblock gain:", self.cur_frame.side_info.subblock_gain) print("region0_count", self.cur_frame.side_info.region0_count) print("region1_count", self.cur_frame.side_info.region1_count) print("preflag", self.cur_frame.side_info.preflag) print("scalefac_scale", self.cur_frame.side_info.scalefac_scale) print( "count1table select:", self.cur_frame.side_info.count1table_select) def decode_CRC(self): if(self.cur_frame.hdr.has_CRC): crc = self.bitbfr.read_bits(16) def decode_frame_header(self): self.cur_frame.hdr.mpeg_version = mp3_hdr_ver_tbl[ self.bitbfr.read_bits(1)] self.cur_frame.hdr.layer = mp3_hdr_layer_tbl[self.bitbfr.read_bits(2)] self.cur_frame.hdr.has_CRC = not self.bitbfr.read_bits(1) self.cur_frame.hdr.bitrate = mp3_hdr_bitrate_tbl[ self.bitbfr.read_bits(4)] self.cur_frame.hdr.smpl_rate = mp3_hdr_smpl_rate_tbl[ self.bitbfr.read_bits(2)] self.cur_frame.hdr.padding = self.bitbfr.read_bits(1) self.bitbfr.read_bits(1) # private bit self.cur_frame.hdr.channel_mode = mp3_hdr_channel_mode_tbl[ self.bitbfr.read_bits(2)] self.cur_frame.hdr.mode_extention = self.bitbfr.read_bits(2) self.cur_frame.hdr.copyrighted = self.bitbfr.read_bits(1) self.cur_frame.hdr.original = self.bitbfr.read_bits(1) self.cur_frame.hdr.emphasis = mp3_hdr_emphasis_tbl[ self.bitbfr.read_bits(2)] if(self.cur_frame.hdr.channel_mode == "mono"): self.cur_frame.hdr.n_channels = 1 else: self.cur_frame.hdr.n_channels = 2 if(dbg_output): print("frame header info") print("ver:", self.cur_frame.hdr.mpeg_version) print("layer:", self.cur_frame.hdr.layer) print("has CRC:", self.cur_frame.hdr.has_CRC) print("bitrate(kps):", self.cur_frame.hdr.bitrate) print("sample rate:", self.cur_frame.hdr.smpl_rate) print("padding:", self.cur_frame.hdr.padding) print("channel mode:", self.cur_frame.hdr.channel_mode) print("n channels:", self.cur_frame.hdr.n_channels) print("mode extention:", self.cur_frame.hdr.mode_extention) print("copyrighted:", self.cur_frame.hdr.copyrighted) print("original copy:", self.cur_frame.hdr.original) print("emphasis:", self.cur_frame.hdr.emphasis) if(self.first_frame): print("bitrate(kps):", self.cur_frame.hdr.bitrate) print("sample rate:", self.cur_frame.hdr.smpl_rate) print("channel mode:", self.cur_frame.hdr.channel_mode) self.first_frame = False def find_next_syncword(self): # align to byte boundry align = self.bitbfr.get_pos() % 8 if(align != 0): self.bitbfr.read_bits(8 - align) cnt = 0 while(self.bitbfr.bits_left() > 0): b = self.bitbfr.read_bits(4) if(b == 0xf): cnt += 1 if(cnt == 3): break else: cnt = 0 if(dbg_output): print("sync found at %d" % (self.bitbfr.get_pos()))