15f21c38aSMilanka Ringwald#!/usr/bin/env python 25f21c38aSMilanka Ringwaldimport numpy as np 35f21c38aSMilanka Ringwaldimport wave 45f21c38aSMilanka Ringwaldimport struct 55f21c38aSMilanka Ringwaldimport sys 65f21c38aSMilanka Ringwaldfrom sbc import * 75f21c38aSMilanka Ringwaldfrom sbc_encoder import * 85f21c38aSMilanka Ringwaldfrom sbc_decoder import * 95f21c38aSMilanka Ringwald 105f21c38aSMilanka Ringwalderror = 0.99 115f21c38aSMilanka Ringwaldmax_error = -1 125f21c38aSMilanka Ringwald 135f21c38aSMilanka Ringwalddef sbc_compare_audio_frames(frame_count, actual_frame, expected_frame): 145f21c38aSMilanka Ringwald global error, max_error 15*5c9bef5bSMilanka Ringwald for ch in range(actual_frame.nr_channels): 165f21c38aSMilanka Ringwald M = mse(actual_frame.audio_sample, expected_frame.audio_sample) 175f21c38aSMilanka Ringwald if M > max_error: 185f21c38aSMilanka Ringwald max_error = M 195f21c38aSMilanka Ringwald 205f21c38aSMilanka Ringwald if M > error: 21*5c9bef5bSMilanka Ringwald print "audio_sample error (%d, %f ) " % (frame_count, M) 225f21c38aSMilanka Ringwald return -1 235f21c38aSMilanka Ringwald return 0 245f21c38aSMilanka Ringwald 255f21c38aSMilanka Ringwalddef sbc_compare_headers(frame_count, actual_frame, expected_frame): 265f21c38aSMilanka Ringwald if actual_frame.syncword != expected_frame.syncword: 275f21c38aSMilanka Ringwald print "syncword wrong ", actual_frame.syncword 285f21c38aSMilanka Ringwald return -1 295f21c38aSMilanka Ringwald 305f21c38aSMilanka Ringwald if actual_frame.sampling_frequency != expected_frame.sampling_frequency: 315f21c38aSMilanka Ringwald print "sampling_frequency wrong ", actual_frame.sampling_frequency 325f21c38aSMilanka Ringwald return -1 335f21c38aSMilanka Ringwald 345f21c38aSMilanka Ringwald if actual_frame.nr_blocks != expected_frame.nr_blocks: 355f21c38aSMilanka Ringwald print "nr_blocks wrong ", actual_frame.nr_blocks 365f21c38aSMilanka Ringwald return -1 375f21c38aSMilanka Ringwald 385f21c38aSMilanka Ringwald if actual_frame.channel_mode != expected_frame.channel_mode: 395f21c38aSMilanka Ringwald print "channel_mode wrong ", actual_frame.channel_mode 405f21c38aSMilanka Ringwald return -1 415f21c38aSMilanka Ringwald 425f21c38aSMilanka Ringwald if actual_frame.nr_channels != expected_frame.nr_channels: 435f21c38aSMilanka Ringwald print "nr_channels wrong ", actual_frame.nr_channels 445f21c38aSMilanka Ringwald return -1 455f21c38aSMilanka Ringwald 465f21c38aSMilanka Ringwald if actual_frame.allocation_method != expected_frame.allocation_method: 475f21c38aSMilanka Ringwald print "allocation_method wrong ", actual_frame.allocation_method 485f21c38aSMilanka Ringwald return -1 495f21c38aSMilanka Ringwald 505f21c38aSMilanka Ringwald if actual_frame.nr_subbands != expected_frame.nr_subbands: 515f21c38aSMilanka Ringwald print "nr_subbands wrong ", actual_frame.nr_subbands 525f21c38aSMilanka Ringwald return -1 535f21c38aSMilanka Ringwald 545f21c38aSMilanka Ringwald if actual_frame.bitpool != expected_frame.bitpool: 555f21c38aSMilanka Ringwald print "bitpool wrong (E: %d, D: %d)" % (actual_frame.bitpool, expected_frame.bitpool) 565f21c38aSMilanka Ringwald return -1 575f21c38aSMilanka Ringwald 585f21c38aSMilanka Ringwald if mse(actual_frame.join, expected_frame.join) > 0: 595f21c38aSMilanka Ringwald print "join error \nE:\n %s \nD:\n %s" % (actual_frame.join, expected_frame.join) 605f21c38aSMilanka Ringwald return -1 615f21c38aSMilanka Ringwald 62*5c9bef5bSMilanka Ringwald 635f21c38aSMilanka Ringwald if mse(actual_frame.scale_factor, expected_frame.scale_factor) > 0: 645f21c38aSMilanka Ringwald print "scale_factor error \nE:\n %s \nD:\n %s" % (actual_frame.scale_factor, expected_frame.scale_factor) 655f21c38aSMilanka Ringwald return -1 665f21c38aSMilanka Ringwald 675f21c38aSMilanka Ringwald if mse(actual_frame.scalefactor, expected_frame.scalefactor) > 0: 685f21c38aSMilanka Ringwald print "scalefactor error \nE:\n %s \nD:\n %s" % (actual_frame.scalefactor, expected_frame.scalefactor) 695f21c38aSMilanka Ringwald return -1 705f21c38aSMilanka Ringwald 715f21c38aSMilanka Ringwald if mse(actual_frame.bits, expected_frame.bits) > 0: 725f21c38aSMilanka Ringwald print "bits error \nE:\n %s \nD:\n %s" % (actual_frame.bits, expected_frame.bits) 735f21c38aSMilanka Ringwald return -1 745f21c38aSMilanka Ringwald 755f21c38aSMilanka Ringwald if actual_frame.crc_check != expected_frame.crc_check: 765f21c38aSMilanka Ringwald print "crc_check wrong (E: %d, D: %d)" % (actual_frame.crc_check, expected_frame.crc_check) 775f21c38aSMilanka Ringwald return -1 785f21c38aSMilanka Ringwald 795f21c38aSMilanka Ringwald return 0 805f21c38aSMilanka Ringwald 815f21c38aSMilanka Ringwald 825665ea35SMilanka Ringwalddef get_actual_frame(fin, nr_blocks, nr_subbands, nr_channels, sampling_frequency, bitpool, allocation_method): 835665ea35SMilanka Ringwald actual_frame = SBCFrame(nr_blocks, nr_subbands, nr_channels, sampling_frequency, bitpool, allocation_method) 845f21c38aSMilanka Ringwald fetch_samples_for_next_sbc_frame(fin, actual_frame) 855f21c38aSMilanka Ringwald sbc_encode(actual_frame) 865f21c38aSMilanka Ringwald return actual_frame 875f21c38aSMilanka Ringwald 885665ea35SMilanka Ringwaldfile_size = 0 895f21c38aSMilanka Ringwalddef get_expected_frame(fin_expected): 905665ea35SMilanka Ringwald global file_size 915f21c38aSMilanka Ringwald expected_frame = SBCFrame() 925665ea35SMilanka Ringwald sbc_unpack_frame(fin_expected, file_size - fin_expected.tell(), expected_frame) 935f21c38aSMilanka Ringwald return expected_frame 945f21c38aSMilanka Ringwald 955f21c38aSMilanka Ringwaldusage = ''' 965665ea35SMilanka RingwaldUsage: ./sbc_encoder_test.py encoder_input.wav blocks subbands bitpool allocation_method encoder_expected_output.sbc 975665ea35SMilanka RingwaldExample: ./sbc_encoder_test.py fanfare.wav 16 4 31 0 fanfare-4sb.sbc 985f21c38aSMilanka Ringwald''' 995f21c38aSMilanka Ringwald 1005665ea35SMilanka Ringwaldif (len(sys.argv) < 7): 1015f21c38aSMilanka Ringwald print(usage) 1025f21c38aSMilanka Ringwald sys.exit(1) 1035f21c38aSMilanka Ringwaldtry: 1045f21c38aSMilanka Ringwald encoder_input_wav = sys.argv[1] 1055f21c38aSMilanka Ringwald nr_blocks = int(sys.argv[2]) 1065f21c38aSMilanka Ringwald nr_subbands = int(sys.argv[3]) 1075f21c38aSMilanka Ringwald bitpool = int(sys.argv[4]) 1085665ea35SMilanka Ringwald allocation_method = int(sys.argv[5]) 1095665ea35SMilanka Ringwald encoder_expected_sbc = sys.argv[6] 1105f21c38aSMilanka Ringwald sampling_frequency = 44100 1115f21c38aSMilanka Ringwald 1125f21c38aSMilanka Ringwald if not encoder_input_wav.endswith('.wav'): 1135f21c38aSMilanka Ringwald print(usage) 1145f21c38aSMilanka Ringwald sys.exit(1) 1155f21c38aSMilanka Ringwald 1165f21c38aSMilanka Ringwald if not encoder_expected_sbc.endswith('.sbc'): 1175f21c38aSMilanka Ringwald print(usage) 1185f21c38aSMilanka Ringwald sys.exit(1) 1195f21c38aSMilanka Ringwald 1205f21c38aSMilanka Ringwald fin = wave.open(encoder_input_wav, 'rb') 1215f21c38aSMilanka Ringwald nr_channels = fin.getnchannels() 1225f21c38aSMilanka Ringwald sampling_frequency = fin.getframerate() 1235f21c38aSMilanka Ringwald nr_audio_frames = fin.getnframes() 1245f21c38aSMilanka Ringwald 1255f21c38aSMilanka Ringwald fin_expected = open(encoder_expected_sbc, 'rb') 1265665ea35SMilanka Ringwald fin_expected.seek(0,2) 1275665ea35SMilanka Ringwald file_size = fin_expected.tell() 1285665ea35SMilanka Ringwald fin_expected.seek(0,0) 1295665ea35SMilanka Ringwald 1305f21c38aSMilanka Ringwald subband_frame_count = 0 1315f21c38aSMilanka Ringwald audio_frame_count = 0 1325f21c38aSMilanka Ringwald nr_samples = nr_blocks * nr_subbands 1335f21c38aSMilanka Ringwald 1345f21c38aSMilanka Ringwald while audio_frame_count < nr_audio_frames: 1355f21c38aSMilanka Ringwald if subband_frame_count % 200 == 0: 1365f21c38aSMilanka Ringwald print("== Frame %d ==" % (subband_frame_count)) 1375f21c38aSMilanka Ringwald 1385665ea35SMilanka Ringwald actual_frame = get_actual_frame(fin, nr_blocks, nr_subbands, nr_channels, bitpool, sampling_frequency, allocation_method) 1395f21c38aSMilanka Ringwald expected_frame = get_expected_frame(fin_expected) 1405f21c38aSMilanka Ringwald 1415f21c38aSMilanka Ringwald err = sbc_compare_headers(subband_frame_count, actual_frame, expected_frame) 1425f21c38aSMilanka Ringwald if err < 0: 1435f21c38aSMilanka Ringwald exit(1) 1445f21c38aSMilanka Ringwald 1455f21c38aSMilanka Ringwald err = sbc_compare_audio_frames(subband_frame_count, actual_frame, expected_frame) 1465f21c38aSMilanka Ringwald if err < 0: 1475f21c38aSMilanka Ringwald exit(1) 1485665ea35SMilanka Ringwald 1495665ea35SMilanka Ringwald if subband_frame_count == 0: 1505665ea35SMilanka Ringwald print actual_frame 1515665ea35SMilanka Ringwald 1525f21c38aSMilanka Ringwald audio_frame_count += nr_samples 1535f21c38aSMilanka Ringwald subband_frame_count += 1 1545f21c38aSMilanka Ringwald 1555f21c38aSMilanka Ringwald print "DONE, max MSE audio sample error %d", max_error 1565f21c38aSMilanka Ringwald fin.close() 1575f21c38aSMilanka Ringwald fin_expected.close() 1585f21c38aSMilanka Ringwald 1595665ea35SMilanka Ringwaldexcept TypeError: 1605665ea35SMilanka Ringwald print "DONE, max MSE audio sample error %d", max_error 1615665ea35SMilanka Ringwald fin.close() 1625665ea35SMilanka Ringwald fin_expected.close() 1635665ea35SMilanka Ringwald 1645f21c38aSMilanka Ringwaldexcept IOError: 1655f21c38aSMilanka Ringwald print(usage) 1665f21c38aSMilanka Ringwald sys.exit(1) 1675f21c38aSMilanka Ringwald 1685f21c38aSMilanka Ringwald 1695f21c38aSMilanka Ringwald 1705f21c38aSMilanka Ringwald 1715f21c38aSMilanka Ringwald 172