andygrundman / Audio-Scan

Audio::Scan - Fast Perl XS metadata and tag reader for all common audio file formats
GNU General Public License v2.0
3 stars 13 forks source link

Convert xing data to floats when calculating mp3 bitrate #15

Open nabertrand opened 4 months ago

nabertrand commented 4 months ago

Certain 192kbps MP3s will return a bitrate of 191kbps without first converting the xing data to floats on perl 5.34 on Ubuntu 22.04. Here's an example of trace output and the result of Audio::Scan->scan of a 192kbps MP3 without this patch:

Buffer allocated with 4096 bytes
Buffering from file @ 0 (min_wanted 10, max_wanted 4096, adjusted to 4096)
Buffered 4096 bytes, new pos 4096
Found ID3v2.4.0 tag, size 45
  skipped buffer data size 45
Found FF sync at offset 45
Frame @55ffe609cfe1: size=626, 1152 samples, 192kbps 44100/2
Frame @55ffe609d253: size=626, 1152 samples, 192kbps 44100/2
Frame @55ffe609d4c5: size=627, 1152 samples, 192kbps 44100/2
  valid frame
Found Xing/Info tag
bitrate from Xing header: 191 (mfs: 0.306250, xing_bytes: 6748995, xing_frames: 10764)
Buffer high water mark: 4096
Seeked to 6748880 looking for APE tag
Buffer allocated with 136 bytes
Buffering from file @ 6748880 (min_wanted 136, max_wanted 136, adjusted to 136)
Buffered 136 bytes, new pos 6749016
Buffer high water mark: 136
Buffer allocated with 4096 bytes
Buffering from file @ 6748912 (min_wanted 128, max_wanted 128, adjusted to 128)
Buffered 128 bytes, new pos 6749040
Buffering from file @ 0 (min_wanted 14, max_wanted 4096, adjusted to 4096)
Buffered 4096 bytes, new pos 4096
Parsing ID3v2.4.0 tag, flags 0, size 45
  TSSE, frame flags 0, size 15
    nfields 2: 0 5
    encoding: 3
Buffer allocated with 14 bytes
    read utf8 string of 14 bytes: Lavf58.45.100
  Found start of padding, aborting
Buffer high water mark: 4096
Buffer high water mark: 14
Scan data: $VAR1 = {
          'info' => {
                      'bitrate' => 191000,
                      'samples_per_frame' => 1152,
                      'layer' => 1,
                      'samplerate' => 44100,
                      'jenkins_hash' => 3308447330,
                      'audio_offset' => 45,
                      'song_length_ms' => 281182,
                      'stereo' => 1,
                      'xing_toc' => [
                                      0,
                                      3,
                                      5,
                                      8,
                                      10,
                                      12,
                                      16,
                                      18,
                                      20,
                                      23,
                                      25,
                                      28,
                                      31,
                                      33,
                                      36,
                                      38,
                                      41,
                                      44,
                                      46,
                                      48,
                                      51,
                                      54,
                                      56,
                                      59,
                                      61,
                                      64,
                                      66,
                                      69,
                                      72,
                                      74,
                                      76,
                                      79,
                                      82,
                                      84,
                                      87,
                                      89,
                                      92,
                                      95,
                                      97,
                                      100,
                                      102,
                                      105,
                                      108,
                                      110,
                                      112,
                                      115,
                                      117,
                                      120,
                                      123,
                                      125,
                                      128,
                                      130,
                                      133,
                                      136,
                                      138,
                                      140,
                                      143,
                                      146,
                                      148,
                                      151,
                                      153,
                                      156,
                                      159,
                                      161,
                                      164,
                                      166,
                                      168,
                                      172,
                                      174,
                                      176,
                                      179,
                                      181,
                                      184,
                                      187,
                                      189,
                                      192,
                                      194,
                                      197,
                                      200,
                                      202,
                                      204,
                                      207,
                                      210,
                                      212,
                                      215,
                                      217,
                                      219,
                                      222,
                                      225,
                                      228,
                                      230,
                                      232,
                                      235,
                                      238,
                                      240,
                                      243,
                                      245,
                                      248,
                                      251,
                                      253
                                    ],
                      'file_size' => 6749040,
                      'audio_size' => 6748995,
                      'id3_version' => 'ID3v2.4.0',
                      'padding' => 0,
                      'xing_frames' => 10764,
                      'dlna_profile' => 'MP3',
                      'xing_bytes' => 6748995
                    },
          'tags' => {
                      'TSSE' => 'Lavf58.45.100'
                    }
        };

And the same with this patch, now showing 192000 bitrate:

Buffer allocated with 4096 bytes
Buffering from file @ 0 (min_wanted 10, max_wanted 4096, adjusted to 4096)
Buffered 4096 bytes, new pos 4096
Found ID3v2.4.0 tag, size 45
  skipped buffer data size 45
Found FF sync at offset 45
Frame @56294bc01411: size=626, 1152 samples, 192kbps 44100/2
Frame @56294bc01683: size=626, 1152 samples, 192kbps 44100/2
Frame @56294bc018f5: size=627, 1152 samples, 192kbps 44100/2
  valid frame
Found Xing/Info tag
bitrate from Xing header: 192 (mfs: 0.306250, xing_bytes: 6748995, xing_frames: 10764)
Buffer high water mark: 4096
Seeked to 6748880 looking for APE tag
Buffer allocated with 136 bytes
Buffering from file @ 6748880 (min_wanted 136, max_wanted 136, adjusted to 136)
Buffered 136 bytes, new pos 6749016
Buffer high water mark: 136
Buffer allocated with 4096 bytes
Buffering from file @ 6748912 (min_wanted 128, max_wanted 128, adjusted to 128)
Buffered 128 bytes, new pos 6749040
Buffering from file @ 0 (min_wanted 14, max_wanted 4096, adjusted to 4096)
Buffered 4096 bytes, new pos 4096
Parsing ID3v2.4.0 tag, flags 0, size 45
  TSSE, frame flags 0, size 15
    nfields 2: 0 5
    encoding: 3
Buffer allocated with 14 bytes
    read utf8 string of 14 bytes: Lavf58.45.100
  Found start of padding, aborting
Buffer high water mark: 4096
Buffer high water mark: 14
Scan data: $VAR1 = {
          'info' => {
                      'xing_toc' => [
                                      0,
                                      3,
                                      5,
                                      8,
                                      10,
                                      12,
                                      16,
                                      18,
                                      20,
                                      23,
                                      25,
                                      28,
                                      31,
                                      33,
                                      36,
                                      38,
                                      41,
                                      44,
                                      46,
                                      48,
                                      51,
                                      54,
                                      56,
                                      59,
                                      61,
                                      64,
                                      66,
                                      69,
                                      72,
                                      74,
                                      76,
                                      79,
                                      82,
                                      84,
                                      87,
                                      89,
                                      92,
                                      95,
                                      97,
                                      100,
                                      102,
                                      105,
                                      108,
                                      110,
                                      112,
                                      115,
                                      117,
                                      120,
                                      123,
                                      125,
                                      128,
                                      130,
                                      133,
                                      136,
                                      138,
                                      140,
                                      143,
                                      146,
                                      148,
                                      151,
                                      153,
                                      156,
                                      159,
                                      161,
                                      164,
                                      166,
                                      168,
                                      172,
                                      174,
                                      176,
                                      179,
                                      181,
                                      184,
                                      187,
                                      189,
                                      192,
                                      194,
                                      197,
                                      200,
                                      202,
                                      204,
                                      207,
                                      210,
                                      212,
                                      215,
                                      217,
                                      219,
                                      222,
                                      225,
                                      228,
                                      230,
                                      232,
                                      235,
                                      238,
                                      240,
                                      243,
                                      245,
                                      248,
                                      251,
                                      253
                                    ],
                      'stereo' => 1,
                      'file_size' => 6749040,
                      'samples_per_frame' => 1152,
                      'dlna_profile' => 'MP3',
                      'padding' => 0,
                      'xing_frames' => 10764,
                      'song_length_ms' => 281182,
                      'jenkins_hash' => 3308447330,
                      'id3_version' => 'ID3v2.4.0',
                      'bitrate' => 192000,
                      'audio_size' => 6748995,
                      'samplerate' => 44100,
                      'xing_bytes' => 6748995,
                      'layer' => 1,
                      'audio_offset' => 45
                    },
          'tags' => {
                      'TSSE' => 'Lavf58.45.100'
                    }
        };
andygrundman commented 4 months ago

Thanks, good catch. Can you send me the first 64KB or so from your file so I can use it in a test? I want to clean this area up a bit, e.g. bitrate gets multiplied by 1000 as the very last thing, but this affects precision of the bitrate as well. It's also being stored in a 16-bit int which was a weird choice.

typedef struct mp3info {
  ...
  uint16_t bitrate;
nabertrand commented 4 months ago

I emailed you a sample. Let me know if you'd prefer it attached here instead.