Commit | Line | Data |
---|---|---|
0024bde0 RK |
1 | /* |
2 | * This file is part of DisOrder. | |
3 | * Copyright (C) 2009 Richard Kettlewell | |
4 | * | |
5 | * This program is free software: you can redistribute it and/or modify | |
6 | * it under the terms of the GNU General Public License as published by | |
7 | * the Free Software Foundation, either version 3 of the License, or | |
8 | * (at your option) any later version. | |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | * GNU General Public License for more details. | |
14 | * | |
15 | * You should have received a copy of the GNU General Public License | |
16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
17 | */ | |
18 | #include "test.h" | |
19 | #include "resample.h" | |
20 | #include "vector.h" | |
21 | ||
22 | /* Accumulate converted bytes in a dynamic string */ | |
23 | static void converted(uint8_t *bytes, | |
24 | size_t nbytes, | |
25 | void *cd) { | |
26 | struct dynstr *d = cd; | |
27 | dynstr_append_bytes(d, (void *)bytes, nbytes); | |
28 | } | |
29 | ||
30 | /* Converter wrapper */ | |
31 | static uint8_t *convert(const struct resampler *rs, | |
32 | const uint8_t *input, size_t input_bytes, | |
33 | size_t *output_bytes) { | |
34 | struct dynstr d[1]; | |
35 | ||
36 | dynstr_init(d); | |
37 | while(input_bytes > 0) { | |
38 | size_t chunk = input_bytes > 1024 ? 1024 : input_bytes; | |
39 | size_t consumed = resample_convert(rs, | |
40 | input, input_bytes, | |
41 | input_bytes == chunk, | |
42 | converted, | |
43 | d); | |
44 | input += consumed; | |
45 | input_bytes -= consumed; | |
46 | } | |
47 | *output_bytes = d->nvec; | |
48 | return (uint8_t *)d->vec; | |
49 | } | |
50 | ||
0024bde0 RK |
51 | static const struct { |
52 | const char *description; | |
53 | int input_bits; | |
54 | int input_channels; | |
55 | int input_rate; | |
56 | int input_signed; | |
57 | int input_endian; | |
bcb960d5 | 58 | const char *input; |
0024bde0 RK |
59 | size_t input_bytes; |
60 | int output_bits; | |
61 | int output_channels; | |
62 | int output_rate; | |
63 | int output_signed; | |
64 | int output_endian; | |
bcb960d5 | 65 | const char *output; |
0024bde0 RK |
66 | size_t output_bytes; |
67 | } conversions[] = { | |
68 | /* Conversions that don't change the sample rate */ | |
69 | { | |
70 | "empty input", | |
bcb960d5 RK |
71 | 8, 1, 8000, 0, ENDIAN_LITTLE, "", 0, |
72 | 8, 1, 8000, 0, ENDIAN_LITTLE, "", 0 | |
0024bde0 RK |
73 | }, |
74 | { | |
bcb960d5 RK |
75 | "sign flip 8-bit unsigned->signed", |
76 | 8, 1, 8000, 0, ENDIAN_LITTLE, "\x00\x7F\x80\xFF", 4, | |
77 | 8, 1, 8000, 1, ENDIAN_LITTLE, "\x80\xFF\x00\x7F", 4 | |
78 | }, | |
79 | { | |
80 | "sign flip 8-bit signed->unsigned", | |
81 | 8, 1, 8000, 1, ENDIAN_BIG, "\x80\xFF\x00\x7F", 4, | |
82 | 8, 1, 8000, 0, ENDIAN_BIG, "\x00\x7F\x80\xFF", 4 | |
0024bde0 | 83 | }, |
7b2c00b2 RK |
84 | { |
85 | "mono to stereo", | |
bcb960d5 RK |
86 | 8, 1, 8000, 0, ENDIAN_LITTLE, "\x00\x7F\x80\xFF", 4, |
87 | 8, 2, 8000, 0, ENDIAN_LITTLE, "\x00\x00\x7F\x7F\x80\x80\xFF\xFF", 8 | |
88 | }, | |
89 | { | |
90 | "stereo to mono", | |
91 | 8, 2, 8000, 0, ENDIAN_LITTLE, "\x00\x01\x7F\x02\x80\x03\xFF\x04", 8, | |
92 | 8, 1, 8000, 0, ENDIAN_LITTLE, "\x00\x7F\x80\xFF", 4 | |
93 | }, | |
94 | { | |
95 | "endian flip little->big", | |
96 | 16, 1, 8000, 0, ENDIAN_LITTLE, "\x00\x01\x00\xFF\x01\x00\x01\xFF", 8, | |
97 | 16, 1, 8000, 0, ENDIAN_BIG, "\x01\x00\xFF\x00\x00\x01\xFF\x01", 8, | |
98 | }, | |
99 | { | |
100 | "endian flip big->little", | |
101 | 16, 1, 8000, 0, ENDIAN_BIG, "\x01\x00\xFF\x00\x00\x01\xFF\x01", 8, | |
102 | 16, 1, 8000, 0, ENDIAN_LITTLE, "\x00\x01\x00\xFF\x01\x00\x01\xFF", 8, | |
103 | }, | |
104 | { | |
105 | "8-bit to 16-bit", | |
106 | 8, 1, 8000, 0, ENDIAN_BIG, "\x00\x7F\x80\xFF", 4, | |
107 | 16, 1, 8000, 0, ENDIAN_BIG, "\x00\x00\x7F\x00\x80\x00\xFF\x00", 8 | |
7b2c00b2 RK |
108 | }, |
109 | { | |
bcb960d5 RK |
110 | "16-bit to 8-bit", |
111 | 16, 1, 8000, 0, ENDIAN_BIG, "\x00\x00\x7F\xFF\x80\x00\xFF\xFF", 8, | |
112 | 8, 1, 8000, 0, ENDIAN_BIG, "\x00\x7F\x80\xFF", 4 | |
7b2c00b2 | 113 | }, |
0024bde0 RK |
114 | #if HAVE_SAMPLERATE_H |
115 | /* Conversions that do change the sample rate */ | |
116 | ||
117 | #endif | |
118 | }; | |
119 | #define NCONVERSIONS (sizeof conversions / sizeof *conversions) | |
120 | ||
121 | static void test_resample(void) { | |
122 | for(size_t n = 0; n < NCONVERSIONS; ++n) { | |
123 | struct resampler rs[1]; | |
124 | ||
125 | resample_init(rs, | |
126 | conversions[n].input_bits, | |
127 | conversions[n].input_channels, | |
128 | conversions[n].input_rate, | |
129 | conversions[n].input_signed, | |
130 | conversions[n].input_endian, | |
131 | conversions[n].output_bits, | |
132 | conversions[n].output_channels, | |
133 | conversions[n].output_rate, | |
134 | conversions[n].output_signed, | |
135 | conversions[n].output_endian); | |
136 | size_t output_bytes; | |
137 | const uint8_t *output = convert(rs, | |
bcb960d5 | 138 | (const uint8_t *)conversions[n].input, |
0024bde0 RK |
139 | conversions[n].input_bytes, |
140 | &output_bytes); | |
141 | if(output_bytes != conversions[n].output_bytes | |
142 | || memcmp(output, conversions[n].output, output_bytes)) { | |
143 | fprintf(stderr, "index %zu description %s mismatch\n", | |
144 | n, conversions[n].description); | |
145 | size_t k = 0; | |
146 | while(k < conversions[n].output_bytes || k < output_bytes) { | |
147 | size_t j = 0; | |
148 | fprintf(stderr, "%8zu E:", k); | |
149 | for(j = 0; j < 16; ++j) { | |
150 | if(j + k < conversions[n].output_bytes) | |
151 | fprintf(stderr, " %02x", conversions[n].output[j + k]); | |
152 | } | |
153 | fprintf(stderr, "\n G:"); | |
154 | for(j = 0; j < 16; ++j) { | |
155 | if(j + k < output_bytes) | |
156 | fprintf(stderr, " %02x", output[j + k]); | |
157 | } | |
158 | fprintf(stderr, "\n"); | |
159 | k += 16; | |
160 | } | |
161 | ++errors; | |
162 | } | |
163 | ++tests; | |
164 | } | |
165 | } | |
166 | ||
167 | TEST(resample); | |
168 | ||
169 | /* | |
170 | Local Variables: | |
171 | c-basic-offset:2 | |
172 | comment-column:40 | |
173 | fill-column:79 | |
174 | indent-tabs-mode:nil | |
175 | End: | |
176 | */ |