daemon: replace colons by dash in per-machine directory names for compat with weird...
[profile/ivi/pulseaudio-panda.git] / 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 }