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