xref: /btstack/test/sbc/sbc_decoder_test.py (revision ef8a7a12f41cfc681f8f5d2d0890863f62c52a4e)
1#!/usr/bin/env python
2import numpy as np
3import wave
4import struct
5import sys
6from sbc import *
7from sbc_encoder import *
8from sbc_decoder import *
9
10error = 0.99
11max_error = -1
12
13def sbc_compare_pcm(frame_count, actual_frame, expected_frame):
14    global error, max_error
15    for ch in range(actual_frame.nr_channels):
16        M = mse(actual_frame.pcm[ch], expected_frame.pcm[ch])
17        if M > max_error:
18            max_error = M
19
20        if max_error > error:
21            print "pcm error (%d, %f ) " % (frame_count, max_error)
22            return -1
23    return 0
24
25
26def sbc_compare_headers(frame_count, actual_frame, expected_frame):
27    if actual_frame.sampling_frequency != expected_frame.sampling_frequency:
28        print "sampling_frequency wrong ", actual_frame.sampling_frequency
29        return -1
30
31    if actual_frame.nr_blocks != expected_frame.nr_blocks:
32        print "nr_blocks wrong ", actual_frame.nr_blocks
33        return -1
34
35    if actual_frame.channel_mode != expected_frame.channel_mode:
36        print "channel_mode wrong ", actual_frame.channel_mode
37        return -1
38
39    if actual_frame.nr_channels != expected_frame.nr_channels:
40        print "nr_channels wrong ", actual_frame.nr_channels
41        return -1
42
43    if actual_frame.allocation_method != expected_frame.allocation_method:
44        print "allocation_method wrong ", actual_frame.allocation_method
45        return -1
46
47    if actual_frame.nr_subbands != expected_frame.nr_subbands:
48        print "nr_subbands wrong ", actual_frame.nr_subbands
49        return -1
50
51    if actual_frame.bitpool != expected_frame.bitpool:
52        print "bitpool wrong (E: %d, D: %d)" % (actual_frame.bitpool, expected_frame.bitpool)
53        return -1
54
55    return 0
56
57file_size = 0
58def get_actual_frame(fin):
59    global file_size
60    actual_frame = SBCFrame()
61    sbc_unpack_frame(fin, file_size - fin.tell(), actual_frame)
62    sbc_reconstruct_subband_samples(actual_frame)
63    sbc_synthesis(actual_frame)
64    return actual_frame
65
66def get_expected_frame(fin_expected, nr_blocks, nr_subbands, nr_channels, sampling_frequency, bitpool, allocation_method):
67    expected_frame = SBCFrame(nr_blocks, nr_subbands, nr_channels, sampling_frequency, bitpool, allocation_method)
68    fetch_samples_for_next_sbc_frame(fin_expected, expected_frame)
69    calculate_channel_mode_and_scale_factors(expected_frame)
70    return expected_frame
71
72usage = '''
73Usage:      ./sbc_decoder_test.py decoder_input.sbc decoder_expected_output.wav
74Example:    ./sbc_decoder_test.py fanfare-4sb.sbc fanfare-4sb-decoded.wav
75'''
76
77if (len(sys.argv) < 3):
78    print(usage)
79    sys.exit(1)
80try:
81    decoder_input_sbc = sys.argv[1]
82    decoder_expected_wav = sys.argv[2]
83
84    if not decoder_input_sbc.endswith('.sbc'):
85        print(usage)
86        sys.exit(1)
87
88    if not decoder_expected_wav.endswith('.wav'):
89        print(usage)
90        sys.exit(1)
91
92    fin_expected = wave.open(decoder_expected_wav, 'rb')
93    nr_channels, sampwidth, sampling_frequency, nr_audio_frames, comptype, compname =  fin_expected.getparams()
94
95    with open(decoder_input_sbc, 'rb') as fin:
96        try:
97            subband_frame_count = 0
98            fin.seek(0,2)
99            file_size = fin.tell()
100            fin.seek(0,0)
101
102            while True:
103                if subband_frame_count % 200 == 0:
104                    print ("== Frame %d ==" % subband_frame_count)
105
106
107                actual_frame = get_actual_frame(fin)
108
109
110                expected_frame = get_expected_frame(fin_expected, actual_frame.nr_blocks,
111                                                actual_frame.nr_subbands, nr_channels,
112                                                actual_frame.bitpool, sampling_frequency,
113                                                actual_frame.allocation_method)
114
115                err = sbc_compare_headers(subband_frame_count, actual_frame, expected_frame)
116
117                if err < 0:
118                    print ("Headers differ \n%s\n%s" % (actual_frame, expected_frame))
119                    sys.exit(1)
120
121                err = sbc_compare_pcm(subband_frame_count, actual_frame, expected_frame)
122                if err < 0:
123                    print ("PCMs differ \n%s\n%s" % (actual_frame.pcm, expected_frame.pcm))
124                    sys.exit(1)
125
126                if subband_frame_count == 0:
127                    print actual_frame, expected_frame
128
129                subband_frame_count += 1
130
131        except TypeError:
132            fin_expected.close()
133            fin.close()
134            print ("DONE, max MSE PCM error %f" % max_error)
135
136except IOError as e:
137    print(usage)
138    sys.exit(1)
139
140
141
142
143
144