-
Notifications
You must be signed in to change notification settings - Fork 37
Description
When a PCM audio block containing silent audio (zero values), the twolame library uses scalefactor value 63, which is invalid.
According to ISO 11172-3 Annex B Table 3-B.1. Layer I,II scalefactors, the scalefactor table contains 63 values with indices ranging from 0 to 62.
The libtwolame/encode.c file defines the scalefactor table thus:
static const FLOAT scalefactor[64]
and the twolame_scalefactor_calc function uses a binary search to calculate the scalefactor. This leads to a scalefactor of 63 when the sample value is zero.
This issue was discovered in version 0.3.13 (the version we are using), and I have confirmed that this also occurs in the main branch @ 90b694b .
A possible fix is below:
diff --git a/libtwolame/encode.c b/libtwolame/encode.c
index 681fe4d..07f7535 100644
--- a/libtwolame/encode.c
+++ b/libtwolame/encode.c
@@ -316,7 +316,7 @@ void twolame_scalefactor_calc(FLOAT sb_sample[][3][SCALE_BLOCK][SBLIMIT],
}
if (cur_max > scalefactor[scale_fac])
scale_fac--;
- sf_index[ch][gr][sb] = scale_fac;
+ sf_index[ch][gr][sb] = scale_fac <= 62 ? scale_fac : 62; /* Limit the scale factor to the range 0 to 62 */
/* There is a direct way of working out the index, if the maximum value is known
but since it involves a log it isn't really speedy. Items in the scalefactor[]
table are calculated by: the n'th entry = 2 / (cuberoot(2) ^ n) And so using a
I have run the tests in the tests directory to check the possible fix, and all the tests pass:
1..118
ok 1 - [1] MD5sum of testcase-44100.wav
ok 2 - [1] twolame response code
ok 3 - [1] MPEG Audio Header - Sync Word
ok 4 - [1] MPEG Audio Header - Version
ok 5 - [1] MPEG Audio Header - Layer
ok 6 - [1] MPEG Audio Header - Mode
ok 7 - [1] MPEG Audio Header - Sample Rate
ok 8 - [1] MPEG Audio Header - Bitrate
ok 9 - [1] MPEG Audio Header - Copyright Flag
ok 10 - [1] MPEG Audio Header - Original Flag
ok 11 - [1] MPEG Audio Header - Private Extension Bit
ok 12 - [1] MPEG Audio Header - Error Protection Flag
ok 13 - [1] MPEG Audio Header - De-emphasis
ok 14 - [1] total number of frames
ok 15 - [1] total number of bytes
ok 16 - [1] total number of samples
ok 17 - [1] file size of output file
ok 18 - [1] md5sum of output file
ok 19 - [2] MD5sum of testcase-44100.wav
ok 20 - [2] twolame response code
ok 21 - [2] MPEG Audio Header - Sync Word
ok 22 - [2] MPEG Audio Header - Version
ok 23 - [2] MPEG Audio Header - Layer
ok 24 - [2] MPEG Audio Header - Mode
ok 25 - [2] MPEG Audio Header - Sample Rate
ok 26 - [2] MPEG Audio Header - Bitrate
ok 27 - [2] MPEG Audio Header - Copyright Flag
ok 28 - [2] MPEG Audio Header - Original Flag
ok 29 - [2] MPEG Audio Header - Private Extension Bit
ok 30 - [2] MPEG Audio Header - Error Protection Flag
ok 31 - [2] MPEG Audio Header - De-emphasis
ok 32 - [2] total number of frames
ok 33 - [2] total number of bytes
ok 34 - [2] total number of samples
ok 35 - [2] file size of output file
ok 36 - [2] md5sum of output file
ok 37 - [3] MD5sum of testcase-22050.wav
ok 38 - [3] twolame response code
ok 39 - [3] MPEG Audio Header - Sync Word
ok 40 - [3] MPEG Audio Header - Version
ok 41 - [3] MPEG Audio Header - Layer
ok 42 - [3] MPEG Audio Header - Mode
ok 43 - [3] MPEG Audio Header - Sample Rate
ok 44 - [3] MPEG Audio Header - Bitrate
ok 45 - [3] MPEG Audio Header - Copyright Flag
ok 46 - [3] MPEG Audio Header - Original Flag
ok 47 - [3] MPEG Audio Header - Private Extension Bit
ok 48 - [3] MPEG Audio Header - Error Protection Flag
ok 49 - [3] MPEG Audio Header - De-emphasis
ok 50 - [3] total number of frames
ok 51 - [3] total number of bytes
ok 52 - [3] total number of samples
ok 53 - [3] file size of output file
ok 54 - [3] md5sum of output file
ok 55 - [4] MD5sum of testcase-44100.wav
ok 56 - [4] twolame response code
ok 57 - [4] MPEG Audio Header - Sync Word
ok 58 - [4] MPEG Audio Header - Version
ok 59 - [4] MPEG Audio Header - Layer
ok 60 - [4] MPEG Audio Header - Mode
ok 61 - [4] MPEG Audio Header - Sample Rate
ok 62 - [4] MPEG Audio Header - Bitrate
ok 63 - [4] MPEG Audio Header - Copyright Flag
ok 64 - [4] MPEG Audio Header - Original Flag
ok 65 - [4] MPEG Audio Header - Private Extension Bit
ok 66 - [4] MPEG Audio Header - Error Protection Flag
ok 67 - [4] MPEG Audio Header - De-emphasis
ok 68 - [4] total number of frames
ok 69 - [4] total number of bytes
ok 70 - [4] total number of samples
ok 71 - [4] file size of output file
ok 72 - [4] md5sum of output file
ok 73 - [5] MD5sum of testcase-44100.wav
ok 74 - [5] twolame response code
ok 75 - [5] MPEG Audio Header - Sync Word
ok 76 - [5] MPEG Audio Header - Version
ok 77 - [5] MPEG Audio Header - Layer
ok 78 - [5] MPEG Audio Header - Mode
ok 79 - [5] MPEG Audio Header - Sample Rate
ok 80 - [5] MPEG Audio Header - Bitrate
ok 81 - [5] MPEG Audio Header - Copyright Flag
ok 82 - [5] MPEG Audio Header - Original Flag
ok 83 - [5] MPEG Audio Header - Private Extension Bit
ok 84 - [5] MPEG Audio Header - Error Protection Flag
ok 85 - [5] MPEG Audio Header - De-emphasis
ok 86 - [5] total number of frames
ok 87 - [5] total number of bytes
ok 88 - [5] total number of samples
ok 89 - [5] file size of output file
ok 90 - [5] md5sum of output file
ok 91 - [6] MD5sum of testcase-float32.wav
ok 92 - [6] twolame response code
ok 93 - [6] MPEG Audio Header - Sync Word
ok 94 - [6] MPEG Audio Header - Version
ok 95 - [6] MPEG Audio Header - Layer
ok 96 - [6] MPEG Audio Header - Mode
ok 97 - [6] MPEG Audio Header - Sample Rate
ok 98 - [6] MPEG Audio Header - Bitrate
ok 99 - [6] MPEG Audio Header - Copyright Flag
ok 100 - [6] MPEG Audio Header - Original Flag
ok 101 - [6] MPEG Audio Header - Private Extension Bit
ok 102 - [6] MPEG Audio Header - Error Protection Flag
ok 103 - [6] MPEG Audio Header - De-emphasis
ok 104 - [6] total number of frames
ok 105 - [6] total number of bytes
ok 106 - [6] total number of samples
ok 107 - [6] file size of output file
twolame_init_params(): 0kbps is an invalid bitrate for 2ch encoding.
Error: configuring libtwolame encoder failed.
ok 108 - 44100 samplerate with bitrate of '0' should result in an error
twolame_get_bitrate_index: 0 is not a legal bitrate for version 'MPEG-2 LSF'
Not a valid bitrate (0) for MPEG version 'MPEG-2 LSF'
Error: configuring libtwolame encoder failed.
ok 109 - 22050 samplerate with bitrate of '0' should result in an error
ok 110 - sndfile-convert to raw response code
ok 111 - converting from STDIN - response code
ok 112 - converting from STDIN - total number of frames
ok 113 - converting from STDIN - total number of bytes
ok 114 - converting from STDIN - md5sum of output file
Using libtwolame version 0.4.0.
Parsing Wave File Header
>>> 44100 Hz sampling freq selected
>>> Input Wave File is Stereo
[0021]
Finished nicely.
ok 115 - converting using simplefrontend - response code
ok 116 - converting using simplefrontend - total number of frames
ok 117 - converting using simplefrontend - total number of bytes
ok 118 - converting using simplefrontend - md5sum of output file
Let me know if you'd like me to create a PR.