| Summary: | detect_music_type() doesn't always detect mp3s | ||
|---|---|---|---|
| Product: | SDL_mixer | Reporter: | David Gow <david> |
| Component: | misc | Assignee: | Ryan C. Gordon <icculus> |
| Status: | RESOLVED FIXED | QA Contact: | Sam Lantinga <slouken> |
| Severity: | minor | ||
| Priority: | P2 | CC: | sezeroz |
| Version: | unspecified | ||
| Hardware: | x86_64 | ||
| OS: | Linux | ||
(In reply to David Gow from comment #0) > My proposed solution would therefore be to change the 0xFE mask to 0xE6, > and compare it again 0xE2, making that line: > > magic[0] == 0xFF && (magic[1] & 0xE6) == 0xE2 Does your suggestion not reject version 1 files? Or am I misreading it? If I am not misreading: We can still check magic[1] & 0xE6, but compare to 0xFA (v1), 0xF2 (v2), and 0xE2 (v2.5) so as to support all three versions. (In reply to Ozkan Sezer from comment #1) > > magic[0] == 0xFF && (magic[1] & 0xE6) == 0xE2 > > Does your suggestion not reject version 1 files? Or am I > misreading it? Obviously, I was misreading. Sorry for the noise. Applied your change: https://hg.libsdl.org/SDL_mixer/rev/ecb8508abf6b Closing as fixed. |
The magic number detection for mp3 files in detect_music_type() checks either for an ID3 tag ('ID3' as the first three bytes), or for a frame header, checking the first two bytes as follows[1]: magic[0] == 0xFF && (magic[1] & 0xFE) == 0xFA This effectively checks the frame sync (first 11 bits are 1), the MPEG audio version (next two bits must be 11, for MPEG 1), and the layer (next two bits are 11, for Layer III). See [2] for a description of the header format. However, some MP3 files use a different MPEG audio version, but otherwise play fine. In my case, I have an MPEG 2 MP3 file[3], which decodes properly with mpg123 (and hence SDL_Mixer), if it's detected, but as it isn't, fails to load (SDL_Mixer thinks it's a MOD). The first two bytes of that file are $FF $F3 (the version field being 10, for MPEG 2). I've worked around this by adding an ID3 tag to the file[4], after which it loads and plays perfectly. Even if SDL_Mixer couldn't play MPEG 2 / MPEG 2.5 MP3 files, it probably would make sense to detect them properly in detect_music_type(), so that at least we'd get MP3 decoding errors, rather than trying to treat it as a .mod file. My proposed solution would therefore be to change the 0xFE mask to 0xE6, and compare it again 0xE2, making that line: magic[0] == 0xFF && (magic[1] & 0xE6) == 0xE2 This would only check the frame sync and layer fields. [1]: https://hg.libsdl.org/SDL_mixer/file/128995c3a5cf/src/music.c#l531 [2]: http://www.mp3-tech.org/programmer/frame_header.html [3]: https://github.com/sulix/ld3sdl/blob/a1cabd9a6d158c7fb5253ca4a74a84c5e0426a95/sfx/shotgun.mp3 [4]: https://github.com/sulix/ld3sdl/blob/d75c81b6fce40468bc72d3db73db789f85308d91/sfx/shotgun.mp3