Disable TCP/IP server support
[cmus.git] / flac.c
blobc4430ee96ad22ed05f013941aec7e2350c710a25
1 #include "ip.h"
2 #include "comment.h"
3 #include "xmalloc.h"
4 #include "debug.h"
6 #include <FLAC/seekable_stream_decoder.h>
7 #include <FLAC/metadata.h>
8 #include <inttypes.h>
9 #include <sys/types.h>
10 #include <unistd.h>
11 #include <errno.h>
13 #ifndef UINT64_MAX
14 #define UINT64_MAX ((uint64_t)-1)
15 #endif
17 /* Reduce typing. Namespaces are nice but FLAC API is fscking ridiculous. */
19 /* functions, types, enums */
20 #define F(s) FLAC__seekable_stream_decoder_ ## s
21 #define T(s) FLAC__SeekableStreamDecoder ## s
22 #define Dec FLAC__SeekableStreamDecoder
23 #define E(s) FLAC__SEEKABLE_STREAM_DECODER_ ## s
25 struct flac_private {
26 /* file/stream position and length */
27 uint64_t pos;
28 uint64_t len;
30 Dec *dec;
32 /* PCM data */
33 char *buf;
34 unsigned int buf_size;
35 unsigned int buf_wpos;
36 unsigned int buf_rpos;
38 struct keyval *comments;
39 int duration;
41 unsigned int eof : 1;
42 unsigned int ignore_next_write : 1;
45 static T(ReadStatus) read_cb(const Dec *dec, unsigned char *buf, unsigned *size, void *data)
47 struct input_plugin_data *ip_data = data;
48 struct flac_private *priv = ip_data->private;
49 int rc;
51 if (priv->eof) {
52 *size = 0;
53 d_print("EOF! EOF! EOF!\n");
54 return E(READ_STATUS_OK);
56 if (*size == 0)
57 return E(READ_STATUS_OK);
59 rc = read(ip_data->fd, buf, *size);
60 if (rc == -1) {
61 *size = 0;
62 if (errno == EINTR || errno == EAGAIN) {
63 /* FIXME: not sure how the flac decoder handles this */
64 d_print("interrupted\n");
65 return E(READ_STATUS_OK);
67 return E(READ_STATUS_ERROR);
69 if (*size != rc) {
70 d_print("%d != %d\n", rc, *size);
72 priv->pos += rc;
73 *size = rc;
74 if (rc == 0) {
75 /* never reached! */
76 priv->eof = 1;
77 d_print("EOF\n");
78 return E(READ_STATUS_OK);
80 return E(READ_STATUS_OK);
83 static T(SeekStatus) seek_cb(const Dec *dec, uint64_t offset, void *data)
85 struct input_plugin_data *ip_data = data;
86 struct flac_private *priv = ip_data->private;
87 off_t off;
89 if (priv->len == UINT64_MAX)
90 return E(SEEK_STATUS_ERROR);
91 off = lseek(ip_data->fd, offset, SEEK_SET);
92 if (off == -1) {
93 return E(SEEK_STATUS_ERROR);
95 priv->pos = off;
96 return E(SEEK_STATUS_OK);
99 static T(TellStatus) tell_cb(const Dec *dec, uint64_t *offset, void *data)
101 struct input_plugin_data *ip_data = data;
102 struct flac_private *priv = ip_data->private;
104 d_print("\n");
105 *offset = priv->pos;
106 return E(TELL_STATUS_OK);
109 static T(LengthStatus) length_cb(const Dec *dec, uint64_t *len, void *data)
111 struct input_plugin_data *ip_data = data;
112 struct flac_private *priv = ip_data->private;
114 d_print("\n");
115 if (ip_data->remote) {
116 return E(LENGTH_STATUS_ERROR);
118 *len = priv->len;
119 return E(LENGTH_STATUS_OK);
122 static int eof_cb(const Dec *dec, void *data)
124 struct input_plugin_data *ip_data = data;
125 struct flac_private *priv = ip_data->private;
126 int eof = priv->eof;
128 if (eof)
129 d_print("EOF\n");
130 return eof;
133 #if defined(WORDS_BIGENDIAN)
135 static inline uint16_t LE16(uint16_t x)
137 return (x >> 8) | (x << 8);
140 static inline uint32_t LE32(uint32_t x)
142 uint32_t x3 = x << 24;
143 uint32_t x0 = x >> 24;
144 uint32_t x2 = (x & 0xff00) << 8;
145 uint32_t x1 = (x >> 8) & 0xff00;
146 return x3 | x2 | x1 | x0;
149 #else
151 #define LE16(x) (x)
152 #define LE32(x) (x)
154 #endif
156 static FLAC__StreamDecoderWriteStatus write_cb(const Dec *dec, const FLAC__Frame *frame,
157 const int32_t * const *buf, void *data)
159 struct input_plugin_data *ip_data = data;
160 struct flac_private *priv = ip_data->private;
161 int frames, bytes, size, channels, bits, depth;
162 int ch, i, j = 0;
164 if (ip_data->sf == 0) {
165 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
168 if (priv->ignore_next_write) {
169 priv->ignore_next_write = 0;
170 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
173 frames = frame->header.blocksize;
174 channels = sf_get_channels(ip_data->sf);
175 bits = sf_get_bits(ip_data->sf);
176 bytes = frames * bits / 8 * channels;
177 size = priv->buf_size;
179 if (size - priv->buf_wpos < bytes) {
180 if (size < bytes)
181 size = bytes;
182 size *= 2;
183 priv->buf = xrenew(char, priv->buf, size);
184 priv->buf_size = size;
187 depth = frame->header.bits_per_sample;
188 if (depth == 8) {
189 char *b = priv->buf + priv->buf_wpos;
191 for (i = 0; i < frames; i++) {
192 for (ch = 0; ch < channels; ch++)
193 b[j++] = buf[ch][i];
195 } else if (depth == 16) {
196 int16_t *b = (int16_t *)(priv->buf + priv->buf_wpos);
198 for (i = 0; i < frames; i++) {
199 for (ch = 0; ch < channels; ch++)
200 b[j++] = LE16(buf[ch][i]);
202 } else if (depth == 32) {
203 int32_t *b = (int32_t *)(priv->buf + priv->buf_wpos);
205 for (i = 0; i < frames; i++) {
206 for (ch = 0; ch < channels; ch++)
207 b[j++] = LE32(buf[ch][i]);
209 } else if (depth == 12) { /* -> 16 */
210 int16_t *b = (int16_t *)(priv->buf + priv->buf_wpos);
212 for (i = 0; i < frames; i++) {
213 for (ch = 0; ch < channels; ch++)
214 b[j++] = LE16(buf[ch][i] << 4);
216 } else if (depth == 20) { /* -> 32 */
217 int32_t *b = (int32_t *)(priv->buf + priv->buf_wpos);
219 for (i = 0; i < frames; i++) {
220 for (ch = 0; ch < channels; ch++)
221 b[j++] = LE32(buf[ch][i] << 12);
223 } else if (depth == 24) { /* -> 32 */
224 int32_t *b = (int32_t *)(priv->buf + priv->buf_wpos);
226 for (i = 0; i < frames; i++) {
227 for (ch = 0; ch < channels; ch++)
228 b[j++] = LE32(buf[ch][i] << 8);
230 } else {
231 d_print("bits per sample changed to %d\n", depth);
234 priv->buf_wpos += bytes;
235 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
238 /* You should make a copy of metadata with FLAC__metadata_object_clone() if you will
239 * need it elsewhere. Since metadata blocks can potentially be large, by
240 * default the decoder only calls the metadata callback for the STREAMINFO
241 * block; you can instruct the decoder to pass or filter other blocks with
242 * FLAC__stream_decoder_set_metadata_*() calls.
244 static void metadata_cb(const Dec *dec, const FLAC__StreamMetadata *metadata, void *data)
246 struct input_plugin_data *ip_data = data;
247 struct flac_private *priv = ip_data->private;
249 switch (metadata->type) {
250 case FLAC__METADATA_TYPE_STREAMINFO:
252 const FLAC__StreamMetadata_StreamInfo *si = &metadata->data.stream_info;
253 int bits = 0;
255 switch (si->bits_per_sample) {
256 case 8:
257 case 16:
258 case 32:
259 bits = si->bits_per_sample;
260 break;
261 case 12:
262 bits = 16;
263 break;
264 case 20:
265 case 24:
266 bits = 32;
267 break;
270 ip_data->sf = sf_rate(si->sample_rate) |
271 sf_bits(bits) |
272 sf_signed(1) |
273 sf_channels(si->channels);
274 if (!ip_data->remote && si->total_samples)
275 priv->duration = si->total_samples / si->sample_rate;
277 break;
278 case FLAC__METADATA_TYPE_VORBIS_COMMENT:
279 d_print("VORBISCOMMENT\n");
280 if (priv->comments) {
281 d_print("Ignoring\n");
282 } else {
283 struct keyval *c;
284 int s, d, nr;
286 nr = metadata->data.vorbis_comment.num_comments;
287 c = xnew0(struct keyval, nr + 1);
288 for (s = 0, d = 0; s < nr; s++) {
289 char *key, *val;
291 /* until you have finished reading this function name
292 * you have already forgot WTF you're doing */
293 if (!FLAC__metadata_object_vorbiscomment_entry_to_name_value_pair(
294 metadata->data.vorbis_comment.comments[s],
295 &key, &val))
296 continue;
298 if (!is_interesting_key(key)) {
299 free(key);
300 free(val);
301 continue;
303 if (!strcasecmp(key, "tracknumber") || !strcasecmp(key, "discnumber"))
304 fix_track_or_disc(val);
306 d_print("comment: '%s=%s'\n", key, val);
307 c[d].key = key;
308 c[d].val = val;
309 d++;
311 priv->comments = c;
313 break;
314 default:
315 d_print("something else\n");
316 break;
320 static void error_cb(const Dec *dec, FLAC__StreamDecoderErrorStatus status, void *data)
322 static const char *strings[3] = {
323 "lost sync",
324 "bad header",
325 "frame crc mismatch"
327 const char *str = "unknown error";
329 if (status >= 0 && status < 3)
330 str = strings[status];
331 d_print("%d %s\n", status, str);
334 static void free_priv(struct input_plugin_data *ip_data)
336 struct flac_private *priv = ip_data->private;
337 int save = errno;
339 F(finish)(priv->dec);
340 F(delete)(priv->dec);
341 if (priv->comments)
342 comments_free(priv->comments);
343 free(priv->buf);
344 free(priv);
345 ip_data->private = NULL;
346 errno = save;
349 static int flac_open(struct input_plugin_data *ip_data)
351 struct flac_private *priv;
352 Dec *dec;
354 dec = F(new)();
355 if (dec == NULL)
356 return -IP_ERROR_INTERNAL;
358 priv = xnew0(struct flac_private, 1);
359 priv->dec = dec;
360 priv->duration = -1;
361 if (ip_data->remote) {
362 priv->len = UINT64_MAX;
363 } else {
364 off_t off = lseek(ip_data->fd, 0, SEEK_END);
366 if (off == -1 || lseek(ip_data->fd, 0, SEEK_SET) == -1) {
367 int save = errno;
369 F(delete)(dec);
370 free(priv);
371 errno = save;
372 return -IP_ERROR_ERRNO;
374 priv->len = off;
376 ip_data->private = priv;
378 F(set_read_callback)(dec, read_cb);
379 F(set_seek_callback)(dec, seek_cb);
380 F(set_tell_callback)(dec, tell_cb);
381 F(set_length_callback)(dec, length_cb);
382 F(set_eof_callback)(dec, eof_cb);
383 F(set_write_callback)(dec, write_cb);
384 F(set_metadata_callback)(dec, metadata_cb);
385 F(set_error_callback)(dec, error_cb);
386 F(set_client_data)(dec, ip_data);
388 /* FLAC__METADATA_TYPE_STREAMINFO already accepted */
389 F(set_metadata_respond)(dec, FLAC__METADATA_TYPE_VORBIS_COMMENT);
391 if (F(init)(dec) != E(OK)) {
392 int save = errno;
394 d_print("init failed\n");
395 F(delete)(priv->dec);
396 free(priv);
397 ip_data->private = NULL;
398 errno = save;
399 return -IP_ERROR_ERRNO;
402 ip_data->sf = 0;
403 while (priv->buf_wpos == 0 && !priv->eof) {
404 if (!F(process_single)(priv->dec)) {
405 free_priv(ip_data);
406 return -IP_ERROR_ERRNO;
410 if (!ip_data->sf) {
411 free_priv(ip_data);
412 return -IP_ERROR_FILE_FORMAT;
414 if (!sf_get_bits(ip_data->sf)) {
415 free_priv(ip_data);
416 return -IP_ERROR_SAMPLE_FORMAT;
419 d_print("sr: %d, ch: %d, bits: %d\n",
420 sf_get_rate(ip_data->sf),
421 sf_get_channels(ip_data->sf),
422 sf_get_bits(ip_data->sf));
423 return 0;
426 static int flac_close(struct input_plugin_data *ip_data)
428 free_priv(ip_data);
429 return 0;
432 static int flac_read(struct input_plugin_data *ip_data, char *buffer, int count)
434 struct flac_private *priv = ip_data->private;
435 int avail;
436 int libflac_suck_count = 0;
438 while (1) {
439 int old_pos = priv->buf_wpos;
441 avail = priv->buf_wpos - priv->buf_rpos;
442 BUG_ON(avail < 0);
443 if (avail > 0)
444 break;
445 if (priv->eof)
446 return 0;
447 if (!F(process_single)(priv->dec)) {
448 d_print("process_single failed\n");
449 return -1;
451 if (old_pos == priv->buf_wpos) {
452 libflac_suck_count++;
453 } else {
454 libflac_suck_count = 0;
456 if (libflac_suck_count > 5) {
457 d_print("libflac sucks\n");
458 priv->eof = 1;
459 return 0;
462 if (count > avail)
463 count = avail;
464 memcpy(buffer, priv->buf + priv->buf_rpos, count);
465 priv->buf_rpos += count;
466 BUG_ON(priv->buf_rpos > priv->buf_wpos);
467 if (priv->buf_rpos == priv->buf_wpos) {
468 priv->buf_rpos = 0;
469 priv->buf_wpos = 0;
471 return count;
474 /* Flush the input and seek to an absolute sample. Decoding will resume at the
475 * given sample. Note that because of this, the next write callback may contain
476 * a partial block.
478 static int flac_seek(struct input_plugin_data *ip_data, double offset)
480 struct flac_private *priv = ip_data->private;
481 uint64_t sample;
483 sample = (uint64_t)(offset * (double)sf_get_rate(ip_data->sf) + 0.5);
484 if (!F(seek_absolute)(priv->dec, sample)) {
485 return -IP_ERROR_ERRNO;
487 priv->ignore_next_write = 1;
488 priv->buf_rpos = 0;
489 priv->buf_wpos = 0;
490 return 0;
493 static int flac_read_comments(struct input_plugin_data *ip_data, struct keyval **comments)
495 struct flac_private *priv = ip_data->private;
497 if (priv->comments) {
498 *comments = comments_dup(priv->comments);
499 } else {
500 *comments = xnew0(struct keyval, 1);
502 return 0;
505 static int flac_duration(struct input_plugin_data *ip_data)
507 struct flac_private *priv = ip_data->private;
509 return priv->duration;
512 const struct input_plugin_ops ip_ops = {
513 .open = flac_open,
514 .close = flac_close,
515 .read = flac_read,
516 .seek = flac_seek,
517 .read_comments = flac_read_comments,
518 .duration = flac_duration
521 const char * const ip_extensions[] = { "flac", "fla", NULL };
522 const char * const ip_mime_types[] = { NULL };