Wave/Wave64/vox metadata parser: optimize just a little.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24992 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Yoshihisa Uchida 2010-03-02 10:59:46 +00:00
parent 04e0d6c12c
commit 66ebc35c55
3 changed files with 40 additions and 69 deletions

View file

@ -38,35 +38,25 @@ bool get_aiff_metadata(int fd, struct mp3entry* id3)
unsigned char* buf = (unsigned char *)id3->path;
unsigned long numChannels = 0;
unsigned long numSampleFrames = 0;
unsigned long sampleSize = 0;
unsigned long sampleRate = 0;
unsigned long numbytes = 0;
int read_bytes;
int i;
bool is_aifc = false;
if ((lseek(fd, 0, SEEK_SET) < 0)
|| ((read_bytes = read(fd, buf, sizeof(id3->path))) < 54))
if ((lseek(fd, 0, SEEK_SET) < 0) ||
((read_bytes = read(fd, buf, sizeof(id3->path))) < 54) ||
(memcmp(buf, "FORM", 4) != 0) || (memcmp(buf + 8, "AIF", 3) != 0) ||
(!(is_aifc = (buf[11] == 'C')) && buf[11] != 'F'))
{
return false;
}
if (memcmp(buf, "FORM",4) != 0)
return false;
if (memcmp(&buf[8], "AIFF", 4) != 0)
{
if (memcmp(&buf[8], "AIFC", 4) != 0)
return false;
is_aifc = true;
}
buf += 12;
read_bytes -= 12;
i = 12;
while ((numbytes == 0) && (read_bytes >= 8))
{
buf += i;
read_bytes -= i;
/* chunkSize */
i = get_long_be(&buf[4]);
@ -76,20 +66,17 @@ bool get_aiff_metadata(int fd, struct mp3entry* id3)
numChannels = ((buf[8]<<8)|buf[9]);
/* numSampleFrames */
numSampleFrames = get_long_be(&buf[10]);
/* sampleSize */
sampleSize = ((buf[14]<<8)|buf[15]);
/* sampleRate */
sampleRate = get_long_be(&buf[18]);
sampleRate = sampleRate >> (16+14-buf[17]);
id3->frequency = get_long_be(&buf[18]);
id3->frequency >>= (16+14-buf[17]);
/* save format infos */
id3->bitrate = (sampleSize * numChannels * sampleRate) / 1000;
id3->frequency = sampleRate;
id3->bitrate = (((buf[14]<<8)|buf[15]) * numChannels * id3->frequency) / 1000;
if (!is_aifc || memcmp(&buf[26], AIFC_FORMAT_QT_IMA_ADPCM, 4) != 0)
id3->length = ((int64_t) numSampleFrames * 1000) / id3->frequency;
else
{
/* QuickTime IMA ADPCM is 1block = 64 data for each channel */
id3->length = (int64_t)(numSampleFrames * 64000LL) / id3->frequency;
id3->length = ((int64_t) numSampleFrames * 64000LL) / id3->frequency;
}
id3->vbr = false; /* AIFF files are CBR */
@ -100,17 +87,9 @@ bool get_aiff_metadata(int fd, struct mp3entry* id3)
numbytes = i - 8;
}
if (i & 0x01)
{
i++; /* odd chunk sizes must be padded */
}
buf += i + 8;
read_bytes -= i + 8;
/* odd chunk sizes must be padded */
i += 8 + (i & 0x01);
}
if ((numbytes == 0) || (numChannels == 0))
{
return false;
}
return true;
return ((numbytes != 0) && (numChannels != 0));
}

View file

@ -32,12 +32,17 @@
bool get_vox_metadata(int fd, struct mp3entry* id3)
{
/* vox is headerless format */
/*
* vox is headerless format
*
* frequency: 8000 Hz
* channels: mono
* bitspersample: 4
*/
id3->frequency = 8000;
id3->vbr = false; /* All VOX files are CBR */
id3->filesize = filesize(fd);
id3->length = ((int64_t) id3->filesize * 2000) / id3->frequency;
id3->vbr = false; /* All VOX files are CBR */
id3->filesize = filesize(fd);
id3->length = id3->filesize >> 2;
return true;
}

View file

@ -48,7 +48,6 @@
#define WAVE64_GUID_RIFF "riff\x2e\x91\xcf\x11\xa5\xd6\x28\xdb\x04\xc1\x00\x00"
#define WAVE64_GUID_WAVE "wave\xf3\xac\xd3\x11\x8c\xd1\x00\xc0\x4f\x8e\xdb\x8a"
#define WAVE64_GUID_FMT "fmt \xf3\xac\xd3\x11\x8c\xd1\x00\xc0\x4f\x8e\xdb\x8a"
#define WAVE64_GUID_FACT "fact\xf3\xac\xd3\x11\x8c\xd1\x00\xc0\x4f\x8e\xdb\x8a"
#define WAVE64_GUID_DATA "data\xf3\xac\xd3\x11\x8c\xd1\x00\xc0\x4f\x8e\xdb\x8a"
enum
@ -90,7 +89,7 @@ static unsigned long get_totalsamples(struct wave_fmt *fmt, struct mp3entry* id3
case IBM_FORMAT_ALAW:
case IBM_FORMAT_MULAW:
totalsamples =
fmt->numbytes / ((((fmt->bitspersample - 1) / 8) + 1) * fmt->channels);
fmt->numbytes / ((fmt->bitspersample >> 3) * fmt->channels);
break;
case WAVE_FORMAT_ADPCM:
case WAVE_FORMAT_DVI_ADPCM:
@ -103,12 +102,12 @@ static unsigned long get_totalsamples(struct wave_fmt *fmt, struct mp3entry* id3
if (fmt->blockalign == ((id3->frequency / 60) + 4) * fmt->channels)
fmt->samplesperblock = id3->frequency / 30;
else
fmt->samplesperblock = fmt->blockalign * 2 / fmt->channels;
fmt->samplesperblock = (fmt->blockalign << 1) / fmt->channels;
}
totalsamples = (fmt->numbytes / fmt->blockalign) * fmt->samplesperblock;
break;
case WAVE_FORMAT_DIALOGIC_OKI_ADPCM:
totalsamples = 2 * fmt->numbytes;
totalsamples = fmt->numbytes << 1;
break;
case WAVE_FORMAT_SWF_ADPCM:
if (fmt->samplesperblock == 0)
@ -188,9 +187,7 @@ bool get_wave_metadata(int fd, struct mp3entry* id3)
if (i < 16)
return false;
read_bytes = 16;
if (i > 19)
read_bytes = 20;
read_bytes = (i > 19)? 20 : 16;
if (read(fd, buf, read_bytes) != read_bytes)
return false;
@ -198,7 +195,7 @@ bool get_wave_metadata(int fd, struct mp3entry* id3)
offset += read_bytes;
i -= read_bytes;
parse_riff_format(buf, i, &fmt, id3);
parse_riff_format(buf, read_bytes, &fmt, id3);
/* Check for ATRAC3 stream */
if (fmt.formattag == WAVE_FORMAT_ATRAC3)
@ -241,8 +238,7 @@ bool get_wave_metadata(int fd, struct mp3entry* id3)
}
/* seek to next chunk (even chunk sizes must be padded) */
if (i & 0x01)
i++;
i += (i & 0x01);
if(lseek(fd, i, SEEK_CUR) < 0)
return false;
@ -290,7 +286,7 @@ bool get_wave64_metadata(int fd, struct mp3entry* id3)
if ((memcmp(buf , WAVE64_GUID_RIFF, 16) != 0)||
(memcmp(buf+24, WAVE64_GUID_WAVE, 16) != 0))
{
DEBUGF("metada error: does not wave64 file\n");
DEBUGF("metadata error: does not wave64 file\n");
return false;
}
@ -302,7 +298,7 @@ bool get_wave64_metadata(int fd, struct mp3entry* id3)
return false;
/* chunkSize (excludes GUID and size length) */
i = get_uint64_le(&buf[16]) - 24;
i = get_uint64_le(buf + 16) - 24;
if (memcmp(buf, WAVE64_GUID_FMT, 16) == 0)
{
@ -310,19 +306,16 @@ bool get_wave64_metadata(int fd, struct mp3entry* id3)
if (i < 16)
return false;
read_bytes = 16;
if (i > 16)
{
read_bytes = 24;
if (i < 24)
i = 24;
}
read_bytes = (i > 16)? 24 : 16;
if ((int)i < read_bytes)
i = 0;
else
i -= read_bytes;
/* get rest of chunk */
if (read(fd, buf, read_bytes) < read_bytes)
return false;
i -= read_bytes;
parse_riff_format(buf, read_bytes, &fmt, id3);
}
else if (memcmp(buf, WAVE64_GUID_DATA, 16) == 0)
@ -331,15 +324,9 @@ bool get_wave64_metadata(int fd, struct mp3entry* id3)
fmt.numbytes = i;
break;
}
else if (memcmp(buf, WAVE64_GUID_FACT, 16) == 0)
{
/* Skip 'fact' chunk */
DEBUGF("find 'fact' chunk\n");
}
/* seek to next chunk (8byte bound) */
if (i & 0x07)
i += 8 - (i & 0x7);
i += (1 + ~i) & 0x07;
if(lseek(fd, i, SEEK_CUR) < 0)
return false;
@ -359,7 +346,7 @@ bool get_wave64_metadata(int fd, struct mp3entry* id3)
id3->vbr = false; /* All Wave64 files are CBR */
id3->filesize = filesize(fd);
/* Calculate track length (in ms) and estimate the bitrate (in kbit/s) */
/* Calculate track length [ms] */
id3->length = ((int64_t) totalsamples * 1000) / id3->frequency;
return true;