]> git.tuebingen.mpg.de Git - paraslash.git/commitdiff
Simplify mixer setup.
authorAndre Noll <maan@tuebingen.mpg.de>
Fri, 30 Dec 2016 23:06:10 +0000 (00:06 +0100)
committerAndre Noll <maan@tuebingen.mpg.de>
Sat, 1 Apr 2017 10:49:24 +0000 (12:49 +0200)
The ->init method of the two mixer implementations initialize the
members of the mixer structure. This structure contains only function
pointers. Their values, once set, never change.

Hence we may initialize the structure at compile time and make it
constant.

alsa_mix.c
configure.ac
mix.h
mixer.c
oss_mix.c

index 3adee929a804434fcea1999a439819dc85c66936..6520416fb83931ede15a299118a972f5893b2f34 100644 (file)
@@ -216,19 +216,13 @@ static int alsa_mix_set(struct mixer_handle *h, int val)
        return 1;
 }
 
        return 1;
 }
 
-/**
- * The init function of the ALSA mixer.
- *
- * \param self The structure to initialize.
- *
- * \sa struct \ref mixer, \ref oss_mix_init().
- */
-void alsa_mix_init(struct mixer *self)
-{
-       self->open = alsa_mix_open;
-       self->get_channels = alsa_mix_get_channels;
-       self->set_channel = alsa_mix_set_channel;
-       self->close = alsa_mix_close;
-       self->get = alsa_mix_get;
-       self->set = alsa_mix_set;
-}
+/** The mixer operations for the ALSA mixer. */
+const struct mixer alsa_mixer = {
+       .name = "alsa",
+       .open = alsa_mix_open,
+       .get_channels = alsa_mix_get_channels,
+       .set_channel = alsa_mix_set_channel,
+       .close = alsa_mix_close,
+       .get = alsa_mix_get,
+       .set = alsa_mix_set
+};
index 4fe45795be482644875d5010be2a8a9fa7fd5c13..b2ea0a72b2eda4548189d189c50ed24320002da9 100644 (file)
@@ -587,36 +587,12 @@ if test $HAVE_OSS = yes -o $HAVE_ALSA = yes; then
        mixer_errlist_objs="mixer exec string fd version"
        if test $HAVE_OSS = yes; then
                mixer_errlist_objs="$mixer_errlist_objs oss_mix"
        mixer_errlist_objs="mixer exec string fd version"
        if test $HAVE_OSS = yes; then
                mixer_errlist_objs="$mixer_errlist_objs oss_mix"
-               mixers="${mixers}oss "
-               default_mixer="OSS_MIX"
        fi
        if test $HAVE_ALSA = yes; then
                mixer_errlist_objs="$mixer_errlist_objs alsa_mix"
        fi
        if test $HAVE_ALSA = yes; then
                mixer_errlist_objs="$mixer_errlist_objs alsa_mix"
-               mixers="${mixers}alsa "
-               default_mixer="ALSA_MIX"
        fi
        mixer_objs="$mixer_errlist_objs"
        AC_SUBST(mixer_objs, add_dot_o($mixer_objs))
        fi
        mixer_objs="$mixer_errlist_objs"
        AC_SUBST(mixer_objs, add_dot_o($mixer_objs))
-       enum="$(
-               for i in $mixers; do
-                       printf "${i}_MIX, " | tr '[a-z]' '[A-Z]'
-               done
-       )"
-       AC_DEFINE_UNQUOTED(MIXER_ENUM, $enum NUM_SUPPORTED_MIXERS,
-               enum of supported mixers)
-       AC_DEFINE_UNQUOTED(DEFAULT_MIXER, $default_mixer,
-               use this mixer if none was specified)
-       names="$(for i in $mixers; do printf \"$i\",' ' ; done)"
-       AC_DEFINE_UNQUOTED(MIXER_NAMES, $names, supported mixer names)
-       inits="$(
-               for i in $mixers; do
-                       printf 'extern void '$i'_mix_init(struct mixer *); '
-               done
-       )"
-       AC_DEFINE_UNQUOTED(DECLARE_MIXER_INITS, $inits,
-               init functions of the supported mixers)
-       array="$(for i in $mixers; do printf '{.init = '$i'_mix_init},'; done)"
-       AC_DEFINE_UNQUOTED(MIXER_ARRAY, $array, array of supported mixers)
 else
        build_mixer="no"
        AC_MSG_WARN([no mixer support])
 else
        build_mixer="no"
        AC_MSG_WARN([no mixer support])
diff --git a/mix.h b/mix.h
index fe85d74622b03a25f2f527118777c646075936db..5d68b2bb0b34df798e38efad7b0ceeff687982fc 100644 (file)
--- a/mix.h
+++ b/mix.h
@@ -16,10 +16,14 @@ struct mixer_handle;
 
 /**
  * Operations provided by each mixer plugin.
 
 /**
  * Operations provided by each mixer plugin.
+ *
+ * Each mixer plugin must define a non-static instance of this structure, with
+ * all pointers initialized to non-NULL values. No other symbols need to be
+ * exported.
  */
 struct mixer {
  */
 struct mixer {
-       /** Called on startup, must fill in all other members. */
-       void (*init)(struct mixer *self);
+       /** Used to identify the mixer. */
+       const char * const name;
        /** Return a handle that can be passed to other methods. */
        int (*open)(const char *dev, struct mixer_handle **handle);
        /** Returns a string of all valid mixer channels. */
        /** Return a handle that can be passed to other methods. */
        int (*open)(const char *dev, struct mixer_handle **handle);
        /** Returns a string of all valid mixer channels. */
@@ -34,3 +38,6 @@ struct mixer {
        /** Free all resources associated with the given handle. */
        void (*close)(struct mixer_handle **handle);
 };
        /** Free all resources associated with the given handle. */
        void (*close)(struct mixer_handle **handle);
 };
+
+/** Declared even if unsupported because it does not hurt and avoids ifdefs. */
+extern const struct mixer alsa_mixer, oss_mixer;
diff --git a/mixer.c b/mixer.c
index d33fa831c9c3ba2cdc29c1ab3609795ab49bba16..0c08e2f6d0ab24f35334aa9961bb2f143e656235 100644 (file)
--- a/mixer.c
+++ b/mixer.c
 /** Array of error strings. */
 DEFINE_PARA_ERRLIST;
 
 /** Array of error strings. */
 DEFINE_PARA_ERRLIST;
 
-enum mixer_id {MIXER_ENUM};
-static char *mixer_name[] = {MIXER_NAMES};
-DECLARE_MIXER_INITS;
-static struct mixer supported_mixer[] = {MIXER_ARRAY};
+/* At least one of the two is defined if this file gets compiled. */
+static const struct mixer *mixers[] = {
+#ifdef HAVE_ALSA
+       &alsa_mixer,
+#endif
+#ifdef HAVE_OSS
+       &oss_mixer,
+#endif
+};
+
+#define NUM_SUPPORTED_MIXERS (ARRAY_SIZE(mixers))
 #define FOR_EACH_MIXER(i) for ((i) = 0; (i) < NUM_SUPPORTED_MIXERS; (i)++)
 
 static struct lls_parse_result *lpr, *sub_lpr;
 #define FOR_EACH_MIXER(i) for ((i) = 0; (i) < NUM_SUPPORTED_MIXERS; (i)++)
 
 static struct lls_parse_result *lpr, *sub_lpr;
@@ -36,7 +43,7 @@ static struct lls_parse_result *lpr, *sub_lpr;
 #define OPT_STRING_VAL(_cmd, _opt) (lls_string_val(0, OPT_RESULT(_cmd, _opt)))
 #define OPT_UINT32_VAL(_cmd, _opt) (lls_uint32_val(0, OPT_RESULT(_cmd, _opt)))
 
 #define OPT_STRING_VAL(_cmd, _opt) (lls_string_val(0, OPT_RESULT(_cmd, _opt)))
 #define OPT_UINT32_VAL(_cmd, _opt) (lls_uint32_val(0, OPT_RESULT(_cmd, _opt)))
 
-typedef int (*mixer_subcommand_handler_t)(struct mixer *, struct mixer_handle *);
+typedef int (*mixer_subcommand_handler_t)(const struct mixer *, struct mixer_handle *);
 
 #define EXPORT_CMD(_cmd) const mixer_subcommand_handler_t \
        lsg_mixer_com_ ## _cmd ## _user_data = &com_ ## _cmd;
 
 #define EXPORT_CMD(_cmd) const mixer_subcommand_handler_t \
        lsg_mixer_com_ ## _cmd ## _user_data = &com_ ## _cmd;
@@ -59,7 +66,8 @@ static __printf_2_3 void date_log(int ll, const char *fmt, ...)
 }
 __printf_2_3 void (*para_log)(int, const char*, ...) = date_log;
 
 }
 __printf_2_3 void (*para_log)(int, const char*, ...) = date_log;
 
-static int set_channel(struct mixer *m, struct mixer_handle *h, const char *channel)
+static int set_channel(const struct mixer *m, struct mixer_handle *h,
+               const char *channel)
 {
 
        PARA_NOTICE_LOG("using %s mixer channel\n", channel?
 {
 
        PARA_NOTICE_LOG("using %s mixer channel\n", channel?
@@ -106,7 +114,7 @@ static unsigned volume_time(double vol, double old_vol, double new_vol,
 }
 
 /* Fade to new volume in fade_time seconds. */
 }
 
 /* Fade to new volume in fade_time seconds. */
-static int fade(struct mixer *m, struct mixer_handle *h, uint32_t new_vol,
+static int fade(const struct mixer *m, struct mixer_handle *h, uint32_t new_vol,
                uint32_t fade_time)
 {
        int i, T, old_vol, ret, slept, incr;
                uint32_t fade_time)
 {
        int i, T, old_vol, ret, slept, incr;
@@ -148,7 +156,7 @@ sleep:
        return ret;
 }
 
        return ret;
 }
 
-static int com_fade(struct mixer *m, struct mixer_handle *h)
+static int com_fade(const struct mixer *m, struct mixer_handle *h)
 {
        uint32_t new_vol = OPT_UINT32_VAL(FADE, FADE_VOL);
        uint32_t fade_time = OPT_UINT32_VAL(FADE, FADE_TIME);
 {
        uint32_t new_vol = OPT_UINT32_VAL(FADE, FADE_VOL);
        uint32_t fade_time = OPT_UINT32_VAL(FADE, FADE_TIME);
@@ -196,7 +204,7 @@ static void change_afs_mode(const char *afs_mode)
        free(cmd);
 }
 
        free(cmd);
 }
 
-static int set_initial_volume(struct mixer *m, struct mixer_handle *h)
+static int set_initial_volume(const struct mixer *m, struct mixer_handle *h)
 {
        int i, ret;
 
 {
        int i, ret;
 
@@ -235,7 +243,7 @@ static int set_initial_volume(struct mixer *m, struct mixer_handle *h)
        return 1;
 }
 
        return 1;
 }
 
-static int com_sleep(struct mixer *m, struct mixer_handle *h)
+static int com_sleep(const struct mixer *m, struct mixer_handle *h)
 {
        time_t t1, wake_time_epoch;
        unsigned int delay;
 {
        time_t t1, wake_time_epoch;
        unsigned int delay;
@@ -328,7 +336,7 @@ static int com_sleep(struct mixer *m, struct mixer_handle *h)
 }
 EXPORT_CMD(sleep);
 
 }
 EXPORT_CMD(sleep);
 
-static int com_snooze(struct mixer *m, struct mixer_handle *h)
+static int com_snooze(const struct mixer *m, struct mixer_handle *h)
 {
        int ret, val;
 
 {
        int ret, val;
 
@@ -355,44 +363,31 @@ static int com_snooze(struct mixer *m, struct mixer_handle *h)
 }
 EXPORT_CMD(snooze);
 
 }
 EXPORT_CMD(snooze);
 
-static void init_mixers(void)
-{
-       int i;
-
-       FOR_EACH_MIXER(i) {
-               struct mixer *m = &supported_mixer[i];
-               PARA_DEBUG_LOG("initializing mixer API #%d (%s)\n",
-                       i, mixer_name[i]);
-               m->init(m);
-       }
-}
-
-static int com_set(struct mixer *m, struct mixer_handle *h)
+static int com_set(const struct mixer *m, struct mixer_handle *h)
 {
        return m->set(h, OPT_UINT32_VAL(SET, VAL));
 }
 EXPORT_CMD(set);
 
 {
        return m->set(h, OPT_UINT32_VAL(SET, VAL));
 }
 EXPORT_CMD(set);
 
-static struct mixer *get_mixer_or_die(void)
+static const struct mixer *get_mixer_or_die(void)
 {
        int i;
 
        if (!OPT_GIVEN(PARA_MIXER, MIXER_API))
 {
        int i;
 
        if (!OPT_GIVEN(PARA_MIXER, MIXER_API))
-               i = DEFAULT_MIXER;
+               i = 0; /* default: use first mixer */
        else
                FOR_EACH_MIXER(i)
        else
                FOR_EACH_MIXER(i)
-                       if (!strcmp(mixer_name[i],
+                       if (!strcmp(mixers[i]->name,
                                        OPT_STRING_VAL(PARA_MIXER, MIXER_API)))
                                break;
        if (i < NUM_SUPPORTED_MIXERS) {
                                        OPT_STRING_VAL(PARA_MIXER, MIXER_API)))
                                break;
        if (i < NUM_SUPPORTED_MIXERS) {
-               PARA_NOTICE_LOG("using %s mixer API\n", mixer_name[i]);
-               return supported_mixer + i;
+               PARA_NOTICE_LOG("using %s mixer API\n", mixers[i]->name);
+               return mixers[i];
        }
        printf("available mixer APIs: ");
        }
        printf("available mixer APIs: ");
-       FOR_EACH_MIXER(i) {
-               int d = (i == DEFAULT_MIXER);
-               printf("%s%s%s ", d? "[" : "", mixer_name[i], d? "]" : "");
-       }
+       FOR_EACH_MIXER(i)
+               printf("%s%s%s ", i == 0? "[" : "", mixers[i]->name,
+                       i == 0? "]" : "");
        printf("\n");
        exit(EXIT_FAILURE);
 }
        printf("\n");
        exit(EXIT_FAILURE);
 }
@@ -410,7 +405,8 @@ static void show_subcommands(void)
 }
 
 
 }
 
 
-static int com_help(__a_unused struct mixer *m, __a_unused struct mixer_handle *h)
+static int com_help(__a_unused const struct mixer *m,
+               __a_unused struct mixer_handle *h)
 {
        const struct lls_command *cmd;
        const struct lls_opt_result *r_l = OPT_RESULT(HELP, LONG);
 {
        const struct lls_command *cmd;
        const struct lls_opt_result *r_l = OPT_RESULT(HELP, LONG);
@@ -536,7 +532,7 @@ int main(int argc, char *argv[])
        int ret;
        char *errctx;
        const char *subcmd;
        int ret;
        char *errctx;
        const char *subcmd;
-       struct mixer *m;
+       const struct mixer *m;
        struct mixer_handle *h;
        unsigned n;
 
        struct mixer_handle *h;
        unsigned n;
 
@@ -567,7 +563,6 @@ int main(int argc, char *argv[])
        ret = parse_and_merge_config_file(cmd);
        if (ret < 0)
                goto free_lpr;
        ret = parse_and_merge_config_file(cmd);
        if (ret < 0)
                goto free_lpr;
-       init_mixers();
        m = get_mixer_or_die();
        ret = m->open(OPT_STRING_VAL(PARA_MIXER, MIXER_DEVICE), &h);
        if (ret < 0)
        m = get_mixer_or_die();
        ret = m->open(OPT_STRING_VAL(PARA_MIXER, MIXER_DEVICE), &h);
        if (ret < 0)
index 8e87452b816e68f03f0931e79efe007d7491b6c8..7fbdba5b770923988e646b96e74582f8ff4e8a1f 100644 (file)
--- a/oss_mix.c
+++ b/oss_mix.c
@@ -135,19 +135,13 @@ static void oss_mix_close(struct mixer_handle **handle)
        *handle = NULL;
 }
 
        *handle = NULL;
 }
 
-/**
- * The init function of the OSS mixer.
- *
- * \param self The structure to initialize.
- *
- * \sa struct \ref mixer, \ref alsa_mix_init().
- */
-void oss_mix_init(struct mixer *self)
-{
-       self->open = oss_mix_open;
-       self->get_channels = oss_mix_get_channels;
-       self->set_channel = oss_mix_set_channel;
-       self->get = oss_mix_get;
-       self->set = oss_mix_set;
-       self->close = oss_mix_close;
-}
+/** The mixer operations for the OSS mixer. */
+const struct mixer oss_mixer = {
+       .name = "oss",
+       .open = oss_mix_open,
+       .get_channels = oss_mix_get_channels,
+       .set_channel = oss_mix_set_channel,
+       .close = oss_mix_close,
+       .get = oss_mix_get,
+       .set = oss_mix_set
+};