forked from len0rd/rockbox
Initial support for ATRAC3 streams in wav containers.
Current state : - Playback and seeking are possible. - We now support ATRAC3 in any of its possible containers (wav/at3, oma/aa3, and rm/ra). TODO : - Fix joint-stereo decoding for ATRAC3 - the decoder currently produces lots of glitches. - Rename atrac3_oma.c since it works for both oma and wav containers. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24689 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
fd5f8f9873
commit
82f05895af
4 changed files with 47 additions and 6 deletions
|
|
@ -75,6 +75,7 @@ next_track:
|
|||
frame_counter = 0;
|
||||
|
||||
ci->set_elapsed(0);
|
||||
ci->seek_buffer(0);
|
||||
ci->advance_buffer(ci->id3->first_frame_offset);
|
||||
|
||||
/* The main decoder loop */
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ static const struct filetype inbuilt_filetypes[] = {
|
|||
{ "tm2", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
|
||||
{ "oma", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
|
||||
{ "aa3", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
|
||||
{ "at3", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
|
||||
#endif
|
||||
{ "m3u", FILE_ATTR_M3U, Icon_Playlist, LANG_PLAYLIST },
|
||||
{ "m3u8",FILE_ATTR_M3U, Icon_Playlist, LANG_PLAYLIST },
|
||||
|
|
|
|||
|
|
@ -60,9 +60,9 @@ const struct afmt_entry audio_formats[AFMT_NUM_CODECS] =
|
|||
/* Audio Interchange File Format */
|
||||
[AFMT_AIFF] =
|
||||
AFMT_ENTRY("AIFF", "aiff", "aiff_enc", "aiff\0aif\0"),
|
||||
/* Uncompressed PCM in a WAV file */
|
||||
/* Uncompressed PCM in a WAV file OR ATRAC3 stream in WAV file (.at3) */
|
||||
[AFMT_PCM_WAV] =
|
||||
AFMT_ENTRY("WAV", "wav", "wav_enc", "wav\0" ),
|
||||
AFMT_ENTRY("WAV", "wav", "wav_enc", "wav\0at3\0" ),
|
||||
/* Ogg Vorbis */
|
||||
[AFMT_OGG_VORBIS] =
|
||||
AFMT_ENTRY("Ogg", "vorbis", NULL, "ogg\0oga\0" ),
|
||||
|
|
|
|||
|
|
@ -29,6 +29,17 @@
|
|||
#include "metadata_common.h"
|
||||
#include "metadata_parsers.h"
|
||||
|
||||
# define AV_WL32(p, d) do { \
|
||||
((uint8_t*)(p))[0] = (d); \
|
||||
((uint8_t*)(p))[1] = (d)>>8; \
|
||||
((uint8_t*)(p))[2] = (d)>>16; \
|
||||
((uint8_t*)(p))[3] = (d)>>24; \
|
||||
} while(0)
|
||||
# define AV_WL16(p, d) do { \
|
||||
((uint8_t*)(p))[0] = (d); \
|
||||
((uint8_t*)(p))[1] = (d)>>8; \
|
||||
} while(0)
|
||||
|
||||
bool get_wave_metadata(int fd, struct mp3entry* id3)
|
||||
{
|
||||
/* Use the trackname part of the id3 structure as a temporary buffer */
|
||||
|
|
@ -37,6 +48,7 @@ bool get_wave_metadata(int fd, struct mp3entry* id3)
|
|||
unsigned long channels = 0;
|
||||
unsigned long bitspersample = 0;
|
||||
unsigned long numbytes = 0;
|
||||
unsigned long offset = 0;
|
||||
int read_bytes;
|
||||
int i;
|
||||
|
||||
|
|
@ -46,6 +58,7 @@ bool get_wave_metadata(int fd, struct mp3entry* id3)
|
|||
{
|
||||
return false;
|
||||
}
|
||||
offset += 12;
|
||||
|
||||
if ((memcmp(buf, "RIFF",4) != 0)
|
||||
|| (memcmp(&buf[8], "WAVE", 4) !=0 ))
|
||||
|
|
@ -59,6 +72,7 @@ bool get_wave_metadata(int fd, struct mp3entry* id3)
|
|||
/* get chunk header */
|
||||
if ((read_bytes = read(fd, buf, 8)) < 8)
|
||||
return false;
|
||||
offset += 8;
|
||||
|
||||
/* chunkSize */
|
||||
i = get_long_le(&buf[4]);
|
||||
|
|
@ -68,9 +82,10 @@ bool get_wave_metadata(int fd, struct mp3entry* id3)
|
|||
/* get rest of chunk */
|
||||
if ((read_bytes = read(fd, buf, 16)) < 16)
|
||||
return false;
|
||||
|
||||
offset += 16;
|
||||
i -= 16;
|
||||
|
||||
|
||||
/* skipping wFormatTag */
|
||||
/* wChannels */
|
||||
channels = buf[2] | (buf[3] << 8);
|
||||
|
|
@ -78,13 +93,33 @@ bool get_wave_metadata(int fd, struct mp3entry* id3)
|
|||
id3->frequency = get_long_le(&buf[4]);
|
||||
/* dwAvgBytesPerSec */
|
||||
id3->bitrate = (get_long_le(&buf[8]) * 8) / 1000;
|
||||
/* skipping wBlockAlign */
|
||||
/* wBlockAlign */
|
||||
id3->bytesperframe = buf[12] | (buf[13] << 8);
|
||||
/* wBitsPerSample */
|
||||
bitspersample = buf[14] | (buf[15] << 8);
|
||||
/* Check for ATRAC3 stream */
|
||||
if((buf[0] | (buf[1] << 8)) == 0x0270)
|
||||
{
|
||||
int jsflag = 0;
|
||||
if(id3->bitrate == 66 || id3->bitrate == 94)
|
||||
jsflag = 1;
|
||||
|
||||
id3->extradata_size = 14;
|
||||
id3->channels = 2;
|
||||
id3->codectype = AFMT_OMA_ATRAC3;
|
||||
/* Store the extradata for the codec */
|
||||
AV_WL16(&id3->id3v2buf[0], 1); // always 1
|
||||
AV_WL32(&id3->id3v2buf[2], id3->frequency); // samples rate
|
||||
AV_WL16(&id3->id3v2buf[6], jsflag); // coding mode
|
||||
AV_WL16(&id3->id3v2buf[8], jsflag); // coding mode
|
||||
AV_WL16(&id3->id3v2buf[10], 1); // always 1
|
||||
AV_WL16(&id3->id3v2buf[12], 0); // always 0
|
||||
}
|
||||
}
|
||||
else if (memcmp(buf, "data", 4) == 0)
|
||||
{
|
||||
numbytes = i;
|
||||
id3->first_frame_offset = offset;
|
||||
break;
|
||||
}
|
||||
else if (memcmp(buf, "fact", 4) == 0)
|
||||
|
|
@ -95,7 +130,7 @@ bool get_wave_metadata(int fd, struct mp3entry* id3)
|
|||
/* get rest of chunk */
|
||||
if ((read_bytes = read(fd, buf, 4)) < 4)
|
||||
return false;
|
||||
|
||||
offset += 4;
|
||||
i -= 4;
|
||||
totalsamples = get_long_le(buf);
|
||||
}
|
||||
|
|
@ -107,6 +142,7 @@ bool get_wave_metadata(int fd, struct mp3entry* id3)
|
|||
|
||||
if(lseek(fd, i, SEEK_CUR) < 0)
|
||||
return false;
|
||||
offset += i;
|
||||
}
|
||||
|
||||
if ((numbytes == 0) || (channels == 0))
|
||||
|
|
@ -125,7 +161,10 @@ bool get_wave_metadata(int fd, struct mp3entry* id3)
|
|||
id3->filesize = filesize(fd);
|
||||
|
||||
/* Calculate track length (in ms) and estimate the bitrate (in kbit/s) */
|
||||
if(id3->codectype != AFMT_OMA_ATRAC3)
|
||||
id3->length = ((int64_t) totalsamples * 1000) / id3->frequency;
|
||||
else
|
||||
id3->length = ((id3->filesize - id3->first_frame_offset) * 8) / id3->bitrate;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue