]> code.delx.au - pulseaudio/blob - src/tests/mix-test.c
daemon: before exec'ing ourselves, make sure nobody plays games with /proc/self/exe
[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_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 memcpy(d, &u8_samples[0], sizeof(u8_samples));
133 break;
134 }
135
136 case PA_SAMPLE_S16NE:
137 case PA_SAMPLE_S16RE: {
138 static const uint16_t u16_samples[] =
139 { 0x0000, 0xFFFF, 0x7FFF, 0x8000, 0x9fff,
140 0x3fff, 0x0001, 0xF000, 0x0020, 0x0021 };
141
142 memcpy(d, &u16_samples[0], sizeof(u16_samples));
143 break;
144 }
145
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 memcpy(d, &u32_samples[0], sizeof(u32_samples));
153 break;
154 }
155
156 case PA_SAMPLE_S24NE:
157 case PA_SAMPLE_S24RE: {
158 /* Need to be on a byte array because they are not aligned */
159 static const uint8_t u24_samples[] =
160 { 0x00, 0x00, 0x01,
161 0xFF, 0xFF, 0x02,
162 0x7F, 0xFF, 0x03,
163 0x80, 0x00, 0x04,
164 0x9f, 0xff, 0x05,
165 0x3f, 0xff, 0x06,
166 0x01, 0x00, 0x07,
167 0xF0, 0x00, 0x08,
168 0x20, 0x00, 0x09,
169 0x21, 0x00, 0x0A };
170
171 memcpy(d, &u24_samples[0], sizeof(u24_samples));
172 break;
173 }
174
175 case PA_SAMPLE_FLOAT32NE:
176 case PA_SAMPLE_FLOAT32RE: {
177 float *u = d;
178 static const float float_samples[] =
179 { 0.0f, -1.0f, 1.0f, 4711.0f, 0.222f,
180 0.33f, -.3f, 99.0f, -0.555f, -.123f };
181
182 if (ss->format == PA_SAMPLE_FLOAT32RE) {
183 for (i = 0; i < 10; i++)
184 u[i] = swap_float(float_samples[i]);
185 } else {
186 memcpy(d, &float_samples[0], sizeof(float_samples));
187 }
188
189 break;
190 }
191
192 default:
193 pa_assert_not_reached();
194 }
195
196 pa_memblock_release(r);
197
198 return r;
199 }
200
201 int main(int argc, char *argv[]) {
202 pa_mempool *pool;
203 pa_sample_spec a;
204 pa_cvolume v;
205
206 oil_init();
207 pa_log_set_level(PA_LOG_DEBUG);
208
209 pa_assert_se(pool = pa_mempool_new(FALSE, 0));
210
211 a.channels = 1;
212 a.rate = 44100;
213
214 v.channels = a.channels;
215 v.values[0] = pa_sw_volume_from_linear(0.9);
216
217 for (a.format = 0; a.format < PA_SAMPLE_MAX; a.format ++) {
218 pa_memchunk i, j, k;
219 pa_mix_info m[2];
220 void *ptr;
221
222 printf("=== mixing: %s\n", pa_sample_format_to_string(a.format));
223
224 /* Generate block */
225 i.memblock = generate_block(pool, &a);
226 i.length = pa_memblock_get_length(i.memblock);
227 i.index = 0;
228
229 dump_block(&a, &i);
230
231 /* Make a copy */
232 j = i;
233 pa_memblock_ref(j.memblock);
234 pa_memchunk_make_writable(&j, 0);
235
236 /* Adjust volume of the copy */
237 pa_volume_memchunk(&j, &a, &v);
238
239 dump_block(&a, &j);
240
241 m[0].chunk = i;
242 m[0].volume.values[0] = PA_VOLUME_NORM;
243 m[0].volume.channels = a.channels;
244 m[1].chunk = j;
245 m[1].volume.values[0] = PA_VOLUME_NORM;
246 m[1].volume.channels = a.channels;
247
248 k.memblock = pa_memblock_new(pool, i.length);
249 k.length = i.length;
250 k.index = 0;
251
252 ptr = (uint8_t*) pa_memblock_acquire(k.memblock) + k.index;
253 pa_mix(m, 2, ptr, k.length, &a, NULL, FALSE);
254 pa_memblock_release(k.memblock);
255
256 dump_block(&a, &k);
257
258 pa_memblock_unref(i.memblock);
259 pa_memblock_unref(j.memblock);
260 pa_memblock_unref(k.memblock);
261 }
262
263 pa_mempool_free(pool);
264
265 return 0;
266 }