add True Audio (TTA) codec
[kugel-rb.git] / apps / metadata / tta.c
blob1d3d95f11885b84e69583bb51ffd6ab647649bd6
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2010 Yoshihisa Uchida
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
21 #include <stdio.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include <ctype.h>
25 #include <inttypes.h>
27 #include "system.h"
28 #include "metadata.h"
29 #include "metadata_common.h"
30 #include "metadata_parsers.h"
31 #include "logf.h"
33 #define TTA1_SIGN 0x31415454
35 #define TTA_HEADER_ID 0
36 #define TTA_HEADER_AUDIO_FORMAT (TTA_HEADER_ID + sizeof(unsigned int))
37 #define TTA_HEADER_NUM_CHANNELS (TTA_HEADER_AUDIO_FORMAT + sizeof(unsigned short))
38 #define TTA_HEADER_BITS_PER_SAMPLE (TTA_HEADER_NUM_CHANNELS + sizeof(unsigned short))
39 #define TTA_HEADER_SAMPLE_RATE (TTA_HEADER_BITS_PER_SAMPLE + sizeof(unsigned short))
40 #define TTA_HEADER_DATA_LENGTH (TTA_HEADER_SAMPLE_RATE + sizeof(unsigned int))
41 #define TTA_HEADER_CRC32 (TTA_HEADER_DATA_LENGTH + sizeof(unsigned int))
42 #define TTA_HEADER_SIZE (TTA_HEADER_CRC32 + sizeof(unsigned int))
44 #define TTA_HEADER_GETTER_ID(x) get_long_le(x)
45 #define TTA_HEADER_GETTER_AUDIO_FORMAT(x) get_short_le(x)
46 #define TTA_HEADER_GETTER_NUM_CHANNELS(x) get_short_le(x)
47 #define TTA_HEADER_GETTER_BITS_PER_SAMPLE(x) get_short_le(x)
48 #define TTA_HEADER_GETTER_SAMPLE_RATE(x) get_long_le(x)
49 #define TTA_HEADER_GETTER_DATA_LENGTH(x) get_long_le(x)
50 #define TTA_HEADER_GETTER_CRC32(x) get_long_le(x)
52 #define GET_HEADER(x, tag) TTA_HEADER_GETTER_ ## tag((x) + TTA_HEADER_ ## tag)
54 static void read_id3_tags(int fd, struct mp3entry* id3)
56 id3->title = NULL;
57 id3->filesize = filesize(fd);
58 id3->id3v2len = getid3v2len(fd);
59 id3->tracknum = 0;
60 id3->discnum = 0;
61 id3->vbr = false; /* All TTA files are CBR */
63 /* first get id3v2 tags. if no id3v2 tags ware found, get id3v1 tags */
64 if (id3->id3v2len)
66 setid3v2title(fd, id3);
67 id3->first_frame_offset = id3->id3v2len;
68 return;
70 setid3v1title(fd, id3);
73 bool get_tta_metadata(int fd, struct mp3entry* id3)
75 unsigned char ttahdr[TTA_HEADER_SIZE];
76 unsigned int datasize;
77 unsigned int origsize;
78 int bps;
80 lseek(fd, 0, SEEK_SET);
82 /* read id3 tags */
83 read_id3_tags(fd, id3);
84 lseek(fd, id3->id3v2len, SEEK_SET);
86 /* read TTA header */
87 if (read(fd, ttahdr, TTA_HEADER_SIZE) < 0)
88 return false;
90 /* check for TTA3 signature */
91 if ((GET_HEADER(ttahdr, ID)) != TTA1_SIGN)
92 return false;
94 /* skip check CRC */
96 id3->channels = (GET_HEADER(ttahdr, NUM_CHANNELS));
97 id3->frequency = (GET_HEADER(ttahdr, SAMPLE_RATE));
98 id3->length = ((GET_HEADER(ttahdr, DATA_LENGTH)) / id3->frequency) * 1000LL;
99 bps = (GET_HEADER(ttahdr, BITS_PER_SAMPLE));
101 datasize = id3->filesize - id3->first_frame_offset;
102 origsize = (GET_HEADER(ttahdr, DATA_LENGTH)) * ((bps + 7) / 8) * id3->channels;
104 id3->bitrate = (int) ((uint64_t) datasize * id3->frequency * id3->channels * bps
105 / (origsize * 1000LL));
107 /* output header info (for debug) */
108 DEBUGF("TTA header info ----\n");
109 DEBUGF("id: %x\n", (unsigned int)(GET_HEADER(ttahdr, ID)));
110 DEBUGF("channels: %d\n", id3->channels);
111 DEBUGF("frequency: %ld\n", id3->frequency);
112 DEBUGF("length: %ld\n", id3->length);
113 DEBUGF("bitrate: %d\n", id3->bitrate);
114 DEBUGF("bits per sample: %d\n", bps);
115 DEBUGF("compressed size: %d\n", datasize);
116 DEBUGF("original size: %d\n", origsize);
117 DEBUGF("id3----\n");
118 DEBUGF("artist: %s\n", id3->artist);
119 DEBUGF("title: %s\n", id3->title);
120 DEBUGF("genre: %s\n", id3->genre_string);
122 return true;