Mercurial > audlegacy
annotate Plugins/Input/mpg123/common.c @ 1564:3a60eafe91c7 trunk
[svn] - m3u and pls plugin implementation
author | nenolod |
---|---|
date | Thu, 10 Aug 2006 20:39:18 -0700 |
parents | f969fe246497 |
children | 4c72daee66e3 |
rev | line source |
---|---|
61 | 1 #include <stdlib.h> |
2 #include <string.h> | |
3 #include <ctype.h> | |
4 | |
5 #include <signal.h> | |
6 #include <sys/types.h> | |
7 #include <sys/stat.h> | |
8 #include <fcntl.h> | |
9 | |
10 #include "mpg123.h" | |
11 | |
12 const int tabsel_123[2][3][16] = { | |
13 {{0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, | |
14 448,}, | |
15 {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384,}, | |
16 {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320,}}, | |
17 {{0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256,}, | |
18 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}, | |
19 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}} | |
20 }; | |
21 | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
22 const int mpgdec_freqs[9] = |
61 | 23 { 44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000 }; |
24 | |
25 struct bitstream_info bsi; | |
26 | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
27 extern gint mpgdec_bitrate, mpgdec_frequency, mpgdec_length; |
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
28 extern gchar *mpgdec_title, *mpgdec_filename; |
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
29 extern gboolean mpgdec_stereo; |
61 | 30 |
31 static int fsizeold = 0, ssize; | |
32 static unsigned char bsspace[2][MAXFRAMESIZE + 512]; /* MAXFRAMESIZE */ | |
33 static unsigned char *bsbuf = bsspace[1], *bsbufold; | |
34 static int bsnum = 0; | |
35 | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
36 unsigned char *mpgdec_pcm_sample; |
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
37 int mpgdec_pcm_point = 0; |
61 | 38 |
39 static VFSFile *filept; | |
40 static int filept_opened; | |
41 | |
42 static int get_fileinfo(void); | |
43 | |
44 static int | |
45 fullread(VFSFile * fd, unsigned char *buf, int count) | |
46 { | |
47 int ret, cnt = 0; | |
48 | |
49 while (cnt < count) { | |
50 if (fd) | |
51 ret = vfs_fread(buf + cnt, 1, count - cnt, fd); | |
52 else | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
53 ret = mpgdec_http_read(buf + cnt, count - cnt); |
61 | 54 if (ret < 0) |
55 return ret; | |
56 if (ret == 0) | |
57 break; | |
58 cnt += ret; | |
59 } | |
60 return cnt; | |
61 } | |
62 | |
63 static int | |
64 stream_init(void) | |
65 { | |
66 if (get_fileinfo() < 0) | |
67 return -1; | |
68 return 0; | |
69 } | |
70 | |
71 void | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
72 mpgdec_stream_close(void) |
61 | 73 { |
74 if (filept) | |
75 vfs_fclose(filept); | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
76 else if (mpgdec_info->network_stream) |
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
77 mpgdec_http_close(); |
61 | 78 } |
79 | |
80 /**************************************** | |
81 * HACK,HACK,HACK: step back <num> frames | |
970
0f294f2b0a9b
[svn] - integer-mode decoding accuracy improvements
nenolod
parents:
957
diff
changeset
|
82 * can only work if the 'stream' isn't a mpgdec_real stream but a file |
61 | 83 static int stream_back_bytes(int bytes) |
84 { | |
85 if (vfs_fseek(filept, -bytes, SEEK_CUR) < 0) | |
86 return -1; | |
87 return 0; | |
88 } | |
89 */ | |
90 | |
91 static int | |
92 stream_head_read(unsigned long *newhead) | |
93 { | |
94 unsigned char hbuf[4]; | |
95 | |
96 if (fullread(filept, hbuf, 4) != 4) | |
97 return FALSE; | |
98 | |
99 *newhead = ((unsigned long) hbuf[0] << 24) | | |
100 ((unsigned long) hbuf[1] << 16) | | |
101 ((unsigned long) hbuf[2] << 8) | (unsigned long) hbuf[3]; | |
102 | |
103 return TRUE; | |
104 } | |
105 | |
106 static int | |
107 stream_head_shift(unsigned long *head) | |
108 { | |
109 unsigned char hbuf; | |
110 | |
111 if (fullread(filept, &hbuf, 1) != 1) | |
112 return 0; | |
113 *head <<= 8; | |
114 *head |= hbuf; | |
115 *head &= 0xffffffff; | |
116 return 1; | |
117 } | |
118 | |
119 static int | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
120 stream_mpgdec_read_frame_body(unsigned char *buf, int size) |
61 | 121 { |
122 long l; | |
123 | |
124 if ((l = fullread(filept, buf, size)) != size) { | |
125 if (l <= 0) | |
126 return 0; | |
127 memset(buf + l, 0, size - l); | |
128 } | |
129 return 1; | |
130 } | |
131 | |
132 static long | |
133 stream_tell(void) | |
134 { | |
135 return vfs_ftell(filept); | |
136 } | |
137 | |
138 /* | |
139 static void stream_rewind(void) | |
140 { | |
141 vfs_fseek(filept, 0, SEEK_SET); | |
142 } | |
143 */ | |
144 | |
145 int | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
146 mpgdec_stream_jump_to_frame(struct frame *fr, int frame) |
61 | 147 { |
148 if (!filept) | |
149 return -1; | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
150 mpgdec_read_frame_init(); |
61 | 151 vfs_fseek(filept, frame * (fr->framesize + 4), SEEK_SET); |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
152 mpgdec_read_frame(fr); |
61 | 153 return 0; |
154 } | |
155 | |
156 int | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
157 mpgdec_stream_jump_to_byte(struct frame *fr, int byte) |
61 | 158 { |
159 if (!filept) | |
160 return -1; | |
161 vfs_fseek(filept, byte, SEEK_SET); | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
162 mpgdec_read_frame(fr); |
61 | 163 return 0; |
164 } | |
165 | |
166 int | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
167 mpgdec_stream_check_for_xing_header(struct frame *fr, xing_header_t * xhead) |
61 | 168 { |
169 unsigned char *head_data; | |
170 int ret; | |
171 | |
172 vfs_fseek(filept, -(fr->framesize + 4), SEEK_CUR); | |
173 head_data = g_malloc(fr->framesize + 4); | |
174 vfs_fread(head_data, 1, fr->framesize + 4, filept); | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
175 ret = mpgdec_get_xing_header(xhead, head_data); |
61 | 176 g_free(head_data); |
177 return ret; | |
178 } | |
179 | |
180 static int | |
181 get_fileinfo(void) | |
182 { | |
183 guchar buf[3]; | |
184 | |
185 if (filept == NULL) | |
186 return -1; | |
187 if (vfs_fseek(filept, 0, SEEK_END) < 0) | |
188 return -1; | |
189 | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
190 mpgdec_info->filesize = vfs_ftell(filept); |
61 | 191 if (vfs_fseek(filept, -128, SEEK_END) < 0) |
192 return -1; | |
193 if (fullread(filept, buf, 3) != 3) | |
194 return -1; | |
195 if (!strncmp((char *) buf, "TAG", 3)) | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
196 mpgdec_info->filesize -= 128; |
61 | 197 if (vfs_fseek(filept, 0, SEEK_SET) < 0) |
198 return -1; | |
199 | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
200 if (mpgdec_info->filesize <= 0) |
61 | 201 return -1; |
202 | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
203 return mpgdec_info->filesize; |
61 | 204 } |
205 | |
206 void | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
207 mpgdec_read_frame_init(void) |
61 | 208 { |
209 memset(bsspace[0], 0, MAXFRAMESIZE + 512); | |
210 memset(bsspace[1], 0, MAXFRAMESIZE + 512); | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
211 mpgdec_info->output_audio = FALSE; |
61 | 212 } |
213 | |
214 int | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
215 mpgdec_head_check(unsigned long head) |
61 | 216 { |
217 if ((head & 0xffe00000) != 0xffe00000) | |
218 return FALSE; | |
219 if (!((head >> 17) & 3)) | |
220 return FALSE; | |
221 if (((head >> 12) & 0xf) == 0xf) | |
222 return FALSE; | |
223 if (!((head >> 12) & 0xf)) | |
224 return FALSE; | |
225 if (((head >> 10) & 0x3) == 0x3) | |
226 return FALSE; | |
227 if (((head >> 19) & 1) == 1 && | |
228 ((head >> 17) & 3) == 3 && ((head >> 16) & 1) == 1) | |
229 return FALSE; | |
230 if ((head & 0xffff0000) == 0xfffe0000) | |
231 return FALSE; | |
232 | |
233 return TRUE; | |
234 } | |
235 | |
236 /***************************************************************** | |
237 * read next frame | |
238 */ | |
239 int | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
240 mpgdec_read_frame(struct frame *fr) |
61 | 241 { |
242 unsigned long newhead; | |
243 | |
244 fsizeold = fr->framesize; /* for Layer3 */ | |
245 | |
246 if (!stream_head_read(&newhead)) | |
247 return FALSE; | |
248 | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
249 if (!mpgdec_head_check(newhead) || !mpgdec_decode_header(fr, newhead)) { |
61 | 250 int try = 0; |
251 | |
252 do { | |
253 try++; | |
1367
d872c88f8c6f
[svn] - fix a regression involving large ID3 tags being bolted right in the middle of a fraunhofer VBRX TOC (iTunes fucking fails)
nenolod
parents:
1156
diff
changeset
|
254 if (!stream_head_shift(&newhead)) |
61 | 255 return 0; |
256 } | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
257 while ((!mpgdec_head_check(newhead) || |
1367
d872c88f8c6f
[svn] - fix a regression involving large ID3 tags being bolted right in the middle of a fraunhofer VBRX TOC (iTunes fucking fails)
nenolod
parents:
1156
diff
changeset
|
258 !mpgdec_decode_header(fr, newhead)) && try < (1024 * 1024)); |
d872c88f8c6f
[svn] - fix a regression involving large ID3 tags being bolted right in the middle of a fraunhofer VBRX TOC (iTunes fucking fails)
nenolod
parents:
1156
diff
changeset
|
259 if (try >= (1024 * 1024)) |
61 | 260 return FALSE; |
1370 | 261 #ifdef MPGDEC_INVBITSTREAM_NOTIFY |
1367
d872c88f8c6f
[svn] - fix a regression involving large ID3 tags being bolted right in the middle of a fraunhofer VBRX TOC (iTunes fucking fails)
nenolod
parents:
1156
diff
changeset
|
262 if (try >= 0) |
1369
2449f180912d
[svn] - bitch about invalid bitstreams right in the middle of our stream
nenolod
parents:
1367
diff
changeset
|
263 g_log("mpgdec", G_LOG_LEVEL_WARNING, "mpgdec: illegal bitstream in the middle of the MPEG stream, skipped %d bytes", try); |
1370 | 264 #endif |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
265 mpgdec_info->filesize -= try; |
61 | 266 } |
267 /* flip/init buffer for Layer 3 */ | |
268 bsbufold = bsbuf; | |
269 bsbuf = bsspace[bsnum] + 512; | |
270 bsnum = (bsnum + 1) & 1; | |
271 | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
272 if (!stream_mpgdec_read_frame_body(bsbuf, fr->framesize)) |
61 | 273 return 0; |
274 | |
275 bsi.bitindex = 0; | |
276 bsi.wordpointer = (unsigned char *) bsbuf; | |
277 | |
278 | |
279 return 1; | |
280 | |
281 } | |
282 | |
283 /* | |
284 * the code a header and write the information | |
285 * into the frame structure | |
286 */ | |
287 int | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
288 mpgdec_decode_header(struct frame *fr, unsigned long newhead) |
61 | 289 { |
290 if (newhead & (1 << 20)) { | |
291 fr->lsf = (newhead & (1 << 19)) ? 0x0 : 0x1; | |
292 fr->mpeg25 = 0; | |
293 } | |
294 else { | |
295 fr->lsf = 1; | |
296 fr->mpeg25 = 1; | |
297 } | |
298 fr->lay = 4 - ((newhead >> 17) & 3); | |
299 if (fr->mpeg25) { | |
300 fr->sampling_frequency = 6 + ((newhead >> 10) & 0x3); | |
301 } | |
302 else | |
303 fr->sampling_frequency = ((newhead >> 10) & 0x3) + (fr->lsf * 3); | |
304 fr->error_protection = ((newhead >> 16) & 0x1) ^ 0x1; | |
305 | |
306 fr->bitrate_index = ((newhead >> 12) & 0xf); | |
307 fr->padding = ((newhead >> 9) & 0x1); | |
308 fr->extension = ((newhead >> 8) & 0x1); | |
309 fr->mode = ((newhead >> 6) & 0x3); | |
310 fr->mode_ext = ((newhead >> 4) & 0x3); | |
311 fr->copyright = ((newhead >> 3) & 0x1); | |
312 fr->original = ((newhead >> 2) & 0x1); | |
313 fr->emphasis = newhead & 0x3; | |
314 | |
315 fr->stereo = (fr->mode == MPG_MD_MONO) ? 1 : 2; | |
316 | |
317 ssize = 0; | |
318 | |
319 if (!fr->bitrate_index) | |
320 return (0); | |
321 | |
322 switch (fr->lay) { | |
323 case 1: | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
324 fr->do_layer = mpgdec_do_layer1; |
61 | 325 /* inits also shared tables with layer1 */ |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
326 mpgdec_init_layer2(fr->synth_type == SYNTH_MMX); |
61 | 327 fr->framesize = |
328 (long) tabsel_123[fr->lsf][0][fr->bitrate_index] * 12000; | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
329 fr->framesize /= mpgdec_freqs[fr->sampling_frequency]; |
61 | 330 fr->framesize = ((fr->framesize + fr->padding) << 2) - 4; |
331 break; | |
332 case 2: | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
333 fr->do_layer = mpgdec_do_layer2; |
61 | 334 /* inits also shared tables with layer1 */ |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
335 mpgdec_init_layer2(fr->synth_type == SYNTH_MMX); |
61 | 336 fr->framesize = |
337 (long) tabsel_123[fr->lsf][1][fr->bitrate_index] * 144000; | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
338 fr->framesize /= mpgdec_freqs[fr->sampling_frequency]; |
61 | 339 fr->framesize += fr->padding - 4; |
340 break; | |
341 case 3: | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
342 fr->do_layer = mpgdec_do_layer3; |
61 | 343 if (fr->lsf) |
344 ssize = (fr->stereo == 1) ? 9 : 17; | |
345 else | |
346 ssize = (fr->stereo == 1) ? 17 : 32; | |
347 if (fr->error_protection) | |
348 ssize += 2; | |
349 fr->framesize = | |
350 (long) tabsel_123[fr->lsf][2][fr->bitrate_index] * 144000; | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
351 fr->framesize /= mpgdec_freqs[fr->sampling_frequency] << (fr->lsf); |
61 | 352 fr->framesize = fr->framesize + fr->padding - 4; |
353 break; | |
354 default: | |
355 return (0); | |
356 } | |
357 if (fr->framesize > MAXFRAMESIZE) | |
358 return 0; | |
359 return 1; | |
360 } | |
361 | |
362 void | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
363 mpgdec_open_stream(char *bs_filenam, int fd) |
61 | 364 { |
365 filept_opened = 1; | |
366 if (!strncasecmp(bs_filenam, "http://", 7)) { | |
367 filept = NULL; | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
368 mpgdec_http_open(bs_filenam); |
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
369 mpgdec_info->filesize = 0; |
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
370 mpgdec_info->network_stream = TRUE; |
61 | 371 } |
372 else { | |
373 if ((filept = vfs_fopen(bs_filenam, "rb")) == NULL || | |
374 stream_init() == -1) | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
375 mpgdec_info->eof = TRUE; |
61 | 376 } |
377 | |
378 } | |
379 | |
380 void | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
381 mpgdec_set_pointer(long backstep) |
61 | 382 { |
383 bsi.wordpointer = bsbuf + ssize - backstep; | |
384 if (backstep) | |
385 memcpy(bsi.wordpointer, bsbufold + fsizeold - backstep, backstep); | |
386 bsi.bitindex = 0; | |
387 } | |
388 | |
389 double | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
390 mpgdec_compute_bpf(struct frame *fr) |
61 | 391 { |
392 double bpf; | |
393 | |
394 switch (fr->lay) { | |
395 case 1: | |
396 bpf = tabsel_123[fr->lsf][0][fr->bitrate_index]; | |
397 bpf *= 12000.0 * 4.0; | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
398 bpf /= mpgdec_freqs[fr->sampling_frequency] << (fr->lsf); |
61 | 399 break; |
400 case 2: | |
401 case 3: | |
402 bpf = tabsel_123[fr->lsf][fr->lay - 1][fr->bitrate_index]; | |
403 bpf *= 144000; | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
404 bpf /= mpgdec_freqs[fr->sampling_frequency] << (fr->lsf); |
61 | 405 break; |
406 default: | |
407 bpf = 1.0; | |
408 } | |
409 | |
410 return bpf; | |
411 } | |
412 | |
413 int | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
414 mpgdec_calc_numframes(struct frame *fr) |
61 | 415 { |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
416 return (int) (mpgdec_info->filesize / mpgdec_compute_bpf(fr)); |
61 | 417 } |
418 | |
419 double | |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
420 mpgdec_relative_pos(void) |
61 | 421 { |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
422 if (!filept || !mpgdec_info->filesize) |
61 | 423 return 0; |
1098
b5ae09a6c2f1
[svn] - prepare to split audacious code away from the actual decoder and use a highlevel API
nenolod
parents:
970
diff
changeset
|
424 return ((double) stream_tell()) / mpgdec_info->filesize; |
61 | 425 } |