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 | ||
51 | static const uint8_t simple_bytes_u[] = { | |
52 | 0, 127, 128, 255, | |
53 | }; | |
54 | ||
55 | static const uint8_t simple_bytes_s[] = { | |
56 | -128, -1, 0, 127, | |
57 | }; | |
58 | ||
59 | static const struct { | |
60 | const char *description; | |
61 | int input_bits; | |
62 | int input_channels; | |
63 | int input_rate; | |
64 | int input_signed; | |
65 | int input_endian; | |
66 | const uint8_t *input; | |
67 | size_t input_bytes; | |
68 | int output_bits; | |
69 | int output_channels; | |
70 | int output_rate; | |
71 | int output_signed; | |
72 | int output_endian; | |
73 | const uint8_t *output; | |
74 | size_t output_bytes; | |
75 | } conversions[] = { | |
76 | /* Conversions that don't change the sample rate */ | |
77 | { | |
78 | "empty input", | |
79 | 8, 1, 8000, 0, ENDIAN_LITTLE, (const uint8_t *)"", 0, | |
80 | 8, 1, 8000, 0, ENDIAN_LITTLE, (const uint8_t *)"", 0 | |
81 | }, | |
82 | { | |
83 | "sign flip", | |
84 | 8, 1, 8000, 0, ENDIAN_LITTLE, simple_bytes_u, 4, | |
85 | 8, 1, 8000, 1, ENDIAN_LITTLE, simple_bytes_s, 4 | |
86 | }, | |
87 | #if HAVE_SAMPLERATE_H | |
88 | /* Conversions that do change the sample rate */ | |
89 | ||
90 | #endif | |
91 | }; | |
92 | #define NCONVERSIONS (sizeof conversions / sizeof *conversions) | |
93 | ||
94 | static void test_resample(void) { | |
95 | for(size_t n = 0; n < NCONVERSIONS; ++n) { | |
96 | struct resampler rs[1]; | |
97 | ||
98 | resample_init(rs, | |
99 | conversions[n].input_bits, | |
100 | conversions[n].input_channels, | |
101 | conversions[n].input_rate, | |
102 | conversions[n].input_signed, | |
103 | conversions[n].input_endian, | |
104 | conversions[n].output_bits, | |
105 | conversions[n].output_channels, | |
106 | conversions[n].output_rate, | |
107 | conversions[n].output_signed, | |
108 | conversions[n].output_endian); | |
109 | size_t output_bytes; | |
110 | const uint8_t *output = convert(rs, | |
111 | conversions[n].input, | |
112 | conversions[n].input_bytes, | |
113 | &output_bytes); | |
114 | if(output_bytes != conversions[n].output_bytes | |
115 | || memcmp(output, conversions[n].output, output_bytes)) { | |
116 | fprintf(stderr, "index %zu description %s mismatch\n", | |
117 | n, conversions[n].description); | |
118 | size_t k = 0; | |
119 | while(k < conversions[n].output_bytes || k < output_bytes) { | |
120 | size_t j = 0; | |
121 | fprintf(stderr, "%8zu E:", k); | |
122 | for(j = 0; j < 16; ++j) { | |
123 | if(j + k < conversions[n].output_bytes) | |
124 | fprintf(stderr, " %02x", conversions[n].output[j + k]); | |
125 | } | |
126 | fprintf(stderr, "\n G:"); | |
127 | for(j = 0; j < 16; ++j) { | |
128 | if(j + k < output_bytes) | |
129 | fprintf(stderr, " %02x", output[j + k]); | |
130 | } | |
131 | fprintf(stderr, "\n"); | |
132 | k += 16; | |
133 | } | |
134 | ++errors; | |
135 | } | |
136 | ++tests; | |
137 | } | |
138 | } | |
139 | ||
140 | TEST(resample); | |
141 | ||
142 | /* | |
143 | Local Variables: | |
144 | c-basic-offset:2 | |
145 | comment-column:40 | |
146 | fill-column:79 | |
147 | indent-tabs-mode:nil | |
148 | End: | |
149 | */ |