]> git.tuebingen.mpg.de Git - paraslash.git/commitdiff
Merge branch 'refs/heads/t/ONESHELL'
authorAndre Noll <maan@tuebingen.mpg.de>
Sun, 8 Sep 2019 09:07:45 +0000 (11:07 +0200)
committerAndre Noll <maan@tuebingen.mpg.de>
Sun, 8 Sep 2019 09:09:02 +0000 (11:09 +0200)
A single patch which instructs the build system to run multi-line
statements in Makefiles in a single shell instance.

Cooking in next for nine months.

* refs/heads/t/ONESHELL:
  build: Use .ONESHELL.

40 files changed:
Makefile.real
NEWS.md
aac_afh.c
afh.c
afh.h
afh_common.c
afh_recv.c
afs.c
afs.h
aft.c
audiod.c
command.c
compress_filter.c
daemon.c
dccp_recv.c
error.h
flac_afh.c
http_recv.c
interactive.c
ipc.c
m4/lls/afh.suite.m4
m4/lls/filter_cmd.suite.m4
m4/lls/play.suite.m4
m4/lls/server_cmd.suite.m4
mixer.c
mp3_afh.c
ogg_afh.c
opus_afh.c
play.c
recv.c
recv.h
recv_common.c
server.c
spx_afh.c
string.c
udp_recv.c
vss.c
web/about.in.html
web/manual.md
wma_afh.c

index c8d30aae7f6d2171e8c45bc037da88512562f92b..7d4eff4fe2eaecc99fb83627a154b9c1672118ca 100644 (file)
@@ -20,7 +20,7 @@ uname_s := $(shell uname -s 2>/dev/null || echo "UNKNOWN_OS")
 uname_rs := $(shell uname -rs)
 cc_version := $(shell $(CC) --version | head -n 1)
 GIT_VERSION := $(shell ./GIT-VERSION-GEN git-version.h)
-COPYRIGHT_YEAR := 2018
+COPYRIGHT_YEAR := 2019
 
 ifeq ("$(origin O)", "command line")
        build_dir := $(O)
@@ -112,7 +112,6 @@ CPPFLAGS += -DBUILD_DATE='"$(build_date)"'
 CPPFLAGS += -DLOGLEVELS='$(LOGLEVELS)'
 CPPFLAGS += -DUNAME_RS='"$(uname_rs)"'
 CPPFLAGS += -DCC_VERSION='"$(cc_version)"'
-CPPFLAGS += -I/usr/local/include
 CPPFLAGS += -I$(lls_suite_dir)
 CPPFLAGS += -I$(yy_build_dir)
 CPPFLAGS += $(lopsub_cppflags)
@@ -193,7 +192,7 @@ $(object_dir)/spx%.o: CPPFLAGS += $(speex_cppflags)
 $(object_dir)/flac%.o: CPPFLAGS += $(flac_cppflags)
 
 $(object_dir)/mp3_afh.o: CPPFLAGS += $(id3tag_cppflags)
-$(object_dir)/crypt.o: CPPFLAGS += $(openssl_cppflags)
+$(object_dir)/openssl.o: CPPFLAGS += $(openssl_cppflags)
 $(object_dir)/gcrypt.o: CPPFLAGS += $(gcrypt_cppflags)
 $(object_dir)/ao_write.o: CPPFLAGS += $(ao_cppflags)
 $(object_dir)/alsa%.o: CPPFLAGS += $(alsa_cppflags)
diff --git a/NEWS.md b/NEWS.md
index 55ef3be947ee76d6b0937b33988b0cd960c0e985..bbe200102627b929907a78ff5a14792cdc45f720 100644 (file)
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,6 +1,24 @@
 NEWS
 ====
 
+----------------------------------------------
+0.6.3 (to be announced) "generalized activity"
+----------------------------------------------
+
+- The ff command now accepts a negative argument to instruct the
+  virtual streaming system to jump backwards in the current audio
+  stream. The old syntax (e.g., "ff 30-") is still supported but it
+  is deprecated and no longer documented. The compatibility code is
+  sheduled for removal after 0.7.0.
+- para_afh: New option: --preserve to reset the modification time to
+  the value of the original file after meta data modification.
+- Overhaul of the compress filter code. The refined algorithm should
+  reduce clipping. The meaning of --aggressiveness has changed, see the
+  updated and extended documentation of the compress filter for details.
+- Cleanup of the audio format handler code.
+- We now build the tree using the .ONESHELL feature of GNU make,
+  which results in a significant speedup.
+
 --------------------------------------
 0.6.2 (2018-06-30) "elastic diversity"
 --------------------------------------
index 3315a42d57a5ea9673be88b077daef1275ab49f6..7f2a22a223ce733aa4b49d0a60ff63d1b95bf321 100644 (file)
--- a/aac_afh.c
+++ b/aac_afh.c
@@ -333,17 +333,17 @@ close:
 }
 
 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,
+};
diff --git a/afh.c b/afh.c
index aa6570e1abc33bfe38e9ce87bf87316707263473..567b560a038f0923a663005b447a0fc688c57b2a 100644 (file)
--- a/afh.c
+++ b/afh.c
@@ -113,6 +113,24 @@ static int rewrite_tags(const char *name, int input_fd, void *map,
                        goto out;
        }
        ret = xrename(tmp_name, name);
+       if (ret < 0)
+               goto out;
+       if (OPT_GIVEN(PRESERVE)) {
+               struct timespec times[2]; /* [0]: atime, [1]: mtime */
+               times[0].tv_nsec = UTIME_OMIT;
+               times[1] = sb.st_mtim;
+               /*
+                * We might well have written a file of identical size. If we
+                * keep the mtime as well, we might fool backup applications
+                * like rsync which skip files whose size and mtime haven't
+                * changed. So we change the mtime slightly.
+                */
+               times[1].tv_sec++;
+               if (futimens(output_fd, times) < 0) {
+                       ret = -ERRNO_TO_PARA_ERROR(errno);
+                       goto out;
+               }
+       }
 out:
        if (ret < 0 && output_fd >= 0)
                unlink(tmp_name); /* ignore errors */
@@ -203,7 +221,6 @@ int main(int argc, char **argv)
        loglevel = OPT_UINT32_VAL(LOGLEVEL);
        version_handle_flag("afh", OPT_GIVEN(VERSION));
        handle_help_flags();
-       afh_init();
        for (i = 0; i < lls_num_inputs(lpr); i++) {
                int ret2;
                const char *path = lls_input(i, lpr);
diff --git a/afh.h b/afh.h
index d2ac93aec96f95a0ca0bf706327f831520145ee7..881db3c24217beff8d2885e1d62c05f3419aa404 100644 (file)
--- a/afh.h
+++ b/afh.h
@@ -80,14 +80,6 @@ struct audio_file_data {
  * in the other part of this struct.
  */
 struct audio_format_handler {
-       /** Name of the audio format. */
-       const char *name;
-       /**
-        * 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;
        /**
@@ -135,7 +127,6 @@ struct audio_format_handler {
                int output_fd, const char *filename);
 };
 
-void afh_init(void);
 int guess_audio_format(const char *name);
 int compute_afhi(const char *path, char *data, size_t size,
        int fd, struct afh_info *afhi);
index bab4d41577952f257ef8c828f9c89c8886a7d2e5..a267f58b106b9f0df09d3a8dad99368c3c519401 100644 (file)
 #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 supported audio formats.
+ * For each audio file the number of its audio format is stored in the
+ * database. Therefore this list, in particular its order, is part of the ABI.
+ * So it's only OK to append new audio formats. All audio formats are listed
+ * here, regardless of whether the audio format handler is compiled in.
+ */
+#define ALL_AUDIO_FORMATS \
+       AUDIO_FORMAT(mp3) \
+       AUDIO_FORMAT(ogg) \
+       AUDIO_FORMAT(aac) \
+       AUDIO_FORMAT(wma) \
+       AUDIO_FORMAT(spx) \
+       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
+/* 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))
+/** \endcond audio_format_handler */
+
+/**
+ * Get the name of the given audio format.
  *
- * We always define the full array of audio formats even if some audio formats
- * were not compiled in. This is because for each audio file the number of its
- * audio format is stored in the database. We don't want these numbers to become
- * stale just because the user installed a new version of paraslash that
- * supports a different set of audio formats.
+ * \param i The audio format number.
  *
- * It can still be easily detected whether an audio format is compiled in by
- * checking if the init function pointer is not \p NULL.
+ * \return This returns a pointer to statically allocated memory so it
+ * must not be freed by the caller.
  */
-static struct audio_format_handler afl[] = {
-       {
-               .name = "mp3",
-               .init = mp3_afh_init,
-       },
-       {
-               .name = "ogg",
-#if defined(HAVE_OGG) && defined(HAVE_VORBIS)
-               .init = ogg_afh_init,
-#endif
-       },
-       {
-               .name = "aac",
-#if defined(HAVE_FAAD)
-               .init = aac_afh_init,
-#endif
-       },
-       {
-               .name = "wma",
-               .init = wma_afh_init,
-       },
-       {
-               .name = "spx",
-#if defined(HAVE_OGG) && defined(HAVE_SPEEX)
-               .init = spx_afh_init,
-#endif
-       },
-       {
-               .name = "flac",
-#if defined(HAVE_OGG) && defined(HAVE_FLAC)
-               .init = flac_afh_init,
-#endif
-       },
-       {
-               .name = "opus",
-#if defined(HAVE_OGG) && defined(HAVE_OPUS)
-               .init = opus_afh_init,
-#endif
-       },
-       {
-               .name = NULL,
-       }
-};
+const char *audio_format_name(int i)
+{
+       if (i < 0 || i >= NUM_AUDIO_FORMATS)
+               return "???";
+       return audio_format_names[i];
+}
 
 static inline int next_audio_format(int format)
 {
        for (;;) {
-               if (!afl[format].name)
-                       return format;
                format++;
-               if (afl[format].init)
+               if (format >= NUM_AUDIO_FORMATS)
+                       return format;
+               if (afl[format]->get_file_info)
                        return format;
        }
 }
 
 /** Iterate over each supported audio format. */
-#define FOR_EACH_AUDIO_FORMAT(i) for (i = 0; afl[i].name; 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]);
-       }
-}
+#define FOR_EACH_AUDIO_FORMAT(i) \
+       for (i = 0; i < NUM_AUDIO_FORMATS; i = next_audio_format(i))
 
 /**
  * Tell whether an audio format handler provides chunk tables.
@@ -127,7 +88,7 @@ void afh_init(void)
  */
 bool afh_supports_dynamic_chunks(int audio_format_id)
 {
-       return afl[audio_format_id].get_chunk;
+       return afl[audio_format_id]->get_chunk;
 }
 
 /**
@@ -144,8 +105,8 @@ int guess_audio_format(const char *name)
        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;
@@ -160,21 +121,6 @@ int guess_audio_format(const char *name)
        return -E_AUDIO_FORMAT;
 }
 
-/**
- * Get the name of the given audio format.
- *
- * \param i The audio format number.
- *
- * \return This returns a pointer to statically allocated memory so it
- * must not be freed by the caller.
- */
-const char *audio_format_name(int i)
-{
-       if (i < 0 || i >= ARRAY_SIZE(afl) - 1)
-               return "???";
-       return afl[i].name;
-}
-
 static int get_file_info(int format, const char *path, char *data,
                size_t size, int fd, struct afh_info *afhi)
 {
@@ -182,7 +128,7 @@ static int get_file_info(int format, const char *path, char *data,
        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));
@@ -303,7 +249,7 @@ __must_check int afh_get_chunk(long unsigned chunk_num, struct afh_info *afhi,
                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;
@@ -313,7 +259,7 @@ __must_check int afh_get_chunk(long unsigned chunk_num, struct afh_info *afhi,
                        if (ret < 0)
                                return ret;
                }
-               ret = afl[audio_format_id].get_chunk(chunk_num, *afh_context,
+               ret = afh->get_chunk(chunk_num, *afh_context,
                        buf, len);
                if (ret < 0) {
                        afh->close(*afh_context);
@@ -340,7 +286,7 @@ __must_check int afh_get_chunk(long unsigned chunk_num, struct afh_info *afhi,
  */
 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;
@@ -403,7 +349,7 @@ int32_t afh_get_start_chunk(int32_t approx_chunk_num,
 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;
@@ -426,7 +372,7 @@ void afh_get_header(struct afh_info *afhi, 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);
@@ -530,7 +476,7 @@ void set_max_chunk_size(struct afh_info *afhi)
 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);
index 6525209bff4119a177eb443f154b4f1f5224845b..4f8ff4974f018ef92e5055ac7a28bf337e3aa301 100644 (file)
@@ -238,9 +238,7 @@ out:
        return ret;
 }
 
-/** See \ref recv_init(). */
 const struct receiver lsg_recv_cmd_com_afh_user_data = {
-       .init = afh_init,
        .open = afh_recv_open,
        .close = afh_recv_close,
        .pre_select = afh_recv_pre_select,
diff --git a/afs.c b/afs.c
index 4fe2140be607effea9d5c0a17c1eec8f41011b59..d9cddeb87b356103164bee70ddf2534122c7923a 100644 (file)
--- a/afs.c
+++ b/afs.c
@@ -589,8 +589,9 @@ static int com_select_callback(struct afs_callback_arg *aca)
        para_printf(&aca->pbout, "activating dummy mood\n");
        activate_mood_or_playlist(NULL, &num_admissible, NULL);
 out:
-       para_printf(&aca->pbout, "activated %s (%d admissible files)\n",
-               current_mop? current_mop : "dummy mood", num_admissible);
+       para_printf(&aca->pbout, "activated %s (%d admissible file%s)\n",
+               current_mop? current_mop : "dummy mood", num_admissible,
+                       num_admissible == 1? "" : "s");
 free_lpr:
        lls_free_parse_result(aca->lpr, cmd);
        return ret;
diff --git a/afs.h b/afs.h
index b0d283f626af87321bc405bceef8fa50036a9a59..cfa9cc6df4c11900739e9ff90fba0c4b30bf16e8 100644 (file)
--- a/afs.h
+++ b/afs.h
@@ -285,10 +285,12 @@ int playlist_check_callback(struct afs_callback_arg *aca);
                struct para_buffer *pb, void *data); \
        extern struct osl_table *table_name ## _table;
 
+/** \cond blob_symbols */
 DECLARE_BLOB_SYMBOLS(lyrics, lyr);
 DECLARE_BLOB_SYMBOLS(images, img);
 DECLARE_BLOB_SYMBOLS(moods, mood);
 DECLARE_BLOB_SYMBOLS(playlists, pl);
+/** \endcond blob_symbols */
 
 /** The columns of an abstract blob table. */
 enum blob_table_columns {
diff --git a/aft.c b/aft.c
index 0db2c5803dfa4c100b092f9c022759f1b85e043b..c04d4f9c99e89afb451afe94be7fcc64461b15e1 100644 (file)
--- a/aft.c
+++ b/aft.c
@@ -396,7 +396,7 @@ static void save_chunk_table(struct afh_info *afhi, char *buf)
 {
        uint32_t n;
 
-       if (!afhi->chunk_table)
+       if (!afhi->chunk_table || afhi->chunks_total == 0)
                return;
        for (n = 0; n <= afhi->chunks_total; n++)
                write_u32(buf + 4 * n, afhi->chunk_table[n]);
index b93f29de4498c50f574e55c4c8b3e9a34dfe0aee..a5a774376b37c50eba92a76a02b1389bd6df67f4 100644 (file)
--- a/audiod.c
+++ b/audiod.c
@@ -1451,7 +1451,6 @@ int main(int argc, char *argv[])
        parse_config_or_die();
        crypt_init();
        daemon_set_priority(OPT_UINT32_VAL(PRIORITY));
-       recv_init();
        if (daemon_init_colors_or_die(OPT_UINT32_VAL(COLOR), COLOR_AUTO,
                        COLOR_NO, OPT_GIVEN(LOGFILE))) {
                for (i = 0; i < OPT_GIVEN(LOG_COLOR); i++)
index 67f6bf3c713b5de3d542d96f63848cb0014326dc..481fd0f637352fb21ff97536d426ece42ec0fda3 100644 (file)
--- a/command.c
+++ b/command.c
@@ -663,8 +663,7 @@ EXPORT_SERVER_CMD_HANDLER(nomore);
 static int com_ff(struct command_context *cc, struct lls_parse_result *lpr)
 {
        long promille;
-       int ret, backwards = 0;
-       unsigned i;
+       int i, ret;
        char c, *errctx;
 
        ret = lls(lls_check_arg_count(lpr, 1, 1, &errctx));
@@ -672,20 +671,33 @@ static int com_ff(struct command_context *cc, struct lls_parse_result *lpr)
                send_errctx(cc, errctx);
                return ret;
        }
-       if (!(ret = sscanf(lls_input(0, lpr), "%u%c", &i, &c)))
-               return -E_COMMAND_SYNTAX;
-       if (ret > 1 && c == '-')
-               backwards = 1; /* jmp backwards */
+       ret = para_atoi32(lls_input(0, lpr), &i);
+       if (ret < 0) {
+               if (ret != -E_ATOI_JUNK_AT_END)
+                       return ret;
+               /*
+                * Compatibility code to keep the historic syntax (ff 30-)
+                * working. This can be removed after 0.7.0.
+                */
+               ret = sscanf(lls_input(0, lpr), "%i%c", &i, &c);
+               if (ret <= 0)
+                       return -E_COMMAND_SYNTAX;
+               if (ret > 1 && c == '-') {
+                       PARA_WARNING_LOG("use of obsolete syntax\n");
+                       i = -i;
+               }
+       }
        mutex_lock(mmd_mutex);
        ret = -E_NO_AUDIO_FILE;
        if (!mmd->afd.afhi.chunks_total || !mmd->afd.afhi.seconds_total)
                goto out;
        ret = 1;
        promille = (1000 * mmd->current_chunk) / mmd->afd.afhi.chunks_total;
-       if (backwards)
-               promille -= 1000 * i / mmd->afd.afhi.seconds_total;
-       else
-               promille += 1000 * i / mmd->afd.afhi.seconds_total;
+       /*
+        * We need this cast because without it the expression on the right
+        * hand side is of unsigned type.
+        */
+       promille += 1000 * i / (int)mmd->afd.afhi.seconds_total;
        if (promille < 0)
                promille = 0;
        if (promille > 1000) {
index 69a982ef5a3aff20a10fcebe468a1af5efd33ba4..15bed6dfa33c896421ab17a89ec426669cf4b025 100644 (file)
@@ -48,8 +48,7 @@ static int compress_post_select(__a_unused struct sched *s, void *context)
        size_t length, i;
        int16_t *ip, *op;
        uint32_t inertia = U32_OPTVAL(INERTIA, fn->lpr);
-       unsigned gain_shift = inertia + U32_OPTVAL(DAMP, fn->lpr),
-               mask = (1U << U32_OPTVAL(BLOCKSIZE, fn->lpr)) - 1U;
+       unsigned mask = (1U << U32_OPTVAL(BLOCKSIZE, fn->lpr)) - 1U;
        //inplace = false;
 next_buffer:
        ret = btr_node_status(btrn, fn->min_iqs, BTR_NT_INTERNAL);
@@ -78,19 +77,22 @@ next_buffer:
                        neg = true;
                }
                sample *= pcd->current_gain;
-               sample >>= gain_shift;
+               sample >>= inertia + 1;
                if (sample > 32767) { /* clip */
+                       PARA_WARNING_LOG("clip: %d\n", sample);
                        sample = 32767;
                        pcd->current_gain = (3 * pcd->current_gain +
                                (1 << inertia)) / 4;
                        pcd->peak = 0;
                } else if (sample > pcd->peak)
                        pcd->peak = sample;
+               sample >>= U32_OPTVAL(DAMP, fn->lpr);
                op[i] = neg? -sample : sample;
                if (++pcd->num_samples & mask)
                        continue;
 //             PARA_DEBUG_LOG("gain: %u, peak: %u\n", pcd->current_gain,
 //                     pcd->peak);
+
                if (pcd->peak < U32_OPTVAL(TARGET_LEVEL, fn->lpr)) {
                        if (pcd->current_gain < pcd->max_gain)
                                pcd->current_gain++;
@@ -121,10 +123,43 @@ static void compress_open(struct filter_node *fn)
        fn->private_data = pcd;
        fn->min_iqs = 2; /* 16 bit audio */
        pcd->current_gain = 1U << inertia;
-       pcd->max_gain = 1U << (inertia + aggressiveness);
+       pcd->max_gain = (1U << inertia) * (1.0 + 3.0 * aggressiveness / 10.0);
+}
+
+static void *compress_setup(const struct lls_parse_result *lpr)
+{
+       uint32_t val;
+
+       val = U32_OPTVAL(BLOCKSIZE, lpr);
+       if (val == 0 || val > 31) {
+               PARA_EMERG_LOG("blocksize (%u) out of range\n", val);
+               exit(EXIT_FAILURE);
+       }
+       val = U32_OPTVAL(AGGRESSIVENESS, lpr);
+       if (val > 10) {
+               PARA_EMERG_LOG("aggressiveness (%u) out of range\n", val);
+               exit(EXIT_FAILURE);
+       }
+       val = U32_OPTVAL(INERTIA, lpr);
+       if (val == 0 || val > 14) {
+               PARA_EMERG_LOG("inertia (%u) out of range\n", val);
+               exit(EXIT_FAILURE);
+       }
+       val = U32_OPTVAL(TARGET_LEVEL, lpr);
+       if (val > 32767) {
+               PARA_EMERG_LOG("target-level (%u) out of range\n", val);
+               exit(EXIT_FAILURE);
+       }
+       val = U32_OPTVAL(DAMP, lpr);
+       if (val > 16) {
+               PARA_EMERG_LOG("damp (%u) out of range\n", val);
+               exit(EXIT_FAILURE);
+       }
+       return NULL; /* no need for a config structure */
 }
 
 const struct filter lsg_filter_cmd_com_compress_user_data = {
+       .setup = compress_setup,
        .open = compress_open,
        .close = compress_close,
        .pre_select = generic_filter_pre_select,
index bfa81487430f62dc7417db6ba6e0c6d53c008051..a4e2f3193730d456ce9908eb55888cdb759154e0 100644 (file)
--- a/daemon.c
+++ b/daemon.c
@@ -146,6 +146,22 @@ void daemon_set_loglevel(const char *loglevel)
        me->loglevel = ret;
 }
 
+/**
+ * Register functions to be called before and after a message is logged.
+ *
+ * \param pre_log_hook Called before the message is logged.
+ * \param post_log_hook Called after the message is logged.
+ *
+ * The purpose of this function is to provide a primitive for multi-threaded
+ * applications to serialize the access to the log facility, preventing
+ * interleaving log messages. This can be achieved by having the pre-log hook
+ * acquire a lock which blocks the other threads on the attempt to log a
+ * message at the same time.  The post-log hook is responsible for releasing
+ * the lock.
+ *
+ * If these hooks are unnecessary, for example because the application is
+ * single-threaded, this function does not need to be called.
+ */
 void daemon_set_hooks(void (*pre_log_hook)(void), void (*post_log_hook)(void))
 {
        me->pre_log_hook = pre_log_hook;
index 8a08504a8930de6a0f3f3a89969357eadf6a7c9f..639c93fcbf99bc93ddc054ad43d03f30811270ac 100644 (file)
@@ -151,7 +151,6 @@ out:
        return ret;
 }
 
-/** See \ref recv_init(). */
 const struct receiver lsg_recv_cmd_com_dccp_user_data = {
        .open = dccp_recv_open,
        .close = dccp_recv_close,
diff --git a/error.h b/error.h
index c06d316d75c19b306ce509d04f43866fbf392b7a..8f4f9bb134027956fbd438cd102be3fe5d1bea7e 100644 (file)
--- a/error.h
+++ b/error.h
 enum para_error_codes {PARA_ERRORS};
 #undef PARA_ERROR
 #define PARA_ERROR(err, msg) msg
-/** Array of error strings. */
+/** All .c files need the declararation of the array of error strings. */
 extern const char * const para_errlist[];
+/** Exactly one .c file per executable must define the array. */
 #define DEFINE_PARA_ERRLIST const char * const para_errlist[] = {PARA_ERRORS}
 
 /**
index 45373ea1993d743ed56ded45444b3d8bb72fc751..6e23683937f6932aaa739095ef8281fc9075da55 100644 (file)
@@ -515,13 +515,12 @@ free_pfad:
 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,
+};
index 3a723299e78b241a9ac4f44a13caf91651f36b6a..1fb60bad810d86dbbb0098a3714c2caa3d9e835b 100644 (file)
@@ -167,7 +167,6 @@ static int http_recv_open(struct receiver_node *rn)
        return 1;
 }
 
-/** See \ref recv_init(). */
 const struct receiver lsg_recv_cmd_com_http_user_data = {
        .open = http_recv_open,
        .close = http_recv_close,
index 190cdf295130a2d711074e7c5f5927174b312076..a8197308e8323c8fe78546117cc2e9479df0fbfd 100644 (file)
@@ -762,17 +762,25 @@ int i9e_print_completions(struct i9e_completer *completers)
        ci.argc = create_argv(ci.buffer, " ", &ci.argv);
        ci.word_num = compute_word_num(ci.buffer, " ", ci.point);
 
+       /* determine the current word to complete */
        end = ci.buffer + ci.point;
+
+       if (*end == ' ') {
+               if (ci.point == 0 || ci.buffer[ci.point - 1] == ' ') {
+                       ci.word = para_strdup(NULL);
+                       goto create_matches;
+               } else /* The cursor is positioned right after a word */
+                       end--;
+       }
        for (p = end; p > ci.buffer && *p != ' '; p--)
                ; /* nothing */
        if (*p == ' ')
                p++;
-
        n = end - p + 1;
        ci.word = para_malloc(n + 1);
        strncpy(ci.word, p, n);
        ci.word[n] = '\0';
-
+create_matches:
        PARA_DEBUG_LOG("line: %s, point: %d (%c), wordnum: %d, word: %s\n",
                ci.buffer, ci.point, ci.buffer[ci.point], ci.word_num, ci.word);
        if (ci.word_num == 0)
diff --git a/ipc.c b/ipc.c
index 85013a636cb3a7f634d190d9044808454274efd8..8e9dd51a2369e7e60ebd4bda3fa889eaed892248 100644 (file)
--- a/ipc.c
+++ b/ipc.c
@@ -7,7 +7,6 @@
 #include "ipc.h"
 #include <sys/types.h>
 #include <sys/param.h>
-#include <sys/sysctl.h>
 
 #include <sys/ipc.h>
 #include <sys/shm.h>
@@ -194,9 +193,8 @@ int shm_detach(void *addr)
 }
 
 # if defined __FreeBSD__ || defined __NetBSD__
+#include <sys/sysctl.h>
 #      define SYSCTL_SHMMAX_VARIABLE "kern.ipc.shmmax"
-# elif defined __APPLE__
-#      define SYSCTL_SHMMAX_VARIABLE "kern.sysv.shmmax"
 # else
 #      undef SYSCTL_SHMMAX_VARIABLE
 # endif
index cf83b9724d824079e720c1d1a357962c9cd6872a..7ebf208c01552e7b17bfd7a5fff37b6f90051c58 100644 (file)
@@ -62,6 +62,12 @@ version-string = GIT_VERSION()
                        The backup suffix is '~'. That is, a single tilde character is appended
                        to the given file name.
                [/help]
+       [option preserve]
+               summary = preserve modification time
+               [help]
+                       If this option is given, the mtime of the modified file is set to
+                       the value prior to the modification.
+               [/help]
        [option year]
                short_opt = y
                summary = set the year tag
index d269d2374176adef783ca1f78ee0ac4832eb86da..c026a628acdda4adfdbf276ac8c5ca8d527e0d24 100644 (file)
@@ -25,7 +25,7 @@ caption = filters
        purpose = dynamically adjust the volume of an audio stream
        [option blocksize]
                short_opt = b
-               summary = use blocks of size 2**bits
+               summary = adjust volume after each block of size 2**bits (1-31)
                typestr = bits
                arg_info = required_arg
                arg_type = uint32
@@ -35,32 +35,52 @@ caption = filters
                [/help]
        [option aggressiveness]
                short_opt = a
-               summary = controls the maximum amount to amplify by
+               summary = controls the maximum amount to amplify by (0-10)
                typestr = bits
                arg_info = required_arg
                arg_type = uint32
                default_val = 4
+               [help]
+                       This controls the maximal gain factor. Zero means to not amplify
+                       at all while the value 10 corresponds to maximal gain factor which
+                       results in a 4-fold increase in volume.
+               [/help]
        [option inertia]
                short_opt = i
-               summary = how much inertia ramping has
+               summary = how much inertia ramping has (1-14)
                typestr = bits
                arg_info = required_arg
                arg_type = uint32
                default_val = 6
+               [help]
+                       Larger values cause smaller volume adjustments.
+               [/help]
        [option target-level]
                short_opt = t
-               summary = target signal level (0-32768)
+               summary = target signal level (0-32767)
                typestr = level
                arg_info = required_arg
                arg_type = uint32
-               default_val = 20000
+               default_val = 16384
+               [help]
+                       If the peak of the previous block is less than the target level,
+                       volume is increased slightly for the next block. Otherwise it is
+                       decreased. The default value is chosen to minimize clipping. There
+                       is usually no reason to change it.
+               [/help]
        [option damp]
                short_opt = d
-               summary = if non-zero, scale down after normalizing
+               summary = if non-zero, scale down after normalizing (0-16)
                typestr = bits
                arg_info = required_arg
                arg_type = uint32
                default_val = 0
+               [help]
+                       This scales down the volume of the audio stream by factor 2**bits.
+                       This is mostly useful if another audio application (e.g., a video
+                       game) is running in parallel and the relative volume of the audio
+                       stream is too high.
+               [/help]
 [subcommand fecdec]
        purpose = decode a (lossy) input stream using forward error correction
 [subcommand flacdec]
index 4af2a05ab05226eefc81b8a9109fa364b436a663..57a9377eb19030cd9bbe1761d1b72b1dcce69aaa 100644 (file)
@@ -9,10 +9,11 @@ version-string = GIT_VERSION()
        [description]
                para_play operates either in command mode or in insert mode. In insert
                mode it presents a prompt and allows the user to enter commands like
-               stop, play, pause etc. In command mode the current audio file and the
-               playback position are shown and the program reads single key strokes
-               from stdin. Keys may be mapped to commands so that the configured
-               command is executed when a mapped key is pressed.
+               play, pause, quit, etc. In command mode the current audio file and the
+               playback position are shown instead of the prompt/command line, and
+               the program reads single key strokes from stdin. Keys may be mapped
+               to commands so that the configured command is executed whenever a
+               mapped key is pressed.
        [/description]
        m4_include(common-option-section.m4)
        m4_include(help.m4)
index 079589d1f36eee98fb9a0c1252906b5d9b1e43a4..2a39907cee624219d1fb166b07dbf84288f67bb4 100644 (file)
@@ -124,18 +124,18 @@ aux_info_prefix = Permissions:
                summary = enable verbose mode
 
 [subcommand ff]
-       purpose = jump N seconds forward or backward
-       synopsis = n[-]
+       purpose = jump forward or backward in the current audio file
+       synopsis = seconds
        aux_info = VSS_READ | VSS_WRITE
        [description]
-               This sets the 'R' (reposition request) bit of the vss status flags
-               which enqueues a request to jump n seconds forwards or backwards.
-
-               Example:
-
-                    para_client ff 30-
-
-               jumps 30 seconds backwards.
+               This enqueues a request to reposition the audio stream according to
+               the argument, which may be a signed or an unsigned integer. Negative
+               values correspond to backward jumps.
+
+               If a negative number is given whose absolute value exceeds the current
+               postition of the stream, a jump to the beginning of the audio file
+               is performed. If a positive amount of seconds is given which exceeds
+               the remaining time of the audio file, the next audio file is loaded.
 
        [/description]
 
diff --git a/mixer.c b/mixer.c
index ad674bf537e89c5d89bb0ebf946bfd14dad1a81a..efa42b93efb9ce0cf6f277b0f117806845455a26 100644 (file)
--- a/mixer.c
+++ b/mixer.c
@@ -1,6 +1,6 @@
 /* Copyright (C) 1998 Andre Noll <maan@tuebingen.mpg.de>, see file COPYING. */
 
-/** \file mixer.c A volume fader and alarm clock for OSS. */
+/** \file mixer.c A volume fader and alarm clock. */
 
 #include <regex.h>
 #include <lopsub.h>
@@ -313,7 +313,6 @@ static int com_sleep(const struct mixer *m, struct mixer_handle *h)
                client_cmd("stop");
        if (!fit || !fi_mood) /* nothing to do */
                return 1;
-       change_afs_mode(fi_mood);
        for (;;) {
                time(&t1);
                if (wake_time_epoch <= t1 + fit)
@@ -324,7 +323,11 @@ static int com_sleep(const struct mixer *m, struct mixer_handle *h)
                        (delay % 3600) / 60);
                sleep(delay);
        }
-       client_cmd("play");
+       change_afs_mode(fi_mood);
+       if (sleep_mood) /* currently playing */
+               client_cmd("next");
+       else /* currently stopped */
+               client_cmd("play");
        ret = fade(m, h, fiv, fit);
        PARA_INFO_LOG("fade complete, returning\n");
        return ret;
@@ -526,7 +529,7 @@ int main(int argc, char *argv[])
        }
        if (ret < 0)
                goto close_mixer;
-       ret = (*(mixer_subcommand_handler_t *)(lls_user_data(cmd)))(m ,h);
+       ret = (*(mixer_subcommand_handler_t *)(lls_user_data(cmd)))(mh);
 close_mixer:
        m->close(&h);
 free_sub_lpr:
index 42dd7539f647b1e1051870f673fc2f300cfa4a4d..6ed73c2aaa2e068ee404dea1d16fec8183ee5237 100644 (file)
--- a/mp3_afh.c
+++ b/mp3_afh.c
@@ -63,8 +63,6 @@ static const int mp3info_bitrate[2][3][14] = {
 };
 
 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>
@@ -433,10 +431,13 @@ static int header_frequency(struct mp3header *h)
        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];
 }
 
@@ -682,15 +683,14 @@ static int mp3_get_file_info(char *map, size_t numbytes, int fd,
 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,
 #ifdef HAVE_LIBID3TAG
-       afh->rewrite_tags = mp3_rewrite_tags;
+       .rewrite_tags = mp3_rewrite_tags,
 #endif /* HAVE_LIBID3TAG */
-}
+};
index 93ad14bbf9c0b5cbade554fbf22103ef460956fa..5da339fe162ecec96d21cfa05fbde48b51f2a307 100644 (file)
--- a/ogg_afh.c
+++ b/ogg_afh.c
@@ -173,14 +173,15 @@ static int vorbis_rewrite_tags(const char *map, size_t mapsize,
 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
+};
index ed6fe5c80625487d6d6cc852a349650f4cd80ad8..dca6cfbad1ce3ff8cdf6d820b01bf33bf9a02110 100644 (file)
@@ -291,14 +291,15 @@ static void opus_get_header(void *map, size_t mapsize, char **buf,
 }
 
 /**
- * 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,
+};
diff --git a/play.c b/play.c
index 647367a396b2d96368931af790c45dd4f188b7c1..86edc4d4e4f47bc1bd38197ed5982e97df9f72cf 100644 (file)
--- a/play.c
+++ b/play.c
@@ -1238,12 +1238,8 @@ int main(int argc, char *argv[])
        int ret;
        unsigned num_inputs;
 
-       /* needed this early to make help work */
-       recv_init();
-
        sched.default_timeout.tv_sec = 5;
        parse_config_or_die(argc, argv);
-       AFH_RECV->init();
        session_open();
        num_inputs = lls_num_inputs(play_lpr);
        init_shuffle_map();
diff --git a/recv.c b/recv.c
index 7b46d78cac4602b1032508818c710fbcd2b0cc98..10d55d218071ccf6a314fc87d4e5f78001012db4 100644 (file)
--- a/recv.c
+++ b/recv.c
@@ -79,7 +79,6 @@ int main(int argc, char *argv[])
        loglevel = OPT_UINT32_VAL(LOGLEVEL, lpr);
        version_handle_flag("recv", OPT_GIVEN(VERSION, lpr));
        handle_help_flag(lpr);
-       recv_init();
        memset(&rn, 0, sizeof(struct receiver_node));
        ret = check_receiver_arg(OPT_STRING_VAL(RECEIVER, lpr), &receiver_lpr);
        if (ret < 0)
diff --git a/recv.h b/recv.h
index f88ebd84897a89df5b748ab86acb399c37917e0a..36b0f1db62e348c9ab7ccdfc3b32ba656d698c5f 100644 (file)
--- a/recv.h
+++ b/recv.h
@@ -39,12 +39,6 @@ struct receiver_node {
  * \sa \ref http_recv.c, \ref udp_recv.c.
  */
 struct receiver {
-       /**
-        * The optional receiver init function.
-        *
-        * Performs any initialization needed before the receiver can be opened.
-        */
-       void (*init)(void);
        /**
         * Open one instance of the receiver.
         *
@@ -114,7 +108,6 @@ struct receiver {
 /** Iterate over all available receivers. */
 #define FOR_EACH_RECEIVER(i) for (i = 1; lls_cmd(i, recv_cmd_suite); i++)
 
-void recv_init(void);
 int check_receiver_arg(const char *ra, struct lls_parse_result **lprp);
 void print_receiver_helps(bool detailed);
 int generic_recv_pre_select(struct sched *s, struct receiver_node *rn);
index 948de4745dda8c62bce88f31ec8362650ae85de0..31fd81f1ec52c3d0b6204e8b3663a7d36e14fbb3 100644 (file)
 #include "recv.h"
 #include "string.h"
 
-/**
- * Call the init function of each paraslash receiver.
- *
- * Receivers employ the user_data feature of the lopsub library: Each receiver
- * of the recv_cmd suite defines a struct receiver as its user data.
- * recv_init() obtains a pointer to this structure by calling lls_user_data().
- * If the receiver has an init function (i.e., if ->init is not NULL), ->init()
- * is called to initialize the receiver.
- */
-void recv_init(void)
-{
-       int i;
-
-       FOR_EACH_RECEIVER(i) {
-               const struct lls_command *cmd = RECV_CMD(i);
-               const struct receiver *r = lls_user_data(cmd);
-               if (r && r->init)
-                       r->init();
-       }
-}
-
 /**
  * Check if the given string is a valid receiver specifier.
  *
index 6370cefd086d8351f91e25c411142ba8fea4f65a..e0d50f4f8689e1de283ef80f8341504bcf386d33 100644 (file)
--- a/server.c
+++ b/server.c
@@ -583,9 +583,6 @@ static void server_init(int argc, char **argv, struct server_command_task *sct)
        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
index e23236470a3efdafb01b1179e49817f79427f40f..caeacb1921341b04b26f117d5de6607a80ab95e9 100644 (file)
--- a/spx_afh.c
+++ b/spx_afh.c
@@ -248,13 +248,14 @@ static int spx_rewrite_tags(const char *map, size_t mapsize,
 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,
+};
index 742eafdfb1887a0dd9b9d34f15c6662d08dff828..65d2240891afc81f40e6b964d5c0f6b7b25a0ddc 100644 (file)
--- a/string.c
+++ b/string.c
@@ -113,9 +113,9 @@ __must_check __malloc char *para_strdup(const char *s)
 }
 
 /**
- * Print a formated message to a dynamically allocated string.
+ * Print a formatted message to a dynamically allocated string.
  *
- * \param result The formated string is returned here.
+ * \param result The formatted string is returned here.
  * \param fmt The format string.
  * \param ap Initialized list of arguments.
  *
index 67846b141926e80baba083edda9177fa8b3b6acf..58d45ab43d6508619d34186b3f4a23f6d455ecc7 100644 (file)
@@ -186,7 +186,6 @@ err:
        return ret;
 }
 
-/** See \ref recv_init(). */
 const struct receiver lsg_recv_cmd_com_udp_user_data = {
        .open = udp_recv_open,
        .close = udp_recv_close,
diff --git a/vss.c b/vss.c
index f6ec83934d971d3f6de50c363e9c15bb7c94866c..73c7231128b94152268b1bc8ea02d1f524b25b6a 100644 (file)
--- a/vss.c
+++ b/vss.c
@@ -941,6 +941,7 @@ static int recv_afs_msg(int afs_socket, int *fd, uint32_t *code, uint32_t *data)
 }
 
 #ifndef MAP_POPULATE
+/** As of 2018, neither FreeBSD-11.2 nor NetBSD-8.0 have MAP_POPULATE. */
 #define MAP_POPULATE 0
 #endif
 
index d91a2ad4d5626c137551ae31ba9bb13b2bfcc7b0..8395864a00a6e376634272954708cd96739afc2f 100644 (file)
@@ -17,7 +17,8 @@ systems. It is written in C and released under the GPLv2.
 </ul>
 
 <b> Author: </b> Andr&eacute; Noll,
-<a href="mailto:maan@tuebingen.mpg.de">maan@tuebingen.mpg.de</a>
+<a href="mailto:maan@tuebingen.mpg.de">maan@tuebingen.mpg.de</a>,
+Homepage: <a href="http://people.tuebingen.mpg.de/maan/">http://people.tuebingen.mpg.de/maan/</a>
 <br>
 Comments and bug reports are welcome. Please provide the version of
 paraslash you are using and relevant parts of the logs.
index e0f5ccf1866d06378d249b3177a923fb6d8aa502..2c806614d1e4ea001f990949d817dd5929e39a00 100644 (file)
@@ -446,7 +446,7 @@ following commands:
 Next, change to the "bar" account on client_host and generate the
 key pair with the commands
 
-       ssh-keygen -q -t rsa -b 2048 -N '' -m PEM -f $key
+       ssh-keygen -q -t rsa -b 2048 -N '' -m PEM
 
 This generates the two files id_rsa and id_rsa.pub in ~/.ssh.  Note
 that para_server won't accept keys shorter than 2048 bits. Moreover,
index e6048a868710e1e1b62213fda895d1dfc90a2bd1..63e49677b0f1b85c13c17160a7b249531c1fbcd4 100644 (file)
--- a/wma_afh.c
+++ b/wma_afh.c
@@ -646,13 +646,13 @@ out:
 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,
+};