1*6ccd8248SMilanka Ringwald#!/usr/bin/env python3 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 13ef8a7a12SMilanka Ringwald 14ef8a7a12SMilanka Ringwalddef sbc_compare_subband_samples(frame_count, actual_frame, expected_frame): 155f21c38aSMilanka Ringwald global error, max_error 16ef8a7a12SMilanka Ringwald for blk in range(actual_frame.nr_blocks): 175c9bef5bSMilanka Ringwald for ch in range(actual_frame.nr_channels): 18ef8a7a12SMilanka Ringwald M = mse(actual_frame.sb_sample[blk][ch], expected_frame.sb_sample[blk][ch]) 195f21c38aSMilanka Ringwald if M > max_error: 205f21c38aSMilanka Ringwald max_error = M 215f21c38aSMilanka Ringwald 22ef8a7a12SMilanka Ringwald if max_error > error: 23*6ccd8248SMilanka Ringwald print ("Frame %d: sb_sample error %f (ch %d, blk %d)" % (frame_count, max_error, ch, blk)) 24*6ccd8248SMilanka Ringwald print (actual_frame.sb_sample[blk]) 25*6ccd8248SMilanka Ringwald print (expected_frame.sb_sample[blk]) 26ef8a7a12SMilanka Ringwald return -1 27ef8a7a12SMilanka Ringwald return 0 28ef8a7a12SMilanka Ringwald 29ef8a7a12SMilanka Ringwalddef sbc_compare_audio_frames(frame_count, actual_frame, expected_frame): 30ef8a7a12SMilanka Ringwald global error, max_error 31ef8a7a12SMilanka Ringwald 32ef8a7a12SMilanka Ringwald for blk in range(actual_frame.nr_blocks): 33ef8a7a12SMilanka Ringwald for ch in range(actual_frame.nr_channels): 34ef8a7a12SMilanka Ringwald M = mse(actual_frame.audio_sample[blk][ch], expected_frame.audio_sample[blk][ch]) 35ef8a7a12SMilanka Ringwald if M > max_error: 36ef8a7a12SMilanka Ringwald max_error = M 37ef8a7a12SMilanka Ringwald 38ef8a7a12SMilanka Ringwald if max_error > error: 39*6ccd8248SMilanka Ringwald print ("audio_sample error (%d, %f ) " % (frame_count, max_error)) 40*6ccd8248SMilanka Ringwald print (actual_frame.audio_sample[blk]) 41*6ccd8248SMilanka Ringwald print (expected_frame.audio_sample[blk]) 42ef8a7a12SMilanka Ringwald 435f21c38aSMilanka Ringwald return -1 445f21c38aSMilanka Ringwald return 0 455f21c38aSMilanka Ringwald 465f21c38aSMilanka Ringwalddef sbc_compare_headers(frame_count, actual_frame, expected_frame): 475f21c38aSMilanka Ringwald if actual_frame.syncword != expected_frame.syncword: 48*6ccd8248SMilanka Ringwald print ("syncword wrong ", actual_frame.syncword) 495f21c38aSMilanka Ringwald return -1 505f21c38aSMilanka Ringwald 515f21c38aSMilanka Ringwald if actual_frame.sampling_frequency != expected_frame.sampling_frequency: 52*6ccd8248SMilanka Ringwald print ("sampling_frequency wrong ", actual_frame.sampling_frequency) 535f21c38aSMilanka Ringwald return -1 545f21c38aSMilanka Ringwald 555f21c38aSMilanka Ringwald if actual_frame.nr_blocks != expected_frame.nr_blocks: 56*6ccd8248SMilanka Ringwald print ("nr_blocks wrong ", actual_frame.nr_blocks) 575f21c38aSMilanka Ringwald return -1 585f21c38aSMilanka Ringwald 595f21c38aSMilanka Ringwald if actual_frame.channel_mode != expected_frame.channel_mode: 60*6ccd8248SMilanka Ringwald print ("channel_mode wrong ", actual_frame.channel_mode) 615f21c38aSMilanka Ringwald return -1 625f21c38aSMilanka Ringwald 635f21c38aSMilanka Ringwald if actual_frame.nr_channels != expected_frame.nr_channels: 64*6ccd8248SMilanka Ringwald print ("nr_channels wrong ", actual_frame.nr_channels) 655f21c38aSMilanka Ringwald return -1 665f21c38aSMilanka Ringwald 675f21c38aSMilanka Ringwald if actual_frame.allocation_method != expected_frame.allocation_method: 68*6ccd8248SMilanka Ringwald print ("allocation_method wrong ", actual_frame.allocation_method) 695f21c38aSMilanka Ringwald return -1 705f21c38aSMilanka Ringwald 715f21c38aSMilanka Ringwald if actual_frame.nr_subbands != expected_frame.nr_subbands: 72*6ccd8248SMilanka Ringwald print ("nr_subbands wrong ", actual_frame.nr_subbands) 735f21c38aSMilanka Ringwald return -1 745f21c38aSMilanka Ringwald 755f21c38aSMilanka Ringwald if actual_frame.bitpool != expected_frame.bitpool: 76*6ccd8248SMilanka Ringwald print ("bitpool wrong (E: %d, D: %d)" % (actual_frame.bitpool, expected_frame.bitpool)) 775f21c38aSMilanka Ringwald return -1 785f21c38aSMilanka Ringwald 795f21c38aSMilanka Ringwald if mse(actual_frame.join, expected_frame.join) > 0: 80*6ccd8248SMilanka Ringwald print ("join error \nE:\n %s \nD:\n %s" % (actual_frame.join, expected_frame.join)) 815f21c38aSMilanka Ringwald return -1 825f21c38aSMilanka Ringwald 835c9bef5bSMilanka Ringwald 845f21c38aSMilanka Ringwald if mse(actual_frame.scale_factor, expected_frame.scale_factor) > 0: 85*6ccd8248SMilanka Ringwald print ("scale_factor error %d \nE:\n %s \nD:\n %s" % (frame_count, actual_frame.scale_factor, expected_frame.scale_factor)) 865f21c38aSMilanka Ringwald return -1 875f21c38aSMilanka Ringwald 885f21c38aSMilanka Ringwald if mse(actual_frame.scalefactor, expected_frame.scalefactor) > 0: 89*6ccd8248SMilanka Ringwald print ("scalefactor error %d \nE:\n %s \nD:\n %s" % (frame_count, actual_frame.scalefactor, expected_frame.scalefactor)) 905f21c38aSMilanka Ringwald return -1 915f21c38aSMilanka Ringwald 925f21c38aSMilanka Ringwald if mse(actual_frame.bits, expected_frame.bits) > 0: 93*6ccd8248SMilanka Ringwald print ("bits error %d \nE:\n %s \nD:\n %s" % (frame_count, actual_frame.bits, expected_frame.bits)) 945f21c38aSMilanka Ringwald return -1 955f21c38aSMilanka Ringwald 965f21c38aSMilanka Ringwald if actual_frame.crc_check != expected_frame.crc_check: 97*6ccd8248SMilanka Ringwald print ("crc_check wrong (E: %d, D: %d)" % (actual_frame.crc_check, expected_frame.crc_check)) 985f21c38aSMilanka Ringwald return -1 995f21c38aSMilanka Ringwald 1005f21c38aSMilanka Ringwald return 0 1015f21c38aSMilanka Ringwald 1025f21c38aSMilanka Ringwald 103ef8a7a12SMilanka Ringwalddef get_actual_frame(fin, nr_blocks, nr_subbands, nr_channels, sampling_frequency, bitpool, allocation_method, force_channel_mode): 1045665ea35SMilanka Ringwald actual_frame = SBCFrame(nr_blocks, nr_subbands, nr_channels, sampling_frequency, bitpool, allocation_method) 1055f21c38aSMilanka Ringwald fetch_samples_for_next_sbc_frame(fin, actual_frame) 106ef8a7a12SMilanka Ringwald sbc_encode(actual_frame, force_channel_mode) 1075f21c38aSMilanka Ringwald return actual_frame 1085f21c38aSMilanka Ringwald 1095665ea35SMilanka Ringwaldfile_size = 0 1105f21c38aSMilanka Ringwalddef get_expected_frame(fin_expected): 1115665ea35SMilanka Ringwald global file_size 1125f21c38aSMilanka Ringwald expected_frame = SBCFrame() 1135665ea35SMilanka Ringwald sbc_unpack_frame(fin_expected, file_size - fin_expected.tell(), expected_frame) 114ef8a7a12SMilanka Ringwald sbc_reconstruct_subband_samples(expected_frame) 1155f21c38aSMilanka Ringwald return expected_frame 1165f21c38aSMilanka Ringwald 1175f21c38aSMilanka Ringwaldusage = ''' 118ef8a7a12SMilanka RingwaldUsage: ./sbc_encoder_test.py encoder_input.wav blocks subbands bitpool allocation_method force_channel_mode encoder_expected_output.sbc 119ef8a7a12SMilanka RingwaldExample: ./sbc_encoder_test.py fanfare.wav 16 4 31 0 2 fanfare-4sb.sbc 1205f21c38aSMilanka Ringwald''' 1215f21c38aSMilanka Ringwald 122ef8a7a12SMilanka Ringwaldif (len(sys.argv) < 8): 1235f21c38aSMilanka Ringwald print(usage) 1245f21c38aSMilanka Ringwald sys.exit(1) 1255f21c38aSMilanka Ringwaldtry: 1265f21c38aSMilanka Ringwald encoder_input_wav = sys.argv[1] 1275f21c38aSMilanka Ringwald nr_blocks = int(sys.argv[2]) 1285f21c38aSMilanka Ringwald nr_subbands = int(sys.argv[3]) 1295f21c38aSMilanka Ringwald bitpool = int(sys.argv[4]) 1305665ea35SMilanka Ringwald allocation_method = int(sys.argv[5]) 1315665ea35SMilanka Ringwald encoder_expected_sbc = sys.argv[6] 132205be8eaSMilanka Ringwald force_channel_mode = int(sys.argv[7]) 1335f21c38aSMilanka Ringwald sampling_frequency = 44100 1345f21c38aSMilanka Ringwald 1355f21c38aSMilanka Ringwald if not encoder_input_wav.endswith('.wav'): 1365f21c38aSMilanka Ringwald print(usage) 1375f21c38aSMilanka Ringwald sys.exit(1) 1385f21c38aSMilanka Ringwald 1395f21c38aSMilanka Ringwald if not encoder_expected_sbc.endswith('.sbc'): 1405f21c38aSMilanka Ringwald print(usage) 1415f21c38aSMilanka Ringwald sys.exit(1) 1425f21c38aSMilanka Ringwald 1435f21c38aSMilanka Ringwald fin = wave.open(encoder_input_wav, 'rb') 1445f21c38aSMilanka Ringwald nr_channels = fin.getnchannels() 1455f21c38aSMilanka Ringwald sampling_frequency = fin.getframerate() 1465f21c38aSMilanka Ringwald nr_audio_frames = fin.getnframes() 1475f21c38aSMilanka Ringwald 1485f21c38aSMilanka Ringwald fin_expected = open(encoder_expected_sbc, 'rb') 1495665ea35SMilanka Ringwald fin_expected.seek(0,2) 1505665ea35SMilanka Ringwald file_size = fin_expected.tell() 1515665ea35SMilanka Ringwald fin_expected.seek(0,0) 1525665ea35SMilanka Ringwald 1535f21c38aSMilanka Ringwald subband_frame_count = 0 1545f21c38aSMilanka Ringwald audio_frame_count = 0 1555f21c38aSMilanka Ringwald nr_samples = nr_blocks * nr_subbands 1565f21c38aSMilanka Ringwald 1575f21c38aSMilanka Ringwald while audio_frame_count < nr_audio_frames: 1585f21c38aSMilanka Ringwald if subband_frame_count % 200 == 0: 1595f21c38aSMilanka Ringwald print("== Frame %d ==" % (subband_frame_count)) 1605f21c38aSMilanka Ringwald 161ef8a7a12SMilanka Ringwald actual_frame = get_actual_frame(fin, nr_blocks, nr_subbands, nr_channels, bitpool, sampling_frequency, allocation_method, force_channel_mode) 1625f21c38aSMilanka Ringwald expected_frame = get_expected_frame(fin_expected) 1635f21c38aSMilanka Ringwald 1645f21c38aSMilanka Ringwald err = sbc_compare_headers(subband_frame_count, actual_frame, expected_frame) 1655f21c38aSMilanka Ringwald if err < 0: 1665f21c38aSMilanka Ringwald exit(1) 1675f21c38aSMilanka Ringwald 1685f21c38aSMilanka Ringwald err = sbc_compare_audio_frames(subband_frame_count, actual_frame, expected_frame) 1695f21c38aSMilanka Ringwald if err < 0: 1705f21c38aSMilanka Ringwald exit(1) 1715665ea35SMilanka Ringwald 1725f21c38aSMilanka Ringwald audio_frame_count += nr_samples 1735f21c38aSMilanka Ringwald subband_frame_count += 1 1745f21c38aSMilanka Ringwald 175ef8a7a12SMilanka Ringwald print ("Max MSE audio sample error %f" % max_error) 1765f21c38aSMilanka Ringwald fin.close() 1775f21c38aSMilanka Ringwald fin_expected.close() 1785f21c38aSMilanka Ringwald 1795665ea35SMilanka Ringwaldexcept TypeError: 180ef8a7a12SMilanka Ringwald print ("Max MSE audio sample error %f" % max_error) 1815665ea35SMilanka Ringwald fin.close() 1825665ea35SMilanka Ringwald fin_expected.close() 1835665ea35SMilanka Ringwald 1845f21c38aSMilanka Ringwaldexcept IOError: 1855f21c38aSMilanka Ringwald print(usage) 1865f21c38aSMilanka Ringwald sys.exit(1) 1875f21c38aSMilanka Ringwald 1885f21c38aSMilanka Ringwald 1895f21c38aSMilanka Ringwald 1905f21c38aSMilanka Ringwald 1915f21c38aSMilanka Ringwald 192