]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | ** Copyright (c) 2002-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 | ||
12 | #include <samplerate.h> | |
13 | ||
14 | #include "util.h" | |
15 | ||
16 | #define BUFFER_LEN 2048 | |
17 | #define CB_READ_LEN 256 | |
18 | ||
19 | static void process_reset_test (int converter) ; | |
20 | static void callback_reset_test (int converter) ; | |
21 | ||
22 | static float data_one [BUFFER_LEN] ; | |
23 | static float data_zero [BUFFER_LEN] ; | |
24 | ||
25 | int | |
26 | main (void) | |
27 | { | |
28 | puts ("") ; | |
29 | ||
30 | process_reset_test (SRC_ZERO_ORDER_HOLD) ; | |
31 | process_reset_test (SRC_LINEAR) ; | |
32 | process_reset_test (SRC_SINC_FASTEST) ; | |
33 | ||
34 | callback_reset_test (SRC_ZERO_ORDER_HOLD) ; | |
35 | callback_reset_test (SRC_LINEAR) ; | |
36 | callback_reset_test (SRC_SINC_FASTEST) ; | |
37 | ||
38 | puts ("") ; | |
39 | ||
40 | return 0 ; | |
41 | } /* main */ | |
42 | ||
43 | static void | |
44 | process_reset_test (int converter) | |
45 | { static float output [BUFFER_LEN] ; | |
46 | ||
47 | SRC_STATE *src_state ; | |
48 | SRC_DATA src_data ; | |
49 | int k, error ; | |
50 | ||
51 | printf ("\tprocess_reset_test (%-28s) ....... ", src_get_name (converter)) ; | |
52 | fflush (stdout) ; | |
53 | ||
54 | for (k = 0 ; k < BUFFER_LEN ; k++) | |
55 | { data_one [k] = 1.0 ; | |
56 | data_zero [k] = 0.0 ; | |
57 | } ; | |
58 | ||
59 | /* Get a converter. */ | |
60 | if ((src_state = src_new (converter, 1, &error)) == NULL) | |
61 | { printf ("\n\nLine %d : src_new() failed : %s.\n\n", __LINE__, src_strerror (error)) ; | |
62 | exit (1) ; | |
63 | } ; | |
64 | ||
65 | /* Process a bunch of 1.0 valued samples. */ | |
66 | src_data.data_in = data_one ; | |
67 | src_data.data_out = output ; | |
68 | src_data.input_frames = BUFFER_LEN ; | |
69 | src_data.output_frames = BUFFER_LEN ; | |
70 | src_data.src_ratio = 0.9 ; | |
71 | src_data.end_of_input = 1 ; | |
72 | ||
73 | if ((error = src_process (src_state, &src_data)) != 0) | |
74 | { printf ("\n\nLine %d : src_simple () returned error : %s\n\n", __LINE__, src_strerror (error)) ; | |
75 | exit (1) ; | |
76 | } ; | |
77 | ||
78 | /* Reset the state of the converter.*/ | |
79 | src_reset (src_state) ; | |
80 | ||
81 | /* Now process some zero data. */ | |
82 | src_data.data_in = data_zero ; | |
83 | src_data.data_out = output ; | |
84 | src_data.input_frames = BUFFER_LEN ; | |
85 | src_data.output_frames = BUFFER_LEN ; | |
86 | src_data.src_ratio = 0.9 ; | |
87 | src_data.end_of_input = 1 ; | |
88 | ||
89 | if ((error = src_process (src_state, &src_data)) != 0) | |
90 | { printf ("\n\nLine %d : src_simple () returned error : %s\n\n", __LINE__, src_strerror (error)) ; | |
91 | exit (1) ; | |
92 | } ; | |
93 | ||
94 | /* Finally make sure that the output data is zero ie reset was sucessful. */ | |
95 | for (k = 0 ; k < BUFFER_LEN / 2 ; k++) | |
96 | if (output [k] != 0.0) | |
97 | { printf ("\n\nLine %d : output [%d] should be 0.0, is %f.\n", __LINE__, k, output [k]) ; | |
98 | exit (1) ; | |
99 | } ; | |
100 | ||
101 | /* Make sure that this function has been exported. */ | |
102 | src_set_ratio (src_state, 1.0) ; | |
103 | ||
104 | /* Delete converter. */ | |
105 | src_state = src_delete (src_state) ; | |
106 | ||
107 | puts ("ok") ; | |
108 | } /* process_reset_test */ | |
109 | ||
110 | /*============================================================================== | |
111 | */ | |
112 | ||
113 | typedef struct | |
114 | { int channels ; | |
115 | long count, total ; | |
116 | float *data ; | |
117 | } TEST_CB_DATA ; | |
118 | ||
119 | static long | |
120 | test_callback_func (void *cb_data, float **data) | |
121 | { TEST_CB_DATA *pcb_data ; | |
122 | ||
123 | long frames ; | |
124 | ||
125 | if ((pcb_data = cb_data) == NULL) | |
126 | return 0 ; | |
127 | ||
128 | if (data == NULL) | |
129 | return 0 ; | |
130 | ||
131 | if (pcb_data->total - pcb_data->count > 0) | |
132 | frames = pcb_data->total - pcb_data->count ; | |
133 | else | |
134 | frames = 0 ; | |
135 | ||
136 | *data = pcb_data->data + pcb_data->count ; | |
137 | pcb_data->count += frames ; | |
138 | ||
139 | return frames ; | |
140 | } /* test_callback_func */ | |
141 | ||
142 | static void | |
143 | callback_reset_test (int converter) | |
144 | { static TEST_CB_DATA test_callback_data ; | |
145 | ||
146 | static float output [BUFFER_LEN] ; | |
147 | ||
148 | SRC_STATE *src_state ; | |
149 | ||
150 | double src_ratio = 1.1 ; | |
151 | long read_count, read_total ; | |
152 | int k, error ; | |
153 | ||
154 | printf ("\tcallback_reset_test (%-28s) ....... ", src_get_name (converter)) ; | |
155 | fflush (stdout) ; | |
156 | ||
157 | for (k = 0 ; k < ARRAY_LEN (data_one) ; k++) | |
158 | { data_one [k] = 1.0 ; | |
159 | data_zero [k] = 0.0 ; | |
160 | } ; | |
161 | ||
162 | if ((src_state = src_callback_new (test_callback_func, converter, 1, &error, &test_callback_data)) == NULL) | |
163 | { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ; | |
164 | exit (1) ; | |
165 | } ; | |
166 | ||
167 | /* Process a bunch of 1.0 valued samples. */ | |
168 | test_callback_data.channels = 1 ; | |
169 | test_callback_data.count = 0 ; | |
170 | test_callback_data.total = ARRAY_LEN (data_one) ; | |
171 | test_callback_data.data = data_one ; | |
172 | ||
173 | read_total = 0 ; | |
174 | do | |
175 | { read_count = (ARRAY_LEN (output) - read_total > CB_READ_LEN) ? CB_READ_LEN : ARRAY_LEN (output) - read_total ; | |
176 | read_count = src_callback_read (src_state, src_ratio, read_count, output + read_total) ; | |
177 | read_total += read_count ; | |
178 | } | |
179 | while (read_count > 0) ; | |
180 | ||
181 | /* Check for errors. */ | |
182 | if ((error = src_error (src_state)) != 0) | |
183 | { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ; | |
184 | exit (1) ; | |
185 | } ; | |
186 | ||
187 | /* Reset the state of the converter.*/ | |
188 | src_reset (src_state) ; | |
189 | ||
190 | /* Process a bunch of 0.0 valued samples. */ | |
191 | test_callback_data.channels = 1 ; | |
192 | test_callback_data.count = 0 ; | |
193 | test_callback_data.total = ARRAY_LEN (data_zero) ; | |
194 | test_callback_data.data = data_zero ; | |
195 | ||
196 | /* Now process some zero data. */ | |
197 | read_total = 0 ; | |
198 | do | |
199 | { read_count = (ARRAY_LEN (output) - read_total > CB_READ_LEN) ? CB_READ_LEN : ARRAY_LEN (output) - read_total ; | |
200 | read_count = src_callback_read (src_state, src_ratio, read_count, output + read_total) ; | |
201 | read_total += read_count ; | |
202 | } | |
203 | while (read_count > 0) ; | |
204 | ||
205 | /* Check for errors. */ | |
206 | if ((error = src_error (src_state)) != 0) | |
207 | { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ; | |
208 | exit (1) ; | |
209 | } ; | |
210 | ||
211 | /* Finally make sure that the output data is zero ie reset was sucessful. */ | |
212 | for (k = 0 ; k < BUFFER_LEN / 2 ; k++) | |
213 | if (output [k] != 0.0) | |
214 | { printf ("\n\nLine %d : output [%d] should be 0.0, is %f.\n\n", __LINE__, k, output [k]) ; | |
215 | save_oct_float ("output.dat", data_one, ARRAY_LEN (data_one), output, ARRAY_LEN (output)) ; | |
216 | exit (1) ; | |
217 | } ; | |
218 | ||
219 | /* Make sure that this function has been exported. */ | |
220 | src_set_ratio (src_state, 1.0) ; | |
221 | ||
222 | /* Delete converter. */ | |
223 | src_state = src_delete (src_state) ; | |
224 | ||
225 | puts ("ok") ; | |
226 | } /* callback_reset_test */ | |
227 | ||
228 |