Branch data Line data Source code
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 : 39 : static void dump_block(const pa_sample_spec *ss, const pa_memchunk *chunk) {
35 : : void *d;
36 : : unsigned i;
37 : :
38 [ - + ][ # # ]: 39 : if (getenv("MAKE_CHECK"))
39 : 39 : return;
40 : :
41 : 0 : d = pa_memblock_acquire(chunk->memblock);
42 : :
43 [ # # # # : 0 : 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 [ # # ][ # # ]: 0 : for (i = 0; i < chunk->length / pa_frame_size(ss); i++)
51 : 0 : 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 [ # # ][ # # ]: 0 : for (i = 0; i < chunk->length / pa_frame_size(ss); i++)
61 : 0 : 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 [ # # ][ # # ]: 0 : for (i = 0; i < chunk->length / pa_frame_size(ss); i++)
73 : 0 : 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 [ # # ][ # # ]: 0 : for (i = 0; i < chunk->length / pa_frame_size(ss); i++) {
83 : 0 : printf("0x%02x%02x%02xx ", *u, *(u+1), *(u+2));
84 : 0 : u += 3;
85 : : }
86 : :
87 : : break;
88 : : }
89 : :
90 : : case PA_SAMPLE_FLOAT32NE:
91 : : case PA_SAMPLE_FLOAT32RE: {
92 : : float *u = d;
93 : :
94 [ # # ][ # # ]: 0 : for (i = 0; i < chunk->length / pa_frame_size(ss); i++) {
95 [ # # ][ # # ]: 0 : printf("%1.5f ", ss->format == PA_SAMPLE_FLOAT32NE ? *u : PA_FLOAT32_SWAP(*u));
96 : 0 : u++;
97 : : }
98 : :
99 : : break;
100 : : }
101 : :
102 : : default:
103 : 0 : pa_assert_not_reached();
104 : : }
105 : :
106 : : printf("\n");
107 : :
108 : 0 : pa_memblock_release(chunk->memblock);
109 : : }
110 : :
111 : 13 : 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 [ - + ]: 13 : pa_assert_se(r = pa_memblock_new(pool, pa_frame_size(ss) * 10));
117 : 13 : d = pa_memblock_acquire(r);
118 : :
119 [ + + + + : 13 : 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 : 2 : 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 [ + + ]: 2 : if (ss->format == PA_SAMPLE_FLOAT32RE) {
186 [ + + ]: 11 : for (i = 0; i < 10; i++)
187 : 20 : 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 : 0 : pa_assert_not_reached();
196 : : }
197 : :
198 : 13 : pa_memblock_release(r);
199 : :
200 : 13 : return r;
201 : : }
202 : :
203 : 1 : int main(int argc, char *argv[]) {
204 : : pa_mempool *pool;
205 : : pa_sample_spec a;
206 : : pa_cvolume v;
207 : :
208 [ - + ]: 1 : if (!getenv("MAKE_CHECK"))
209 : 0 : pa_log_set_level(PA_LOG_DEBUG);
210 : :
211 [ - + ]: 1 : pa_assert_se(pool = pa_mempool_new(FALSE, 0));
212 : :
213 : 1 : a.channels = 1;
214 : 1 : a.rate = 44100;
215 : :
216 : 1 : v.channels = a.channels;
217 : 1 : v.values[0] = pa_sw_volume_from_linear(0.9);
218 : :
219 [ + + ]: 14 : 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 : 13 : pa_log_debug("=== mixing: %s\n", pa_sample_format_to_string(a.format));
225 : :
226 : : /* Generate block */
227 : 13 : i.memblock = generate_block(pool, &a);
228 : 13 : i.length = pa_memblock_get_length(i.memblock);
229 : 13 : i.index = 0;
230 : :
231 : 13 : dump_block(&a, &i);
232 : :
233 : : /* Make a copy */
234 : 13 : j = i;
235 : 13 : pa_memblock_ref(j.memblock);
236 : 13 : pa_memchunk_make_writable(&j, 0);
237 : :
238 : : /* Adjust volume of the copy */
239 : 13 : pa_volume_memchunk(&j, &a, &v);
240 : :
241 : 13 : dump_block(&a, &j);
242 : :
243 : 13 : m[0].chunk = i;
244 : 13 : m[0].volume.values[0] = PA_VOLUME_NORM;
245 : 13 : m[0].volume.channels = a.channels;
246 : 13 : m[1].chunk = j;
247 : 13 : m[1].volume.values[0] = PA_VOLUME_NORM;
248 : 13 : m[1].volume.channels = a.channels;
249 : :
250 : 13 : k.memblock = pa_memblock_new(pool, i.length);
251 : 13 : k.length = i.length;
252 : 13 : k.index = 0;
253 : :
254 : 13 : ptr = (uint8_t*) pa_memblock_acquire(k.memblock) + k.index;
255 : 13 : pa_mix(m, 2, ptr, k.length, &a, NULL, FALSE);
256 : 13 : pa_memblock_release(k.memblock);
257 : :
258 : 13 : dump_block(&a, &k);
259 : :
260 : 13 : pa_memblock_unref(i.memblock);
261 : 13 : pa_memblock_unref(j.memblock);
262 : 13 : pa_memblock_unref(k.memblock);
263 : : }
264 : :
265 : 1 : pa_mempool_free(pool);
266 : :
267 : : return 0;
268 : : }
|