Skip to content

Commit 99589c6

Browse files
committed
Add test to catch out of bound array access.
This is to repro a bug reported in #208
1 parent 20819b6 commit 99589c6

File tree

2 files changed

+164
-0
lines changed

2 files changed

+164
-0
lines changed

tests/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ add_executable(misc_test misc_test.c util.c util.h)
2121
target_link_libraries(misc_test PRIVATE samplerate)
2222
add_test(NAME misc_test COMMAND misc_test WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/src)
2323

24+
add_executable(vari_streaming_test vari_streaming_test.c util.c util.h)
25+
target_link_libraries(vari_streaming_test PRIVATE samplerate)
26+
add_test(NAME vari_streaming_test COMMAND vari_streaming_test WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/src)
27+
2428
add_executable(termination_test termination_test.c util.c util.h)
2529
target_link_libraries(termination_test PRIVATE samplerate)
2630
add_test(NAME termination_test COMMAND termination_test WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/src)

tests/vari_streaming_test.c

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
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/libsndfile/libsamplerate/blob/master/COPYING
7+
*/
8+
9+
#ifdef HAVE_CONFIG_H
10+
#include "config.h"
11+
#endif
12+
13+
#include <math.h>
14+
#include <samplerate.h>
15+
#include <stdint.h>
16+
#include <stdio.h>
17+
#include <stdlib.h>
18+
#include <string.h>
19+
20+
#include "util.h"
21+
22+
#define BUFFER_LEN (1 << 15)
23+
#define INPUT_BUFFER_LEN (BUFFER_LEN)
24+
#define OUTPUT_BUFFER_LEN (BUFFER_LEN)
25+
#define BLOCK_LEN 192
26+
27+
static void vari_stream_test(int converter, double ratio);
28+
29+
int main(void) {
30+
static double src_ratios[] = {0.3, 0.9, 1.1, 3.0};
31+
32+
int k;
33+
34+
puts("\n Zero Order Hold interpolator:");
35+
for (k = 0; k < ARRAY_LEN(src_ratios); k++)
36+
vari_stream_test(SRC_ZERO_ORDER_HOLD, src_ratios[k]);
37+
38+
puts("\n Linear interpolator:");
39+
for (k = 0; k < ARRAY_LEN(src_ratios); k++)
40+
vari_stream_test(SRC_LINEAR, src_ratios[k]);
41+
42+
puts("\n Sinc interpolator:");
43+
for (k = 0; k < ARRAY_LEN(src_ratios); k++)
44+
vari_stream_test(SRC_SINC_FASTEST, src_ratios[k]);
45+
46+
puts("");
47+
48+
return 0;
49+
} /* main */
50+
51+
struct generate_waveform_state_s {
52+
float phase;
53+
float phase_increment;
54+
};
55+
56+
static void generate_waveform(struct generate_waveform_state_s* state, float* output, size_t len) {
57+
for(size_t n = 0; n < len; ++n) {
58+
output[n] = state->phase;
59+
state->phase += state->phase_increment;
60+
if (state->phase > 1.0 || state->phase < -1.0)
61+
state->phase = state->phase > 0 ? -1.0 : 1.0;
62+
}
63+
}
64+
65+
static void vari_stream_test(int converter, double src_ratio) {
66+
float input[INPUT_BUFFER_LEN], output[OUTPUT_BUFFER_LEN];
67+
68+
SRC_STATE *src_state;
69+
70+
int error, terminate;
71+
72+
printf("\tvari_streaming_test (SRC ratio = %6.4f) ........... ", src_ratio);
73+
fflush(stdout);
74+
75+
/* Perform sample rate conversion. */
76+
if ((src_state = src_new(converter, 1, &error)) == NULL) {
77+
printf("\n\nLine %d : src_new() failed : %s\n\n", __LINE__,
78+
src_strerror(error));
79+
exit(1);
80+
};
81+
82+
struct generate_waveform_state_s generator = {
83+
.phase = 0.0,
84+
.phase_increment = 2 / 48000, // 1Hz at 48000kHz samplerate.
85+
};
86+
87+
double resampled_time = 0;
88+
const size_t input_period_sizes[] = {
89+
BLOCK_LEN,
90+
BLOCK_LEN,
91+
BLOCK_LEN,
92+
1,
93+
BLOCK_LEN,
94+
};
95+
96+
int num_input_frame_used = 0;
97+
int num_frames_outputed = 0;
98+
int total_num_input_frames = 0;
99+
100+
int current_num_frames = 0;
101+
for (size_t n = 0; n < ARRAY_LEN(input_period_sizes); ++n) {
102+
generate_waveform(&generator, input, input_period_sizes[n]);
103+
total_num_input_frames += input_period_sizes[n];
104+
current_num_frames += input_period_sizes[n];
105+
SRC_DATA src_data = {
106+
.data_in = input,
107+
.data_out = output,
108+
.input_frames = input_period_sizes[n],
109+
.output_frames = OUTPUT_BUFFER_LEN,
110+
.input_frames_used = 0,
111+
.output_frames_gen = 0,
112+
.end_of_input = n == ARRAY_LEN(input_period_sizes) - 1,
113+
.src_ratio = src_ratio,
114+
};
115+
// printf("eoi: %d\n", src_data.end_of_input);
116+
if ((error = src_process(src_state, &src_data))) {
117+
printf("\n\nLine %d : %s\n\n", __LINE__, src_strerror(error));
118+
119+
printf("src_data.input_frames : %ld\n", src_data.input_frames);
120+
printf("src_data.output_frames : %ld\n", src_data.output_frames);
121+
122+
exit(1);
123+
};
124+
125+
126+
num_input_frame_used += src_data.input_frames_used;
127+
num_frames_outputed += src_data.output_frames_gen;
128+
129+
memmove(
130+
input,
131+
input + src_data.input_frames_used,
132+
(INPUT_BUFFER_LEN - src_data.input_frames_used) * sizeof(input[0])
133+
);
134+
current_num_frames -= src_data.input_frames_used;
135+
if (src_data.end_of_input) break;
136+
};
137+
138+
src_state = src_delete(src_state);
139+
140+
terminate = (int)ceil((src_ratio >= 1.0) ? src_ratio : 1.0 / src_ratio);
141+
142+
if (fabs(num_frames_outputed - src_ratio * total_num_input_frames) > 2 * terminate) {
143+
printf("\n\nLine %d : bad output data length %d should be %d.\n", __LINE__,
144+
num_frames_outputed, (int)floor(src_ratio * total_num_input_frames));
145+
printf("\tsrc_ratio : %.4f\n", src_ratio);
146+
printf("\tinput_len : %d\n\toutput_len : %d\n\n", total_num_input_frames, num_frames_outputed);
147+
exit(1);
148+
};
149+
150+
if (num_input_frame_used != total_num_input_frames) {
151+
printf("\n\nLine %d : unused %d input frames.\n", __LINE__, current_num_frames);
152+
printf("\tinput_len : %d\n", total_num_input_frames);
153+
printf("\tinput_frames_used : %d\n\n", num_input_frame_used);
154+
exit(1);
155+
};
156+
157+
puts("ok");
158+
159+
return;
160+
} /* stream_test */

0 commit comments

Comments
 (0)