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