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 13def sbc_compare_pcm(frame_count, actual_frame, expected_frame): 14 global error, max_error 15 for ch in range(actual_frame.nr_channels): 16 M = mse(actual_frame.pcm[ch], expected_frame.pcm[ch]) 17 if M > max_error: 18 max_error = M 19 20 if max_error > error: 21 print("pcm error (%d, %f ) " % (frame_count, max_error)) 22 return -1 23 return 0 24 25 26def sbc_compare_headers(frame_count, actual_frame, expected_frame): 27 if actual_frame.sampling_frequency != expected_frame.sampling_frequency: 28 print("sampling_frequency wrong ", actual_frame.sampling_frequency) 29 return -1 30 31 if actual_frame.nr_blocks != expected_frame.nr_blocks: 32 print("nr_blocks wrong ", actual_frame.nr_blocks) 33 return -1 34 35 if actual_frame.channel_mode != expected_frame.channel_mode: 36 print("channel_mode wrong ", actual_frame.channel_mode) 37 return -1 38 39 if actual_frame.nr_channels != expected_frame.nr_channels: 40 print("nr_channels wrong ", actual_frame.nr_channels) 41 return -1 42 43 if actual_frame.allocation_method != expected_frame.allocation_method: 44 print("allocation_method wrong ", actual_frame.allocation_method) 45 return -1 46 47 if actual_frame.nr_subbands != expected_frame.nr_subbands: 48 print("nr_subbands wrong ", actual_frame.nr_subbands) 49 return -1 50 51 if actual_frame.bitpool != expected_frame.bitpool: 52 print("bitpool wrong (E: %d, D: %d)" % (actual_frame.bitpool, expected_frame.bitpool)) 53 return -1 54 55 return 0 56 57file_size = 0 58def get_actual_frame(fin, implementation, frame_count): 59 global file_size 60 actual_frame = SBCFrame() 61 sbc_unpack_frame(fin, file_size - fin.tell(), actual_frame) 62 sbc_reconstruct_subband_samples(actual_frame) 63 if subband_frame_count == 0: 64 sbc_init_sythesis(actual_frame.nr_subbands, implementation) 65 print(actual_frame) 66 sbc_synthesis(actual_frame, implementation) 67 return actual_frame 68 69def get_expected_frame(fin_expected, nr_blocks, nr_subbands, nr_channels, sampling_frequency, bitpool, allocation_method): 70 expected_frame = SBCFrame(nr_blocks, nr_subbands, nr_channels, sampling_frequency, bitpool, allocation_method) 71 fetch_samples_for_next_sbc_frame(fin_expected, expected_frame) 72 calculate_channel_mode_and_scale_factors(expected_frame, 0) 73 return expected_frame 74 75usage = ''' 76Usage: ./sbc_decoder_test.py decoder_input.sbc force_channel_mode[No=0, Stereo=2, Joint Stereo=3] implementation[SIG, V1] decoder_expected_output.wav 77Example: ./sbc_decoder_test.py fanfare-4sb.sbc 0 fanfare-4sb-decoded.wav 78''' 79 80if (len(sys.argv) < 5): 81 print(usage) 82 sys.exit(1) 83try: 84 decoder_input_sbc = sys.argv[1] 85 force_channel_mode = int(sys.argv[2]) 86 implementation = sys.argv[3] 87 decoder_expected_wav = sys.argv[4] 88 89 if not decoder_input_sbc.endswith('.sbc'): 90 print(usage) 91 sys.exit(1) 92 93 if not decoder_expected_wav.endswith('.wav'): 94 print(usage) 95 sys.exit(1) 96 97 98 99 fin_expected = wave.open(decoder_expected_wav, 'rb') 100 nr_channels, sampwidth, sampling_frequency, nr_audio_frames, comptype, compname = fin_expected.getparams() 101 102 with open(decoder_input_sbc, 'rb') as fin: 103 try: 104 subband_frame_count = 0 105 fin.seek(0,2) 106 file_size = fin.tell() 107 fin.seek(0,0) 108 109 while True: 110 if subband_frame_count % 200 == 0: 111 print("== Frame %d ==" % subband_frame_count) 112 113 114 actual_frame = get_actual_frame(fin, implementation, subband_frame_count) 115 116 expected_frame = get_expected_frame(fin_expected, actual_frame.nr_blocks, 117 actual_frame.nr_subbands, nr_channels, 118 actual_frame.bitpool, sampling_frequency, 119 actual_frame.allocation_method) 120 121 err = sbc_compare_headers(subband_frame_count, actual_frame, expected_frame) 122 123 if err < 0: 124 print("Frame %d: Headers differ \n%s\n%s" % (subband_frame_count, actual_frame, expected_frame)) 125 sys.exit(1) 126 127 err = sbc_compare_pcm(subband_frame_count, actual_frame, expected_frame) 128 if err < 0: 129 print("Frame %d: PCMs differ %f \n%s\n%s" % (subband_frame_count, max_error, actual_frame.pcm, expected_frame.pcm)) 130 sys.exit(1) 131 132 133 subband_frame_count += 1 134 135 except TypeError: 136 fin_expected.close() 137 fin.close() 138 print("DONE, max MSE PCM error %f" % max_error) 139 140except IOError as e: 141 print(usage) 142 sys.exit(1) 143 144 145 146 147 148