summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohamed Tarek <mt@rockbox.org>2010-02-16 03:34:39 +0000
committerMohamed Tarek <mt@rockbox.org>2010-02-16 03:34:39 +0000
commit82f05895af2e361b983aa782e4294a641b287429 (patch)
treee2c6dd216900418ca41d3d4a6c19e460a666543e
parentfd5f8f987396a63ff75b5322e922a9dcfd2b229b (diff)
downloadrockbox-82f05895af2e361b983aa782e4294a641b287429.tar.gz
rockbox-82f05895af2e361b983aa782e4294a641b287429.zip
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
-rw-r--r--apps/codecs/atrac3_oma.c1
-rw-r--r--apps/filetypes.c1
-rw-r--r--apps/metadata.c4
-rw-r--r--apps/metadata/wave.c47
4 files changed, 47 insertions, 6 deletions
diff --git a/apps/codecs/atrac3_oma.c b/apps/codecs/atrac3_oma.c
index 55299007d7..df3499913c 100644
--- a/apps/codecs/atrac3_oma.c
+++ b/apps/codecs/atrac3_oma.c
@@ -75,6 +75,7 @@ next_track:
75 frame_counter = 0; 75 frame_counter = 0;
76 76
77 ci->set_elapsed(0); 77 ci->set_elapsed(0);
78 ci->seek_buffer(0);
78 ci->advance_buffer(ci->id3->first_frame_offset); 79 ci->advance_buffer(ci->id3->first_frame_offset);
79 80
80 /* The main decoder loop */ 81 /* The main decoder loop */
diff --git a/apps/filetypes.c b/apps/filetypes.c
index 3feb0f5ab8..e74edff5c2 100644
--- a/apps/filetypes.c
+++ b/apps/filetypes.c
@@ -100,6 +100,7 @@ static const struct filetype inbuilt_filetypes[] = {
100 { "tm2", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA }, 100 { "tm2", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
101 { "oma", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA }, 101 { "oma", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
102 { "aa3", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA }, 102 { "aa3", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
103 { "at3", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
103#endif 104#endif
104 { "m3u", FILE_ATTR_M3U, Icon_Playlist, LANG_PLAYLIST }, 105 { "m3u", FILE_ATTR_M3U, Icon_Playlist, LANG_PLAYLIST },
105 { "m3u8",FILE_ATTR_M3U, Icon_Playlist, LANG_PLAYLIST }, 106 { "m3u8",FILE_ATTR_M3U, Icon_Playlist, LANG_PLAYLIST },
diff --git a/apps/metadata.c b/apps/metadata.c
index 619a06e72d..ce3a4ec22a 100644
--- a/apps/metadata.c
+++ b/apps/metadata.c
@@ -60,9 +60,9 @@ const struct afmt_entry audio_formats[AFMT_NUM_CODECS] =
60 /* Audio Interchange File Format */ 60 /* Audio Interchange File Format */
61 [AFMT_AIFF] = 61 [AFMT_AIFF] =
62 AFMT_ENTRY("AIFF", "aiff", "aiff_enc", "aiff\0aif\0"), 62 AFMT_ENTRY("AIFF", "aiff", "aiff_enc", "aiff\0aif\0"),
63 /* Uncompressed PCM in a WAV file */ 63 /* Uncompressed PCM in a WAV file OR ATRAC3 stream in WAV file (.at3) */
64 [AFMT_PCM_WAV] = 64 [AFMT_PCM_WAV] =
65 AFMT_ENTRY("WAV", "wav", "wav_enc", "wav\0" ), 65 AFMT_ENTRY("WAV", "wav", "wav_enc", "wav\0at3\0" ),
66 /* Ogg Vorbis */ 66 /* Ogg Vorbis */
67 [AFMT_OGG_VORBIS] = 67 [AFMT_OGG_VORBIS] =
68 AFMT_ENTRY("Ogg", "vorbis", NULL, "ogg\0oga\0" ), 68 AFMT_ENTRY("Ogg", "vorbis", NULL, "ogg\0oga\0" ),
diff --git a/apps/metadata/wave.c b/apps/metadata/wave.c
index cf676f89b0..acef32dd38 100644
--- a/apps/metadata/wave.c
+++ b/apps/metadata/wave.c
@@ -29,6 +29,17 @@
29#include "metadata_common.h" 29#include "metadata_common.h"
30#include "metadata_parsers.h" 30#include "metadata_parsers.h"
31 31
32# define AV_WL32(p, d) do { \
33 ((uint8_t*)(p))[0] = (d); \
34 ((uint8_t*)(p))[1] = (d)>>8; \
35 ((uint8_t*)(p))[2] = (d)>>16; \
36 ((uint8_t*)(p))[3] = (d)>>24; \
37 } while(0)
38# define AV_WL16(p, d) do { \
39 ((uint8_t*)(p))[0] = (d); \
40 ((uint8_t*)(p))[1] = (d)>>8; \
41 } while(0)
42
32bool get_wave_metadata(int fd, struct mp3entry* id3) 43bool get_wave_metadata(int fd, struct mp3entry* id3)
33{ 44{
34 /* Use the trackname part of the id3 structure as a temporary buffer */ 45 /* 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)
37 unsigned long channels = 0; 48 unsigned long channels = 0;
38 unsigned long bitspersample = 0; 49 unsigned long bitspersample = 0;
39 unsigned long numbytes = 0; 50 unsigned long numbytes = 0;
51 unsigned long offset = 0;
40 int read_bytes; 52 int read_bytes;
41 int i; 53 int i;
42 54
@@ -46,6 +58,7 @@ bool get_wave_metadata(int fd, struct mp3entry* id3)
46 { 58 {
47 return false; 59 return false;
48 } 60 }
61 offset += 12;
49 62
50 if ((memcmp(buf, "RIFF",4) != 0) 63 if ((memcmp(buf, "RIFF",4) != 0)
51 || (memcmp(&buf[8], "WAVE", 4) !=0 )) 64 || (memcmp(&buf[8], "WAVE", 4) !=0 ))
@@ -59,6 +72,7 @@ bool get_wave_metadata(int fd, struct mp3entry* id3)
59 /* get chunk header */ 72 /* get chunk header */
60 if ((read_bytes = read(fd, buf, 8)) < 8) 73 if ((read_bytes = read(fd, buf, 8)) < 8)
61 return false; 74 return false;
75 offset += 8;
62 76
63 /* chunkSize */ 77 /* chunkSize */
64 i = get_long_le(&buf[4]); 78 i = get_long_le(&buf[4]);
@@ -68,9 +82,10 @@ bool get_wave_metadata(int fd, struct mp3entry* id3)
68 /* get rest of chunk */ 82 /* get rest of chunk */
69 if ((read_bytes = read(fd, buf, 16)) < 16) 83 if ((read_bytes = read(fd, buf, 16)) < 16)
70 return false; 84 return false;
71 85 offset += 16;
72 i -= 16; 86 i -= 16;
73 87
88
74 /* skipping wFormatTag */ 89 /* skipping wFormatTag */
75 /* wChannels */ 90 /* wChannels */
76 channels = buf[2] | (buf[3] << 8); 91 channels = buf[2] | (buf[3] << 8);
@@ -78,13 +93,33 @@ bool get_wave_metadata(int fd, struct mp3entry* id3)
78 id3->frequency = get_long_le(&buf[4]); 93 id3->frequency = get_long_le(&buf[4]);
79 /* dwAvgBytesPerSec */ 94 /* dwAvgBytesPerSec */
80 id3->bitrate = (get_long_le(&buf[8]) * 8) / 1000; 95 id3->bitrate = (get_long_le(&buf[8]) * 8) / 1000;
81 /* skipping wBlockAlign */ 96 /* wBlockAlign */
97 id3->bytesperframe = buf[12] | (buf[13] << 8);
82 /* wBitsPerSample */ 98 /* wBitsPerSample */
83 bitspersample = buf[14] | (buf[15] << 8); 99 bitspersample = buf[14] | (buf[15] << 8);
100 /* Check for ATRAC3 stream */
101 if((buf[0] | (buf[1] << 8)) == 0x0270)
102 {
103 int jsflag = 0;
104 if(id3->bitrate == 66 || id3->bitrate == 94)
105 jsflag = 1;
106
107 id3->extradata_size = 14;
108 id3->channels = 2;
109 id3->codectype = AFMT_OMA_ATRAC3;
110 /* Store the extradata for the codec */
111 AV_WL16(&id3->id3v2buf[0], 1); // always 1
112 AV_WL32(&id3->id3v2buf[2], id3->frequency); // samples rate
113 AV_WL16(&id3->id3v2buf[6], jsflag); // coding mode
114 AV_WL16(&id3->id3v2buf[8], jsflag); // coding mode
115 AV_WL16(&id3->id3v2buf[10], 1); // always 1
116 AV_WL16(&id3->id3v2buf[12], 0); // always 0
117 }
84 } 118 }
85 else if (memcmp(buf, "data", 4) == 0) 119 else if (memcmp(buf, "data", 4) == 0)
86 { 120 {
87 numbytes = i; 121 numbytes = i;
122 id3->first_frame_offset = offset;
88 break; 123 break;
89 } 124 }
90 else if (memcmp(buf, "fact", 4) == 0) 125 else if (memcmp(buf, "fact", 4) == 0)
@@ -95,7 +130,7 @@ bool get_wave_metadata(int fd, struct mp3entry* id3)
95 /* get rest of chunk */ 130 /* get rest of chunk */
96 if ((read_bytes = read(fd, buf, 4)) < 4) 131 if ((read_bytes = read(fd, buf, 4)) < 4)
97 return false; 132 return false;
98 133 offset += 4;
99 i -= 4; 134 i -= 4;
100 totalsamples = get_long_le(buf); 135 totalsamples = get_long_le(buf);
101 } 136 }
@@ -107,6 +142,7 @@ bool get_wave_metadata(int fd, struct mp3entry* id3)
107 142
108 if(lseek(fd, i, SEEK_CUR) < 0) 143 if(lseek(fd, i, SEEK_CUR) < 0)
109 return false; 144 return false;
145 offset += i;
110 } 146 }
111 147
112 if ((numbytes == 0) || (channels == 0)) 148 if ((numbytes == 0) || (channels == 0))
@@ -125,7 +161,10 @@ bool get_wave_metadata(int fd, struct mp3entry* id3)
125 id3->filesize = filesize(fd); 161 id3->filesize = filesize(fd);
126 162
127 /* Calculate track length (in ms) and estimate the bitrate (in kbit/s) */ 163 /* Calculate track length (in ms) and estimate the bitrate (in kbit/s) */
128 id3->length = ((int64_t) totalsamples * 1000) / id3->frequency; 164 if(id3->codectype != AFMT_OMA_ATRAC3)
165 id3->length = ((int64_t) totalsamples * 1000) / id3->frequency;
166 else
167 id3->length = ((id3->filesize - id3->first_frame_offset) * 8) / id3->bitrate;
129 168
130 return true; 169 return true;
131} 170}