1#!/usr/bin/env python 2import numpy as np 3import wave 4import struct 5import sys 6from sbc import * 7 8X = np.zeros(40) 9 10def fetch_samples_for_next_sbc_frame(fin, nr_audio_frames, frame): 11 raw_data = fin.readframes(nr_audio_frames) # Returns byte data 12 13 total_samples = nr_audio_frames * frame.nr_channels 14 fmt = "%ih" % total_samples # read signed 2 byte shorts 15 16 frame.pcm = np.array(struct.unpack(fmt, raw_data)) 17 del raw_data 18 19 # channels = [ [] for ch in range(frame.nr_channels) ] 20 # for index, value in enumerate(integer_data): 21 # bucket = index % nr_channels 22 # channels[bucket].append(value) 23 24 25def sbc_analyse(frame, ch, blk, C, debug): 26 global X 27 M = frame.nr_subbands 28 L = 10 * M 29 M2 = 2*M 30 L2 = 2*L 31 32 Z = np.zeros(L) 33 Y = np.zeros(M2) 34 W = np.zeros(shape=(M, M2)) 35 S = np.zeros(M) 36 37 for i in range(L-1, M-1, -1): 38 X[i] = X[i-M] 39 for i in range(M-1, -1, -1): 40 X[i] = frame.EX[M-1-i] 41 42 for i in range(L): 43 Z[i] = X[i] * C[i] 44 45 for i in range(M2): 46 for k in range(5): 47 Y[i] += Z[i+k*8] 48 49 for i in range(M): 50 for k in range(M2): 51 W[i][k] = np.cos((i+0.5)*(k-2)*np.pi/M) 52 S[i] += W[i][k] * Y[k] 53 54 if debug: 55 #print "EX:", frame.EX 56 print "X:", X 57 print "Z:" 58 print "Y:", Y 59 print "W:", W 60 print "S:", S 61 62 for sb in range(M): 63 frame.sb_sample[blk][ch][sb] = S[sb] 64 65 66def sbc_encode(frame,debug): 67 if frame.nr_subbands == 4: 68 proto_table = Proto_4_40 69 elif frame.nr_subbands == 8: 70 proto_table = Proto_8_80 71 else: 72 return -1 73 74 frame.sb_sample = np.ndarray(shape=(frame.nr_blocks, frame.nr_channels, frame.nr_subbands)) 75 76 # channels = [ [] for ch in range(frame.nr_channels) ] 77 # for index, value in enumerate(frame.pcm): 78 # bucket = index % frame.nr_channels 79 # channels[bucket].append(value) 80 81 # print "encoder pcm ", frame.pcm 82 83 index = 0 84 for ch in range(frame.nr_channels): 85 for blk in range(frame.nr_blocks): 86 for sb in range(frame.nr_subbands): 87 frame.EX[sb] = frame.pcm[index] #channels[ch][blk * frame.nr_subbands + sb] 88 index+=1 89 sbc_analyse(frame, ch, blk, proto_table,debug) 90 sbc_quantization(frame) 91 92 93def should_use_joint_coding(frame): 94 return False 95 96def calculate_scalefactor(max_subbandsample): 97 x = 0 98 while True: 99 y = 1 << x + 1 100 if y > max_subbandsample: 101 break 102 x += 1 103 return (x,y) 104 105 106def frame_to_bitstream(frame): 107 global bitstream, bitstream_bits_available 108 init_bitstream() 109 110 add_bits(frame.syncword, 8) 111 add_bits(frame.sampling_frequency, 2) 112 add_bits(frame.nr_blocks/4-1, 2) 113 add_bits(frame.channel_mode, 2) 114 add_bits(frame.allocation_method, 1) 115 add_bits(frame.nr_subbands/4-1, 1) 116 add_bits(frame.bitpool, 8) 117 add_bits(frame.crc_check, 8) 118 119 for sb in range(frame.nr_subbands): 120 add_bits(frame.join[sb],1) 121 122 for ch in range(frame.nr_channels): 123 for sb in range(frame.nr_subbands): 124 add_bits(frame.scale_factor[ch][sb], 4) 125 126 for blk in range(frame.nr_blocks): 127 for ch in range(frame.nr_channels): 128 for sb in range(frame.nr_subbands): 129 add_bits(frame.audio_sample[blk][ch][sb], frame.bits[ch][sb]) 130 131 # bitstream_len = 16 + frame.nr_subbands + frame.nr_channels * frame.nr_subbands * 4 132 return bitstream 133 134def sbc_quantization(frame): 135 136 frame.join = np.zeros(frame.nr_subbands, dtype = np.uint8) 137 if should_use_joint_coding(frame): 138 return 139 140 max_subbandsample = np.zeros(shape = (frame.nr_channels, frame.nr_subbands)) 141 142 for blk in range(frame.nr_blocks): 143 for ch in range(frame.nr_channels): 144 for sb in range(frame.nr_subbands): 145 m = abs(frame.sb_sample[blk][ch][sb]) 146 if max_subbandsample[ch][sb] < m: 147 max_subbandsample[ch][sb] = m 148 149 150 for ch in range(frame.nr_channels): 151 for sb in range(frame.nr_subbands): 152 (frame.scale_factor[ch][sb], frame.scalefactor[ch][sb]) = calculate_scalefactor(max_subbandsample[ch][sb]) 153 154 frame.bits = sbc_bit_allocation(frame) 155 156 # Reconstruct the Audio Samples 157 frame.levels = np.zeros(shape=(frame.nr_channels, frame.nr_subbands), dtype = np.int32) 158 for ch in range(frame.nr_channels): 159 for sb in range(frame.nr_subbands): 160 frame.levels[ch][sb] = pow(2.0, frame.bits[ch][sb]) - 1 161 162 frame.syncword = 156 163 frame.crc_check = calculate_crc(frame) 164 165 for blk in range(frame.nr_blocks): 166 for ch in range(frame.nr_channels): 167 for sb in range(frame.nr_subbands): 168 if frame.levels[ch][sb] > 0: 169 SB = frame.sb_sample[blk][ch][sb] 170 SF = frame.scalefactor[ch][sb] 171 L = frame.levels[ch][sb] 172 AS = np.uint16(((SB * L / SF + L) - 1.0)/2.0) 173 frame.audio_sample[blk][ch][sb] = AS 174 else: 175 frame.audio_sample[blk][ch][sb] = 0 176 177 178 return 0 179 180 181# usage = ''' 182# Usage: ./sbc_encoder.py input.wav block_size nr_subbands bitpool 183# ''' 184# nr_blocks = 0 185# nr_subbands = 0 186 187# if (len(sys.argv) < 5): 188# print(usage) 189# sys.exit(1) 190# try: 191# infile = sys.argv[1] 192# if not infile.endswith('.wav'): 193# print(usage) 194# sys.exit(1) 195# nr_blocks = int(sys.argv[2]) 196# nr_subbands = int(sys.argv[3]) 197# bitpool = int(sys.argv[4]) 198# sbcfile = infile.replace('.wav', '-encoded.sbc') 199 200# fin = wave.open(infile, 'rb') 201 202# wav_nr_channels = fin.getnchannels() 203# wav_sample_rate = fin.getframerate() 204# wav_nr_frames = fin.getnframes() 205# sbc_sampling_frequency = sbc_sampling_frequency_index(wav_sample_rate) 206 207# sbc_frame_count = 0 208# audio_frame_count = 0 209 210# while audio_frame_count < wav_nr_frames: 211# if sbc_frame_count % 200 == 0: 212# print "== Frame %d ==" % (sbc_frame_count) 213 214# sbc_encoder_frame = SBCFrame(nr_blocks, nr_subbands, wav_nr_channels, sbc_sampling_frequency, bitpool) 215 216# wav_nr_audio_frames = sbc_encoder_frame.nr_blocks * sbc_encoder_frame.nr_subbands 217# fetch_samples_for_next_sbc_frame(fin, wav_nr_audio_frames, sbc_encoder_frame) 218# sbc_encode(sbc_encoder_frame) 219 220# # stream = frame_to_bitstream(frame) 221# audio_frame_count += wav_nr_audio_frames 222# sbc_frame_count += 1 223 224# # except TypeError: 225# # fin.close() 226# # print "DONE, WAV file %s encoded into SBC file %s ", (infile, sbcfile) 227 228# #channels, num_audio_frames, wav_nr_channels, wav_sample_rate = read_waw_file(wavfile) 229 230 231# except IOError as e: 232# print(usage) 233# sys.exit(1) 234 235 236 237 238 239