Fix int normalisation when reading in floats with the replacement reader (#702)

* Use the correct scale when normalising an integer read on the fallback floating point path.
Without this the values were only being scaled to a short's max value.

* Add a second pass over the floating point tests that enables the replacement read functionality.
These cover the issue fixed by the previous commit.

* Add an entry to CHANGELOG.md for #702.
This commit is contained in:
bobsayshilol 2021-02-14 04:45:07 +00:00 committed by GitHub
parent 06fd6f626e
commit ecb9672aaa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 11 additions and 7 deletions

View File

@ -22,5 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Typo in `docs/index.md`.
* Memory leak in `caf_read_header`(), credit to OSS-Fuzz ([issue 30375](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=30375)).
* Normalisation issue when scaling floating point data to `int` in
`replace_read_f2i`() (#702).
[Unreleased]: https://github.com/libsndfile/libsndfile/compare/1.0.31...HEAD

View File

@ -787,7 +787,7 @@ replace_read_f2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
float scale ;
bufferlen = ARRAY_LEN (ubuf.fbuf) ;
scale = (psf->float_int_mult == 0) ? 1.0 : 0x7FFF / psf->float_max ;
scale = (psf->float_int_mult == 0) ? 1.0 : 2147483648.0f / psf->float_max ;
while (len > 0)
{ if (len < bufferlen)

View File

@ -42,7 +42,7 @@ static void float_scaled_test (const char *filename, int allow_exit, int replace
static void double_scaled_test (const char *filename, int allow_exit, int replace_float, int filetype, double target_snr) ;
[+ FOR float_type +][+ FOR int_type +][+ FOR endian_type
+]static void [+ (get "float_name") +]_[+ (get "int_name") +]_[+ (get "end_name") +]_test (const char * filename) ;
+]static void [+ (get "float_name") +]_[+ (get "int_name") +]_[+ (get "end_name") +]_test (const char * filename, int replace_float) ;
[+ ENDFOR endian_type +][+ ENDFOR int_type +][+ ENDFOR float_type
+]
@ -187,10 +187,10 @@ main (int argc, char *argv [])
putchar ('\n') ;
/* Float int tests. */
[+ FOR float_type +][+ FOR int_type +][+ FOR endian_type
+] [+ (get "float_name") +]_[+ (get "int_name") +]_[+ (get "end_name") +]_test ("[+ (get "float_name") +]_[+ (get "int_name") +]_[+ (get "end_name") +].au") ;
[+ ENDFOR endian_type +][+ ENDFOR int_type +][+ ENDFOR float_type
+]
[+ FOR float_type +][+ FOR int_type +][+ FOR endian_type +]
[+ (get "float_name") +]_[+ (get "int_name") +]_[+ (get "end_name") +]_test ("[+ (get "float_name") +]_[+ (get "int_name") +]_[+ (get "end_name") +].au", SF_FALSE) ;
[+ (get "float_name") +]_[+ (get "int_name") +]_[+ (get "end_name") +]_test ("[+ (get "float_name") +]_[+ (get "int_name") +]_[+ (get "end_name") +]_replace.au", SF_TRUE) ;
[+ ENDFOR endian_type +][+ ENDFOR int_type +][+ ENDFOR float_type +]
return 0 ;
} /* main */
@ -311,7 +311,7 @@ double_scaled_test (const char *filename, int allow_exit, int replace_float, int
[+ FOR float_type +][+ FOR int_type +][+ FOR endian_type
+]
static void
[+ (get "float_name") +]_[+ (get "int_name") +]_[+ (get "end_name") +]_test (const char * filename)
[+ (get "float_name") +]_[+ (get "int_name") +]_[+ (get "end_name") +]_test (const char * filename, int replace_float)
{ SNDFILE *file ;
SF_INFO sfinfo ;
int max ;
@ -328,10 +328,12 @@ static void
sfinfo.format = [+ (get "end_type") +] | SF_FORMAT_AU | [+ (get "minor_type") +] ;
file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
sf_command (file, SFC_TEST_IEEE_FLOAT_REPLACE, NULL, replace_float) ;
test_write_[+ (get "float_name") +]_or_die (file, 0, [+ (get "float_name") +]_data, ARRAY_LEN ([+ (get "float_name") +]_data), __LINE__) ;
sf_close (file) ;
file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
sf_command (file, SFC_TEST_IEEE_FLOAT_REPLACE, NULL, replace_float) ;
if (sfinfo.frames != ARRAY_LEN ([+ (get "float_name") +]_data))
{ printf ("\n\nLine %d: Incorrect number of frames in file (too short). (%" PRId64 " should be %d)\n", __LINE__, sfinfo.frames, DFT_DATA_LENGTH) ;