1#!/usr/bin/env python 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): 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 sbc_synthesis(actual_frame) 64 return actual_frame 65 66def get_expected_frame(fin_expected, nr_blocks, nr_subbands, nr_channels, sampling_frequency, bitpool, allocation_method): 67 expected_frame = SBCFrame(nr_blocks, nr_subbands, nr_channels, sampling_frequency, bitpool, allocation_method) 68 fetch_samples_for_next_sbc_frame(fin_expected, expected_frame) 69 calculate_channel_mode_and_scale_factors(expected_frame) 70 return expected_frame 71 72usage = ''' 73Usage: ./sbc_decoder_test.py decoder_input.sbc decoder_expected_output.wav 74Example: ./sbc_decoder_test.py fanfare-4sb.sbc fanfare-4sb-decoded.wav 75''' 76 77if (len(sys.argv) < 3): 78 print(usage) 79 sys.exit(1) 80try: 81 decoder_input_sbc = sys.argv[1] 82 decoder_expected_wav = sys.argv[2] 83 84 if not decoder_input_sbc.endswith('.sbc'): 85 print(usage) 86 sys.exit(1) 87 88 if not decoder_expected_wav.endswith('.wav'): 89 print(usage) 90 sys.exit(1) 91 92 fin_expected = wave.open(decoder_expected_wav, 'rb') 93 nr_channels, sampwidth, sampling_frequency, nr_audio_frames, comptype, compname = fin_expected.getparams() 94 95 with open(decoder_input_sbc, 'rb') as fin: 96 try: 97 subband_frame_count = 0 98 fin.seek(0,2) 99 file_size = fin.tell() 100 fin.seek(0,0) 101 102 while True: 103 if subband_frame_count % 200 == 0: 104 print ("== Frame %d ==" % subband_frame_count) 105 106 107 actual_frame = get_actual_frame(fin) 108 109 110 expected_frame = get_expected_frame(fin_expected, actual_frame.nr_blocks, 111 actual_frame.nr_subbands, nr_channels, 112 actual_frame.bitpool, sampling_frequency, 113 actual_frame.allocation_method) 114 115 err = sbc_compare_headers(subband_frame_count, actual_frame, expected_frame) 116 117 if err < 0: 118 print ("Headers differ \n%s\n%s" % (actual_frame, expected_frame)) 119 sys.exit(1) 120 121 err = sbc_compare_pcm(subband_frame_count, actual_frame, expected_frame) 122 if err < 0: 123 print ("PCMs differ \n%s\n%s" % (actual_frame.pcm, expected_frame.pcm)) 124 sys.exit(1) 125 126 if subband_frame_count == 0: 127 print actual_frame, expected_frame 128 129 subband_frame_count += 1 130 131 except TypeError: 132 fin_expected.close() 133 fin.close() 134 print ("DONE, max MSE PCM error %f" % max_error) 135 136except IOError as e: 137 print(usage) 138 sys.exit(1) 139 140 141 142 143 144