1 /* Spa
2  *
3  * Copyright © 2019 Wim Taymans
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  */
24 
25 #include <string.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <unistd.h>
29 #include <errno.h>
30 #include <time.h>
31 
32 #include <spa/support/log-impl.h>
33 #include <spa/debug/mem.h>
34 
35 SPA_LOG_IMPL(logger);
36 
37 #include "resample.h"
38 
39 #define N_SAMPLES	253
40 #define N_CHANNELS	11
41 
42 static float samp_in[N_SAMPLES * 4];
43 static float samp_out[N_SAMPLES * 4];
44 
feed_1(struct resample * r)45 static void feed_1(struct resample *r)
46 {
47 	uint32_t i;
48 	const void *src[1];
49 	void *dst[1];
50 
51 	spa_zero(samp_out);
52 	src[0] = samp_in;
53 	dst[0] = samp_out;
54 
55 	for (i = 0; i < 500; i++) {
56 		uint32_t in, out;
57 
58 		in = out = 1;
59 		samp_in[0] = i;
60 		resample_process(r, src, &in, dst, &out);
61 		fprintf(stderr, "%d %d %f %d\n", i, in, samp_out[0], out);
62 	}
63 }
64 
test_native(void)65 static void test_native(void)
66 {
67 	struct resample r;
68 
69 	spa_zero(r);
70 	r.log = &logger.log;
71 	r.channels = 1;
72 	r.i_rate = 44100;
73 	r.o_rate = 44100;
74 	r.quality = RESAMPLE_DEFAULT_QUALITY;
75 	resample_native_init(&r);
76 
77 	feed_1(&r);
78 	resample_free(&r);
79 
80 	spa_zero(r);
81 	r.log = &logger.log;
82 	r.channels = 1;
83 	r.i_rate = 44100;
84 	r.o_rate = 48000;
85 	r.quality = RESAMPLE_DEFAULT_QUALITY;
86 	resample_native_init(&r);
87 
88 	feed_1(&r);
89 	resample_free(&r);
90 }
91 
pull_blocks(struct resample * r,uint32_t first,uint32_t size)92 static void pull_blocks(struct resample *r, uint32_t first, uint32_t size)
93 {
94 	uint32_t i;
95 	float in[SPA_MAX(size, first) * 2];
96 	float out[SPA_MAX(size, first) * 2];
97 	const void *src[1];
98 	void *dst[1];
99 	uint32_t in_len, out_len;
100 	uint32_t pin_len, pout_len;
101 
102 	src[0] = in;
103 	dst[0] = out;
104 
105 	for (i = 0; i < 500; i++) {
106 		pout_len = out_len = i == 0 ? first : size;
107 		pin_len = in_len = resample_in_len(r, out_len);
108 
109 		resample_process(r, src, &pin_len, dst, &pout_len);
110 
111 		fprintf(stderr, "%d: %d %d %d %d %d\n", i,
112 				in_len, pin_len, out_len, pout_len,
113 				resample_in_len(r, size));
114 
115 		spa_assert_se(in_len == pin_len);
116 		spa_assert_se(out_len == pout_len);
117 	}
118 }
119 
test_in_len(void)120 static void test_in_len(void)
121 {
122 	struct resample r;
123 
124 	spa_zero(r);
125 	r.log = &logger.log;
126 	r.channels = 1;
127 	r.i_rate = 32000;
128 	r.o_rate = 48000;
129 	r.quality = RESAMPLE_DEFAULT_QUALITY;
130 	resample_native_init(&r);
131 
132 	pull_blocks(&r, 1024, 1024);
133 	resample_free(&r);
134 
135 	spa_zero(r);
136 	r.log = &logger.log;
137 	r.channels = 1;
138 	r.i_rate = 44100;
139 	r.o_rate = 48000;
140 	r.quality = RESAMPLE_DEFAULT_QUALITY;
141 	resample_native_init(&r);
142 
143 	pull_blocks(&r, 1024, 1024);
144 	resample_free(&r);
145 
146 	spa_zero(r);
147 	r.log = &logger.log;
148 	r.channels = 1;
149 	r.i_rate = 48000;
150 	r.o_rate = 44100;
151 	r.quality = RESAMPLE_DEFAULT_QUALITY;
152 	resample_native_init(&r);
153 
154 	pull_blocks(&r, 1024, 1024);
155 	resample_free(&r);
156 
157 	spa_zero(r);
158 	r.log = &logger.log;
159 	r.channels = 1;
160 	r.i_rate = 44100;
161 	r.o_rate = 48000;
162 	r.quality = RESAMPLE_DEFAULT_QUALITY;
163 	resample_native_init(&r);
164 
165 	pull_blocks(&r, 513, 64);
166 	resample_free(&r);
167 }
168 
main(int argc,char * argv[])169 int main(int argc, char *argv[])
170 {
171 	logger.log.level = SPA_LOG_LEVEL_TRACE;
172 
173 	test_native();
174 	test_in_len();
175 
176 	return 0;
177 }
178