annotate src/libsamplerate-0.1.9/tests/callback_test.c @ 83:ae30d91d2ffe

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