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_audio_frames(frame_count, actual_frame, expected_frame): 14*5f21c38aSMilanka Ringwald global error, max_error 15*5f21c38aSMilanka Ringwald 16*5f21c38aSMilanka Ringwald M = mse(actual_frame.audio_sample, expected_frame.audio_sample) 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 "audio_sample 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.syncword != expected_frame.syncword: 28*5f21c38aSMilanka Ringwald print "syncword wrong ", actual_frame.syncword 29*5f21c38aSMilanka Ringwald return -1 30*5f21c38aSMilanka Ringwald 31*5f21c38aSMilanka Ringwald if actual_frame.sampling_frequency != expected_frame.sampling_frequency: 32*5f21c38aSMilanka Ringwald print "sampling_frequency wrong ", actual_frame.sampling_frequency 33*5f21c38aSMilanka Ringwald return -1 34*5f21c38aSMilanka Ringwald 35*5f21c38aSMilanka Ringwald if actual_frame.nr_blocks != expected_frame.nr_blocks: 36*5f21c38aSMilanka Ringwald print "nr_blocks wrong ", actual_frame.nr_blocks 37*5f21c38aSMilanka Ringwald return -1 38*5f21c38aSMilanka Ringwald 39*5f21c38aSMilanka Ringwald if actual_frame.channel_mode != expected_frame.channel_mode: 40*5f21c38aSMilanka Ringwald print "channel_mode wrong ", actual_frame.channel_mode 41*5f21c38aSMilanka Ringwald return -1 42*5f21c38aSMilanka Ringwald 43*5f21c38aSMilanka Ringwald if actual_frame.nr_channels != expected_frame.nr_channels: 44*5f21c38aSMilanka Ringwald print "nr_channels wrong ", actual_frame.nr_channels 45*5f21c38aSMilanka Ringwald return -1 46*5f21c38aSMilanka Ringwald 47*5f21c38aSMilanka Ringwald if actual_frame.allocation_method != expected_frame.allocation_method: 48*5f21c38aSMilanka Ringwald print "allocation_method wrong ", actual_frame.allocation_method 49*5f21c38aSMilanka Ringwald return -1 50*5f21c38aSMilanka Ringwald 51*5f21c38aSMilanka Ringwald if actual_frame.nr_subbands != expected_frame.nr_subbands: 52*5f21c38aSMilanka Ringwald print "nr_subbands wrong ", actual_frame.nr_subbands 53*5f21c38aSMilanka Ringwald return -1 54*5f21c38aSMilanka Ringwald 55*5f21c38aSMilanka Ringwald if actual_frame.bitpool != expected_frame.bitpool: 56*5f21c38aSMilanka Ringwald print "bitpool wrong (E: %d, D: %d)" % (actual_frame.bitpool, expected_frame.bitpool) 57*5f21c38aSMilanka Ringwald return -1 58*5f21c38aSMilanka Ringwald 59*5f21c38aSMilanka Ringwald if mse(actual_frame.join, expected_frame.join) > 0: 60*5f21c38aSMilanka Ringwald print "join error \nE:\n %s \nD:\n %s" % (actual_frame.join, expected_frame.join) 61*5f21c38aSMilanka Ringwald return -1 62*5f21c38aSMilanka Ringwald 63*5f21c38aSMilanka Ringwald if mse(actual_frame.scale_factor, expected_frame.scale_factor) > 0: 64*5f21c38aSMilanka Ringwald print "scale_factor error \nE:\n %s \nD:\n %s" % (actual_frame.scale_factor, expected_frame.scale_factor) 65*5f21c38aSMilanka Ringwald return -1 66*5f21c38aSMilanka Ringwald 67*5f21c38aSMilanka Ringwald if mse(actual_frame.scalefactor, expected_frame.scalefactor) > 0: 68*5f21c38aSMilanka Ringwald print "scalefactor error \nE:\n %s \nD:\n %s" % (actual_frame.scalefactor, expected_frame.scalefactor) 69*5f21c38aSMilanka Ringwald return -1 70*5f21c38aSMilanka Ringwald 71*5f21c38aSMilanka Ringwald if mse(actual_frame.bits, expected_frame.bits) > 0: 72*5f21c38aSMilanka Ringwald print "bits error \nE:\n %s \nD:\n %s" % (actual_frame.bits, expected_frame.bits) 73*5f21c38aSMilanka Ringwald return -1 74*5f21c38aSMilanka Ringwald 75*5f21c38aSMilanka Ringwald if actual_frame.crc_check != expected_frame.crc_check: 76*5f21c38aSMilanka Ringwald print "crc_check wrong (E: %d, D: %d)" % (actual_frame.crc_check, expected_frame.crc_check) 77*5f21c38aSMilanka Ringwald return -1 78*5f21c38aSMilanka Ringwald 79*5f21c38aSMilanka Ringwald return 0 80*5f21c38aSMilanka Ringwald 81*5f21c38aSMilanka Ringwald 82*5f21c38aSMilanka Ringwalddef get_actual_frame(fin, nr_blocks, nr_subbands, nr_channels, sampling_frequency, bitpool): 83*5f21c38aSMilanka Ringwald actual_frame = SBCFrame(nr_blocks, nr_subbands, nr_channels, sampling_frequency, bitpool) 84*5f21c38aSMilanka Ringwald fetch_samples_for_next_sbc_frame(fin, actual_frame) 85*5f21c38aSMilanka Ringwald sbc_encode(actual_frame) 86*5f21c38aSMilanka Ringwald return actual_frame 87*5f21c38aSMilanka Ringwald 88*5f21c38aSMilanka Ringwalddef get_expected_frame(fin_expected): 89*5f21c38aSMilanka Ringwald expected_frame = SBCFrame() 90*5f21c38aSMilanka Ringwald sbc_unpack_frame(fin_expected, expected_frame) 91*5f21c38aSMilanka Ringwald return expected_frame 92*5f21c38aSMilanka Ringwald 93*5f21c38aSMilanka Ringwaldusage = ''' 94*5f21c38aSMilanka RingwaldUsage: ./sbc_encoder_test.py encoder_input.wav blocks subbands bitpool encoder_expected_output.sbc 95*5f21c38aSMilanka RingwaldExample: ./sbc_encoder_test.py fanfare.wav 16 4 31 fanfare-4sb.sbc 96*5f21c38aSMilanka Ringwald''' 97*5f21c38aSMilanka Ringwald 98*5f21c38aSMilanka Ringwaldif (len(sys.argv) < 6): 99*5f21c38aSMilanka Ringwald print(usage) 100*5f21c38aSMilanka Ringwald sys.exit(1) 101*5f21c38aSMilanka Ringwaldtry: 102*5f21c38aSMilanka Ringwald encoder_input_wav = sys.argv[1] 103*5f21c38aSMilanka Ringwald nr_blocks = int(sys.argv[2]) 104*5f21c38aSMilanka Ringwald nr_subbands = int(sys.argv[3]) 105*5f21c38aSMilanka Ringwald bitpool = int(sys.argv[4]) 106*5f21c38aSMilanka Ringwald encoder_expected_sbc = sys.argv[5] 107*5f21c38aSMilanka Ringwald sampling_frequency = 44100 108*5f21c38aSMilanka Ringwald 109*5f21c38aSMilanka Ringwald if not encoder_input_wav.endswith('.wav'): 110*5f21c38aSMilanka Ringwald print(usage) 111*5f21c38aSMilanka Ringwald sys.exit(1) 112*5f21c38aSMilanka Ringwald 113*5f21c38aSMilanka Ringwald if not encoder_expected_sbc.endswith('.sbc'): 114*5f21c38aSMilanka Ringwald print(usage) 115*5f21c38aSMilanka Ringwald sys.exit(1) 116*5f21c38aSMilanka Ringwald 117*5f21c38aSMilanka Ringwald fin = wave.open(encoder_input_wav, 'rb') 118*5f21c38aSMilanka Ringwald nr_channels = fin.getnchannels() 119*5f21c38aSMilanka Ringwald sampling_frequency = fin.getframerate() 120*5f21c38aSMilanka Ringwald nr_audio_frames = fin.getnframes() 121*5f21c38aSMilanka Ringwald 122*5f21c38aSMilanka Ringwald fin_expected = open(encoder_expected_sbc, 'rb') 123*5f21c38aSMilanka Ringwald subband_frame_count = 0 124*5f21c38aSMilanka Ringwald audio_frame_count = 0 125*5f21c38aSMilanka Ringwald nr_samples = nr_blocks * nr_subbands 126*5f21c38aSMilanka Ringwald 127*5f21c38aSMilanka Ringwald while audio_frame_count < nr_audio_frames: 128*5f21c38aSMilanka Ringwald if subband_frame_count % 200 == 0: 129*5f21c38aSMilanka Ringwald print("== Frame %d ==" % (subband_frame_count)) 130*5f21c38aSMilanka Ringwald 131*5f21c38aSMilanka Ringwald actual_frame = get_actual_frame(fin, nr_blocks, nr_subbands, nr_channels, bitpool, sampling_frequency) 132*5f21c38aSMilanka Ringwald expected_frame = get_expected_frame(fin_expected) 133*5f21c38aSMilanka Ringwald 134*5f21c38aSMilanka Ringwald err = sbc_compare_headers(subband_frame_count, actual_frame, expected_frame) 135*5f21c38aSMilanka Ringwald if err < 0: 136*5f21c38aSMilanka Ringwald exit(1) 137*5f21c38aSMilanka Ringwald 138*5f21c38aSMilanka Ringwald err = sbc_compare_audio_frames(subband_frame_count, actual_frame, expected_frame) 139*5f21c38aSMilanka Ringwald if err < 0: 140*5f21c38aSMilanka Ringwald exit(1) 141*5f21c38aSMilanka Ringwald audio_frame_count += nr_samples 142*5f21c38aSMilanka Ringwald subband_frame_count += 1 143*5f21c38aSMilanka Ringwald 144*5f21c38aSMilanka Ringwald print "DONE, max MSE audio sample error %d", max_error 145*5f21c38aSMilanka Ringwald fin.close() 146*5f21c38aSMilanka Ringwald fin_expected.close() 147*5f21c38aSMilanka Ringwald 148*5f21c38aSMilanka Ringwaldexcept IOError: 149*5f21c38aSMilanka Ringwald print(usage) 150*5f21c38aSMilanka Ringwald sys.exit(1) 151*5f21c38aSMilanka Ringwald 152*5f21c38aSMilanka Ringwald 153*5f21c38aSMilanka Ringwald 154*5f21c38aSMilanka Ringwald 155*5f21c38aSMilanka Ringwald 156