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 135f21c38aSMilanka Ringwalddef sbc_compare_pcm(frame_count, actual_frame, expected_frame): 145f21c38aSMilanka Ringwald global error, max_error 151522543dSMilanka Ringwald for ch in range(actual_frame.nr_channels): 161522543dSMilanka Ringwald M = mse(actual_frame.pcm[ch], expected_frame.pcm[ch]) 175f21c38aSMilanka Ringwald if M > max_error: 185f21c38aSMilanka Ringwald max_error = M 195f21c38aSMilanka Ringwald 20ef8a7a12SMilanka Ringwald if max_error > error: 21*6ccd8248SMilanka Ringwald print("pcm error (%d, %f ) " % (frame_count, max_error)) 225f21c38aSMilanka Ringwald return -1 235f21c38aSMilanka Ringwald return 0 245f21c38aSMilanka Ringwald 255f21c38aSMilanka Ringwald 265f21c38aSMilanka Ringwalddef sbc_compare_headers(frame_count, actual_frame, expected_frame): 275f21c38aSMilanka Ringwald if actual_frame.sampling_frequency != expected_frame.sampling_frequency: 28*6ccd8248SMilanka Ringwald print("sampling_frequency wrong ", actual_frame.sampling_frequency) 295f21c38aSMilanka Ringwald return -1 305f21c38aSMilanka Ringwald 315f21c38aSMilanka Ringwald if actual_frame.nr_blocks != expected_frame.nr_blocks: 32*6ccd8248SMilanka Ringwald print("nr_blocks wrong ", actual_frame.nr_blocks) 335f21c38aSMilanka Ringwald return -1 345f21c38aSMilanka Ringwald 355f21c38aSMilanka Ringwald if actual_frame.channel_mode != expected_frame.channel_mode: 36*6ccd8248SMilanka Ringwald print("channel_mode wrong ", actual_frame.channel_mode) 375f21c38aSMilanka Ringwald return -1 385f21c38aSMilanka Ringwald 395f21c38aSMilanka Ringwald if actual_frame.nr_channels != expected_frame.nr_channels: 40*6ccd8248SMilanka Ringwald print("nr_channels wrong ", actual_frame.nr_channels) 415f21c38aSMilanka Ringwald return -1 425f21c38aSMilanka Ringwald 435f21c38aSMilanka Ringwald if actual_frame.allocation_method != expected_frame.allocation_method: 44*6ccd8248SMilanka Ringwald print("allocation_method wrong ", actual_frame.allocation_method) 455f21c38aSMilanka Ringwald return -1 465f21c38aSMilanka Ringwald 475f21c38aSMilanka Ringwald if actual_frame.nr_subbands != expected_frame.nr_subbands: 48*6ccd8248SMilanka Ringwald print("nr_subbands wrong ", actual_frame.nr_subbands) 495f21c38aSMilanka Ringwald return -1 505f21c38aSMilanka Ringwald 515f21c38aSMilanka Ringwald if actual_frame.bitpool != expected_frame.bitpool: 52*6ccd8248SMilanka Ringwald print("bitpool wrong (E: %d, D: %d)" % (actual_frame.bitpool, expected_frame.bitpool)) 535f21c38aSMilanka Ringwald return -1 545f21c38aSMilanka Ringwald 555f21c38aSMilanka Ringwald return 0 565f21c38aSMilanka Ringwald 574771dcb8SMilanka Ringwaldfile_size = 0 58205be8eaSMilanka Ringwalddef get_actual_frame(fin, implementation, frame_count): 594771dcb8SMilanka Ringwald global file_size 605f21c38aSMilanka Ringwald actual_frame = SBCFrame() 614771dcb8SMilanka Ringwald sbc_unpack_frame(fin, file_size - fin.tell(), actual_frame) 625f21c38aSMilanka Ringwald sbc_reconstruct_subband_samples(actual_frame) 63205be8eaSMilanka Ringwald if subband_frame_count == 0: 64205be8eaSMilanka Ringwald sbc_init_sythesis(actual_frame.nr_subbands, implementation) 65*6ccd8248SMilanka Ringwald print(actual_frame) 66205be8eaSMilanka Ringwald sbc_synthesis(actual_frame, implementation) 675f21c38aSMilanka Ringwald return actual_frame 685f21c38aSMilanka Ringwald 695665ea35SMilanka Ringwalddef get_expected_frame(fin_expected, nr_blocks, nr_subbands, nr_channels, sampling_frequency, bitpool, allocation_method): 705665ea35SMilanka Ringwald expected_frame = SBCFrame(nr_blocks, nr_subbands, nr_channels, sampling_frequency, bitpool, allocation_method) 715f21c38aSMilanka Ringwald fetch_samples_for_next_sbc_frame(fin_expected, expected_frame) 72205be8eaSMilanka Ringwald calculate_channel_mode_and_scale_factors(expected_frame, 0) 735f21c38aSMilanka Ringwald return expected_frame 745f21c38aSMilanka Ringwald 755f21c38aSMilanka Ringwaldusage = ''' 76205be8eaSMilanka RingwaldUsage: ./sbc_decoder_test.py decoder_input.sbc force_channel_mode[No=0, Stereo=2, Joint Stereo=3] implementation[SIG, V1] decoder_expected_output.wav 77205be8eaSMilanka RingwaldExample: ./sbc_decoder_test.py fanfare-4sb.sbc 0 fanfare-4sb-decoded.wav 785f21c38aSMilanka Ringwald''' 795f21c38aSMilanka Ringwald 80205be8eaSMilanka Ringwaldif (len(sys.argv) < 5): 815f21c38aSMilanka Ringwald print(usage) 825f21c38aSMilanka Ringwald sys.exit(1) 835f21c38aSMilanka Ringwaldtry: 845f21c38aSMilanka Ringwald decoder_input_sbc = sys.argv[1] 85205be8eaSMilanka Ringwald force_channel_mode = int(sys.argv[2]) 86205be8eaSMilanka Ringwald implementation = sys.argv[3] 87205be8eaSMilanka Ringwald decoder_expected_wav = sys.argv[4] 885f21c38aSMilanka Ringwald 895f21c38aSMilanka Ringwald if not decoder_input_sbc.endswith('.sbc'): 905f21c38aSMilanka Ringwald print(usage) 915f21c38aSMilanka Ringwald sys.exit(1) 925f21c38aSMilanka Ringwald 935f21c38aSMilanka Ringwald if not decoder_expected_wav.endswith('.wav'): 945f21c38aSMilanka Ringwald print(usage) 955f21c38aSMilanka Ringwald sys.exit(1) 965f21c38aSMilanka Ringwald 97205be8eaSMilanka Ringwald 98205be8eaSMilanka Ringwald 995f21c38aSMilanka Ringwald fin_expected = wave.open(decoder_expected_wav, 'rb') 1005f21c38aSMilanka Ringwald nr_channels, sampwidth, sampling_frequency, nr_audio_frames, comptype, compname = fin_expected.getparams() 1015f21c38aSMilanka Ringwald 1025f21c38aSMilanka Ringwald with open(decoder_input_sbc, 'rb') as fin: 1035f21c38aSMilanka Ringwald try: 1045f21c38aSMilanka Ringwald subband_frame_count = 0 1054771dcb8SMilanka Ringwald fin.seek(0,2) 1064771dcb8SMilanka Ringwald file_size = fin.tell() 1074771dcb8SMilanka Ringwald fin.seek(0,0) 1084771dcb8SMilanka Ringwald 1095f21c38aSMilanka Ringwald while True: 1105f21c38aSMilanka Ringwald if subband_frame_count % 200 == 0: 1114771dcb8SMilanka Ringwald print("== Frame %d ==" % subband_frame_count) 1125f21c38aSMilanka Ringwald 113f08a674bSMilanka Ringwald 114205be8eaSMilanka Ringwald actual_frame = get_actual_frame(fin, implementation, subband_frame_count) 1154771dcb8SMilanka Ringwald 1165f21c38aSMilanka Ringwald expected_frame = get_expected_frame(fin_expected, actual_frame.nr_blocks, 1175f21c38aSMilanka Ringwald actual_frame.nr_subbands, nr_channels, 1185665ea35SMilanka Ringwald actual_frame.bitpool, sampling_frequency, 1195665ea35SMilanka Ringwald actual_frame.allocation_method) 1205f21c38aSMilanka Ringwald 1215f21c38aSMilanka Ringwald err = sbc_compare_headers(subband_frame_count, actual_frame, expected_frame) 122f08a674bSMilanka Ringwald 1235f21c38aSMilanka Ringwald if err < 0: 124205be8eaSMilanka Ringwald print("Frame %d: Headers differ \n%s\n%s" % (subband_frame_count, actual_frame, expected_frame)) 125ef8a7a12SMilanka Ringwald sys.exit(1) 1265f21c38aSMilanka Ringwald 1275f21c38aSMilanka Ringwald err = sbc_compare_pcm(subband_frame_count, actual_frame, expected_frame) 1285f21c38aSMilanka Ringwald if err < 0: 129205be8eaSMilanka Ringwald print("Frame %d: PCMs differ %f \n%s\n%s" % (subband_frame_count, max_error, actual_frame.pcm, expected_frame.pcm)) 130ef8a7a12SMilanka Ringwald sys.exit(1) 1315f21c38aSMilanka Ringwald 1325665ea35SMilanka Ringwald 1335f21c38aSMilanka Ringwald subband_frame_count += 1 1345f21c38aSMilanka Ringwald 1355f21c38aSMilanka Ringwald except TypeError: 1365f21c38aSMilanka Ringwald fin_expected.close() 1375f21c38aSMilanka Ringwald fin.close() 138f08a674bSMilanka Ringwald print("DONE, max MSE PCM error %f" % max_error) 1395f21c38aSMilanka Ringwald 1405f21c38aSMilanka Ringwaldexcept IOError as e: 1415f21c38aSMilanka Ringwald print(usage) 1425f21c38aSMilanka Ringwald sys.exit(1) 1435f21c38aSMilanka Ringwald 1445f21c38aSMilanka Ringwald 1455f21c38aSMilanka Ringwald 1465f21c38aSMilanka Ringwald 1475f21c38aSMilanka Ringwald 148