]> code.delx.au - pulseaudio/blob - src/tests/mix-test.c
mix-test: fix test for s24-32 samples
[pulseaudio] / src / tests / mix-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 #include <liboil/liboil.h>
36
37 static float swap_float(float a) {
38 uint32_t *b = (uint32_t*) &a;
39 *b = PA_UINT32_SWAP(*b);
40 return a;
41 }
42
43 static void dump_block(const pa_sample_spec *ss, const pa_memchunk *chunk) {
44 void *d;
45 unsigned i;
46
47 d = pa_memblock_acquire(chunk->memblock);
48
49 switch (ss->format) {
50
51 case PA_SAMPLE_U8:
52 case PA_SAMPLE_ULAW:
53 case PA_SAMPLE_ALAW: {
54 uint8_t *u = d;
55
56 for (i = 0; i < chunk->length / pa_frame_size(ss); i++)
57 printf("0x%02x ", *(u++));
58
59 break;
60 }
61
62 case PA_SAMPLE_S16NE:
63 case PA_SAMPLE_S16RE: {
64 uint16_t *u = d;
65
66 for (i = 0; i < chunk->length / pa_frame_size(ss); i++)
67 printf("0x%04x ", *(u++));
68
69 break;
70 }
71
72 case PA_SAMPLE_S24_32NE:
73 case PA_SAMPLE_S24_32RE:
74 case PA_SAMPLE_S32NE:
75 case PA_SAMPLE_S32RE: {
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_S24NE:
85 case PA_SAMPLE_S24RE: {
86 uint8_t *u = d;
87
88 for (i = 0; i < chunk->length / pa_frame_size(ss); i++) {
89 printf("0x%02x%02x%02xx ", *u, *(u+1), *(u+2));
90 u += 3;
91 }
92
93 break;
94 }
95
96 case PA_SAMPLE_FLOAT32NE:
97 case PA_SAMPLE_FLOAT32RE: {
98 float *u = d;
99
100 for (i = 0; i < chunk->length / pa_frame_size(ss); i++) {
101 printf("%1.5f ", ss->format == PA_SAMPLE_FLOAT32NE ? *u : swap_float(*u));
102 u++;
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 static const uint8_t u8_samples[] = {
131 0x00, 0xFF, 0x7F, 0x80, 0x9f,
132 0x3f, 0x01, 0xF0, 0x20, 0x21
133 };
134
135 memcpy(d, u8_samples, sizeof(u8_samples));
136 break;
137 }
138
139 case PA_SAMPLE_S16NE:
140 case PA_SAMPLE_S16RE: {
141 static const uint16_t u16_samples[] = {
142 0x0000, 0xFFFF, 0x7FFF, 0x8000, 0x9fff,
143 0x3fff, 0x0001, 0xF000, 0x0020, 0x0021
144 };
145
146 memcpy(d, u16_samples, sizeof(u16_samples));
147 break;
148 }
149
150 case PA_SAMPLE_S24_32NE:
151 case PA_SAMPLE_S24_32RE:
152 case PA_SAMPLE_S32NE:
153 case PA_SAMPLE_S32RE: {
154 static const uint32_t u32_samples[] = {
155 0x00000001, 0xFFFF0002, 0x7FFF0003, 0x80000004, 0x9fff0005,
156 0x3fff0006, 0x00010007, 0xF0000008, 0x00200009, 0x0021000A
157 };
158
159 memcpy(d, u32_samples, sizeof(u32_samples));
160 break;
161 }
162
163 case PA_SAMPLE_S24NE:
164 case PA_SAMPLE_S24RE: {
165 /* Need to be on a byte array because they are not aligned */
166 static const uint8_t u24_samples[] = {
167 0x00, 0x00, 0x01,
168 0xFF, 0xFF, 0x02,
169 0x7F, 0xFF, 0x03,
170 0x80, 0x00, 0x04,
171 0x9f, 0xff, 0x05,
172 0x3f, 0xff, 0x06,
173 0x01, 0x00, 0x07,
174 0xF0, 0x00, 0x08,
175 0x20, 0x00, 0x09,
176 0x21, 0x00, 0x0A
177 };
178
179 memcpy(d, u24_samples, sizeof(u24_samples));
180 break;
181 }
182
183 case PA_SAMPLE_FLOAT32NE:
184 case PA_SAMPLE_FLOAT32RE: {
185 float *u = d;
186 static const float float_samples[] = {
187 0.0f, -1.0f, 1.0f, 4711.0f, 0.222f,
188 0.33f, -.3f, 99.0f, -0.555f, -.123f
189 };
190
191 if (ss->format == PA_SAMPLE_FLOAT32RE) {
192 for (i = 0; i < 10; i++)
193 u[i] = swap_float(float_samples[i]);
194 } else
195 memcpy(d, float_samples, sizeof(float_samples));
196
197 break;
198 }
199
200 default:
201 pa_assert_not_reached();
202 }
203
204 pa_memblock_release(r);
205
206 return r;
207 }
208
209 int main(int argc, char *argv[]) {
210 pa_mempool *pool;
211 pa_sample_spec a;
212 pa_cvolume v;
213
214 oil_init();
215 pa_log_set_level(PA_LOG_DEBUG);
216
217 pa_assert_se(pool = pa_mempool_new(FALSE, 0));
218
219 a.channels = 1;
220 a.rate = 44100;
221
222 v.channels = a.channels;
223 v.values[0] = pa_sw_volume_from_linear(0.9);
224
225 for (a.format = 0; a.format < PA_SAMPLE_MAX; a.format ++) {
226 pa_memchunk i, j, k;
227 pa_mix_info m[2];
228 void *ptr;
229
230 printf("=== mixing: %s\n", pa_sample_format_to_string(a.format));
231
232 /* Generate block */
233 i.memblock = generate_block(pool, &a);
234 i.length = pa_memblock_get_length(i.memblock);
235 i.index = 0;
236
237 dump_block(&a, &i);
238
239 /* Make a copy */
240 j = i;
241 pa_memblock_ref(j.memblock);
242 pa_memchunk_make_writable(&j, 0);
243
244 /* Adjust volume of the copy */
245 pa_volume_memchunk(&j, &a, &v);
246
247 dump_block(&a, &j);
248
249 m[0].chunk = i;
250 m[0].volume.values[0] = PA_VOLUME_NORM;
251 m[0].volume.channels = a.channels;
252 m[1].chunk = j;
253 m[1].volume.values[0] = PA_VOLUME_NORM;
254 m[1].volume.channels = a.channels;
255
256 k.memblock = pa_memblock_new(pool, i.length);
257 k.length = i.length;
258 k.index = 0;
259
260 ptr = (uint8_t*) pa_memblock_acquire(k.memblock) + k.index;
261 pa_mix(m, 2, ptr, k.length, &a, NULL, FALSE);
262 pa_memblock_release(k.memblock);
263
264 dump_block(&a, &k);
265
266 pa_memblock_unref(i.memblock);
267 pa_memblock_unref(j.memblock);
268 pa_memblock_unref(k.memblock);
269 }
270
271 pa_mempool_free(pool);
272
273 return 0;
274 }