summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
c4504b2)
The audio_format_handler structure contains only pointers, and the
->init method of each instance initializes these pointers to constant
values. The ->init() method is thus useless at best, and it prevents
the structures from being declared constant.
This patch removes ->init() of struct audio_format_handler and the
public afh_init() which iterates over all audio formats to call each
->init() method. The audio format handlers are modified to define an
instance of the structure rather than an init function which fills the
fields of the given structure. The structure can be declared constant,
but not static because afh_common.c needs a way to refer to it.
We rely on weak symbols to deal with audio format handlers which are
not compiled in. The codec-independent code in afh_common.c defines
a weak instance of the audio_format_handler structure for each audio
format. The command handlers which are compiled in override the weak
symbol with their own definition.
The afh receiver used to define afh_init() as its (receiver!) init
function, which no longer exists. Since receiver init functions are
optional, we don't need to supply a replacement. However, play.c
calls ->init() of the afh_receiver unconditionally. This call needs
to be removed to avoid a null pointer dereference.
13 files changed:
}
static const char * const aac_suffixes[] = {"m4a", "mp4", NULL};
}
static const char * const aac_suffixes[] = {"m4a", "mp4", NULL};
- * the init function of the aac audio format handler
+ * The audio format handler for the Advanced Audio Codec.
- * \param afh pointer to the struct to initialize
+ * This is only compiled in if the faad library is installed.
-void aac_afh_init(struct audio_format_handler *afh)
-{
- afh->get_file_info = aac_get_file_info,
- afh->suffixes = aac_suffixes;
- afh->rewrite_tags = aac_afh_rewrite_tags;
- afh->open = aac_afh_open;
- afh->get_chunk = aac_afh_get_chunk;
- afh->close = aac_afh_close;
-}
+const struct audio_format_handler aac_afh = {
+ .get_file_info = aac_get_file_info,
+ .suffixes = aac_suffixes,
+ .rewrite_tags = aac_afh_rewrite_tags,
+ .open = aac_afh_open,
+ .get_chunk = aac_afh_get_chunk,
+ .close = aac_afh_close,
+};
loglevel = OPT_UINT32_VAL(LOGLEVEL);
version_handle_flag("afh", OPT_GIVEN(VERSION));
handle_help_flags();
loglevel = OPT_UINT32_VAL(LOGLEVEL);
version_handle_flag("afh", OPT_GIVEN(VERSION));
handle_help_flags();
for (i = 0; i < lls_num_inputs(lpr); i++) {
int ret2;
const char *path = lls_input(i, lpr);
for (i = 0; i < lls_num_inputs(lpr); i++) {
int ret2;
const char *path = lls_input(i, lpr);
* in the other part of this struct.
*/
struct audio_format_handler {
* in the other part of this struct.
*/
struct audio_format_handler {
- /**
- * Pointer to the audio format handler's init function.
- *
- * Must initialize all function pointers and is assumed to succeed.
- */
- void (*init)(struct audio_format_handler*);
/** Typical file endings for files that can be handled by this afh. */
const char * const *suffixes;
/**
/** Typical file endings for files that can be handled by this afh. */
const char * const *suffixes;
/**
int output_fd, const char *filename);
};
int output_fd, const char *filename);
};
int guess_audio_format(const char *name);
int compute_afhi(const char *path, char *data, size_t size,
int fd, struct afh_info *afhi);
int guess_audio_format(const char *name);
int compute_afhi(const char *path, char *data, size_t size,
int fd, struct afh_info *afhi);
#include "string.h"
#include "afh.h"
#include "string.h"
#include "afh.h"
-typedef void afh_init_func(struct audio_format_handler *);
-
-/*
- * Declaration of the audio format handler init functions.
- *
- * These symbols are referenced in the afl array below.
- *
- * Most audio format handlers depend on an external library and are not
- * compiled in if the library is not installed. Hence it is well possible that
- * not all of these functions are defined. It does not hurt to declare them
- * anyway, and this avoids another set of ifdefs.
- */
-extern afh_init_func mp3_afh_init, ogg_afh_init, aac_afh_init, wma_afh_init,
- spx_afh_init, flac_afh_init, opus_afh_init;
-
/** The list of all status items */
const char *status_item_list[] = {STATUS_ITEMS};
/** The list of all status items */
const char *status_item_list[] = {STATUS_ITEMS};
AUDIO_FORMAT(flac) \
AUDIO_FORMAT(opus) \
AUDIO_FORMAT(flac) \
AUDIO_FORMAT(opus) \
+/** \cond audio_format_handler */
#define AUDIO_FORMAT(_fmt) #_fmt,
static const char * const audio_format_names[] = {ALL_AUDIO_FORMATS};
#undef AUDIO_FORMAT
#define AUDIO_FORMAT(_fmt) #_fmt,
static const char * const audio_format_names[] = {ALL_AUDIO_FORMATS};
#undef AUDIO_FORMAT
-
-/*
- * It can be detected whether an audio format is compiled in by checking if the
- * init function pointer is NULL.
- */
-static struct audio_format_handler afl[] = {
- {
- .init = mp3_afh_init,
- },
- {
-#if defined(HAVE_OGG) && defined(HAVE_VORBIS)
- .init = ogg_afh_init,
-#endif
- },
- {
-#if defined(HAVE_FAAD)
- .init = aac_afh_init,
-#endif
- },
- {
- .init = wma_afh_init,
- },
- {
-#if defined(HAVE_OGG) && defined(HAVE_SPEEX)
- .init = spx_afh_init,
-#endif
- },
- {
-#if defined(HAVE_OGG) && defined(HAVE_FLAC)
- .init = flac_afh_init,
-#endif
- },
- {
-#if defined(HAVE_OGG) && defined(HAVE_OPUS)
- .init = opus_afh_init,
-#endif
- },
-};
-
-/** This includes audio formats not compiled in. */
+/* Weak declarations must be public. */
+#define AUDIO_FORMAT(_fmt) \
+ struct audio_format_handler _fmt ## _afh __attribute__ ((weak)) \
+ = {.get_file_info = NULL};
+ALL_AUDIO_FORMATS
+#undef AUDIO_FORMAT
+#define AUDIO_FORMAT(_fmt) & _fmt ## _afh,
+static struct audio_format_handler *afl[] = {ALL_AUDIO_FORMATS};
+#undef AUDIO_FORMAT
#define NUM_AUDIO_FORMATS (ARRAY_SIZE(afl))
#define NUM_AUDIO_FORMATS (ARRAY_SIZE(afl))
+/** \endcond audio_format_handler */
/**
* Get the name of the given audio format.
/**
* Get the name of the given audio format.
format++;
if (format >= NUM_AUDIO_FORMATS)
return format;
format++;
if (format >= NUM_AUDIO_FORMATS)
return format;
+ if (afl[format]->get_file_info)
#define FOR_EACH_AUDIO_FORMAT(i) \
for (i = 0; i < NUM_AUDIO_FORMATS; i = next_audio_format(i))
#define FOR_EACH_AUDIO_FORMAT(i) \
for (i = 0; i < NUM_AUDIO_FORMATS; i = next_audio_format(i))
-/**
- * Call the init function of each supported audio format handler.
- */
-void afh_init(void)
-{
- int i;
-
- PARA_NOTICE_LOG("supported audio formats: %s\n", AUDIO_FORMAT_HANDLERS);
- FOR_EACH_AUDIO_FORMAT(i) {
- PARA_INFO_LOG("initializing %s handler\n",
- audio_format_name(i));
- afl[i].init(&afl[i]);
- }
-}
-
/**
* Tell whether an audio format handler provides chunk tables.
*
/**
* Tell whether an audio format handler provides chunk tables.
*
*/
bool afh_supports_dynamic_chunks(int audio_format_id)
{
*/
bool afh_supports_dynamic_chunks(int audio_format_id)
{
- return afl[audio_format_id].get_chunk;
+ return afl[audio_format_id]->get_chunk;
int i,j, len = strlen(name);
FOR_EACH_AUDIO_FORMAT(i) {
int i,j, len = strlen(name);
FOR_EACH_AUDIO_FORMAT(i) {
- for (j = 0; afl[i].suffixes[j]; j++) {
- const char *p = afl[i].suffixes[j];
+ for (j = 0; afl[i]->suffixes[j]; j++) {
+ const char *p = afl[i]->suffixes[j];
int plen = strlen(p);
if (len < plen + 1)
continue;
int plen = strlen(p);
if (len < plen + 1)
continue;
const char *fmt = audio_format_name(format);
memset(afhi, 0, sizeof(*afhi));
const char *fmt = audio_format_name(format);
memset(afhi, 0, sizeof(*afhi));
- ret = afl[format].get_file_info(data, size, fd, afhi);
+ ret = afl[format]->get_file_info(data, size, fd, afhi);
if (ret < 0) {
PARA_WARNING_LOG("%s: %s format not detected: %s\n",
path, fmt, para_strerror(-ret));
if (ret < 0) {
PARA_WARNING_LOG("%s: %s format not detected: %s\n",
path, fmt, para_strerror(-ret));
uint8_t audio_format_id, const void *map, size_t mapsize,
const char **buf, size_t *len, void **afh_context)
{
uint8_t audio_format_id, const void *map, size_t mapsize,
const char **buf, size_t *len, void **afh_context)
{
- struct audio_format_handler *afh = afl + audio_format_id;
+ struct audio_format_handler *afh = afl[audio_format_id];
if (afh_supports_dynamic_chunks(audio_format_id)) {
int ret;
if (afh_supports_dynamic_chunks(audio_format_id)) {
int ret;
*/
void afh_close(void *afh_context, uint8_t audio_format_id)
{
*/
void afh_close(void *afh_context, uint8_t audio_format_id)
{
- struct audio_format_handler *afh = afl + audio_format_id;
+ struct audio_format_handler *afh = afl[audio_format_id];
if (!afh_supports_dynamic_chunks(audio_format_id))
return;
if (!afh_supports_dynamic_chunks(audio_format_id))
return;
void afh_get_header(struct afh_info *afhi, uint8_t audio_format_id,
void *map, size_t mapsize, char **buf, size_t *len)
{
void afh_get_header(struct afh_info *afhi, uint8_t audio_format_id,
void *map, size_t mapsize, char **buf, size_t *len)
{
- struct audio_format_handler *afh = afl + audio_format_id;
+ struct audio_format_handler *afh = afl[audio_format_id];
if (!map || !afhi || !afhi->header_len) {
*buf = NULL;
if (!map || !afhi || !afhi->header_len) {
*buf = NULL;
*/
void afh_free_header(char *header_buf, uint8_t audio_format_id)
{
*/
void afh_free_header(char *header_buf, uint8_t audio_format_id)
{
- struct audio_format_handler *afh = afl + audio_format_id;
+ struct audio_format_handler *afh = afl[audio_format_id];
if (afh->get_header)
free(header_buf);
if (afh->get_header)
free(header_buf);
int afh_rewrite_tags(int audio_format_id, void *map, size_t mapsize,
struct taginfo *tags, int output_fd, const char *filename)
{
int afh_rewrite_tags(int audio_format_id, void *map, size_t mapsize,
struct taginfo *tags, int output_fd, const char *filename)
{
- struct audio_format_handler *afh = afl + audio_format_id;
+ struct audio_format_handler *afh = afl[audio_format_id];
if (!afh->rewrite_tags)
return -ERRNO_TO_PARA_ERROR(ENOTSUP);
if (!afh->rewrite_tags)
return -ERRNO_TO_PARA_ERROR(ENOTSUP);
/** See \ref recv_init(). */
const struct receiver lsg_recv_cmd_com_afh_user_data = {
/** See \ref recv_init(). */
const struct receiver lsg_recv_cmd_com_afh_user_data = {
.open = afh_recv_open,
.close = afh_recv_close,
.pre_select = afh_recv_pre_select,
.open = afh_recv_open,
.close = afh_recv_close,
.pre_select = afh_recv_pre_select,
static const char * const flac_suffixes[] = {"flac", NULL};
/**
static const char * const flac_suffixes[] = {"flac", NULL};
/**
- * The init function of the flac audio format handler.
+ * The audio format handler for flac (free lossless audio decoder).
- * \param afh pointer to the struct to initialize
+ * It depends on libflac and on libogg.
-void flac_afh_init(struct audio_format_handler *afh)
-{
- afh->get_file_info = flac_get_file_info,
- afh->suffixes = flac_suffixes;
- afh->rewrite_tags = flac_rewrite_tags;
-}
+const struct audio_format_handler flac_afh = {
+ .get_file_info = flac_get_file_info,
+ .suffixes = flac_suffixes,
+ .rewrite_tags = flac_rewrite_tags,
+};
static const char * const 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_afh_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,
- afh->rewrite_tags = mp3_rewrite_tags;
+ .rewrite_tags = mp3_rewrite_tags,
#endif /* HAVE_LIBID3TAG */
#endif /* HAVE_LIBID3TAG */
static const char * const ogg_suffixes[] = {"ogg", NULL};
/**
static const char * const ogg_suffixes[] = {"ogg", NULL};
/**
- * The init function of the ogg vorbis audio format handler.
+ * The ogg vorbis audio format handler.
- * \param afh Pointer to the struct to initialize.
+ * It should actually be called vorbis because the ogg container format is also
+ * employed for the speex and flac codecs. Both the ogg and the vorbis
+ * libraries must be installed to get this audio format handler.
-void ogg_afh_init(struct audio_format_handler *afh)
-{
- afh->get_file_info = ogg_vorbis_get_file_info;
- afh->get_header = vorbis_get_header;
- afh->suffixes = ogg_suffixes;
- afh->rewrite_tags = vorbis_rewrite_tags;
-}
+const struct audio_format_handler ogg_afh = {
+ .get_file_info = ogg_vorbis_get_file_info,
+ .get_header = vorbis_get_header,
+ .suffixes = ogg_suffixes,
+ .rewrite_tags = vorbis_rewrite_tags
+};
- * The init function of the ogg/opus audio format handler.
+ * The audio format handler for ogg/opus.
- * \param afh Pointer to the struct to initialize.
+ * The opus codec was standardized by the Internet Engineering Task Force and
+ * is described in RFC 6716 (2012). The audio format handler depends on the ogg
+ * and the opus libraries.
-void opus_afh_init(struct audio_format_handler *afh)
-{
- afh->get_file_info = opus_get_file_info,
- afh->get_header = opus_get_header;
- afh->suffixes = opus_suffixes;
- afh->rewrite_tags = opus_rewrite_tags;
-}
+const struct audio_format_handler opus_afh = {
+ .get_file_info = opus_get_file_info,
+ .get_header = opus_get_header,
+ .suffixes = opus_suffixes,
+ .rewrite_tags = opus_rewrite_tags,
+};
sched.default_timeout.tv_sec = 5;
parse_config_or_die(argc, argv);
sched.default_timeout.tv_sec = 5;
parse_config_or_die(argc, argv);
session_open();
num_inputs = lls_num_inputs(play_lpr);
init_shuffle_map();
session_open();
num_inputs = lls_num_inputs(play_lpr);
init_shuffle_map();
init_ipc_or_die(); /* init mmd struct, mmd and log mutex */
daemon_set_start_time();
daemon_set_hooks(pre_log_hook, post_log_hook);
init_ipc_or_die(); /* init mmd struct, mmd and log mutex */
daemon_set_start_time();
daemon_set_hooks(pre_log_hook, post_log_hook);
- PARA_NOTICE_LOG("initializing audio format handlers\n");
- afh_init();
-
/*
* Although afs uses its own signal handling we must ignore SIGUSR1
* _before_ the afs child process gets born by init_afs() below. It's
/*
* Although afs uses its own signal handling we must ignore SIGUSR1
* _before_ the afs child process gets born by init_afs() below. It's
static const char * const speex_suffixes[] = {"spx", "speex", NULL};
/**
static const char * const speex_suffixes[] = {"spx", "speex", NULL};
/**
- * The init function of the ogg/speex audio format handler.
+ * The ogg/speex audio format handler.
- * \param afh Pointer to the struct to initialize.
+ * This codec is considered obsolete because the opus codec surpasses its
+ * performance in all areas. It is only compiled in if both the ogg and the
+ * speex library are installed.
-void spx_afh_init(struct audio_format_handler *afh)
-{
- afh->get_file_info = spx_get_file_info,
- afh->suffixes = speex_suffixes;
- afh->rewrite_tags = spx_rewrite_tags;
-}
+const struct audio_format_handler spx_afh = {
+ .get_file_info = spx_get_file_info,
+ .suffixes = speex_suffixes,
+ .rewrite_tags = spx_rewrite_tags,
+};
static const char * const wma_suffixes[] = {"wma", NULL};
/**
static const char * const wma_suffixes[] = {"wma", NULL};
/**
- * The init function of the wma audio format handler.
+ * The audio format handler for Windows Media Audio.
- * \param afh Pointer to the struct to initialize.
+ * Only WMA version 2 is supported. This audio format handler does not depend
+ * on any third party libraries and is therefore always compiled in.
-void wma_afh_init(struct audio_format_handler *afh)
-{
- afh->get_file_info = wma_get_file_info;
- afh->suffixes = wma_suffixes;
- afh->rewrite_tags = wma_rewrite_tags;
-}
+const struct audio_format_handler wma_afh = {
+ .get_file_info = wma_get_file_info,
+ .suffixes = wma_suffixes,
+ .rewrite_tags = wma_rewrite_tags,
+};