xref: /btstack/test/sbc/sbc_decoder_test.py (revision 5665ea35c6aeb92912f2adba24f1fcfce0aa3616)
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_pcm(frame_count, actual_frame, expected_frame):
145f21c38aSMilanka Ringwald    global error, max_error
155f21c38aSMilanka Ringwald
165f21c38aSMilanka Ringwald    M = mse(actual_frame.pcm, expected_frame.pcm)
175f21c38aSMilanka Ringwald    if M > max_error:
185f21c38aSMilanka Ringwald        max_error = M
195f21c38aSMilanka Ringwald
205f21c38aSMilanka Ringwald    if M > error:
215f21c38aSMilanka Ringwald        print "pcm error (%d, %d ) " % (frame_count, M)
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:
285f21c38aSMilanka 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:
325f21c38aSMilanka 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:
365f21c38aSMilanka 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:
405f21c38aSMilanka 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:
445f21c38aSMilanka 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:
485f21c38aSMilanka Ringwald        print "nr_subbands wrong ", actual_frame.nr_subbands
495f21c38aSMilanka Ringwald        return -1
505f21c38aSMilanka Ringwald
515f21c38aSMilanka Ringwald    if actual_frame.bitpool != expected_frame.bitpool:
525f21c38aSMilanka 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
575f21c38aSMilanka Ringwald
585f21c38aSMilanka Ringwalddef get_actual_frame(fin):
595f21c38aSMilanka Ringwald    actual_frame = SBCFrame()
605f21c38aSMilanka Ringwald    sbc_unpack_frame(fin, actual_frame)
615f21c38aSMilanka Ringwald    sbc_reconstruct_subband_samples(actual_frame)
625f21c38aSMilanka Ringwald    sbc_synthesis(actual_frame)
635f21c38aSMilanka Ringwald    return actual_frame
645f21c38aSMilanka Ringwald
65*5665ea35SMilanka Ringwalddef get_expected_frame(fin_expected, nr_blocks, nr_subbands, nr_channels, sampling_frequency, bitpool, allocation_method):
66*5665ea35SMilanka Ringwald    expected_frame = SBCFrame(nr_blocks, nr_subbands, nr_channels, sampling_frequency, bitpool, allocation_method)
675f21c38aSMilanka Ringwald    fetch_samples_for_next_sbc_frame(fin_expected, expected_frame)
685f21c38aSMilanka Ringwald    return expected_frame
695f21c38aSMilanka Ringwald
705f21c38aSMilanka Ringwaldusage = '''
715f21c38aSMilanka RingwaldUsage:      ./sbc_decoder_test.py decoder_input.sbc decoder_expected_output.wav
725f21c38aSMilanka RingwaldExample:    ./sbc_decoder_test.py fanfare-4sb.sbc fanfare-4sb-decoded.wav
735f21c38aSMilanka Ringwald'''
745f21c38aSMilanka Ringwald
755f21c38aSMilanka Ringwaldif (len(sys.argv) < 3):
765f21c38aSMilanka Ringwald    print(usage)
775f21c38aSMilanka Ringwald    sys.exit(1)
785f21c38aSMilanka Ringwaldtry:
795f21c38aSMilanka Ringwald    decoder_input_sbc = sys.argv[1]
805f21c38aSMilanka Ringwald    decoder_expected_wav = sys.argv[2]
815f21c38aSMilanka Ringwald
825f21c38aSMilanka Ringwald    if not decoder_input_sbc.endswith('.sbc'):
835f21c38aSMilanka Ringwald        print(usage)
845f21c38aSMilanka Ringwald        sys.exit(1)
855f21c38aSMilanka Ringwald
865f21c38aSMilanka Ringwald    if not decoder_expected_wav.endswith('.wav'):
875f21c38aSMilanka Ringwald        print(usage)
885f21c38aSMilanka Ringwald        sys.exit(1)
895f21c38aSMilanka Ringwald
905f21c38aSMilanka Ringwald    fin_expected = wave.open(decoder_expected_wav, 'rb')
915f21c38aSMilanka Ringwald    nr_channels, sampwidth, sampling_frequency, nr_audio_frames, comptype, compname =  fin_expected.getparams()
925f21c38aSMilanka Ringwald
935f21c38aSMilanka Ringwald    # print nr_channels, sampwidth, sampling_frequency, nr_audio_frames, comptype, compname
945f21c38aSMilanka Ringwald
955f21c38aSMilanka Ringwald    with open(decoder_input_sbc, 'rb') as fin:
965f21c38aSMilanka Ringwald        try:
975f21c38aSMilanka Ringwald            subband_frame_count = 0
985f21c38aSMilanka Ringwald            while True:
995f21c38aSMilanka Ringwald                if subband_frame_count % 200 == 0:
1005f21c38aSMilanka Ringwald                    print "== Frame %d ==" % (subband_frame_count)
1015f21c38aSMilanka Ringwald
1025f21c38aSMilanka Ringwald                actual_frame = get_actual_frame(fin)
1035f21c38aSMilanka Ringwald
1045f21c38aSMilanka Ringwald                expected_frame = get_expected_frame(fin_expected, actual_frame.nr_blocks,
1055f21c38aSMilanka Ringwald                                                actual_frame.nr_subbands, nr_channels,
106*5665ea35SMilanka Ringwald                                                actual_frame.bitpool, sampling_frequency,
107*5665ea35SMilanka Ringwald                                                actual_frame.allocation_method)
1085f21c38aSMilanka Ringwald
1095f21c38aSMilanka Ringwald
1105f21c38aSMilanka Ringwald                err = sbc_compare_headers(subband_frame_count, actual_frame, expected_frame)
1115f21c38aSMilanka Ringwald                if err < 0:
1125f21c38aSMilanka Ringwald                    exit(1)
1135f21c38aSMilanka Ringwald
1145f21c38aSMilanka Ringwald                err = sbc_compare_pcm(subband_frame_count, actual_frame, expected_frame)
1155f21c38aSMilanka Ringwald                if err < 0:
1165f21c38aSMilanka Ringwald                    exit(1)
1175f21c38aSMilanka Ringwald
118*5665ea35SMilanka Ringwald                if subband_frame_count == 0:
119*5665ea35SMilanka Ringwald                    print actual_frame
120*5665ea35SMilanka Ringwald
1215f21c38aSMilanka Ringwald                subband_frame_count += 1
1225f21c38aSMilanka Ringwald
1235f21c38aSMilanka Ringwald        except TypeError:
1245f21c38aSMilanka Ringwald            fin_expected.close()
1255f21c38aSMilanka Ringwald            fin.close()
1265f21c38aSMilanka Ringwald            print "DONE, max MSE PCM error %d", max_error
1275f21c38aSMilanka Ringwald            exit(0)
1285f21c38aSMilanka Ringwald
1295f21c38aSMilanka Ringwaldexcept IOError as e:
1305f21c38aSMilanka Ringwald    print(usage)
1315f21c38aSMilanka Ringwald    sys.exit(1)
1325f21c38aSMilanka Ringwald
1335f21c38aSMilanka Ringwald
1345f21c38aSMilanka Ringwald
1355f21c38aSMilanka Ringwald
1365f21c38aSMilanka Ringwald
137