diff options
| author | Mohamed Tarek <mt@rockbox.org> | 2010-02-16 03:34:39 +0000 |
|---|---|---|
| committer | Mohamed Tarek <mt@rockbox.org> | 2010-02-16 03:34:39 +0000 |
| commit | 82f05895af2e361b983aa782e4294a641b287429 (patch) | |
| tree | e2c6dd216900418ca41d3d4a6c19e460a666543e /apps/metadata | |
| parent | fd5f8f987396a63ff75b5322e922a9dcfd2b229b (diff) | |
| download | rockbox-82f05895af2e361b983aa782e4294a641b287429.zip rockbox-82f05895af2e361b983aa782e4294a641b287429.tar.gz rockbox-82f05895af2e361b983aa782e4294a641b287429.tar.bz2 rockbox-82f05895af2e361b983aa782e4294a641b287429.tar.xz | |
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
Diffstat (limited to 'apps/metadata')
| -rw-r--r-- | apps/metadata/wave.c | 47 |
1 files changed, 43 insertions, 4 deletions
diff --git a/apps/metadata/wave.c b/apps/metadata/wave.c index cf676f8..acef32d 100644 --- a/apps/metadata/wave.c +++ b/apps/metadata/wave.c @@ -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) */ - id3->length = ((int64_t) totalsamples * 1000) / id3->frequency; + 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; } |