-/*
- * Copyright (C) 2003 Andre Noll <maan@tuebingen.mpg.de>
- *
- * Licensed under the GPL v2. For licencing details see COPYING.
- */
+/* Copyright (C) 2003 Andre Noll <maan@tuebingen.mpg.de>, see file COPYING. */
/** \file mp3_afh.c para_server's mp3 audio format handler */
};
static const int frame_size_index[] = {24000, 72000, 72000};
-static const char *mode_text[] = {"stereo", "joint stereo", "dual channel", "mono", "invalid"};
-
#ifdef HAVE_ID3TAG
#include <id3tag.h>
if (!val || !*val)
return 0;
fr = id3_frame_new(id);
- PARA_DEBUG_LOG("frame desc: %s, %d fields\n", fr->description, fr->nfields);
+ PARA_DEBUG_LOG("frame desc: %s, %u fields\n", fr->description, fr->nfields);
/* Frame 0 contains the encoding. We always use UTF-8. */
field = id3_frame_field(fr, 0);
static void free_tag(struct id3_tag *id3_t)
{
int i, j;
+
+ if (!id3_t)
+ return;
for (i = 0; i < id3_t->nframes; i++) {
struct id3_frame *fr = id3_t->frames[i];
for (j = 0; j < fr->nfields; j++) {
if (v2_tag) {
PARA_NOTICE_LOG("replacing id3v2 tag\n");
old_v2size = v2_tag->paddedsize;
- } else if (!v1_tag) {
- PARA_NOTICE_LOG("no id3 tags found, adding id3v2 tag\n");
+ } else {
+ PARA_NOTICE_LOG("adding id3v2 tag\n");
v2_tag = id3_tag_new();
assert(v2_tag);
}
- if (v2_tag) {
- /*
- * Turn off all options to avoid creating an extended header.
- * id321 does not understand it.
- */
- id3_tag_options(v2_tag, ~0U, 0);
- ret = replace_tags(v2_tag, tags);
- if (ret < 0)
- goto out;
- new_v2size = id3_tag_render(v2_tag, NULL);
- v2_buffer = para_malloc(new_v2size);
- id3_tag_render(v2_tag, v2_buffer);
- PARA_INFO_LOG("writing v2 tag (%lu bytes)\n", new_v2size);
- ret = write_all(fd, (char *)v2_buffer, new_v2size);
- free(v2_buffer);
- if (ret < 0)
- goto out;
- }
+ /*
+ * Turn off all options to avoid creating an extended header. id321
+ * does not understand it.
+ */
+ id3_tag_options(v2_tag, ~0U, 0);
+ ret = replace_tags(v2_tag, tags);
+ if (ret < 0)
+ goto out;
+ new_v2size = id3_tag_render(v2_tag, NULL);
+ v2_buffer = alloc(new_v2size);
+ id3_tag_render(v2_tag, v2_buffer);
+ PARA_INFO_LOG("writing v2 tag (%lu bytes)\n", new_v2size);
+ ret = write_all(fd, (char *)v2_buffer, new_v2size);
+ free(v2_buffer);
+ if (ret < 0)
+ goto out;
data_sz = mapsize - old_v2size;
if (v1_tag && data_sz >= 128)
data_sz -= 128;
ret = write_all(fd, (char *)v1_buffer, 128);
}
out:
- if (v1_tag)
- free_tag(v1_tag);
- if (v2_tag)
- free_tag(v2_tag);
+ free_tag(v1_tag);
+ free_tag(v2_tag);
return ret;
}
return frequencies[h->version][h->freq];
}
-static const char *header_mode(struct mp3header *h)
+static const char *header_mode(const struct mp3header *h)
{
- if (h->mode > 4)
- h->mode = 4; /* invalid */
+ const char * const mode_text[] = {"stereo", "joint stereo",
+ "dual channel", "mono"};
+
+ if (h->mode >= ARRAY_SIZE(mode_text))
+ return "invalid";
return mode_text[h->mode];
}
const char *tag_versions[] = {"no", "id3v1", "id3v2", "id3v1+id3v2"};
afhi->chunks_total = 0;
- afhi->chunk_table = para_malloc(chunk_table_size * sizeof(uint32_t));
+ afhi->chunk_table = arr_alloc(chunk_table_size, sizeof(uint32_t));
while (1) {
int freq, br;
struct timeval tmp, cct; /* current chunk time */
total_time = tmp;
if (afhi->chunks_total >= chunk_table_size) {
chunk_table_size *= 2;
- afhi->chunk_table = para_realloc(afhi->chunk_table,
- chunk_table_size * sizeof(uint32_t));
+ afhi->chunk_table = arr_realloc(afhi->chunk_table,
+ chunk_table_size, sizeof(uint32_t));
}
afhi->chunk_table[afhi->chunks_total] = fpos;
afhi->chunks_total++;
afhi->channels = header_channels(&header);
afhi->seconds_total = (tv2ms(&total_time) + 500) / 1000;
tv_divide(afhi->chunks_total, &total_time, &afhi->chunk_tv);
- PARA_DEBUG_LOG("%" PRIu32 "chunks, each %lums\n", afhi->chunks_total,
+ PARA_DEBUG_LOG("%" PRIu32 " chunks, each %lums\n", afhi->chunks_total,
tv2ms(&afhi->chunk_tv));
+ set_max_chunk_size(afhi);
ret = mp3_get_id3(map, numbytes, fd, &afhi->tags);
afhi->techinfo = make_message("%cbr, %s, %s tags", vbr? 'v' : 'c',
header_mode(&header), tag_versions[ret]);
return 1;
err_out:
- PARA_ERROR_LOG("%s\n", para_strerror(-ret));
free(afhi->chunk_table);
return ret;
}
ret = mp3_read_info((unsigned char *)map, numbytes, fd, afhi);
if (ret < 0)
return ret;
- if (afhi->seconds_total < 2 || !afhi->chunks_total)
+ if (afhi->chunks_total == 0)
return -E_MP3_INFO;
return 1;
}
-static const char* mp3_suffixes[] = {"mp3", NULL};
+static const char * const mp3_suffixes[] = {"mp3", NULL};
/**
- * the init function of the mp3 audio format handler
+ * The mp3 audio format handler.
*
- * \param afh pointer to the struct to initialize
+ * It does not depend on any libraries and is hence always compiled in.
*/
-void mp3_init(struct audio_format_handler *afh)
-{
- afh->get_file_info = mp3_get_file_info;
- afh->suffixes = mp3_suffixes;
+const struct audio_format_handler mp3_afh = {
+ .get_file_info = mp3_get_file_info,
+ .suffixes = mp3_suffixes,
#ifdef HAVE_LIBID3TAG
- afh->rewrite_tags = mp3_rewrite_tags;
+ .rewrite_tags = mp3_rewrite_tags,
#endif /* HAVE_LIBID3TAG */
-}
+};