1
0
Fork 0
forked from len0rd/rockbox

AAC: Improve SBR detection, to fix incorrect frequency on some files (and hopefully not break others :).

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13255 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Magnus Holmgren 2007-04-24 19:22:21 +00:00
parent 72e6dd5e0c
commit ab707b8362

View file

@ -1255,23 +1255,26 @@ static bool read_mp4_esds(int fd, struct mp3entry* id3,
unsigned long bits; unsigned long bits;
unsigned int length; unsigned int length;
unsigned int index; unsigned int index;
int type; unsigned int type;
/* Read the (leading part of the) decoder config. */ /* Read the (leading part of the) decoder config. */
length = read_mp4_length(fd, size); length = read_mp4_length(fd, size);
length = MIN(length, *size); length = MIN(length, *size);
length = MIN(length, sizeof(buf)); length = MIN(length, sizeof(buf));
memset(buf, 0, sizeof(buf));
read(fd, buf, length); read(fd, buf, length);
*size -= length; *size -= length;
/* Maybe time to write a simple read_bits function... */
/* Decoder config format: /* Decoder config format:
* Object type - 5 bits * Object type - 5 bits
* Frequency index - 4 bits * Frequency index - 4 bits
* Channel configuration - 4 bits * Channel configuration - 4 bits
*/ */
bits = get_long_be(buf); bits = get_long_be(buf);
type = bits >> 27; type = bits >> 27; /* Object type - 5 bits */
index = (bits >> 23) & 0xf; index = (bits >> 23) & 0xf; /* Frequency index - 4 bits */
if (index < (sizeof(sample_rates) / sizeof(*sample_rates))) if (index < (sizeof(sample_rates) / sizeof(*sample_rates)))
{ {
@ -1280,29 +1283,65 @@ static bool read_mp4_esds(int fd, struct mp3entry* id3,
if (type == 5) if (type == 5)
{ {
DEBUGF("MP4: SBR\n");
unsigned int old_index = index;
sbr = true; sbr = true;
/* Extended frequency index - 4 bits */ index = (bits >> 15) & 0xf; /* Frequency index - 4 bits */
index = (bits >> 15) & 0xf;
if (index == 15) if (index == 15)
{ {
/* 17 bits read so far... */ /* 17 bits read so far... */
bits = get_long_be(&buf[2]); bits = get_long_be(&buf[2]);
id3->frequency = (bits >> 7) & 0x00FFFFFF; id3->frequency = (bits >> 7) & 0x00ffffff;
} }
else if (index < (sizeof(sample_rates) / sizeof(*sample_rates))) else if (index < (sizeof(sample_rates) / sizeof(*sample_rates)))
{ {
id3->frequency = sample_rates[index]; id3->frequency = sample_rates[index];
} }
}
else if (id3->frequency < 24000) if (old_index == index)
{ {
/* SBR not indicated, but the file might still contain SBR. /* Downsampled SBR */
* MPEG specification says that one should assume SBR if
* samplerate <= 24000 Hz.
*/
id3->frequency *= 2; id3->frequency *= 2;
sbr = true; }
}
/* TODO: Should check that there is at least 16 bits left */
/* Skip 13 bits from above, plus 3 bits, then read 11 bits */
else if (((bits >> 5) & 0x7ff) == 0x2b7) /* extensionAudioObjectType */
{
DEBUGF("MP4: extensionAudioType\n");
type = bits & 0x1f; /* Object type - 5 bits*/
bits = get_long_be(&buf[4]);
if (type == 5)
{
sbr = bits >> 31;
if (sbr)
{
unsigned int old_index = index;
/* 1 bit read so far */
index = (bits >> 27) & 0xf; /* Frequency index - 4 bits */
if (index == 15)
{
/* 5 bits read so far */
id3->frequency = (bits >> 3) & 0x00ffffff;
}
else if (index < (sizeof(sample_rates) / sizeof(*sample_rates)))
{
id3->frequency = sample_rates[index];
}
if (old_index == index)
{
/* Downsampled SBR */
id3->frequency *= 2;
}
}
}
} }
} }