1*5f21c38aSMilanka Ringwald#!/usr/bin/env python 2*5f21c38aSMilanka Ringwaldimport numpy as np 3*5f21c38aSMilanka Ringwaldimport wave 4*5f21c38aSMilanka Ringwaldimport struct 5*5f21c38aSMilanka Ringwaldimport sys 6*5f21c38aSMilanka Ringwaldfrom sbc import * 7*5f21c38aSMilanka Ringwaldfrom sbc_encoder import * 8*5f21c38aSMilanka Ringwaldfrom sbc_decoder import * 9*5f21c38aSMilanka Ringwald 10*5f21c38aSMilanka Ringwalderror = 0.99 11*5f21c38aSMilanka Ringwaldmax_error = -1 12*5f21c38aSMilanka Ringwald 13*5f21c38aSMilanka Ringwalddef sbc_compare_pcm(frame_count, actual_frame, expected_frame): 14*5f21c38aSMilanka Ringwald global error, max_error 15*5f21c38aSMilanka Ringwald 16*5f21c38aSMilanka Ringwald M = mse(actual_frame.pcm, expected_frame.pcm) 17*5f21c38aSMilanka Ringwald if M > max_error: 18*5f21c38aSMilanka Ringwald max_error = M 19*5f21c38aSMilanka Ringwald 20*5f21c38aSMilanka Ringwald if M > error: 21*5f21c38aSMilanka Ringwald print "pcm error (%d, %d ) " % (frame_count, M) 22*5f21c38aSMilanka Ringwald return -1 23*5f21c38aSMilanka Ringwald return 0 24*5f21c38aSMilanka Ringwald 25*5f21c38aSMilanka Ringwald 26*5f21c38aSMilanka Ringwalddef sbc_compare_headers(frame_count, actual_frame, expected_frame): 27*5f21c38aSMilanka Ringwald if actual_frame.sampling_frequency != expected_frame.sampling_frequency: 28*5f21c38aSMilanka Ringwald print "sampling_frequency wrong ", actual_frame.sampling_frequency 29*5f21c38aSMilanka Ringwald return -1 30*5f21c38aSMilanka Ringwald 31*5f21c38aSMilanka Ringwald if actual_frame.nr_blocks != expected_frame.nr_blocks: 32*5f21c38aSMilanka Ringwald print "nr_blocks wrong ", actual_frame.nr_blocks 33*5f21c38aSMilanka Ringwald return -1 34*5f21c38aSMilanka Ringwald 35*5f21c38aSMilanka Ringwald if actual_frame.channel_mode != expected_frame.channel_mode: 36*5f21c38aSMilanka Ringwald print "channel_mode wrong ", actual_frame.channel_mode 37*5f21c38aSMilanka Ringwald return -1 38*5f21c38aSMilanka Ringwald 39*5f21c38aSMilanka Ringwald if actual_frame.nr_channels != expected_frame.nr_channels: 40*5f21c38aSMilanka Ringwald print "nr_channels wrong ", actual_frame.nr_channels 41*5f21c38aSMilanka Ringwald return -1 42*5f21c38aSMilanka Ringwald 43*5f21c38aSMilanka Ringwald if actual_frame.allocation_method != expected_frame.allocation_method: 44*5f21c38aSMilanka Ringwald print "allocation_method wrong ", actual_frame.allocation_method 45*5f21c38aSMilanka Ringwald return -1 46*5f21c38aSMilanka Ringwald 47*5f21c38aSMilanka Ringwald if actual_frame.nr_subbands != expected_frame.nr_subbands: 48*5f21c38aSMilanka Ringwald print "nr_subbands wrong ", actual_frame.nr_subbands 49*5f21c38aSMilanka Ringwald return -1 50*5f21c38aSMilanka Ringwald 51*5f21c38aSMilanka Ringwald if actual_frame.bitpool != expected_frame.bitpool: 52*5f21c38aSMilanka Ringwald print "bitpool wrong (E: %d, D: %d)" % (actual_frame.bitpool, expected_frame.bitpool) 53*5f21c38aSMilanka Ringwald return -1 54*5f21c38aSMilanka Ringwald 55*5f21c38aSMilanka Ringwald return 0 56*5f21c38aSMilanka Ringwald 57*5f21c38aSMilanka Ringwald 58*5f21c38aSMilanka Ringwalddef get_actual_frame(fin): 59*5f21c38aSMilanka Ringwald actual_frame = SBCFrame() 60*5f21c38aSMilanka Ringwald sbc_unpack_frame(fin, actual_frame) 61*5f21c38aSMilanka Ringwald sbc_reconstruct_subband_samples(actual_frame) 62*5f21c38aSMilanka Ringwald sbc_synthesis(actual_frame) 63*5f21c38aSMilanka Ringwald return actual_frame 64*5f21c38aSMilanka Ringwald 65*5f21c38aSMilanka Ringwalddef get_expected_frame(fin_expected, nr_blocks, nr_subbands, nr_channels, sampling_frequency, bitpool): 66*5f21c38aSMilanka Ringwald expected_frame = SBCFrame(nr_blocks, nr_subbands, nr_channels, sampling_frequency, bitpool) 67*5f21c38aSMilanka Ringwald fetch_samples_for_next_sbc_frame(fin_expected, expected_frame) 68*5f21c38aSMilanka Ringwald return expected_frame 69*5f21c38aSMilanka Ringwald 70*5f21c38aSMilanka Ringwaldusage = ''' 71*5f21c38aSMilanka RingwaldUsage: ./sbc_decoder_test.py decoder_input.sbc decoder_expected_output.wav 72*5f21c38aSMilanka RingwaldExample: ./sbc_decoder_test.py fanfare-4sb.sbc fanfare-4sb-decoded.wav 73*5f21c38aSMilanka Ringwald''' 74*5f21c38aSMilanka Ringwald 75*5f21c38aSMilanka Ringwaldif (len(sys.argv) < 3): 76*5f21c38aSMilanka Ringwald print(usage) 77*5f21c38aSMilanka Ringwald sys.exit(1) 78*5f21c38aSMilanka Ringwaldtry: 79*5f21c38aSMilanka Ringwald decoder_input_sbc = sys.argv[1] 80*5f21c38aSMilanka Ringwald decoder_expected_wav = sys.argv[2] 81*5f21c38aSMilanka Ringwald 82*5f21c38aSMilanka Ringwald if not decoder_input_sbc.endswith('.sbc'): 83*5f21c38aSMilanka Ringwald print(usage) 84*5f21c38aSMilanka Ringwald sys.exit(1) 85*5f21c38aSMilanka Ringwald 86*5f21c38aSMilanka Ringwald if not decoder_expected_wav.endswith('.wav'): 87*5f21c38aSMilanka Ringwald print(usage) 88*5f21c38aSMilanka Ringwald sys.exit(1) 89*5f21c38aSMilanka Ringwald 90*5f21c38aSMilanka Ringwald fin_expected = wave.open(decoder_expected_wav, 'rb') 91*5f21c38aSMilanka Ringwald nr_channels, sampwidth, sampling_frequency, nr_audio_frames, comptype, compname = fin_expected.getparams() 92*5f21c38aSMilanka Ringwald 93*5f21c38aSMilanka Ringwald # print nr_channels, sampwidth, sampling_frequency, nr_audio_frames, comptype, compname 94*5f21c38aSMilanka Ringwald 95*5f21c38aSMilanka Ringwald with open(decoder_input_sbc, 'rb') as fin: 96*5f21c38aSMilanka Ringwald try: 97*5f21c38aSMilanka Ringwald subband_frame_count = 0 98*5f21c38aSMilanka Ringwald while True: 99*5f21c38aSMilanka Ringwald if subband_frame_count % 200 == 0: 100*5f21c38aSMilanka Ringwald print "== Frame %d ==" % (subband_frame_count) 101*5f21c38aSMilanka Ringwald 102*5f21c38aSMilanka Ringwald actual_frame = get_actual_frame(fin) 103*5f21c38aSMilanka Ringwald 104*5f21c38aSMilanka Ringwald expected_frame = get_expected_frame(fin_expected, actual_frame.nr_blocks, 105*5f21c38aSMilanka Ringwald actual_frame.nr_subbands, nr_channels, 106*5f21c38aSMilanka Ringwald actual_frame.bitpool, sampling_frequency) 107*5f21c38aSMilanka Ringwald 108*5f21c38aSMilanka Ringwald 109*5f21c38aSMilanka Ringwald err = sbc_compare_headers(subband_frame_count, actual_frame, expected_frame) 110*5f21c38aSMilanka Ringwald if err < 0: 111*5f21c38aSMilanka Ringwald exit(1) 112*5f21c38aSMilanka Ringwald 113*5f21c38aSMilanka Ringwald err = sbc_compare_pcm(subband_frame_count, actual_frame, expected_frame) 114*5f21c38aSMilanka Ringwald if err < 0: 115*5f21c38aSMilanka Ringwald exit(1) 116*5f21c38aSMilanka Ringwald 117*5f21c38aSMilanka Ringwald subband_frame_count += 1 118*5f21c38aSMilanka Ringwald 119*5f21c38aSMilanka Ringwald except TypeError: 120*5f21c38aSMilanka Ringwald fin_expected.close() 121*5f21c38aSMilanka Ringwald fin.close() 122*5f21c38aSMilanka Ringwald print "DONE, max MSE PCM error %d", max_error 123*5f21c38aSMilanka Ringwald exit(0) 124*5f21c38aSMilanka Ringwald 125*5f21c38aSMilanka Ringwaldexcept IOError as e: 126*5f21c38aSMilanka Ringwald print(usage) 127*5f21c38aSMilanka Ringwald sys.exit(1) 128*5f21c38aSMilanka Ringwald 129*5f21c38aSMilanka Ringwald 130*5f21c38aSMilanka Ringwald 131*5f21c38aSMilanka Ringwald 132*5f21c38aSMilanka Ringwald 133