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