Mercurial > hg > sv-dependency-builds
comparison src/libsamplerate-0.1.8/tests/callback_test.c @ 0:c7265573341e
Import initial set of sources
author | Chris Cannam |
---|---|
date | Mon, 18 Mar 2013 14:12:14 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c7265573341e |
---|---|
1 /* | |
2 ** Copyright (C) 2003-2011 Erik de Castro Lopo <erikd@mega-nerd.com> | |
3 ** | |
4 ** This program is free software; you can redistribute it and/or modify | |
5 ** it under the terms of the GNU General Public License as published by | |
6 ** the Free Software Foundation; either version 2 of the License, or | |
7 ** (at your option) any later version. | |
8 ** | |
9 ** This program is distributed in the hope that it will be useful, | |
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 ** GNU General Public License for more details. | |
13 ** | |
14 ** You should have received a copy of the GNU General Public License | |
15 ** along with this program; if not, write to the Free Software | |
16 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | |
17 */ | |
18 | |
19 #include <stdio.h> | |
20 #include <stdlib.h> | |
21 #include <string.h> | |
22 #include <math.h> | |
23 | |
24 #include <samplerate.h> | |
25 | |
26 #include "util.h" | |
27 | |
28 #define BUFFER_LEN 10000 | |
29 #define CB_READ_LEN 256 | |
30 | |
31 static void callback_test (int converter, double ratio) ; | |
32 static void end_of_stream_test (int converter) ; | |
33 | |
34 int | |
35 main (void) | |
36 { static double src_ratios [] = | |
37 { 1.0, 0.099, 0.1, 0.33333333, 0.789, 1.0001, 1.9, 3.1, 9.9 | |
38 } ; | |
39 | |
40 int k ; | |
41 | |
42 puts ("") ; | |
43 | |
44 puts (" Zero Order Hold interpolator :") ; | |
45 for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++) | |
46 callback_test (SRC_ZERO_ORDER_HOLD, src_ratios [k]) ; | |
47 | |
48 puts (" Linear interpolator :") ; | |
49 for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++) | |
50 callback_test (SRC_LINEAR, src_ratios [k]) ; | |
51 | |
52 puts (" Sinc interpolator :") ; | |
53 for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++) | |
54 callback_test (SRC_SINC_FASTEST, src_ratios [k]) ; | |
55 | |
56 puts ("") ; | |
57 | |
58 puts (" End of stream test :") ; | |
59 end_of_stream_test (SRC_ZERO_ORDER_HOLD) ; | |
60 end_of_stream_test (SRC_LINEAR) ; | |
61 end_of_stream_test (SRC_SINC_FASTEST) ; | |
62 | |
63 puts ("") ; | |
64 return 0 ; | |
65 } /* main */ | |
66 | |
67 /*===================================================================================== | |
68 */ | |
69 | |
70 typedef struct | |
71 { int channels ; | |
72 long count, total ; | |
73 int end_of_data ; | |
74 float data [BUFFER_LEN] ; | |
75 } TEST_CB_DATA ; | |
76 | |
77 static long | |
78 test_callback_func (void *cb_data, float **data) | |
79 { TEST_CB_DATA *pcb_data ; | |
80 | |
81 long frames ; | |
82 | |
83 if ((pcb_data = cb_data) == NULL) | |
84 return 0 ; | |
85 | |
86 if (data == NULL) | |
87 return 0 ; | |
88 | |
89 if (pcb_data->total - pcb_data->count > CB_READ_LEN) | |
90 frames = CB_READ_LEN / pcb_data->channels ; | |
91 else | |
92 frames = (pcb_data->total - pcb_data->count) / pcb_data->channels ; | |
93 | |
94 *data = pcb_data->data + pcb_data->count ; | |
95 pcb_data->count += frames ; | |
96 | |
97 return frames ; | |
98 } /* test_callback_func */ | |
99 | |
100 | |
101 static void | |
102 callback_test (int converter, double src_ratio) | |
103 { static TEST_CB_DATA test_callback_data ; | |
104 static float output [BUFFER_LEN] ; | |
105 | |
106 SRC_STATE *src_state ; | |
107 | |
108 long read_count, read_total ; | |
109 int error ; | |
110 | |
111 printf ("\tcallback_test (SRC ratio = %6.4f) ........... ", src_ratio) ; | |
112 fflush (stdout) ; | |
113 | |
114 test_callback_data.channels = 2 ; | |
115 test_callback_data.count = 0 ; | |
116 test_callback_data.end_of_data = 0 ; | |
117 test_callback_data.total = ARRAY_LEN (test_callback_data.data) ; | |
118 | |
119 if ((src_state = src_callback_new (test_callback_func, converter, test_callback_data.channels, &error, &test_callback_data)) == NULL) | |
120 { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ; | |
121 exit (1) ; | |
122 } ; | |
123 | |
124 read_total = 0 ; | |
125 do | |
126 { /* We will be throwing away output data, so just grab as much as possible. */ | |
127 read_count = ARRAY_LEN (output) / test_callback_data.channels ; | |
128 read_count = src_callback_read (src_state, src_ratio, read_count, output) ; | |
129 read_total += read_count ; | |
130 } | |
131 while (read_count > 0) ; | |
132 | |
133 if ((error = src_error (src_state)) != 0) | |
134 { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ; | |
135 exit (1) ; | |
136 } ; | |
137 | |
138 src_state = src_delete (src_state) ; | |
139 | |
140 if (fabs (read_total / src_ratio - ARRAY_LEN (test_callback_data.data)) > 2.0) | |
141 { printf ("\n\nLine %d : input / output length mismatch.\n\n", __LINE__) ; | |
142 printf (" input len : %d\n", ARRAY_LEN (test_callback_data.data)) ; | |
143 printf (" output len : %ld (should be %g +/- 2)\n\n", read_total, | |
144 floor (0.5 + src_ratio * ARRAY_LEN (test_callback_data.data))) ; | |
145 exit (1) ; | |
146 } ; | |
147 | |
148 puts ("ok") ; | |
149 | |
150 return ; | |
151 } /* callback_test */ | |
152 | |
153 /*===================================================================================== | |
154 */ | |
155 | |
156 static long | |
157 eos_callback_func (void *cb_data, float **data) | |
158 { | |
159 TEST_CB_DATA *pcb_data ; | |
160 long frames ; | |
161 | |
162 if (data == NULL) | |
163 return 0 ; | |
164 | |
165 if ((pcb_data = cb_data) == NULL) | |
166 return 0 ; | |
167 | |
168 /* | |
169 ** Return immediately if there is no more data. | |
170 ** In this case, the output pointer 'data' will not be set and | |
171 ** valgrind should not warn about it. | |
172 */ | |
173 if (pcb_data->end_of_data) | |
174 return 0 ; | |
175 | |
176 if (pcb_data->total - pcb_data->count > CB_READ_LEN) | |
177 frames = CB_READ_LEN / pcb_data->channels ; | |
178 else | |
179 frames = (pcb_data->total - pcb_data->count) / pcb_data->channels ; | |
180 | |
181 *data = pcb_data->data + pcb_data->count ; | |
182 pcb_data->count += frames ; | |
183 | |
184 /* | |
185 ** Set end_of_data so that the next call to the callback function will | |
186 ** return zero ocunt without setting the 'data' pointer. | |
187 */ | |
188 if (pcb_data->total < 2 * pcb_data->count) | |
189 pcb_data->end_of_data = 1 ; | |
190 | |
191 return frames ; | |
192 } /* eos_callback_data */ | |
193 | |
194 | |
195 static void | |
196 end_of_stream_test (int converter) | |
197 { static TEST_CB_DATA test_callback_data ; | |
198 static float output [BUFFER_LEN] ; | |
199 | |
200 SRC_STATE *src_state ; | |
201 | |
202 double src_ratio = 0.3 ; | |
203 long read_count, read_total ; | |
204 int error ; | |
205 | |
206 printf ("\t%-30s ........... ", src_get_name (converter)) ; | |
207 fflush (stdout) ; | |
208 | |
209 test_callback_data.channels = 2 ; | |
210 test_callback_data.count = 0 ; | |
211 test_callback_data.end_of_data = 0 ; | |
212 test_callback_data.total = ARRAY_LEN (test_callback_data.data) ; | |
213 | |
214 if ((src_state = src_callback_new (eos_callback_func, converter, test_callback_data.channels, &error, &test_callback_data)) == NULL) | |
215 { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ; | |
216 exit (1) ; | |
217 } ; | |
218 | |
219 read_total = 0 ; | |
220 do | |
221 { /* We will be throwing away output data, so just grab as much as possible. */ | |
222 read_count = ARRAY_LEN (output) / test_callback_data.channels ; | |
223 read_count = src_callback_read (src_state, src_ratio, read_count, output) ; | |
224 read_total += read_count ; | |
225 } | |
226 while (read_count > 0) ; | |
227 | |
228 if ((error = src_error (src_state)) != 0) | |
229 { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ; | |
230 exit (1) ; | |
231 } ; | |
232 | |
233 src_state = src_delete (src_state) ; | |
234 | |
235 if (test_callback_data.end_of_data == 0) | |
236 { printf ("\n\nLine %d : test_callback_data.end_of_data should not be 0." | |
237 " This is a bug in the test.\n\n", __LINE__) ; | |
238 exit (1) ; | |
239 } ; | |
240 | |
241 puts ("ok") ; | |
242 return ; | |
243 } /* end_of_stream_test */ |