14
#define MAP_FAILED ( (void *) -1 )
18
static int get_fileinfo(struct reader *,char *buf);
21
/*******************************************************************
22
* stream based operation
24
static int fullread(int fd,unsigned char *buf,int count)
29
ret = read(fd,buf+cnt,count-cnt);
40
static int default_init(struct reader *rds)
45
rds->filelen = get_fileinfo(rds,buf);
47
if(rds->filelen > 0) {
48
if(!strncmp(buf,"TAG",3)) {
49
rds->flags |= READER_ID3TAG;
50
memcpy(rds->id3buf,buf,128);
56
void stream_close(struct reader *rds)
58
if (rds->flags & READER_FD_OPENED)
62
/****************************************
63
* HACK,HACK,HACK: step back <num> frames
64
* can only work if the 'stream' isn't a real stream but a file
66
static int stream_back_bytes(struct reader *rds,int bytes)
68
if(lseek(rds->filept,-bytes,SEEK_CUR) < 0)
75
static int stream_back_frame(struct reader *rds,struct frame *fr,int num)
79
unsigned long newhead;
84
bytes = (fr->framesize+8)*(num+2);
86
/* Skipping back/forth requires a bit more work in buffered mode.
87
* See mapped_back_frame().
90
bytes += (long)(xfermem_get_usedspace(buffermem) /
91
(buffermem->buf[0] * buffermem->buf[1]
92
* (buffermem->buf[2] & AUDIO_FORMAT_MASK ?
94
* (tabsel_123[fr->lsf][fr->lay-1][fr->bitrate_index] << 10));
96
bytes += (long)(compute_buffer_offset(fr)*compute_bpf(fr));
98
if(lseek(rds->filept,-bytes,SEEK_CUR) < 0)
101
if(fullread(rds->filept,buf,4) != 4)
104
newhead = (buf[0]<<24) + (buf[1]<<16) + (buf[2]<<8) + buf[3];
106
while( (newhead & HDRCMPMASK) != (firsthead & HDRCMPMASK) ) {
107
if(fullread(rds->filept,buf,1) != 1)
111
newhead &= 0xffffffff;
114
if( lseek(rds->filept,-4,SEEK_CUR) < 0)
130
static int stream_head_read(struct reader *rds,unsigned long *newhead)
132
unsigned char hbuf[4];
134
if(fullread(rds->filept,hbuf,4) != 4)
137
*newhead = ((unsigned long) hbuf[0] << 24) |
138
((unsigned long) hbuf[1] << 16) |
139
((unsigned long) hbuf[2] << 8) |
140
(unsigned long) hbuf[3];
145
static int stream_head_shift(struct reader *rds,unsigned long *head)
149
if(fullread(rds->filept,&hbuf,1) != 1)
157
static int stream_skip_bytes(struct reader *rds,int len)
159
if (!param.usebuffer)
160
return lseek(rds->filept,len,SEEK_CUR);
164
int ret = lseek(rds->filept,len,SEEK_CUR);
171
static int stream_read_frame_body(struct reader *rds,unsigned char *buf,
176
if( (l=fullread(rds->filept,buf,size)) != size)
180
memset(buf+l,0,size-l);
186
static long stream_tell(struct reader *rds)
188
return lseek(rds->filept,0,SEEK_CUR);
191
static void stream_rewind(struct reader *rds)
193
lseek(rds->filept,0,SEEK_SET);
199
* returns length of a file (if filept points to a file)
200
* reads the last 128 bytes information into buffer
202
static int get_fileinfo(struct reader *rds,char *buf)
206
if((len=lseek(rds->filept,0,SEEK_END)) < 0) {
209
if(lseek(rds->filept,-128,SEEK_END) < 0)
211
if(fullread(rds->filept,(unsigned char *)buf,128) != 128) {
214
if(!strncmp(buf,"TAG",3)) {
217
if(lseek(rds->filept,0,SEEK_SET) < 0)
226
/*********************************************************+
227
* memory mapped operation
230
static unsigned char *mapbuf;
231
static unsigned char *mappnt;
232
static unsigned char *mapend;
234
static int mapped_init(struct reader *rds)
239
len = get_fileinfo(rds,buf);
243
if(!strncmp(buf,"TAG",3)) {
244
rds->flags |= READER_ID3TAG;
245
memcpy(rds->id3buf,buf,128);
248
mappnt = mapbuf = (unsigned char *)
249
mmap(NULL, len, PROT_READ, MAP_SHARED , rds->filept, 0);
250
if(!mapbuf || mapbuf == MAP_FAILED)
253
mapend = mapbuf + len;
255
if(param.verbose > 1)
256
fprintf(stderr,"Using memory mapped IO for this stream.\n");
262
static void mapped_rewind(struct reader *rds)
269
static void mapped_close(struct reader *rds)
271
munmap((void *)mapbuf,mapend-mapbuf);
272
if (rds->flags & READER_FD_OPENED)
276
static int mapped_head_read(struct reader *rds,unsigned long *newhead)
280
if(mappnt + 4 > mapend)
283
nh = (*mappnt++) << 24;
284
nh |= (*mappnt++) << 16;
285
nh |= (*mappnt++) << 8;
292
static int mapped_head_shift(struct reader *rds,unsigned long *head)
294
if(mappnt + 1 > mapend)
302
static int mapped_skip_bytes(struct reader *rds,int len)
304
if(mappnt + len > mapend)
312
static int mapped_read_frame_body(struct reader *rds,unsigned char *buf,
316
fprintf(stderr,"Ouch. Read_frame called with size <= 0\n");
319
if(mappnt + size > mapend)
321
memcpy(buf,mappnt,size);
327
static int mapped_back_bytes(struct reader *rds,int bytes)
329
if( (mappnt - bytes) < mapbuf || (mappnt - bytes + 4) > mapend)
337
static int mapped_back_frame(struct reader *rds,struct frame *fr,int num)
340
unsigned long newhead;
346
bytes = (fr->framesize+8)*(num+2);
348
/* Buffered mode is a bit trickier. From the size of the buffered
349
* output audio stream we have to make a guess at the number of frames
350
* this corresponds to.
353
bytes += (long)(xfermem_get_usedspace(buffermem) /
354
(buffermem->buf[0] * buffermem->buf[1]
355
* (buffermem->buf[2] & AUDIO_FORMAT_MASK ?
357
* (tabsel_123[fr->lsf][fr->lay-1][fr->bitrate_index] << 10));
359
bytes += (long)(compute_buffer_offset(fr)*compute_bpf(fr));
362
if( (mappnt - bytes) < mapbuf || (mappnt - bytes + 4) > mapend)
366
newhead = (mappnt[0]<<24) + (mappnt[1]<<16) + (mappnt[2]<<8) + mappnt[3];
369
while( (newhead & HDRCMPMASK) != (firsthead & HDRCMPMASK) ) {
370
if(mappnt + 1 > mapend)
373
newhead |= *mappnt++;
374
newhead &= 0xffffffff;
390
static long mapped_tell(struct reader *rds)
392
return mappnt - mapbuf;
397
/*****************************************************************
402
struct reader readers[] = {
405
NULL, /* filled in by system_init() */
420
mapped_read_frame_body,
431
stream_read_frame_body,
440
/* open the device to read the bit stream from it */
442
void open_stream(char *bs_filenam,int fd)
445
int filept_opened = 1;
456
else if (!strncmp(bs_filenam, "http://", 7))
457
filept = http_open(bs_filenam);
461
else if ( (filept = open(bs_filenam, O_RDONLY|O_BINARY)) < 0) {
468
readers[i].filelen = -1;
469
readers[i].filept = filept;
470
readers[i].flags = 0;
472
readers[i].flags |= READER_FD_OPENED;
473
if(!readers[i].init) {
474
fprintf(stderr,"Fatal error!\n");
477
if(readers[i].init(readers+i) >= 0) {
483
if(rd && rd->flags & READER_ID3TAG) {
484
print_id3_tag(rd->id3buf);