2 * Copyright 2004 Timo Hirvonen
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * 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
25 #include "read_wrapper.h"
29 #include <sys/types.h>
31 #include <sys/types.h>
35 /* ------------------------------------------------------------------------- */
37 static ssize_t
read_func(void *datasource
, void *buffer
, size_t count
)
39 struct input_plugin_data
*ip_data
= datasource
;
41 return read_wrapper(ip_data
, buffer
, count
);
44 static off_t
lseek_func(void *datasource
, off_t offset
, int whence
)
46 struct input_plugin_data
*ip_data
= datasource
;
48 return lseek(ip_data
->fd
, offset
, whence
);
51 static int close_func(void *datasource
)
53 struct input_plugin_data
*ip_data
= datasource
;
55 return close(ip_data
->fd
);
58 static struct nomad_callbacks callbacks
= {
64 /* ------------------------------------------------------------------------- */
66 static int mad_open(struct input_plugin_data
*ip_data
)
69 struct nomad_info info
;
73 rc
= nomad_open_callbacks(&nomad
, ip_data
, fast
, &callbacks
);
75 case -NOMAD_ERROR_ERRNO
:
77 case -NOMAD_ERROR_FILE_FORMAT
:
78 return -IP_ERROR_FILE_FORMAT
;
80 ip_data
->private = nomad
;
82 nomad_info(nomad
, &info
);
84 /* always 16-bit signed little-endian */
85 ip_data
->sf
= sf_rate(info
.sample_rate
) | sf_channels(info
.channels
) |
86 sf_bits(16) | sf_signed(1);
90 static int mad_close(struct input_plugin_data
*ip_data
)
94 nomad
= ip_data
->private;
97 ip_data
->private = NULL
;
101 static int mad_read(struct input_plugin_data
*ip_data
, char *buffer
, int count
)
105 nomad
= ip_data
->private;
106 return nomad_read(nomad
, buffer
, count
);
109 static int mad_seek(struct input_plugin_data
*ip_data
, double offset
)
113 nomad
= ip_data
->private;
114 return nomad_time_seek(nomad
, offset
);
117 static int mad_read_comments(struct input_plugin_data
*ip_data
,
118 struct keyval
**comments
)
125 fd
= open(ip_data
->filename
, O_RDONLY
);
129 d_print("filename: %s\n", ip_data
->filename
);
132 rc
= id3_read_tags(&id3
, fd
, ID3_V1
| ID3_V2
);
138 d_print("error: %s\n", strerror(errno
));
141 d_print("corrupted tag?\n");
145 for (i
= 0; i
< NUM_ID3_KEYS
; i
++) {
146 char *val
= id3_get_comment(&id3
, i
);
149 comments_add(&c
, id3_key_names
[i
], val
);
155 rc
= ape_read_tags(&ape
, ip_data
->fd
, 0);
159 for (i
= 0; i
< rc
; i
++) {
161 k
= ape_get_comment(&ape
, &v
);
164 comments_add(&c
, k
, v
);
171 keyvals_terminate(&c
);
172 *comments
= c
.keyvals
;
176 static int mad_duration(struct input_plugin_data
*ip_data
)
180 nomad
= ip_data
->private;
181 return nomad_time_total(nomad
);
184 const struct input_plugin_ops ip_ops
= {
189 .read_comments
= mad_read_comments
,
190 .duration
= mad_duration
193 const char * const ip_extensions
[] = { "mp3", "mp2", NULL
};
194 const char * const ip_mime_types
[] = {
195 "audio/mpeg", "audio/x-mp3", "audio/x-mpeg", NULL