xref: /btstack/test/sbc/sbc_encoder_test.py (revision 5c9bef5ba273d4d18de0f76f9370002de99dfae4)
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_audio_frames(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.audio_sample, expected_frame.audio_sample)
17        if M > max_error:
18            max_error = M
19
20        if M > error:
21            print "audio_sample error (%d, %f ) " % (frame_count, M)
22            return -1
23    return 0
24
25def sbc_compare_headers(frame_count, actual_frame, expected_frame):
26    if actual_frame.syncword != expected_frame.syncword:
27        print "syncword wrong ", actual_frame.syncword
28        return -1
29
30    if actual_frame.sampling_frequency != expected_frame.sampling_frequency:
31        print "sampling_frequency wrong ", actual_frame.sampling_frequency
32        return -1
33
34    if actual_frame.nr_blocks != expected_frame.nr_blocks:
35        print "nr_blocks wrong ", actual_frame.nr_blocks
36        return -1
37
38    if actual_frame.channel_mode != expected_frame.channel_mode:
39        print "channel_mode wrong ", actual_frame.channel_mode
40        return -1
41
42    if actual_frame.nr_channels != expected_frame.nr_channels:
43        print "nr_channels wrong ", actual_frame.nr_channels
44        return -1
45
46    if actual_frame.allocation_method != expected_frame.allocation_method:
47        print "allocation_method wrong ", actual_frame.allocation_method
48        return -1
49
50    if actual_frame.nr_subbands != expected_frame.nr_subbands:
51        print "nr_subbands wrong ", actual_frame.nr_subbands
52        return -1
53
54    if actual_frame.bitpool != expected_frame.bitpool:
55        print "bitpool wrong (E: %d, D: %d)" % (actual_frame.bitpool, expected_frame.bitpool)
56        return -1
57
58    if  mse(actual_frame.join, expected_frame.join) > 0:
59        print "join error \nE:\n %s \nD:\n %s" % (actual_frame.join, expected_frame.join)
60        return -1
61
62
63    if  mse(actual_frame.scale_factor, expected_frame.scale_factor) > 0:
64        print "scale_factor error \nE:\n %s \nD:\n %s" % (actual_frame.scale_factor, expected_frame.scale_factor)
65        return -1
66
67    if  mse(actual_frame.scalefactor, expected_frame.scalefactor) > 0:
68        print "scalefactor error \nE:\n %s \nD:\n %s" % (actual_frame.scalefactor, expected_frame.scalefactor)
69        return -1
70
71    if  mse(actual_frame.bits, expected_frame.bits) > 0:
72        print "bits error \nE:\n %s \nD:\n %s" % (actual_frame.bits, expected_frame.bits)
73        return -1
74
75    if actual_frame.crc_check != expected_frame.crc_check:
76        print "crc_check wrong (E: %d, D: %d)" % (actual_frame.crc_check, expected_frame.crc_check)
77        return -1
78
79    return 0
80
81
82def get_actual_frame(fin, nr_blocks, nr_subbands, nr_channels, sampling_frequency, bitpool, allocation_method):
83    actual_frame = SBCFrame(nr_blocks, nr_subbands, nr_channels, sampling_frequency, bitpool, allocation_method)
84    fetch_samples_for_next_sbc_frame(fin, actual_frame)
85    sbc_encode(actual_frame)
86    return actual_frame
87
88file_size = 0
89def get_expected_frame(fin_expected):
90    global file_size
91    expected_frame = SBCFrame()
92    sbc_unpack_frame(fin_expected, file_size - fin_expected.tell(), expected_frame)
93    return expected_frame
94
95usage = '''
96Usage:      ./sbc_encoder_test.py encoder_input.wav blocks subbands bitpool allocation_method encoder_expected_output.sbc
97Example:    ./sbc_encoder_test.py fanfare.wav 16 4 31 0 fanfare-4sb.sbc
98'''
99
100if (len(sys.argv) < 7):
101    print(usage)
102    sys.exit(1)
103try:
104    encoder_input_wav = sys.argv[1]
105    nr_blocks = int(sys.argv[2])
106    nr_subbands = int(sys.argv[3])
107    bitpool = int(sys.argv[4])
108    allocation_method = int(sys.argv[5])
109    encoder_expected_sbc = sys.argv[6]
110    sampling_frequency = 44100
111
112    if not encoder_input_wav.endswith('.wav'):
113        print(usage)
114        sys.exit(1)
115
116    if not encoder_expected_sbc.endswith('.sbc'):
117        print(usage)
118        sys.exit(1)
119
120    fin = wave.open(encoder_input_wav, 'rb')
121    nr_channels = fin.getnchannels()
122    sampling_frequency = fin.getframerate()
123    nr_audio_frames = fin.getnframes()
124
125    fin_expected = open(encoder_expected_sbc, 'rb')
126    fin_expected.seek(0,2)
127    file_size = fin_expected.tell()
128    fin_expected.seek(0,0)
129
130    subband_frame_count = 0
131    audio_frame_count = 0
132    nr_samples = nr_blocks * nr_subbands
133
134    while audio_frame_count < nr_audio_frames:
135        if subband_frame_count % 200 == 0:
136            print("== Frame %d ==" % (subband_frame_count))
137
138        actual_frame = get_actual_frame(fin, nr_blocks, nr_subbands, nr_channels, bitpool, sampling_frequency, allocation_method)
139        expected_frame = get_expected_frame(fin_expected)
140
141        err = sbc_compare_headers(subband_frame_count, actual_frame, expected_frame)
142        if err < 0:
143            exit(1)
144
145        err = sbc_compare_audio_frames(subband_frame_count, actual_frame, expected_frame)
146        if err < 0:
147            exit(1)
148
149        if subband_frame_count == 0:
150            print actual_frame
151
152        audio_frame_count += nr_samples
153        subband_frame_count += 1
154
155    print "DONE, max MSE audio sample error %d", max_error
156    fin.close()
157    fin_expected.close()
158
159except TypeError:
160    print "DONE, max MSE audio sample error %d", max_error
161    fin.close()
162    fin_expected.close()
163
164except IOError:
165    print(usage)
166    sys.exit(1)
167
168
169
170
171
172