chiark / gitweb /
Merge from dmanual branch
[disorder] / libtests / t-resample.c
CommitLineData
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 */
23static 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 */
31static 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
51static 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
121static 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
167TEST(resample);
168
169/*
170Local Variables:
171c-basic-offset:2
172comment-column:40
173fill-column:79
174indent-tabs-mode:nil
175End:
176*/