~ubuntu-dev/ubuntu/lucid/mpd/lucid-201002101854

« back to all changes in this revision

Viewing changes to src/inputPlugins/mp3_plugin.c

  • Committer: Bazaar Package Importer
  • Author(s): Charles Majola
  • Date: 2005-02-15 10:43:58 UTC
  • Revision ID: james.westby@ubuntu.com-20050215104358-w8b7yaqqfmsoxj5k
Tags: upstream-0.11.5
ImportĀ upstreamĀ versionĀ 0.11.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* the Music Player Daemon (MPD)
 
2
 * (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu)
 
3
 * This project's homepage is: http://www.musicpd.org
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License as published by
 
7
 * the Free Software Foundation; either version 2 of the License, or
 
8
 * (at your option) any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 * You should have received a copy of the GNU General Public License
 
15
 * along with this program; if not, write to the Free Software
 
16
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
17
 */
 
18
 
 
19
#include "../inputPlugin.h"
 
20
 
 
21
#ifdef HAVE_MAD
 
22
 
 
23
#include "../pcm_utils.h"
 
24
#ifdef USE_MPD_MAD
 
25
#include "../libmad/mad.h"
 
26
#else
 
27
#include <mad.h>
 
28
#endif
 
29
#ifdef HAVE_ID3TAG
 
30
#ifdef USE_MPD_ID3TAG
 
31
#include "../libid3tag/id3tag.h"
 
32
#else
 
33
#include <id3tag.h>
 
34
#endif
 
35
#endif
 
36
#include "../log.h"
 
37
#include "../utils.h"
 
38
#include "../tag.h"
 
39
 
 
40
#include <stdio.h>
 
41
#include <string.h>
 
42
#include <sys/types.h>
 
43
#include <sys/stat.h>
 
44
#include <unistd.h>
 
45
#include <errno.h>
 
46
 
 
47
#define FRAMES_CUSHION          2000
 
48
 
 
49
#define READ_BUFFER_SIZE        40960
 
50
 
 
51
#define DECODE_SKIP             -3
 
52
#define DECODE_BREAK            -2
 
53
#define DECODE_CONT             -1
 
54
#define DECODE_OK               0
 
55
 
 
56
#define MUTEFRAME_SKIP          1
 
57
#define MUTEFRAME_SEEK          2
 
58
 
 
59
/* this is stolen from mpg321! */
 
60
struct audio_dither {
 
61
        mad_fixed_t error[3];
 
62
        mad_fixed_t random;
 
63
};
 
64
 
 
65
unsigned long prng(unsigned long state) {
 
66
        return (state * 0x0019660dL + 0x3c6ef35fL) & 0xffffffffL;
 
67
}
 
68
 
 
69
signed long audio_linear_dither(unsigned int bits, mad_fixed_t sample, struct audio_dither *dither) {
 
70
        unsigned int scalebits;
 
71
        mad_fixed_t output, mask, random;
 
72
 
 
73
        enum {
 
74
                MIN = -MAD_F_ONE,
 
75
                MAX =  MAD_F_ONE - 1
 
76
        };
 
77
 
 
78
        sample += dither->error[0] - dither->error[1] + dither->error[2];
 
79
 
 
80
        dither->error[2] = dither->error[1];
 
81
        dither->error[1] = dither->error[0] / 2;
 
82
 
 
83
        output = sample + (1L << (MAD_F_FRACBITS + 1 - bits - 1));
 
84
 
 
85
        scalebits = MAD_F_FRACBITS + 1 - bits;
 
86
        mask = (1L << scalebits) - 1;
 
87
 
 
88
        random  = prng(dither->random);
 
89
        output += (random & mask) - (dither->random & mask);
 
90
 
 
91
        dither->random = random;
 
92
 
 
93
        if (output > MAX) {
 
94
                output = MAX;
 
95
 
 
96
                if (sample > MAX)
 
97
                        sample = MAX;
 
98
        }
 
99
        else if (output < MIN) {
 
100
                output = MIN;
 
101
 
 
102
                if (sample < MIN)
 
103
                        sample = MIN;
 
104
        }
 
105
 
 
106
        output &= ~mask;
 
107
 
 
108
        dither->error[0] = sample - output;
 
109
 
 
110
        return output >> scalebits;
 
111
}
 
112
/* end of stolen stuff from mpg321 */
 
113
 
 
114
/* decoder stuff is based on madlld */
 
115
 
 
116
#define MP3_DATA_OUTPUT_BUFFER_SIZE 4096
 
117
 
 
118
typedef struct _mp3DecodeData {
 
119
        struct mad_stream stream;
 
120
        struct mad_frame frame;
 
121
        struct mad_synth synth;
 
122
        mad_timer_t timer;
 
123
        unsigned char readBuffer[READ_BUFFER_SIZE];
 
124
        char outputBuffer[MP3_DATA_OUTPUT_BUFFER_SIZE];
 
125
        char * outputPtr;
 
126
        char * outputBufferEnd;
 
127
        float totalTime;
 
128
        float elapsedTime;
 
129
        int muteFrame;
 
130
        long * frameOffset;
 
131
        mad_timer_t * times;
 
132
        long highestFrame;
 
133
        long maxFrames;
 
134
        long currentFrame;
 
135
        int flush;
 
136
        unsigned long bitRate;
 
137
        InputStream * inStream;
 
138
        struct audio_dither dither;
 
139
} mp3DecodeData;
 
140
 
 
141
void initMp3DecodeData(mp3DecodeData * data, InputStream * inStream) {
 
142
        data->outputPtr = data->outputBuffer;
 
143
        data->outputBufferEnd = data->outputBuffer+MP3_DATA_OUTPUT_BUFFER_SIZE;
 
144
        data->muteFrame = 0;
 
145
        data->highestFrame = 0;
 
146
        data->maxFrames = 0;
 
147
        data->frameOffset = NULL;
 
148
        data->times = NULL;
 
149
        data->currentFrame = 0;
 
150
        data->flush = 1;
 
151
        data->inStream = inStream;
 
152
        memset(&(data->dither), 0, sizeof(struct audio_dither));
 
153
 
 
154
        mad_stream_init(&data->stream);
 
155
        data->stream.options |= MAD_OPTION_IGNORECRC;
 
156
        mad_frame_init(&data->frame);
 
157
        mad_synth_init(&data->synth);
 
158
        mad_timer_reset(&data->timer);
 
159
}
 
160
 
 
161
int seekMp3InputBuffer(mp3DecodeData * data, long offset) {
 
162
        if(seekInputStream(data->inStream,offset,SEEK_SET) < 0) {
 
163
                return -1;
 
164
        }
 
165
 
 
166
        mad_stream_buffer(&data->stream,data->readBuffer,0);
 
167
        (data->stream).error = 0;
 
168
 
 
169
        return 0;
 
170
}
 
171
 
 
172
int fillMp3InputBuffer(mp3DecodeData * data) {
 
173
        size_t readSize;
 
174
        size_t remaining;
 
175
        size_t readed;
 
176
        unsigned char * readStart;
 
177
 
 
178
        if((data->stream).next_frame!=NULL) {
 
179
                remaining = (data->stream).bufend-(data->stream).next_frame;
 
180
                memmove(data->readBuffer,(data->stream).next_frame,remaining);
 
181
                readStart = (data->readBuffer)+remaining;
 
182
                readSize = READ_BUFFER_SIZE-remaining;
 
183
        }
 
184
        else {
 
185
                readSize = READ_BUFFER_SIZE;
 
186
                readStart = data->readBuffer,
 
187
                remaining = 0;
 
188
        }
 
189
 
 
190
        readed = readFromInputStream(data->inStream, readStart, (size_t)1, 
 
191
                        readSize);
 
192
        if(readed <= 0 && inputStreamAtEOF(data->inStream)) return -1;
 
193
        /* sleep for a fraction of a second! */
 
194
        else if(readed <= 0) {
 
195
                readed = 0;
 
196
                my_usleep(10000);
 
197
        }
 
198
 
 
199
        mad_stream_buffer(&data->stream,data->readBuffer,readed+remaining);
 
200
        (data->stream).error = 0;
 
201
 
 
202
        return 0;
 
203
}
 
204
 
 
205
#ifdef HAVE_ID3TAG
 
206
static MpdTag * mp3_parseId3Tag(mp3DecodeData * data, signed long tagsize) {
 
207
        MpdTag * ret = NULL;
 
208
        struct id3_tag * id3Tag = NULL;
 
209
        id3_length_t count;
 
210
        id3_byte_t const *id3_data;
 
211
        id3_byte_t * allocated = NULL;
 
212
 
 
213
        count = data->stream.bufend - data->stream.this_frame;
 
214
 
 
215
        if(tagsize <= count) {
 
216
                id3_data = data->stream.this_frame;
 
217
                mad_stream_skip(&(data->stream), tagsize);
 
218
        }
 
219
        else {
 
220
                allocated = malloc(tagsize);
 
221
                if(!allocated) goto fail;
 
222
 
 
223
                memcpy(allocated, data->stream.this_frame, count);
 
224
                mad_stream_skip(&(data->stream), count);
 
225
 
 
226
                while(count < tagsize) {
 
227
                        int len;
 
228
 
 
229
                        len = readFromInputStream(data->inStream, 
 
230
                                allocated+count, (size_t)1, 
 
231
                                tagsize-count);
 
232
                        if(len <= 0 && inputStreamAtEOF(data->inStream))                                {
 
233
                                break;
 
234
                        }
 
235
                        else if(len <= 0) my_usleep(10000);
 
236
                        else count += len;
 
237
                }
 
238
 
 
239
                if(count != tagsize) {
 
240
                        DEBUG("mp3_decode: error parsing ID3 tag\n");
 
241
                        goto fail;
 
242
                }
 
243
 
 
244
                id3_data = allocated;
 
245
        }
 
246
 
 
247
        id3Tag = id3_tag_parse(id3_data, tagsize);
 
248
 
 
249
        if(id3Tag) {
 
250
                ret = parseId3Tag(id3Tag);
 
251
                id3_tag_delete(id3Tag);
 
252
        }
 
253
 
 
254
fail:
 
255
        if(allocated) free(allocated);
 
256
        return ret;
 
257
}
 
258
#endif
 
259
 
 
260
int decodeNextFrameHeader(mp3DecodeData * data, MpdTag ** tag) {
 
261
        if((data->stream).buffer==NULL || (data->stream).error==MAD_ERROR_BUFLEN) {
 
262
                if(fillMp3InputBuffer(data) < 0) {
 
263
                        return DECODE_BREAK;
 
264
                }
 
265
        }
 
266
        if(mad_header_decode(&data->frame.header,&data->stream)) {
 
267
#ifdef HAVE_ID3TAG
 
268
                if((data->stream).error==MAD_ERROR_LOSTSYNC && 
 
269
                                (data->stream).this_frame) 
 
270
                {
 
271
                        signed long tagsize = id3_tag_query(
 
272
                                        (data->stream).this_frame,
 
273
                                        (data->stream).bufend-
 
274
                                        (data->stream).this_frame);
 
275
 
 
276
                        if(tagsize>0) {
 
277
                                if(tag && !(*tag)) {
 
278
                                        *tag = mp3_parseId3Tag(data, tagsize);
 
279
                                        
 
280
                                }
 
281
                                else {
 
282
                                        mad_stream_skip(&(data->stream),
 
283
                                                        tagsize);
 
284
                                }
 
285
                                return DECODE_CONT;
 
286
                        }
 
287
                }
 
288
#endif
 
289
                if(MAD_RECOVERABLE((data->stream).error)) {
 
290
                        return DECODE_SKIP;
 
291
                }
 
292
                else {
 
293
                        if((data->stream).error==MAD_ERROR_BUFLEN) return DECODE_CONT;
 
294
                        else
 
295
                        {
 
296
                                ERROR("unrecoverable frame level error "
 
297
                                        "(%s).\n",
 
298
                                        mad_stream_errorstr(&data->stream));
 
299
                                data->flush = 0;
 
300
                                return DECODE_BREAK;
 
301
                        }
 
302
                }
 
303
        }
 
304
        if(data->frame.header.layer != MAD_LAYER_III) {
 
305
                return DECODE_SKIP;
 
306
        }
 
307
 
 
308
        return DECODE_OK;
 
309
}
 
310
 
 
311
int decodeNextFrame(mp3DecodeData * data) {
 
312
        if((data->stream).buffer==NULL || (data->stream).error==MAD_ERROR_BUFLEN) {
 
313
                if(fillMp3InputBuffer(data) < 0) {
 
314
                        return DECODE_BREAK;
 
315
                }
 
316
        }
 
317
        if(mad_frame_decode(&data->frame,&data->stream)) {
 
318
#ifdef HAVE_ID3TAG
 
319
                if((data->stream).error==MAD_ERROR_LOSTSYNC) {
 
320
                        signed long tagsize = id3_tag_query(
 
321
                                        (data->stream).this_frame,
 
322
                                        (data->stream).bufend-
 
323
                                        (data->stream).this_frame);
 
324
                        if(tagsize>0) {
 
325
                                mad_stream_skip(&(data->stream),tagsize);
 
326
                                return DECODE_CONT;
 
327
                        }
 
328
                }
 
329
#endif
 
330
                if(MAD_RECOVERABLE((data->stream).error)) {
 
331
                        return DECODE_SKIP;
 
332
                }
 
333
                else {
 
334
                        if((data->stream).error==MAD_ERROR_BUFLEN) return DECODE_CONT;
 
335
                        else
 
336
                        {
 
337
                                ERROR("unrecoverable frame level error "
 
338
                                        "(%s).\n",
 
339
                                        mad_stream_errorstr(&data->stream));
 
340
                                data->flush = 0;
 
341
                                return DECODE_BREAK;
 
342
                        }
 
343
                }
 
344
        }
 
345
 
 
346
        return DECODE_OK;
 
347
}
 
348
 
 
349
/* xing stuff stolen from alsaplayer */
 
350
# define XING_MAGIC     (('X' << 24) | ('i' << 16) | ('n' << 8) | 'g')
 
351
 
 
352
struct xing {
 
353
        long flags;                     /* valid fields (see below) */
 
354
        unsigned long frames;           /* total number of frames */
 
355
        unsigned long bytes;            /* total number of bytes */
 
356
        unsigned char toc[100];         /* 100-point seek table */
 
357
        long scale;                     /* ?? */
 
358
};
 
359
 
 
360
enum {
 
361
        XING_FRAMES = 0x00000001L,
 
362
        XING_BYTES  = 0x00000002L,
 
363
        XING_TOC    = 0x00000004L,
 
364
        XING_SCALE  = 0x00000008L
 
365
};
 
366
 
 
367
int parse_xing(struct xing *xing, struct mad_bitptr ptr, unsigned int bitlen)
 
368
{
 
369
        if (bitlen < 64 || mad_bit_read(&ptr, 32) != XING_MAGIC) goto fail;
 
370
 
 
371
        xing->flags = mad_bit_read(&ptr, 32);
 
372
        bitlen -= 64;
 
373
 
 
374
        if (xing->flags & XING_FRAMES) {
 
375
                if (bitlen < 32) goto fail;
 
376
                xing->frames = mad_bit_read(&ptr, 32);
 
377
                bitlen -= 32;
 
378
        }
 
379
 
 
380
        if (xing->flags & XING_BYTES) {
 
381
                if (bitlen < 32) goto fail;
 
382
                xing->bytes = mad_bit_read(&ptr, 32);
 
383
                bitlen -= 32;
 
384
        }
 
385
 
 
386
        if (xing->flags & XING_TOC) {
 
387
                int i;
 
388
                if (bitlen < 800) goto fail;
 
389
                for (i = 0; i < 100; ++i) xing->toc[i] = mad_bit_read(&ptr, 8);
 
390
                bitlen -= 800;
 
391
        }
 
392
 
 
393
        if (xing->flags & XING_SCALE) {
 
394
                if (bitlen < 32) goto fail;
 
395
                xing->scale = mad_bit_read(&ptr, 32);
 
396
                bitlen -= 32;
 
397
        }
 
398
 
 
399
         return 1;
 
400
 
 
401
fail:
 
402
        xing->flags = 0;
 
403
        return 0;
 
404
}
 
405
 
 
406
int decodeFirstFrame(mp3DecodeData * data, DecoderControl * dc,
 
407
                MpdTag ** tag) 
 
408
{
 
409
        struct xing xing;
 
410
        int ret;
 
411
        int skip;
 
412
 
 
413
        memset(&xing,0,sizeof(struct xing));
 
414
        xing.flags = 0;
 
415
 
 
416
        while(1) {
 
417
                skip = 0;
 
418
                while((ret = decodeNextFrameHeader(data, tag))==DECODE_CONT && 
 
419
                                (!dc || !dc->stop));
 
420
                if(ret==DECODE_SKIP) skip = 1;
 
421
                else if(ret==DECODE_BREAK || (dc && dc->stop)) return -1;
 
422
                while((ret = decodeNextFrame(data))==DECODE_CONT && 
 
423
                                (!dc || !dc->stop));
 
424
                if(ret==DECODE_BREAK || (dc && dc->stop)) return -1;
 
425
                if(!skip && ret==DECODE_OK) break;
 
426
        }
 
427
 
 
428
        if(parse_xing(&xing,data->stream.anc_ptr,data->stream.anc_bitlen)) {
 
429
                if(xing.flags & XING_FRAMES) {
 
430
                        mad_timer_t duration = data->frame.header.duration;
 
431
                        mad_timer_multiply(&duration,xing.frames);
 
432
                        data->muteFrame = MUTEFRAME_SKIP;
 
433
                        data->totalTime = ((float)mad_timer_count(duration,
 
434
                                                MAD_UNITS_MILLISECONDS))/1000;
 
435
                        data->maxFrames = xing.frames;
 
436
                }
 
437
        }
 
438
        else {
 
439
                size_t offset = data->inStream->offset;
 
440
                mad_timer_t duration = data->frame.header.duration;
 
441
                float frameTime = ((float)mad_timer_count(duration,
 
442
                                        MAD_UNITS_MILLISECONDS))/1000;
 
443
                if(data->stream.this_frame!=NULL) {
 
444
                        offset-= data->stream.bufend-data->stream.this_frame;
 
445
                }
 
446
                else {
 
447
                        offset-= data->stream.bufend-data->stream.buffer;
 
448
                }
 
449
                if(data->inStream->size >= offset) {
 
450
                        data->totalTime = ((data->inStream->size-offset)*8.0)/
 
451
                                        (data->frame).header.bitrate;
 
452
                        data->maxFrames = 
 
453
                                data->totalTime/frameTime+FRAMES_CUSHION;
 
454
                }
 
455
                else {
 
456
                        data->maxFrames = FRAMES_CUSHION;
 
457
                        data->totalTime = 0;
 
458
                }
 
459
        }
 
460
 
 
461
        data->frameOffset = malloc(sizeof(long)*data->maxFrames);
 
462
        data->times = malloc(sizeof(mad_timer_t)*data->maxFrames);
 
463
 
 
464
        return 0;
 
465
}
 
466
 
 
467
void mp3DecodeDataFinalize(mp3DecodeData * data) {
 
468
        mad_synth_finish(&data->synth);
 
469
        mad_frame_finish(&data->frame);
 
470
        mad_stream_finish(&data->stream);
 
471
 
 
472
        if(data->frameOffset) free(data->frameOffset);
 
473
        if(data->times) free(data->times);
 
474
}
 
475
 
 
476
/* this is primarily used for getting total time for tags */
 
477
int getMp3TotalTime(char * file) {
 
478
        InputStream inStream;
 
479
        mp3DecodeData data;
 
480
        int ret;
 
481
 
 
482
        if(openInputStream(&inStream, file) < 0) return -1;
 
483
        initMp3DecodeData(&data,&inStream);
 
484
        if(decodeFirstFrame(&data, NULL, NULL)<0) ret = -1;
 
485
        else ret = data.totalTime+0.5;
 
486
        mp3DecodeDataFinalize(&data);
 
487
        closeInputStream(&inStream);
 
488
 
 
489
        return ret;
 
490
}
 
491
 
 
492
int openMp3FromInputStream(InputStream * inStream, mp3DecodeData * data,
 
493
                DecoderControl * dc, MpdTag ** tag) 
 
494
{
 
495
        initMp3DecodeData(data, inStream);
 
496
        *tag = NULL;
 
497
        if(decodeFirstFrame(data, dc, tag)<0) {
 
498
                mp3DecodeDataFinalize(data);
 
499
                if(tag && *tag) freeMpdTag(*tag);
 
500
                return -1;
 
501
        }
 
502
 
 
503
        return 0;
 
504
}
 
505
 
 
506
int mp3Read(mp3DecodeData * data, OutputBuffer * cb, DecoderControl * dc) {
 
507
        int i;
 
508
        int ret;
 
509
        int skip;
 
510
 
 
511
        if(data->currentFrame>=data->highestFrame) { 
 
512
                mad_timer_add(&data->timer,(data->frame).header.duration);
 
513
                data->bitRate = (data->frame).header.bitrate;
 
514
                if(data->currentFrame>=data->maxFrames) {
 
515
                        data->currentFrame = data->maxFrames - 1;
 
516
                }
 
517
                else data->highestFrame++;
 
518
                data->frameOffset[data->currentFrame] = data->inStream->offset;
 
519
                if(data->stream.this_frame!=NULL) {
 
520
                        data->frameOffset[data->currentFrame]-= 
 
521
                                        data->stream.bufend-
 
522
                                        data->stream.this_frame;
 
523
                }
 
524
                else {
 
525
                        data->frameOffset[data->currentFrame]-= 
 
526
                                        data->stream.bufend-data->stream.buffer;
 
527
                }
 
528
                data->times[data->currentFrame] = data->timer;
 
529
        }
 
530
        else data->timer = data->times[data->currentFrame];
 
531
        data->currentFrame++;
 
532
        data->elapsedTime = ((float)mad_timer_count(data->timer,MAD_UNITS_MILLISECONDS))/1000;
 
533
 
 
534
        switch(data->muteFrame) {
 
535
        case MUTEFRAME_SKIP:
 
536
                data->muteFrame = 0;
 
537
                break;
 
538
        case MUTEFRAME_SEEK:
 
539
                if(dc->seekWhere<=data->elapsedTime) {
 
540
                        data->outputPtr = data->outputBuffer;
 
541
                        clearOutputBuffer(cb);
 
542
                        data->muteFrame = 0;
 
543
                        dc->seek = 0;
 
544
                }
 
545
                break;
 
546
        default:
 
547
                mad_synth_frame(&data->synth,&data->frame);
 
548
 
 
549
                if(data->inStream->metaTitle) {
 
550
                        MpdTag * tag = newMpdTag();
 
551
                        if(data->inStream->metaName) {
 
552
                                tag->name = strdup(data->inStream->metaName);
 
553
                        }
 
554
                        tag->title = strdup(data->inStream->metaTitle);
 
555
                        free(data->inStream->metaTitle);
 
556
                        data->inStream->metaTitle = NULL;
 
557
                        copyMpdTagToOutputBuffer(cb, tag);
 
558
                        freeMpdTag(tag);
 
559
                }
 
560
 
 
561
                for(i=0;i<(data->synth).pcm.length;i++) {
 
562
                        mpd_sint16 * sample;
 
563
 
 
564
                        sample = (mpd_sint16 *)data->outputPtr; 
 
565
                        *sample = (mpd_sint16) audio_linear_dither(16,
 
566
                                        (data->synth).pcm.samples[0][i],
 
567
                                        &(data->dither));
 
568
                        data->outputPtr+=2;
 
569
 
 
570
                        if(MAD_NCHANNELS(&(data->frame).header)==2) {
 
571
                                sample = (mpd_sint16 *)data->outputPtr; 
 
572
                                *sample = (mpd_sint16) audio_linear_dither(16,
 
573
                                                (data->synth).pcm.samples[1][i],
 
574
                                                &(data->dither));
 
575
                                data->outputPtr+=2;
 
576
                        }
 
577
 
 
578
                        if(data->outputPtr>=data->outputBufferEnd) {
 
579
                                long ret;
 
580
                                ret = sendDataToOutputBuffer(cb,
 
581
                                                data->inStream,
 
582
                                                dc,
 
583
                                                data->inStream->seekable,
 
584
                                                data->outputBuffer,
 
585
                                                data->outputPtr-
 
586
                                                data->outputBuffer,
 
587
                                                data->elapsedTime,
 
588
                                                data->bitRate/1000);
 
589
                                if(ret == OUTPUT_BUFFER_DC_STOP) {
 
590
                                        data->flush = 0;
 
591
                                        return DECODE_BREAK;
 
592
                                }
 
593
 
 
594
                                data->outputPtr = data->outputBuffer;
 
595
 
 
596
                                if(ret == OUTPUT_BUFFER_DC_SEEK) break;
 
597
                        }
 
598
                }
 
599
 
 
600
                if(dc->seek && data->inStream->seekable) {
 
601
                        long i = 0;
 
602
                        data->muteFrame = MUTEFRAME_SEEK;
 
603
                        while(i<data->highestFrame && dc->seekWhere >
 
604
                                        ((float)mad_timer_count(data->times[i],
 
605
                                        MAD_UNITS_MILLISECONDS))/1000) 
 
606
                        {
 
607
                                i++;
 
608
                        }
 
609
                        if(i<data->highestFrame) {
 
610
                                if(seekMp3InputBuffer(data,
 
611
                                                data->frameOffset[i]) == 0)
 
612
                                {
 
613
                                        data->outputPtr = data->outputBuffer;
 
614
                                        clearOutputBuffer(cb);
 
615
                                        data->currentFrame = i;
 
616
                                }
 
617
                                else dc->seekError = 1;
 
618
                                data->muteFrame = 0;
 
619
                                dc->seek = 0;
 
620
                        }
 
621
                }
 
622
                else if(dc->seek && !data->inStream->seekable) {
 
623
                        dc->seek = 0;
 
624
                        dc->seekError = 1;
 
625
                }
 
626
        }
 
627
 
 
628
        while(1) {
 
629
                skip = 0;
 
630
                while((ret = decodeNextFrameHeader(data, NULL))==DECODE_CONT &&
 
631
                                !dc->stop && !dc->seek);
 
632
                if(ret==DECODE_BREAK || dc->stop || dc->seek) break;
 
633
                else if(ret==DECODE_SKIP) skip = 1;
 
634
                if(!data->muteFrame) {
 
635
                        while((ret = decodeNextFrame(data))==DECODE_CONT &&
 
636
                                        !dc->stop && !dc->seek);
 
637
                        if(ret==DECODE_BREAK || dc->stop || dc->seek) break;
 
638
                }
 
639
                if(!skip && ret==DECODE_OK) break;
 
640
        }
 
641
 
 
642
        if(dc->stop) return DECODE_BREAK;
 
643
 
 
644
        return ret;
 
645
}
 
646
 
 
647
void initAudioFormatFromMp3DecodeData(mp3DecodeData * data, AudioFormat * af) {
 
648
        af->bits = 16;
 
649
        af->sampleRate = (data->frame).header.samplerate;
 
650
        af->channels = MAD_NCHANNELS(&(data->frame).header);
 
651
}
 
652
 
 
653
int mp3_decode(OutputBuffer * cb, DecoderControl * dc, InputStream * inStream) {
 
654
        mp3DecodeData data;
 
655
        MpdTag * tag = NULL;
 
656
 
 
657
        if(openMp3FromInputStream(inStream, &data, dc, &tag) < 0) {
 
658
                closeInputStream(inStream);
 
659
                if(!dc->stop) {
 
660
                        ERROR("Input does not appear to be a mp3 bit stream.\n");
 
661
                        return -1;
 
662
                }
 
663
                else {
 
664
                        dc->state = DECODE_STATE_STOP;
 
665
                        dc->stop = 0;
 
666
                }
 
667
                return 0;
 
668
        }
 
669
 
 
670
        initAudioFormatFromMp3DecodeData(&data, &(dc->audioFormat));
 
671
        getOutputAudioFormat(&(dc->audioFormat), &(cb->audioFormat));
 
672
        
 
673
        dc->totalTime = data.totalTime;
 
674
 
 
675
        if(inStream->metaTitle) {
 
676
                if(tag) freeMpdTag(tag);
 
677
                tag = newMpdTag();
 
678
                tag->title = strdup(inStream->metaTitle);
 
679
                free(inStream->metaTitle);
 
680
                inStream->metaTitle = NULL;
 
681
                if(inStream->metaName) {
 
682
                        tag->name = strdup(inStream->metaName);
 
683
                }
 
684
                copyMpdTagToOutputBuffer(cb, tag);
 
685
                freeMpdTag(tag);
 
686
        }
 
687
        else if(tag) {
 
688
                if(inStream->metaName) {
 
689
                        if(tag->name) free(tag->name);
 
690
                        tag->name = strdup(inStream->metaName);
 
691
                }
 
692
                copyMpdTagToOutputBuffer(cb, tag);
 
693
                freeMpdTag(tag);
 
694
        }
 
695
        else if(inStream->metaName) {
 
696
                tag = newMpdTag();
 
697
                if(inStream->metaName) {
 
698
                        tag->name = strdup(inStream->metaName);
 
699
                }
 
700
                copyMpdTagToOutputBuffer(cb, tag);
 
701
                freeMpdTag(tag);
 
702
        }
 
703
 
 
704
        dc->state = DECODE_STATE_DECODE;
 
705
 
 
706
        while(mp3Read(&data,cb,dc)!=DECODE_BREAK);
 
707
        /* send last little bit if not dc->stop */
 
708
        if(!dc->stop && data.outputPtr!=data.outputBuffer && data.flush)  {
 
709
                sendDataToOutputBuffer(cb, NULL, dc, 
 
710
                                data.inStream->seekable,
 
711
                                data.outputBuffer,
 
712
                                data.outputPtr-data.outputBuffer,
 
713
                                data.elapsedTime,data.bitRate/1000);
 
714
        }
 
715
 
 
716
        closeInputStream(inStream);
 
717
 
 
718
        if(dc->seek && data.muteFrame == MUTEFRAME_SEEK) {
 
719
                clearOutputBuffer(cb);
 
720
                dc->seek = 0;
 
721
        }
 
722
 
 
723
        flushOutputBuffer(cb);
 
724
        mp3DecodeDataFinalize(&data);
 
725
 
 
726
        if(dc->stop) {
 
727
                dc->state = DECODE_STATE_STOP;
 
728
                dc->stop = 0;
 
729
        }
 
730
        else dc->state = DECODE_STATE_STOP;
 
731
                
 
732
        return 0;
 
733
}
 
734
 
 
735
MpdTag * mp3_tagDup(char * file) {
 
736
        MpdTag * ret = NULL;
 
737
        int time;
 
738
 
 
739
        ret = id3Dup(file);
 
740
 
 
741
        time = getMp3TotalTime(file);
 
742
 
 
743
        if(time>=0) {
 
744
                if(!ret) ret = newMpdTag();
 
745
                ret->time = time;
 
746
        }
 
747
 
 
748
        return ret;
 
749
}
 
750
 
 
751
char * mp3_suffixes[] = {"mp3", NULL};
 
752
char * mp3_mimeTypes[] = {"audio/mpeg", NULL};
 
753
 
 
754
InputPlugin mp3Plugin = 
 
755
{
 
756
        "mp3",
 
757
        NULL,
 
758
        NULL,
 
759
        mp3_decode,
 
760
        NULL,
 
761
        mp3_tagDup,
 
762
        INPUT_PLUGIN_STREAM_FILE | INPUT_PLUGIN_STREAM_URL,
 
763
        mp3_suffixes,
 
764
        mp3_mimeTypes
 
765
};
 
766
#else
 
767
 
 
768
InputPlugin mp3Plugin = 
 
769
{
 
770
        NULL,
 
771
        NULL,
 
772
        NULL,
 
773
        NULL,
 
774
        NULL,
 
775
        NULL,
 
776
        0,
 
777
        NULL,
 
778
        NULL
 
779
};
 
780
 
 
781
#endif