annotate src/tta/ttadec.c @ 912:5bd17596c7e9 trunk

[svn] - patches from upstream TTA author. see http://boards.nenolod.net/viewtopic.php?t=375
author nenolod
date Wed, 04 Apr 2007 10:52:15 -0700
parents c0f69d57483b
children d0d99b22e393
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
290
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
1 /*
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
2 * ttadec.c
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
3 *
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
4 * Description: TTAv1 decoder library for HW players.
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
5 * Developed by: Alexander Djourik <sasha@iszf.irk.ru>
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
6 * Pavel Zhilin <pzh@iszf.irk.ru>
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
7 *
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
8 * Copyright (c) 1999-2004 Alexander Djourik. All rights reserved.
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
9 *
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
10 */
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
11
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
12 /*
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
13 * This library is free software; you can redistribute it and/or
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
14 * modify it under the terms of the GNU Lesser General Public
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
15 * License as published by the Free Software Foundation; either
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
16 * version 2.1 of the License, or (at your option) any later version.
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
17 *
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
18 * This library is distributed in the hope that it will be useful,
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
21 * Lesser General Public License for more details.
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
22 *
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
23 * You should have received a copy of the GNU Lesser General Public
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
24 * License along with this library; if not, write to the Free Software
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
26 *
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
27 * Please see the file COPYING in this directory for full copyright
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
28 * information.
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
29 */
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
30
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
31 #include <stdlib.h>
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
32 #include <stdio.h>
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
33 #include <string.h>
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
34
912
5bd17596c7e9 [svn] - patches from upstream TTA author. see http://boards.nenolod.net/viewtopic.php?t=375
nenolod
parents: 551
diff changeset
35 #include "ttadec.h"
290
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
36 #include "ttalib.h"
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
37 #include "crc32.h"
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
38 #include "filters.h"
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
39
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
40 /******************* static variables and structures *******************/
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
41
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
42 static unsigned char isobuffers[ISO_BUFFERS_SIZE + 4];
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
43 static unsigned char *iso_buffers_end = isobuffers + ISO_BUFFERS_SIZE;
551
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
44 static unsigned int pcm_buffer_size;
290
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
45
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
46 static decoder tta[MAX_NCH]; // decoder state
551
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
47 static int cache[MAX_NCH]; // decoder cache
290
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
48
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
49 tta_info *ttainfo; // currently playing file info
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
50
551
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
51 static unsigned int fframes; // number of frames in file
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
52 static unsigned int framelen; // the frame length in samples
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
53 static unsigned int lastlen; // the length of the last frame in samples
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
54 static unsigned int data_pos; // currently playing frame index
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
55 static unsigned int data_cur; // the playing position in frame
290
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
56
551
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
57 static int maxvalue; // output data max value
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
58 static unsigned int *seek_table; // the playing position table
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
59 static unsigned int st_state; //seek table status
290
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
60
912
5bd17596c7e9 [svn] - patches from upstream TTA author. see http://boards.nenolod.net/viewtopic.php?t=375
nenolod
parents: 551
diff changeset
61 static __uint32_t frame_crc32;
5bd17596c7e9 [svn] - patches from upstream TTA author. see http://boards.nenolod.net/viewtopic.php?t=375
nenolod
parents: 551
diff changeset
62 static __uint32_t bit_count;
5bd17596c7e9 [svn] - patches from upstream TTA author. see http://boards.nenolod.net/viewtopic.php?t=375
nenolod
parents: 551
diff changeset
63 static __uint32_t bit_cache;
290
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
64 static unsigned char *bitpos;
551
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
65 static unsigned int bitrate;
290
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
66
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
67 void get_id3v1_tag (tta_info *ttainfo);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
68 int get_id3v2_tag (tta_info *ttainfo);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
69
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
70 /************************* bit operations ******************************/
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
71
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
72 static void init_buffer_read() {
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
73 frame_crc32 = 0xFFFFFFFFUL;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
74 bit_count = bit_cache = 0;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
75 bitpos = iso_buffers_end;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
76 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
77
551
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
78 __inline void get_binary(unsigned int *value, unsigned int bits) {
290
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
79 while (bit_count < bits) {
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
80 if (bitpos == iso_buffers_end) {
551
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
81 int res = fread(isobuffers, 1,
290
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
82 ISO_BUFFERS_SIZE, ttainfo->HANDLE);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
83 if (!res) {
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
84 ttainfo->STATE = READ_ERROR;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
85 return;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
86 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
87 bitpos = isobuffers;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
88 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
89
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
90 UPDATE_CRC32(*bitpos, frame_crc32);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
91 bit_cache |= *bitpos << bit_count;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
92 bit_count += 8;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
93 bitpos++;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
94 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
95
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
96 *value = bit_cache & bit_mask[bits];
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
97 bit_cache >>= bits;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
98 bit_count -= bits;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
99 bit_cache &= bit_mask[bit_count];
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
100 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
101
551
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
102 __inline void get_unary(unsigned int *value) {
290
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
103 *value = 0;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
104
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
105 while (!(bit_cache ^ bit_mask[bit_count])) {
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
106 if (bitpos == iso_buffers_end) {
551
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
107 int res = fread(isobuffers, 1,
290
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
108 ISO_BUFFERS_SIZE, ttainfo->HANDLE);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
109 if (!res) {
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
110 ttainfo->STATE = READ_ERROR;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
111 return;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
112 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
113 bitpos = isobuffers;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
114 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
115
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
116 *value += bit_count;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
117 bit_cache = *bitpos++;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
118 UPDATE_CRC32(bit_cache, frame_crc32);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
119 bit_count = 8;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
120 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
121
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
122 while (bit_cache & 1) {
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
123 (*value)++;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
124 bit_cache >>= 1;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
125 bit_count--;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
126 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
127
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
128 bit_cache >>= 1;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
129 bit_count--;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
130 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
131
551
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
132 static int done_buffer_read() {
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
133 unsigned int crc32, rbytes, res;
290
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
134 frame_crc32 ^= 0xFFFFFFFFUL;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
135
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
136 rbytes = iso_buffers_end - bitpos;
551
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
137 if (rbytes < sizeof(int)) {
290
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
138 memcpy(isobuffers, bitpos, 4);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
139 res = fread(isobuffers + rbytes, 1,
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
140 ISO_BUFFERS_SIZE - rbytes, ttainfo->HANDLE);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
141 if (!res) {
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
142 ttainfo->STATE = READ_ERROR;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
143 return 0;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
144 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
145 bitpos = isobuffers;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
146 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
147
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
148 memcpy(&crc32, bitpos, 4);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
149 crc32 = ENDSWAP_INT32(crc32);
551
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
150 bitpos += sizeof(int);
290
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
151 res = (crc32 != frame_crc32);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
152
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
153 bit_cache = bit_count = 0;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
154 frame_crc32 = 0xFFFFFFFFUL;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
155
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
156 // calculate dynamic bitrate
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
157 if (data_pos < fframes) {
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
158 rbytes = seek_table[data_pos] -
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
159 seek_table[data_pos - 1];
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
160 bitrate = (rbytes << 3) / 1070;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
161 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
162
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
163 return res;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
164 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
165
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
166 /************************* decoder functions ****************************/
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
167
551
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
168 static int skip_id3v2_header (FILE *infile) {
290
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
169 struct {
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
170 unsigned char id[3];
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
171 unsigned short version;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
172 unsigned char flags;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
173 unsigned char size[4];
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
174 } __ATTRIBUTE_PACKED__ id3v2;
551
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
175 unsigned int len = 0;
290
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
176
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
177 // read ID3V2 header
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
178 if (fread (&id3v2, sizeof(id3v2), 1, infile) == 0) {
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
179 fclose (infile);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
180 ttainfo->STATE = READ_ERROR;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
181 return -1;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
182 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
183
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
184 // skip ID3V2 header
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
185 if (!memcmp (id3v2.id, "ID3", 3)) {
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
186 if (id3v2.size[0] & 0x80) {
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
187 fclose (infile);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
188 ttainfo->STATE = FILE_ERROR;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
189 return FILE_ERROR;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
190 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
191 len = (id3v2.size[0] & 0x7f);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
192 len = (len << 7) | (id3v2.size[1] & 0x7f);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
193 len = (len << 7) | (id3v2.size[2] & 0x7f);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
194 len = (len << 7) | (id3v2.size[3] & 0x7f);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
195 len += 10;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
196 if (id3v2.flags & (1 << 4)) len += 10;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
197 fseek (infile, len, SEEK_SET);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
198 } else fseek (infile, 0, SEEK_SET);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
199
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
200 return len;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
201 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
202
551
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
203 int open_tta_file (const char *filename, tta_info *info, unsigned int data_offset) {
290
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
204 FILE *infile;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
205 tta_hdr ttahdr;
551
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
206 unsigned int checksum;
290
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
207
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
208 // clear the memory
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
209 memset (info, 0, sizeof(tta_info));
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
210
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
211 // printf("0: open_tta_file\n");
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
212 info->HANDLE = infile = fopen(filename, "rb");
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
213 if (!infile) return OPEN_ERROR;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
214
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
215 // printf("1: data_offset %ld\n", data_offset);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
216 // read id3v2 header
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
217 if (!data_offset) {
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
218 // data_offset = skip_id3v2_header(infile);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
219 // data_offset = get_id3v2_tag(info);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
220 data_offset = skip_v2_header(info);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
221 // printf("2: data_offset %ld\n", data_offset);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
222 // get_id3v1_tag (info);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
223 if (data_offset < 0) return -1;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
224 } else fseek (infile, data_offset, SEEK_SET);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
225
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
226 get_id3_tags (filename, info);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
227
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
228 // read TTA header
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
229 if (fread (&ttahdr, 1, sizeof (ttahdr), infile) == 0) {
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
230 fclose (infile);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
231 info->STATE = READ_ERROR;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
232 return -1;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
233 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
234
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
235 // check for TTA3 signature
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
236 if (ENDSWAP_INT32(ttahdr.TTAid) != TTA1_SIGN) {
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
237 fclose (infile);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
238 info->STATE = FORMAT_ERROR;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
239 return -1;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
240 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
241
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
242 ttahdr.CRC32 = ENDSWAP_INT32(ttahdr.CRC32);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
243 checksum = crc32((unsigned char *) &ttahdr,
551
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
244 sizeof(tta_hdr) - sizeof(int));
290
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
245 if (checksum != ttahdr.CRC32) {
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
246 fclose (infile);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
247 info->STATE = FILE_ERROR;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
248 return -1;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
249 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
250
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
251 ttahdr.AudioFormat = ENDSWAP_INT16(ttahdr.AudioFormat);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
252 ttahdr.NumChannels = ENDSWAP_INT16(ttahdr.NumChannels);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
253 ttahdr.BitsPerSample = ENDSWAP_INT16(ttahdr.BitsPerSample);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
254 ttahdr.SampleRate = ENDSWAP_INT32(ttahdr.SampleRate);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
255 ttahdr.DataLength = ENDSWAP_INT32(ttahdr.DataLength);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
256
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
257 // check for player supported formats
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
258 if (ttahdr.AudioFormat != WAVE_FORMAT_PCM ||
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
259 ttahdr.NumChannels > MAX_NCH ||
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
260 ttahdr.BitsPerSample > MAX_BPS ||(
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
261 ttahdr.SampleRate != 16000 &&
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
262 ttahdr.SampleRate != 22050 &&
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
263 ttahdr.SampleRate != 24000 &&
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
264 ttahdr.SampleRate != 32000 &&
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
265 ttahdr.SampleRate != 44100 &&
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
266 ttahdr.SampleRate != 48000 &&
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
267 ttahdr.SampleRate != 64000 &&
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
268 ttahdr.SampleRate != 88200 &&
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
269 ttahdr.SampleRate != 96000)) {
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
270 fclose (infile);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
271 info->STATE = FORMAT_ERROR;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
272 return FORMAT_ERROR;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
273 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
274
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
275 // fill the File Info
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
276 info->HANDLE = infile;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
277 info->NCH = ttahdr.NumChannels;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
278 info->BPS = ttahdr.BitsPerSample;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
279 info->BSIZE = (ttahdr.BitsPerSample + 7)/8;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
280 info->FORMAT = ttahdr.AudioFormat;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
281 info->SAMPLERATE = ttahdr.SampleRate;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
282 info->DATALENGTH = ttahdr.DataLength;
551
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
283 info->FRAMELEN = (int) (FRAME_TIME * ttahdr.SampleRate);
290
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
284 info->LENGTH = ttahdr.DataLength / ttahdr.SampleRate;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
285 info->DATAPOS = data_offset;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
286
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
287
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
288 return 0;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
289 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
290
551
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
291 static void rice_init(adapt *rice, unsigned int k0, unsigned int k1) {
290
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
292 rice->k0 = k0;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
293 rice->k1 = k1;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
294 rice->sum0 = shift_16[k0];
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
295 rice->sum1 = shift_16[k1];
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
296 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
297
551
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
298 static void decoder_init(decoder *tta, int nch, int byte_size) {
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
299 int shift = flt_set[byte_size - 1];
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
300 int i;
290
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
301
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
302 for (i = 0; i < nch; i++) {
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
303 filter_init(&tta[i].fst, shift);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
304 rice_init(&tta[i].rice, 10, 10);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
305 tta[i].last = 0;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
306 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
307 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
308
551
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
309 static void seek_table_init (unsigned int *seek_table,
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
310 unsigned int len, unsigned int data_offset) {
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
311 unsigned int *st, frame_len;
290
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
312
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
313 for (st = seek_table; st < (seek_table + len); st++) {
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
314 frame_len = ENDSWAP_INT32(*st);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
315 *st = data_offset;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
316 data_offset += frame_len;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
317 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
318 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
319
551
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
320 int set_position (unsigned int pos) {
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
321 unsigned int seek_pos;
290
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
322
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
323 if (pos >= fframes) return 0;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
324 if (!st_state) {
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
325 ttainfo->STATE = FILE_ERROR;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
326 return -1;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
327 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
328
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
329 seek_pos = ttainfo->DATAPOS + seek_table[data_pos = pos];
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
330 fseek(ttainfo->HANDLE, seek_pos, SEEK_SET);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
331
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
332 data_cur = 0;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
333 framelen = 0;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
334
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
335 // init bit reader
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
336 init_buffer_read();
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
337
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
338 return 0;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
339 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
340
551
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
341 int player_init (tta_info *info) {
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
342 unsigned int checksum;
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
343 unsigned int data_offset;
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
344 unsigned int st_size;
290
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
345
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
346 ttainfo = info;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
347
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
348 framelen = 0;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
349 data_pos = 0;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
350 data_cur = 0;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
351 bitrate = 0;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
352
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
353 lastlen = ttainfo->DATALENGTH % ttainfo->FRAMELEN;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
354 fframes = ttainfo->DATALENGTH / ttainfo->FRAMELEN + (lastlen ? 1:0);
551
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
355 st_size = (fframes + 1) * sizeof(int);
290
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
356
551
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
357 seek_table = (unsigned int *) malloc(st_size);
290
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
358 if (!seek_table) {
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
359 ttainfo->STATE = MEMORY_ERROR;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
360 return -1;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
361 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
362
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
363 // read seek table
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
364 if (!fread(seek_table, st_size, 1, ttainfo->HANDLE)) {
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
365 ttainfo->STATE = READ_ERROR;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
366 return -1;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
367 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
368
551
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
369 checksum = crc32((unsigned char *) seek_table, st_size - sizeof(int));
290
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
370 st_state = (checksum == ENDSWAP_INT32(seek_table[fframes]));
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
371 data_offset = sizeof(tta_hdr) + st_size;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
372
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
373 // init seek table
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
374 seek_table_init(seek_table, fframes, data_offset);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
375
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
376 // init bit reader
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
377 init_buffer_read();
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
378
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
379 pcm_buffer_size = PCM_BUFFER_LENGTH * ttainfo->BSIZE * ttainfo->NCH;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
380 maxvalue = (1UL << ttainfo->BPS) - 1;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
381
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
382 return 0;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
383 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
384
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
385 void close_tta_file (tta_info *info) {
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
386 if (info->HANDLE) {
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
387 fclose (info->HANDLE);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
388 info->HANDLE = NULL;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
389 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
390 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
391
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
392 void player_stop () {
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
393 if (seek_table) {
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
394 free(seek_table);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
395 seek_table = NULL;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
396 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
397 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
398
551
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
399 int get_bitrate () {
290
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
400 return bitrate;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
401 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
402
551
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
403 int get_samples (byte *buffer) {
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
404 unsigned int k, depth, unary, binary;
290
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
405 byte *p = buffer;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
406 decoder *dec = tta;
551
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
407 int *prev = cache;
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
408 int value, res;
290
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
409
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
410 for (res = 0; p < buffer + pcm_buffer_size;) {
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
411 fltst *fst = &dec->fst;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
412 adapt *rice = &dec->rice;
551
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
413 int *last = &dec->last;
290
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
414
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
415 if (data_cur == framelen) {
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
416 if (data_pos == fframes) break;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
417 if (framelen && done_buffer_read()) {
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
418 if (set_position(data_pos) < 0)
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
419 return -1;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
420 if (res) break;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
421 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
422
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
423 if (data_pos == fframes - 1 && lastlen)
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
424 framelen = lastlen;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
425 else framelen = ttainfo->FRAMELEN;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
426
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
427 decoder_init(tta, ttainfo->NCH, ttainfo->BSIZE);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
428 data_pos++; data_cur = 0;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
429 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
430
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
431 // decode Rice unsigned
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
432 get_unary(&unary);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
433
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
434 switch (unary) {
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
435 case 0: depth = 0; k = rice->k0; break;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
436 default:
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
437 depth = 1; k = rice->k1;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
438 unary--;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
439 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
440
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
441 if (k) {
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
442 get_binary(&binary, k);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
443 value = (unary << k) + binary;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
444 } else value = unary;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
445
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
446 switch (depth) {
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
447 case 1:
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
448 rice->sum1 += value - (rice->sum1 >> 4);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
449 if (rice->k1 > 0 && rice->sum1 < shift_16[rice->k1])
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
450 rice->k1--;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
451 else if (rice->sum1 > shift_16[rice->k1 + 1])
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
452 rice->k1++;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
453 value += bit_shift[rice->k0];
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
454 default:
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
455 rice->sum0 += value - (rice->sum0 >> 4);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
456 if (rice->k0 > 0 && rice->sum0 < shift_16[rice->k0])
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
457 rice->k0--;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
458 else if (rice->sum0 > shift_16[rice->k0 + 1])
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
459 rice->k0++;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
460 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
461
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
462 value = DEC(value);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
463
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
464 // decompress stage 1: adaptive hybrid filter
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
465 hybrid_filter(fst, &value);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
466
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
467 // decompress stage 2: fixed order 1 prediction
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
468 switch (ttainfo->BSIZE) {
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
469 case 1: value += PREDICTOR1(*last, 4); break; // bps 8
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
470 case 2: value += PREDICTOR1(*last, 5); break; // bps 16
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
471 case 3: value += PREDICTOR1(*last, 5); break; // bps 24
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
472 case 4: value += *last; break; // bps 32
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
473 } *last = value;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
474
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
475 // check for errors
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
476 if (abs(value) > maxvalue) {
551
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
477 unsigned int tail =
290
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
478 pcm_buffer_size / (ttainfo->BSIZE * ttainfo->NCH) - res;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
479 memset(buffer, 0, pcm_buffer_size);
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
480 data_cur += tail; res += tail;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
481 break;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
482 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
483
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
484 if (dec < tta + (ttainfo->NCH - 1)) {
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
485 *prev++ = value; dec++;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
486 } else {
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
487 *prev = value;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
488 if (ttainfo->NCH > 1) {
551
c0f69d57483b [svn] - change some references for long to int, reported by and patch by
nenolod
parents: 290
diff changeset
489 int *r = prev - 1;
290
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
490 for (*prev += *r/2; r >= cache; r--)
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
491 *r = *(r + 1) - *r;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
492 for (r = cache; r < prev; r++)
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
493 WRITE_BUFFER(r, ttainfo->BSIZE, p)
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
494 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
495 WRITE_BUFFER(prev, ttainfo->BSIZE, p)
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
496 prev = cache;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
497 data_cur++; res++;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
498 dec = tta;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
499 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
500 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
501
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
502 return res;
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
503 }
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
504
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
505 /* end */
fbd06b4aa776 [svn] - add TrueAudio plugin
yaz
parents:
diff changeset
506