chiark / gitweb /
1dbdf8b999aff56b77a579b0556058670dd6b26c
[disorder] / libtests / t-resample.c
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 */