1
0
Fork 0
forked from len0rd/rockbox

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

View file

@ -32,12 +32,17 @@
bool get_vox_metadata(int fd, struct mp3entry* id3) 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->frequency = 8000;
id3->vbr = false; /* All VOX files are CBR */ id3->vbr = false; /* All VOX files are CBR */
id3->filesize = filesize(fd); id3->filesize = filesize(fd);
id3->length = ((int64_t) id3->filesize * 2000) / id3->frequency; id3->length = id3->filesize >> 2;
return true; 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_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_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_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" #define WAVE64_GUID_DATA "data\xf3\xac\xd3\x11\x8c\xd1\x00\xc0\x4f\x8e\xdb\x8a"
enum enum
@ -90,7 +89,7 @@ static unsigned long get_totalsamples(struct wave_fmt *fmt, struct mp3entry* id3
case IBM_FORMAT_ALAW: case IBM_FORMAT_ALAW:
case IBM_FORMAT_MULAW: case IBM_FORMAT_MULAW:
totalsamples = totalsamples =
fmt->numbytes / ((((fmt->bitspersample - 1) / 8) + 1) * fmt->channels); fmt->numbytes / ((fmt->bitspersample >> 3) * fmt->channels);
break; break;
case WAVE_FORMAT_ADPCM: case WAVE_FORMAT_ADPCM:
case WAVE_FORMAT_DVI_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) if (fmt->blockalign == ((id3->frequency / 60) + 4) * fmt->channels)
fmt->samplesperblock = id3->frequency / 30; fmt->samplesperblock = id3->frequency / 30;
else else
fmt->samplesperblock = fmt->blockalign * 2 / fmt->channels; fmt->samplesperblock = (fmt->blockalign << 1) / fmt->channels;
} }
totalsamples = (fmt->numbytes / fmt->blockalign) * fmt->samplesperblock; totalsamples = (fmt->numbytes / fmt->blockalign) * fmt->samplesperblock;
break; break;
case WAVE_FORMAT_DIALOGIC_OKI_ADPCM: case WAVE_FORMAT_DIALOGIC_OKI_ADPCM:
totalsamples = 2 * fmt->numbytes; totalsamples = fmt->numbytes << 1;
break; break;
case WAVE_FORMAT_SWF_ADPCM: case WAVE_FORMAT_SWF_ADPCM:
if (fmt->samplesperblock == 0) if (fmt->samplesperblock == 0)
@ -188,9 +187,7 @@ bool get_wave_metadata(int fd, struct mp3entry* id3)
if (i < 16) if (i < 16)
return false; return false;
read_bytes = 16; read_bytes = (i > 19)? 20 : 16;
if (i > 19)
read_bytes = 20;
if (read(fd, buf, read_bytes) != read_bytes) if (read(fd, buf, read_bytes) != read_bytes)
return false; return false;
@ -198,7 +195,7 @@ bool get_wave_metadata(int fd, struct mp3entry* id3)
offset += read_bytes; offset += read_bytes;
i -= read_bytes; i -= read_bytes;
parse_riff_format(buf, i, &fmt, id3); parse_riff_format(buf, read_bytes, &fmt, id3);
/* Check for ATRAC3 stream */ /* Check for ATRAC3 stream */
if (fmt.formattag == WAVE_FORMAT_ATRAC3) 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) */ /* seek to next chunk (even chunk sizes must be padded) */
if (i & 0x01) i += (i & 0x01);
i++;
if(lseek(fd, i, SEEK_CUR) < 0) if(lseek(fd, i, SEEK_CUR) < 0)
return false; return false;
@ -290,7 +286,7 @@ bool get_wave64_metadata(int fd, struct mp3entry* id3)
if ((memcmp(buf , WAVE64_GUID_RIFF, 16) != 0)|| if ((memcmp(buf , WAVE64_GUID_RIFF, 16) != 0)||
(memcmp(buf+24, WAVE64_GUID_WAVE, 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; return false;
} }
@ -302,7 +298,7 @@ bool get_wave64_metadata(int fd, struct mp3entry* id3)
return false; return false;
/* chunkSize (excludes GUID and size length) */ /* 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) if (memcmp(buf, WAVE64_GUID_FMT, 16) == 0)
{ {
@ -310,19 +306,16 @@ bool get_wave64_metadata(int fd, struct mp3entry* id3)
if (i < 16) if (i < 16)
return false; return false;
read_bytes = 16; read_bytes = (i > 16)? 24 : 16;
if (i > 16) if ((int)i < read_bytes)
{ i = 0;
read_bytes = 24; else
if (i < 24) i -= read_bytes;
i = 24;
}
/* get rest of chunk */ /* get rest of chunk */
if (read(fd, buf, read_bytes) < read_bytes) if (read(fd, buf, read_bytes) < read_bytes)
return false; return false;
i -= read_bytes;
parse_riff_format(buf, read_bytes, &fmt, id3); parse_riff_format(buf, read_bytes, &fmt, id3);
} }
else if (memcmp(buf, WAVE64_GUID_DATA, 16) == 0) 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; fmt.numbytes = i;
break; break;
} }
else if (memcmp(buf, WAVE64_GUID_FACT, 16) == 0)
{
/* Skip 'fact' chunk */
DEBUGF("find 'fact' chunk\n");
}
/* seek to next chunk (8byte bound) */ /* seek to next chunk (8byte bound) */
if (i & 0x07) i += (1 + ~i) & 0x07;
i += 8 - (i & 0x7);
if(lseek(fd, i, SEEK_CUR) < 0) if(lseek(fd, i, SEEK_CUR) < 0)
return false; return false;
@ -359,7 +346,7 @@ bool get_wave64_metadata(int fd, struct mp3entry* id3)
id3->vbr = false; /* All Wave64 files are CBR */ id3->vbr = false; /* All Wave64 files are CBR */
id3->filesize = filesize(fd); 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; id3->length = ((int64_t) totalsamples * 1000) / id3->frequency;
return true; return true;