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
24 #include "read_wrapper.h"
28 #include <sys/types.h>
30 #include <sys/types.h>
34 /* ------------------------------------------------------------------------- */
36 static ssize_t
read_func(void *datasource
, void *buffer
, size_t count
)
38 struct input_plugin_data
*ip_data
= datasource
;
40 return read_wrapper(ip_data
, buffer
, count
);
43 static off_t
lseek_func(void *datasource
, off_t offset
, int whence
)
45 struct input_plugin_data
*ip_data
= datasource
;
47 return lseek(ip_data
->fd
, offset
, whence
);
50 static int close_func(void *datasource
)
52 struct input_plugin_data
*ip_data
= datasource
;
54 return close(ip_data
->fd
);
57 static struct nomad_callbacks callbacks
= {
63 /* ------------------------------------------------------------------------- */
65 static int mad_open(struct input_plugin_data
*ip_data
)
68 struct nomad_info info
;
72 rc
= nomad_open_callbacks(&nomad
, ip_data
, fast
, &callbacks
);
74 case -NOMAD_ERROR_ERRNO
:
76 case -NOMAD_ERROR_FILE_FORMAT
:
77 return -IP_ERROR_FILE_FORMAT
;
79 ip_data
->private = nomad
;
81 nomad_info(nomad
, &info
);
83 /* always 16-bit signed little-endian */
84 ip_data
->sf
= sf_rate(info
.sample_rate
) | sf_channels(info
.channels
) |
85 sf_bits(16) | sf_signed(1);
89 static int mad_close(struct input_plugin_data
*ip_data
)
93 nomad
= ip_data
->private;
96 ip_data
->private = NULL
;
100 static int mad_read(struct input_plugin_data
*ip_data
, char *buffer
, int count
)
104 nomad
= ip_data
->private;
105 return nomad_read(nomad
, buffer
, count
);
108 static int mad_seek(struct input_plugin_data
*ip_data
, double offset
)
112 nomad
= ip_data
->private;
113 return nomad_time_seek(nomad
, offset
);
116 static void get_comment(struct keyval
*c
, int *iptr
, ID3
*id3
, enum id3_key key
, const char *key_name
)
120 c
[i
].val
= id3_get_comment(id3
, key
);
121 if (c
[i
].val
== NULL
)
123 c
[i
].key
= xstrdup(key_name
);
127 static int mad_read_comments(struct input_plugin_data
*ip_data
,
128 struct keyval
**comments
)
134 fd
= open(ip_data
->filename
, O_RDONLY
);
138 d_print("filename: %s\n", ip_data
->filename
);
141 rc
= id3_read_tags(id3
, fd
, ID3_V1
| ID3_V2
);
147 d_print("error: %s\n", strerror(errno
));
150 d_print("corrupted tag?\n");
151 *comments
= xnew0(struct keyval
, 1);
155 c
= xnew0(struct keyval
, NUM_ID3_KEYS
+ 1);
157 get_comment(c
, &i
, id3
, ID3_ARTIST
, "artist");
158 get_comment(c
, &i
, id3
, ID3_ALBUM
, "album");
159 get_comment(c
, &i
, id3
, ID3_TITLE
, "title");
160 get_comment(c
, &i
, id3
, ID3_DATE
, "date");
161 get_comment(c
, &i
, id3
, ID3_GENRE
, "genre");
162 get_comment(c
, &i
, id3
, ID3_DISC
, "discnumber");
163 get_comment(c
, &i
, id3
, ID3_TRACK
, "tracknumber");
164 get_comment(c
, &i
, id3
, ID3_ALBUMARTIST
, "albumartist");
170 static int mad_duration(struct input_plugin_data
*ip_data
)
174 nomad
= ip_data
->private;
175 return nomad_time_total(nomad
);
178 const struct input_plugin_ops ip_ops
= {
183 .read_comments
= mad_read_comments
,
184 .duration
= mad_duration
187 const char * const ip_extensions
[] = { "mp3", "mp2", NULL
};
188 const char * const ip_mime_types
[] = {
189 "audio/mpeg", "audio/x-mp3", "audio/x-mpeg", "audio/x-mpegurl", NULL