|
| 1 | +// Test the various sample count computations and against output |
| 2 | +// buffer overflow of libsyn123. |
| 3 | + |
| 4 | +#include "mpg123config.h" |
| 5 | +#include <syn123.h> |
| 6 | +#include <inttypes.h> |
| 7 | + |
| 8 | +#include <stdlib.h> |
| 9 | +#include <stdio.h> |
| 10 | + |
| 11 | +#include "common/debug.h" |
| 12 | + |
| 13 | +const long arate = 22050; |
| 14 | +const long brate = 48000; |
| 15 | +const size_t outs = 0x10000; |
| 16 | +const int buffer_runs = 100; |
| 17 | +const float canary = 2317.; |
| 18 | + |
| 19 | +int main() |
| 20 | +{ |
| 21 | + size_t ins = syn123_resample_incount(arate, brate, outs); |
| 22 | + size_t outs2 = syn123_resample_count(arate, brate, ins); |
| 23 | + size_t fillins = syn123_resample_fillcount(arate, brate, outs); |
| 24 | + size_t fillouts = syn123_resample_count(arate, brate, fillins); |
| 25 | + printf("%zu output buffer size\n", outs); |
| 26 | + printf("%zu minimal input samples to ensure we can fill that buffer\n", ins); |
| 27 | + printf("%zu maximum output samples to result from the above\n", outs2); |
| 28 | + printf("%zu maximum input samples to not overflow that buffer\n", fillins); |
| 29 | + printf("%zu maximum output samples to result from the above\n", fillouts); |
| 30 | + int err = 0; |
| 31 | + |
| 32 | + syn123_handle *sh = syn123_new( brate, 1, MPG123_ENC_FLOAT_32, 1024, &err); |
| 33 | + if(!sh) |
| 34 | + mereturn(1, "handle alloc failure: %s", syn123_strerror(err)); |
| 35 | + |
| 36 | + // A dirty resampler. |
| 37 | + if(SYN123_OK != (err =syn123_setup_resample(sh, arate, brate, 1, 1, 0))) |
| 38 | + mereturn(1, "resample setup failure: %s", syn123_strerror(err)); |
| 39 | + |
| 40 | + // Default sine wave as source signal. |
| 41 | + if( SYN123_OK != |
| 42 | + (err =syn123_setup_waves( sh, 0, NULL, NULL, NULL, NULL, NULL)) ) |
| 43 | + mereturn(1, "wave setup failure: %s", syn123_strerror(err)); |
| 44 | + |
| 45 | + float *inbuf = malloc(sizeof(float)*ins); |
| 46 | + float *outbuf = malloc(sizeof(float)*(outs2+10)); |
| 47 | + if(!inbuf || !outbuf) |
| 48 | + ereturn(1, "buffer alloc failure"); |
| 49 | + |
| 50 | + for(int r=0; r<buffer_runs; ++r) |
| 51 | + { |
| 52 | + // Prepare input, |
| 53 | + size_t got = syn123_read(sh, inbuf, sizeof(float)*ins); |
| 54 | + if(got != sizeof(float)*ins) |
| 55 | + mereturn( 1 |
| 56 | + , "unexpected byte count from generator in run %d: %zu != %zu" |
| 57 | + , r, got, sizeof(float)*ins); |
| 58 | + // Prime output buffer with some weird large number. |
| 59 | + for(int o=0; o<(outs2+10); ++o) outbuf[o] = canary; |
| 60 | + size_t exp = syn123_resample_out(sh, ins, NULL); |
| 61 | + // Resample, check if anything is overwritten beyond the desired end. |
| 62 | + got = syn123_resample(sh, outbuf, inbuf, ins); |
| 63 | + if(!got || exp != got) |
| 64 | + mereturn( 1 |
| 65 | + , "got nothing or at least not what was expected" |
| 66 | + " in run %d: %zu != %zu" |
| 67 | + , r, got, exp ); |
| 68 | + if(got < outs) |
| 69 | + mereturn( 1 |
| 70 | + , "got less than promised minimum output sample count" |
| 71 | + " in run %d: %zu < %zu" |
| 72 | + , r, got, outs ); |
| 73 | + if(got > outs2) |
| 74 | + mereturn( 1 |
| 75 | + , "got more than promised maximum output sample count" |
| 76 | + " in run %d: %zu > %zu" |
| 77 | + , r, got, outs2 ); |
| 78 | + size_t over = 0; |
| 79 | + for(int o=outs2; o<(outs2+10); ++o) |
| 80 | + if(outbuf[o] != canary) |
| 81 | + { |
| 82 | + merror( "resample output overflow at %zu+%zu in run %d: %f != %f" |
| 83 | + , outs2, o-outs2, r, outbuf[o], canary ); |
| 84 | + ++over; |
| 85 | + } |
| 86 | + if(over) |
| 87 | + mereturn(1, "%zu samples overflow in run %d", over, r); |
| 88 | + } |
| 89 | + printf("%d resampler runs without issue\n", buffer_runs); |
| 90 | + printf("PASS\n"); |
| 91 | + |
| 92 | + free(outbuf); |
| 93 | + free(inbuf); |
| 94 | + syn123_del(sh); |
| 95 | + |
| 96 | + return 0; |
| 97 | +} |
0 commit comments