summaryrefslogtreecommitdiffstats
path: root/apps/metadata
diff options
context:
space:
mode:
authorYoshihisa Uchida <uchida@rockbox.org>2010-05-13 12:40:09 +0000
committerYoshihisa Uchida <uchida@rockbox.org>2010-05-13 12:40:09 +0000
commit0f5c6d47d4fdd17260b840024880ba6dd3fdf935 (patch)
tree6d2526a58816aa9f6431a22a8f1a56278a445dfd /apps/metadata
parent889b4a8ce838bd4191c736d01d9665c177e6d390 (diff)
downloadrockbox-0f5c6d47d4fdd17260b840024880ba6dd3fdf935.tar.gz
rockbox-0f5c6d47d4fdd17260b840024880ba6dd3fdf935.zip
add True Audio (TTA) codec
decoding speed iPod video ~153% But in some players, the decoding speed is not enough. (e.g., H180 52.4% (thanks amiconn), H300 55.09% (thanks n1s)) git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25994 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/metadata')
-rw-r--r--apps/metadata/metadata_parsers.h2
-rw-r--r--apps/metadata/mp3.c2
-rw-r--r--apps/metadata/tta.c123
3 files changed, 126 insertions, 1 deletions
diff --git a/apps/metadata/metadata_parsers.h b/apps/metadata/metadata_parsers.h
index 0e813ccb48..7238b71a30 100644
--- a/apps/metadata/metadata_parsers.h
+++ b/apps/metadata/metadata_parsers.h
@@ -22,6 +22,7 @@
char* id3_get_num_genre(unsigned int genre_num);
int getid3v2len(int fd);
bool setid3v1title(int fd, struct mp3entry *entry);
+void setid3v2title(int fd, struct mp3entry *entry);
bool get_mp3_metadata(int fd, struct mp3entry* id3, const char *filename);
bool get_adx_metadata(int fd, struct mp3entry* id3);
@@ -46,3 +47,4 @@ bool get_smaf_metadata(int fd, struct mp3entry* id3);
bool get_au_metadata(int fd, struct mp3entry* id3);
bool get_vox_metadata(int fd, struct mp3entry* id3);
bool get_wave64_metadata(int fd, struct mp3entry* id3);
+bool get_tta_metadata(int fd, struct mp3entry* id3);
diff --git a/apps/metadata/mp3.c b/apps/metadata/mp3.c
index 49d5c7362e..0f786bd52b 100644
--- a/apps/metadata/mp3.c
+++ b/apps/metadata/mp3.c
@@ -640,7 +640,7 @@ bool setid3v1title(int fd, struct mp3entry *entry)
*
* Returns: true if a title was found and created, else false
*/
-static void setid3v2title(int fd, struct mp3entry *entry)
+void setid3v2title(int fd, struct mp3entry *entry)
{
int minframesize;
int size;
diff --git a/apps/metadata/tta.c b/apps/metadata/tta.c
new file mode 100644
index 0000000000..1d3d95f118
--- /dev/null
+++ b/apps/metadata/tta.c
@@ -0,0 +1,123 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2010 Yoshihisa Uchida
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <inttypes.h>
+
+#include "system.h"
+#include "metadata.h"
+#include "metadata_common.h"
+#include "metadata_parsers.h"
+#include "logf.h"
+
+#define TTA1_SIGN 0x31415454
+
+#define TTA_HEADER_ID 0
+#define TTA_HEADER_AUDIO_FORMAT (TTA_HEADER_ID + sizeof(unsigned int))
+#define TTA_HEADER_NUM_CHANNELS (TTA_HEADER_AUDIO_FORMAT + sizeof(unsigned short))
+#define TTA_HEADER_BITS_PER_SAMPLE (TTA_HEADER_NUM_CHANNELS + sizeof(unsigned short))
+#define TTA_HEADER_SAMPLE_RATE (TTA_HEADER_BITS_PER_SAMPLE + sizeof(unsigned short))
+#define TTA_HEADER_DATA_LENGTH (TTA_HEADER_SAMPLE_RATE + sizeof(unsigned int))
+#define TTA_HEADER_CRC32 (TTA_HEADER_DATA_LENGTH + sizeof(unsigned int))
+#define TTA_HEADER_SIZE (TTA_HEADER_CRC32 + sizeof(unsigned int))
+
+#define TTA_HEADER_GETTER_ID(x) get_long_le(x)
+#define TTA_HEADER_GETTER_AUDIO_FORMAT(x) get_short_le(x)
+#define TTA_HEADER_GETTER_NUM_CHANNELS(x) get_short_le(x)
+#define TTA_HEADER_GETTER_BITS_PER_SAMPLE(x) get_short_le(x)
+#define TTA_HEADER_GETTER_SAMPLE_RATE(x) get_long_le(x)
+#define TTA_HEADER_GETTER_DATA_LENGTH(x) get_long_le(x)
+#define TTA_HEADER_GETTER_CRC32(x) get_long_le(x)
+
+#define GET_HEADER(x, tag) TTA_HEADER_GETTER_ ## tag((x) + TTA_HEADER_ ## tag)
+
+static void read_id3_tags(int fd, struct mp3entry* id3)
+{
+ id3->title = NULL;
+ id3->filesize = filesize(fd);
+ id3->id3v2len = getid3v2len(fd);
+ id3->tracknum = 0;
+ id3->discnum = 0;
+ id3->vbr = false; /* All TTA files are CBR */
+
+ /* first get id3v2 tags. if no id3v2 tags ware found, get id3v1 tags */
+ if (id3->id3v2len)
+ {
+ setid3v2title(fd, id3);
+ id3->first_frame_offset = id3->id3v2len;
+ return;
+ }
+ setid3v1title(fd, id3);
+}
+
+bool get_tta_metadata(int fd, struct mp3entry* id3)
+{
+ unsigned char ttahdr[TTA_HEADER_SIZE];
+ unsigned int datasize;
+ unsigned int origsize;
+ int bps;
+
+ lseek(fd, 0, SEEK_SET);
+
+ /* read id3 tags */
+ read_id3_tags(fd, id3);
+ lseek(fd, id3->id3v2len, SEEK_SET);
+
+ /* read TTA header */
+ if (read(fd, ttahdr, TTA_HEADER_SIZE) < 0)
+ return false;
+
+ /* check for TTA3 signature */
+ if ((GET_HEADER(ttahdr, ID)) != TTA1_SIGN)
+ return false;
+
+ /* skip check CRC */
+
+ id3->channels = (GET_HEADER(ttahdr, NUM_CHANNELS));
+ id3->frequency = (GET_HEADER(ttahdr, SAMPLE_RATE));
+ id3->length = ((GET_HEADER(ttahdr, DATA_LENGTH)) / id3->frequency) * 1000LL;
+ bps = (GET_HEADER(ttahdr, BITS_PER_SAMPLE));
+
+ datasize = id3->filesize - id3->first_frame_offset;
+ origsize = (GET_HEADER(ttahdr, DATA_LENGTH)) * ((bps + 7) / 8) * id3->channels;
+
+ id3->bitrate = (int) ((uint64_t) datasize * id3->frequency * id3->channels * bps
+ / (origsize * 1000LL));
+
+ /* output header info (for debug) */
+ DEBUGF("TTA header info ----\n");
+ DEBUGF("id: %x\n", (unsigned int)(GET_HEADER(ttahdr, ID)));
+ DEBUGF("channels: %d\n", id3->channels);
+ DEBUGF("frequency: %ld\n", id3->frequency);
+ DEBUGF("length: %ld\n", id3->length);
+ DEBUGF("bitrate: %d\n", id3->bitrate);
+ DEBUGF("bits per sample: %d\n", bps);
+ DEBUGF("compressed size: %d\n", datasize);
+ DEBUGF("original size: %d\n", origsize);
+ DEBUGF("id3----\n");
+ DEBUGF("artist: %s\n", id3->artist);
+ DEBUGF("title: %s\n", id3->title);
+ DEBUGF("genre: %s\n", id3->genre_string);
+
+ return true;
+}