Git init
[framework/multimedia/pulseaudio.git] / src / tests / resampler-test.c
1 /***
2   This file is part of PulseAudio.
3
4   PulseAudio is free software; you can redistribute it and/or modify
5   it under the terms of the GNU Lesser General Public License as published
6   by the Free Software Foundation; either version 2.1 of the License,
7   or (at your option) any later version.
8
9   PulseAudio is distributed in the hope that it will be useful, but
10   WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12   General Public License for more details.
13
14   You should have received a copy of the GNU Lesser General Public License
15   along with PulseAudio; if not, write to the Free Software
16   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17   USA.
18 ***/
19
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include <stdio.h>
25
26 #include <pulse/sample.h>
27 #include <pulse/volume.h>
28
29 #include <pulsecore/resampler.h>
30 #include <pulsecore/macro.h>
31 #include <pulsecore/endianmacros.h>
32 #include <pulsecore/memblock.h>
33 #include <pulsecore/sample-util.h>
34
35 static void dump_block(const pa_sample_spec *ss, const pa_memchunk *chunk) {
36     void *d;
37     unsigned i;
38
39     d = pa_memblock_acquire(chunk->memblock);
40
41     switch (ss->format) {
42
43         case PA_SAMPLE_U8:
44         case PA_SAMPLE_ULAW:
45         case PA_SAMPLE_ALAW: {
46             uint8_t *u = d;
47
48             for (i = 0; i < chunk->length / pa_frame_size(ss); i++)
49                 printf("      0x%02x ", *(u++));
50
51             break;
52         }
53
54         case PA_SAMPLE_S16NE:
55         case PA_SAMPLE_S16RE: {
56             uint16_t *u = d;
57
58             for (i = 0; i < chunk->length / pa_frame_size(ss); i++)
59                 printf("    0x%04x ", *(u++));
60
61             break;
62         }
63
64         case PA_SAMPLE_S32NE:
65         case PA_SAMPLE_S32RE: {
66             uint32_t *u = d;
67
68             for (i = 0; i < chunk->length / pa_frame_size(ss); i++)
69                 printf("0x%08x ", *(u++));
70
71             break;
72         }
73
74         case PA_SAMPLE_S24_32NE:
75         case PA_SAMPLE_S24_32RE: {
76             uint32_t *u = d;
77
78             for (i = 0; i < chunk->length / pa_frame_size(ss); i++)
79                 printf("0x%08x ", *(u++));
80
81             break;
82         }
83
84         case PA_SAMPLE_FLOAT32NE:
85         case PA_SAMPLE_FLOAT32RE: {
86             float *u = d;
87
88             for (i = 0; i < chunk->length / pa_frame_size(ss); i++) {
89                 printf("%4.3g ", ss->format == PA_SAMPLE_FLOAT32NE ? *u : PA_FLOAT32_SWAP(*u));
90                 u++;
91             }
92
93             break;
94         }
95
96         case PA_SAMPLE_S24LE:
97         case PA_SAMPLE_S24BE: {
98             uint8_t *u = d;
99
100             for (i = 0; i < chunk->length / pa_frame_size(ss); i++) {
101                 printf("  0x%06x ", PA_READ24NE(u));
102                 u += pa_frame_size(ss);
103             }
104
105             break;
106         }
107
108         default:
109             pa_assert_not_reached();
110     }
111
112     printf("\n");
113
114     pa_memblock_release(chunk->memblock);
115 }
116
117 static pa_memblock* generate_block(pa_mempool *pool, const pa_sample_spec *ss) {
118     pa_memblock *r;
119     void *d;
120     unsigned i;
121
122     pa_assert_se(r = pa_memblock_new(pool, pa_frame_size(ss) * 10));
123     d = pa_memblock_acquire(r);
124
125     switch (ss->format) {
126
127         case PA_SAMPLE_U8:
128         case PA_SAMPLE_ULAW:
129         case PA_SAMPLE_ALAW: {
130             uint8_t *u = d;
131
132             u[0] = 0x00;
133             u[1] = 0xFF;
134             u[2] = 0x7F;
135             u[3] = 0x80;
136             u[4] = 0x9f;
137             u[5] = 0x3f;
138             u[6] = 0x1;
139             u[7] = 0xF0;
140             u[8] = 0x20;
141             u[9] = 0x21;
142             break;
143         }
144
145         case PA_SAMPLE_S16NE:
146         case PA_SAMPLE_S16RE: {
147             uint16_t *u = d;
148
149             u[0] = 0x0000;
150             u[1] = 0xFFFF;
151             u[2] = 0x7FFF;
152             u[3] = 0x8000;
153             u[4] = 0x9fff;
154             u[5] = 0x3fff;
155             u[6] = 0x1;
156             u[7] = 0xF000;
157             u[8] = 0x20;
158             u[9] = 0x21;
159             break;
160         }
161
162         case PA_SAMPLE_S32NE:
163         case PA_SAMPLE_S32RE: {
164             uint32_t *u = d;
165
166             u[0] = 0x00000001;
167             u[1] = 0xFFFF0002;
168             u[2] = 0x7FFF0003;
169             u[3] = 0x80000004;
170             u[4] = 0x9fff0005;
171             u[5] = 0x3fff0006;
172             u[6] =    0x10007;
173             u[7] = 0xF0000008;
174             u[8] =   0x200009;
175             u[9] =   0x21000A;
176             break;
177         }
178
179         case PA_SAMPLE_S24_32NE:
180         case PA_SAMPLE_S24_32RE: {
181             uint32_t *u = d;
182
183             u[0] = 0x000001;
184             u[1] = 0xFF0002;
185             u[2] = 0x7F0003;
186             u[3] = 0x800004;
187             u[4] = 0x9f0005;
188             u[5] = 0x3f0006;
189             u[6] =    0x107;
190             u[7] = 0xF00008;
191             u[8] =   0x2009;
192             u[9] =   0x210A;
193             break;
194         }
195
196         case PA_SAMPLE_FLOAT32NE:
197         case PA_SAMPLE_FLOAT32RE: {
198             float *u = d;
199
200             u[0] = 0.0f;
201             u[1] = -1.0f;
202             u[2] = 1.0f;
203             u[3] = 4711.0f;
204             u[4] = 0.222f;
205             u[5] = 0.33f;
206             u[6] = -.3f;
207             u[7] = 99.0f;
208             u[8] = -0.555f;
209             u[9] = -.123f;
210
211             if (ss->format == PA_SAMPLE_FLOAT32RE)
212                 for (i = 0; i < 10; i++)
213                     u[i] = PA_FLOAT32_SWAP(u[i]);
214
215             break;
216         }
217
218         case PA_SAMPLE_S24NE:
219         case PA_SAMPLE_S24RE: {
220             uint8_t *u = d;
221
222             PA_WRITE24NE(u,    0x000001);
223             PA_WRITE24NE(u+3,  0xFF0002);
224             PA_WRITE24NE(u+6,  0x7F0003);
225             PA_WRITE24NE(u+9,  0x800004);
226             PA_WRITE24NE(u+12, 0x9f0005);
227             PA_WRITE24NE(u+15, 0x3f0006);
228             PA_WRITE24NE(u+18,    0x107);
229             PA_WRITE24NE(u+21, 0xF00008);
230             PA_WRITE24NE(u+24,   0x2009);
231             PA_WRITE24NE(u+27,   0x210A);
232             break;
233         }
234
235         default:
236             pa_assert_not_reached();
237     }
238
239     pa_memblock_release(r);
240
241     return r;
242 }
243
244 int main(int argc, char *argv[]) {
245     pa_mempool *pool;
246     pa_sample_spec a, b;
247     pa_cvolume v;
248
249     pa_log_set_level(PA_LOG_DEBUG);
250
251     pa_assert_se(pool = pa_mempool_new(FALSE, 0));
252
253     a.channels = b.channels = 1;
254     a.rate = b.rate = 44100;
255
256     v.channels = a.channels;
257     v.values[0] = pa_sw_volume_from_linear(0.5);
258
259     for (a.format = 0; a.format < PA_SAMPLE_MAX; a.format ++) {
260         for (b.format = 0; b.format < PA_SAMPLE_MAX; b.format ++) {
261             pa_resampler *forth, *back;
262             pa_memchunk i, j, k;
263
264             printf("=== %s -> %s -> %s -> /2\n",
265                    pa_sample_format_to_string(a.format),
266                    pa_sample_format_to_string(b.format),
267                    pa_sample_format_to_string(a.format));
268
269             pa_assert_se(forth = pa_resampler_new(pool, &a, NULL, &b, NULL, PA_RESAMPLER_AUTO, 0));
270             pa_assert_se(back = pa_resampler_new(pool, &b, NULL, &a, NULL, PA_RESAMPLER_AUTO, 0));
271
272             i.memblock = generate_block(pool, &a);
273             i.length = pa_memblock_get_length(i.memblock);
274             i.index = 0;
275             pa_resampler_run(forth, &i, &j);
276             pa_resampler_run(back, &j, &k);
277
278             printf("before:  ");
279             dump_block(&a, &i);
280             printf("after :  ");
281             dump_block(&b, &j);
282             printf("reverse: ");
283             dump_block(&a, &k);
284
285             pa_memblock_unref(j.memblock);
286             pa_memblock_unref(k.memblock);
287
288             pa_volume_memchunk(&i, &a, &v);
289             printf("volume:  ");
290             dump_block(&a, &i);
291
292             pa_memblock_unref(i.memblock);
293
294             pa_resampler_free(forth);
295             pa_resampler_free(back);
296         }
297     }
298
299     pa_mempool_free(pool);
300
301     return 0;
302 }