1#!/usr/bin/env python3 2import numpy as np 3import wave 4import struct 5import sys 6from sbc import * 7from sbc_encoder import * 8from sbc_decoder import * 9 10error = 0.99 11max_error = -1 12 13 14def sbc_compare_subband_samples(frame_count, actual_frame, expected_frame): 15 global error, max_error 16 for blk in range(actual_frame.nr_blocks): 17 for ch in range(actual_frame.nr_channels): 18 M = mse(actual_frame.sb_sample[blk][ch], expected_frame.sb_sample[blk][ch]) 19 if M > max_error: 20 max_error = M 21 22 if max_error > error: 23 print ("Frame %d: sb_sample error %f (ch %d, blk %d)" % (frame_count, max_error, ch, blk)) 24 print (actual_frame.sb_sample[blk]) 25 print (expected_frame.sb_sample[blk]) 26 return -1 27 return 0 28 29def sbc_compare_audio_frames(frame_count, actual_frame, expected_frame): 30 global error, max_error 31 32 for blk in range(actual_frame.nr_blocks): 33 for ch in range(actual_frame.nr_channels): 34 M = mse(actual_frame.audio_sample[blk][ch], expected_frame.audio_sample[blk][ch]) 35 if M > max_error: 36 max_error = M 37 38 if max_error > error: 39 print ("audio_sample error (%d, %f ) " % (frame_count, max_error)) 40 print (actual_frame.audio_sample[blk]) 41 print (expected_frame.audio_sample[blk]) 42 43 return -1 44 return 0 45 46def sbc_compare_headers(frame_count, actual_frame, expected_frame): 47 if actual_frame.syncword != expected_frame.syncword: 48 print ("syncword wrong ", actual_frame.syncword) 49 return -1 50 51 if actual_frame.sampling_frequency != expected_frame.sampling_frequency: 52 print ("sampling_frequency wrong ", actual_frame.sampling_frequency) 53 return -1 54 55 if actual_frame.nr_blocks != expected_frame.nr_blocks: 56 print ("nr_blocks wrong ", actual_frame.nr_blocks) 57 return -1 58 59 if actual_frame.channel_mode != expected_frame.channel_mode: 60 print ("channel_mode wrong ", actual_frame.channel_mode) 61 return -1 62 63 if actual_frame.nr_channels != expected_frame.nr_channels: 64 print ("nr_channels wrong ", actual_frame.nr_channels) 65 return -1 66 67 if actual_frame.allocation_method != expected_frame.allocation_method: 68 print ("allocation_method wrong ", actual_frame.allocation_method) 69 return -1 70 71 if actual_frame.nr_subbands != expected_frame.nr_subbands: 72 print ("nr_subbands wrong ", actual_frame.nr_subbands) 73 return -1 74 75 if actual_frame.bitpool != expected_frame.bitpool: 76 print ("bitpool wrong (E: %d, D: %d)" % (actual_frame.bitpool, expected_frame.bitpool)) 77 return -1 78 79 if mse(actual_frame.join, expected_frame.join) > 0: 80 print ("join error \nE:\n %s \nD:\n %s" % (actual_frame.join, expected_frame.join)) 81 return -1 82 83 84 if mse(actual_frame.scale_factor, expected_frame.scale_factor) > 0: 85 print ("scale_factor error %d \nE:\n %s \nD:\n %s" % (frame_count, actual_frame.scale_factor, expected_frame.scale_factor)) 86 return -1 87 88 if mse(actual_frame.scalefactor, expected_frame.scalefactor) > 0: 89 print ("scalefactor error %d \nE:\n %s \nD:\n %s" % (frame_count, actual_frame.scalefactor, expected_frame.scalefactor)) 90 return -1 91 92 if mse(actual_frame.bits, expected_frame.bits) > 0: 93 print ("bits error %d \nE:\n %s \nD:\n %s" % (frame_count, actual_frame.bits, expected_frame.bits)) 94 return -1 95 96 if actual_frame.crc_check != expected_frame.crc_check: 97 print ("crc_check wrong (E: %d, D: %d)" % (actual_frame.crc_check, expected_frame.crc_check)) 98 return -1 99 100 return 0 101 102 103def get_actual_frame(fin, nr_blocks, nr_subbands, nr_channels, sampling_frequency, bitpool, allocation_method, force_channel_mode): 104 actual_frame = SBCFrame(nr_blocks, nr_subbands, nr_channels, sampling_frequency, bitpool, allocation_method) 105 fetch_samples_for_next_sbc_frame(fin, actual_frame) 106 sbc_encode(actual_frame, force_channel_mode) 107 return actual_frame 108 109file_size = 0 110def get_expected_frame(fin_expected): 111 global file_size 112 expected_frame = SBCFrame() 113 sbc_unpack_frame(fin_expected, file_size - fin_expected.tell(), expected_frame) 114 sbc_reconstruct_subband_samples(expected_frame) 115 return expected_frame 116 117usage = ''' 118Usage: ./sbc_encoder_test.py encoder_input.wav blocks subbands bitpool allocation_method force_channel_mode encoder_expected_output.sbc 119Example: ./sbc_encoder_test.py fanfare.wav 16 4 31 0 2 fanfare-4sb.sbc 120''' 121 122if (len(sys.argv) < 8): 123 print(usage) 124 sys.exit(1) 125try: 126 encoder_input_wav = sys.argv[1] 127 nr_blocks = int(sys.argv[2]) 128 nr_subbands = int(sys.argv[3]) 129 bitpool = int(sys.argv[4]) 130 allocation_method = int(sys.argv[5]) 131 encoder_expected_sbc = sys.argv[6] 132 force_channel_mode = int(sys.argv[7]) 133 sampling_frequency = 44100 134 135 if not encoder_input_wav.endswith('.wav'): 136 print(usage) 137 sys.exit(1) 138 139 if not encoder_expected_sbc.endswith('.sbc'): 140 print(usage) 141 sys.exit(1) 142 143 fin = wave.open(encoder_input_wav, 'rb') 144 nr_channels = fin.getnchannels() 145 sampling_frequency = fin.getframerate() 146 nr_audio_frames = fin.getnframes() 147 148 fin_expected = open(encoder_expected_sbc, 'rb') 149 fin_expected.seek(0,2) 150 file_size = fin_expected.tell() 151 fin_expected.seek(0,0) 152 153 subband_frame_count = 0 154 audio_frame_count = 0 155 nr_samples = nr_blocks * nr_subbands 156 157 while audio_frame_count < nr_audio_frames: 158 if subband_frame_count % 200 == 0: 159 print("== Frame %d ==" % (subband_frame_count)) 160 161 actual_frame = get_actual_frame(fin, nr_blocks, nr_subbands, nr_channels, bitpool, sampling_frequency, allocation_method, force_channel_mode) 162 expected_frame = get_expected_frame(fin_expected) 163 164 err = sbc_compare_headers(subband_frame_count, actual_frame, expected_frame) 165 if err < 0: 166 exit(1) 167 168 err = sbc_compare_audio_frames(subband_frame_count, actual_frame, expected_frame) 169 if err < 0: 170 exit(1) 171 172 audio_frame_count += nr_samples 173 subband_frame_count += 1 174 175 print ("Max MSE audio sample error %f" % max_error) 176 fin.close() 177 fin_expected.close() 178 179except TypeError: 180 print ("Max MSE audio sample error %f" % max_error) 181 fin.close() 182 fin_expected.close() 183 184except IOError: 185 print(usage) 186 sys.exit(1) 187 188 189 190 191 192