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