Merge branch 'refs/heads/t/audiod-time-string'
authorAndre Noll <maan@tuebingen.mpg.de>
Sat, 4 Jun 2016 17:39:01 +0000 (19:39 +0200)
committerAndre Noll <maan@tuebingen.mpg.de>
Sat, 4 Jun 2016 17:40:59 +0000 (19:40 +0200)
Was cooking for several months.

* refs/heads/t/audiod-time-string:
  audiod: Improve get_time_string().
  audiod: Force status dump on slot changes.
  audiod: Avoid to report 100% time at startup.
  audiod: Simplify get_time_string()

44 files changed:
INSTALL
Makefile.in
Makefile.real
NEWS [deleted file]
NEWS.md [new file with mode: 0644]
README
aac_afh.c
afh.h
afs.c
afs.h
aft.c
attribute.c
bitstream.c
bitstream.h
blob.c
client.c
configure.ac
error.h
filter.c
flac_afh.c
gui.c
m4/gengetopt/gui.m4
m4/gengetopt/makefile
mm.c
mood.c
mood.h
mp3_afh.c
net.c
ogg_afh.c
opus_afh.c
opus_common.c
play.c
playlist.c
spx_afh.c
string.c
string.h
t/t0004-server.sh
t/test-lib.sh
udp_send.c
vss.c
web/manual.m4 [deleted file]
web/manual.md [new file with mode: 0644]
wma_afh.c
wmadec_filter.c

diff --git a/INSTALL b/INSTALL
index 4cc4b1feb5c882f069f09f9151df8a693336b15f..85b4fab1ff04219e136ea00fe6cfb2d1a5ea97ab 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -34,5 +34,3 @@ Example for cross-compiling
 For details see the user manual:
 
        http://people.tuebingen.mpg.de/maan/paraslash/manual.html
-or
-       http://paraslash.systemlinux.org/manual.html
index a8e2a8b90a400b08a36edeca459335ef766ba560..61da659f370442e75173cd3a1810911a07c2575f 100644 (file)
@@ -9,6 +9,7 @@ PACKAGE_TARNAME := @PACKAGE_TARNAME@
 PACKAGE_VERSION := @PACKAGE_VERSION@
 
 INSTALL := @INSTALL@
+M4 := @M4@
 GENGETOPT := @GENGETOPT@
 HELP2MAN := @HELP2MAN@
 
index 289e027a0b387acd26259624dbce45fd0c823eb9..cc8225ba07852de3779fd21742b59442ba0cf336 100644 (file)
@@ -19,7 +19,6 @@ 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)
-build_date := $(shell date)
 
 ifeq ("$(origin O)", "command line")
        build_dir := $(O)
diff --git a/NEWS b/NEWS
deleted file mode 100644 (file)
index a5bef9f..0000000
--- a/NEWS
+++ /dev/null
@@ -1,1273 +0,0 @@
-NEWS
-====
-
-------------------------------------------
-current master branch "cascading gradient"
-------------------------------------------
-
-       - para_afh learned to modify meta tags of mp3 wma ogg spx
-         opus flac aac files.
-       - afs commands propagate error codes to the client.
-       - The check command now also checks the attribute table for
-         inconsistencies.
-       - New -v flag for the version command (print verbose version string)
-       - New option --priority for para_server and para_audiod.
-
-
---------------------------------------
-0.5.5 (2015-09-20) "magnetic momentum"
---------------------------------------
-
-Many new features and a lot of other improvements.
-
-       - On Linux systems, local sockets are now created in the
-         abstract name space by default. This allows to get rid of
-         the socket specials in /var/paraslash.
-       - The --user-allow option of para_audiod now accepts also
-         usernames rather than only user IDs.
-       - New autoconf macros to avoid duplication in configure.ac.
-       - Status items (as shown by para_gui) are updated correctly
-         when the meta information of the current audio changes.
-       - para_server and para_audiod no longer refuse to start in
-         the background if no log file is given. Instead, all log
-         messages go to /dev/null in this case.
-       - Web page cleanup.
-       - New syntax for the -l and -s options of the ls command.
-         These options should now be specified as -l=v rather than
-         -lv, for example. The old syntax still works, but support
-         will be dropped in v0.6.0.
-
-Download: ./releases/paraslash-0.5.5.tar.bz2 (tarball)
-./releases/paraslash-0.5.5.tar.bz2.asc (signature)
-
-------------------------------------------
-0.5.4 (2015-01-23) "exponential alignment"
-------------------------------------------
-
-Another cleanup and bugfix release.
-
-       - New server command: tasks.
-       - Minor cleanups to daemon.c.
-       - New URLs for home page and git services.
-       - Improved error diagnostics for the mvblob commands.
-       - New sender subcommand: status.
-       - Improved help text for server and afs commands.
-       - audiod memory leak fixes.
-       - Miscellaneous improvements to the build system.
-       - oss_writer improvements.
-       - Improved handling of mp3 files with both id3v1 and id3v2 tags.
-
-Downloads: ./releases/paraslash-0.5.4.tar.bz2 (tarball)
-./releases/paraslash-0.5.4.tar.bz2.asc (signature)
-
----------------------------------------------
-0.5.3 (2014-08-01) "symbolic synchronization"
----------------------------------------------
-
-Not many new features, but lots of fixes and usability improvements.
-
-       - para_gui has been converted to use the paraslash scheduler.
-       - Various alsa-related fixes, mostly for the raspberry pi.
-       - Many scheduler improvements and cleanups.
-       - The test suite has been extended to include sanity checks
-         for the generated man pages.
-       - ao_writer fixes. This writer was in a quite bad shape. Many
-         serious bugs have been fixed.
-       - new audiod command: version.
-       - Minor improvements to the bitstream API.
-       - The cpsi command now prints a meaningful error message if
-         none of the given patterns matched any audio file.
-
-Downloads: ./releases/paraslash-0.5.3.tar.bz2 (tarball),
-./releases/paraslash-0.5.3.tar.bz2.asc (signature)
-
-----------------------------------------
-0.5.2 (2014-04-11) "orthogonal interior"
-----------------------------------------
-
-The new sync filter, the AES_CTR128 stream cipher and the overhauled
-network code are the highlights of this release. It also includes a
-fair number of smaller fixes and improvements not mentioned here.
-
-       - The new sync filter synchronizes playback between multiple
-         clients.
-       - Connections between para_server and para_client are now
-         encrypted by means of AES rather than RC4 if both sides
-         support it. RC4 is still available as a fallback. This
-         feature is fully transparent, i.e. no command line options
-         are necessary, and a client linked against openssl can
-         speak with a server linked against libgcrypt and vice versa.
-       - Major cleanup of the networking subsystem.
-       - Improvements to para_fade: the new set mode, multi-channel
-         initial volumes, better error logging.
-       - The man pages of para_audiod, para_filter, para_recv, and
-         para_write contain the relevant options for receivers, filters,
-         writers. This broke in 0.5.0.
-       - ogg/vorbis latency improvements.
-       - Improved user manual.
-       - Minor fixes to avoid clang warnings.
-
-Downloads: ./releases/paraslash-0.5.2.tar.bz2 (tarball),
-./releases/paraslash-0.5.2.tar.bz2.asc (signature)
-
-------------------------------------------
-0.5.1 (2013-12-20) "temporary implication"
-------------------------------------------
-
-Lots of fixes and improvements all over the place, and a major overhaul
-of the build system.
-
-       - Audiod improvements and fixes.
-       - Buffer tree robustness improvements.
-       - Cleanup of the mood subsystem.
-       - Fixes and cleanups for the flac decoder.
-       - Latency improvements for the ogg/opus decoder.
-       - Crypto support is now optional. On systems without
-         openssl/gcrypt, the build succeeds but para_server,
-         para_audiod, para_client won't be built.
-       - The build system now works for cross-compile setups.
-       - The dependency tree has been flattened, which speeds up
-         builds and avoids to recreate the man pages on every change.
-       - The error code helper has been rewritten from perl to C,
-         which further improves build time.
-       - Many small bugs in the build system have been identified
-         and fixed.
-
-Downloads: ./releases/paraslash-0.5.1.tar.bz2 (tarball),
-./releases/paraslash-0.5.1.tar.bz2.asc (signature)
-
-----------------------------------------
-0.5.0 (2013-08-23) "invertible validity"
-----------------------------------------
-
-Some API-breaking changes, one serious bug fix, and a lot of bike-shedding.
-
-       - The sideband compatibility code has been removed, hence
-         sideband connections (introduced in 0.4.11) are now mandatory.
-       - Addblob commands can produce output.
-       - The stat command no longer sends garbage when para_server was
-         compiled against libgcrypt.
-       - Dependencies for gengetopt files are computed automatically.
-         This eliminates a constant source of build bugs.
-       - The setatt command now accepts file name patterns rather than only
-         path names.
-       - overview.pdf is now based on dia, a simple diagram creation program.
-         The new version is much more detailed and contains descriptions of
-         the various programs of the paraslash package.
-       - The separator of all multi-word options has been changed from
-         underscore to dash. For example --log_color becomes --log-color.
-       - Overhauled web pages and the new logo.
-
-Downloads: ./releases/paraslash-0.5.0.tar.bz2 (tarball),
-./releases/paraslash-0.5.0.tar.bz2.asc (signature)
-
---------------------------------------
-0.4.13 (2013-07-29) "spectral gravity"
---------------------------------------
-
-One more 0.4.x release before the API-breaking changes for 0.5.0 go
-in. The main features of this release are the ogg/opus audio format,
-and UTF-8 support, but it includes also tons of other improvements
-and fixes all over the place.
-
-       - New audio format: ogg/opus.
-       - UTF8 support for para_gui and the mp3 audio format handler.
-       - Scheduler improvements and fixes.
-       - The obsolete gettimeofday() function has been replaced
-         by clock_gettime() on systems which support it.
-       - Speed and usability improvements for para_gui.
-       - para_client now restores the fd flags of stdin and stdout
-         on shutdown.
-       - Improved manual pages.
-       - Consistent version strings for all executables.
-       - Reduced dependencies on generated files result in fewer
-         recompilations on changes.
-       - Performance improvements for the compress filter.
-       - Improved downloads web page.
-
------------------------------------------
-0.4.12 (2012-12-20) "volatile relativity"
------------------------------------------
-The new command line player, the resample filter, ALSA support for
-para_fade, and the improved build system are the highlights of this
-release which probably marks the end of the 0.4.x series.
-
-       - The afh receiver and the para_play executable.
-       - The resample filter: A sample rate converter based on
-         libsamplerate.
-       - The "versions" directory has been removed from the master
-         branch. The tarballs of the old releases are now available
-         in the new "releases" branch.
-       - Overhaul of the build system: All generated files are now
-         written to the "build" directory.
-       - The modular mixer API and the alsa mixer.
-       - Minor fixes for the osx writer.
-
---------------------------------------
-0.4.11 (2012-07-20) "mutual diversity"
---------------------------------------
-
-The major feature in this release is the new sideband API for
-client-server communication. This API will be used exclusively starting
-with 0.5.0, which breaks backward compatibility but allows to get rid
-of quite some compatibility code. Other noteworthy changes include
-decoder latency improvements and a long-standing bug fix for the
-ALSA writer.
-
-       - Sideband connections: If both para_server and para_client
-         support this feature, data is sent as a multiplexed stream.
-       - The --no_default_filters option of para_filter has been
-         removed.
-       - Several fixes and latency improvements to various decoders.
-       - The ALSA writer now limits the prebuffer time to 500ms.
-       - Documentation improvements.
-       - Overhaul of the command_util.sh script.
-       - Fixes for some minor problems found by the clang analyzer.
-       - Compiles (almost) without warnings on gcc-3.
-       - Robustness improvements of the buffer tree code.
-
-------------------------------------------
-0.4.10 (2012-03-30) "heterogeneous vacuum"
-------------------------------------------
-
-Nothing earth-shaking in this release, but quite a few usability
-improvements and the usual mix of cleanups and fixes.
-
-       - The --no_default_filters option of para_filter has been
-         deprecated. It still works but has no effect and will be
-         removed in the next version.
-       - para_gui now prints also the stderr output of the executing
-         command in the bottom window.
-       - Cleanup and consolidation of the various wrappers for
-         write(), writev(), send() and friends.
-       - The obscure error messages on mmap() failures have been
-         replaced by meaningful messages. This affects mainly
-         para_afh.
-       - para_audioc: Cleanups and memory leak fixes.
-       - Test 0004-server no longer fails if para_server is not
-         being built.
-       - New configure options: --with-id3tag-{headers,libs}.
-
--------------------------------------
-0.4.9 (2011-12-06) "hybrid causality"
--------------------------------------
-
-Support for another audio format, interactive mode for para_client
-and para_audiod and many small improvements/fixes all over the place.
-
-       - Support for flac, the free lossless audio codec.
-       - Fix for an endless loop in the mp3 decoder for certain
-         (corrupt) mp3 files.
-       - When executed without specifying a command, para_client
-         and para_audioc start an interactive shell (requires
-         libreadline being installed). The interactive mode offers
-         full tab completion and command line history.
-       - autogen.sh now detects a distcc setup and adjusts the
-         parameter for the -j option of make accordingly.
-       - Shared memory areas are no longer restricted to 64K. We now
-         detect the maximal size of a shared memory area at runtime.
-       - cleanup of the internal uptime API.
-       - para_server prefaults the mmapped audio file to avoid
-         delays on slow media.
-       - A new test for the test-suite that exercises the
-         communication between para_server and para_audiod.
-       - The alsa writer eats up less CPU cycles when configured to
-         use the DMIX plugin.
-       - Simplified and unified receiver code.
-       - Makefile cleanups.
-       - Commands which print a list of matching audio files now
-         emit a meaningful error message if no audio file matched the
-         given pattern(s).
-
---------------------------------------
-0.4.8 (2011-08-19) "nested assignment"
---------------------------------------
-
-Gcrypt support, the overhauled osx writer and regex format specifiers
-are the highlights of this release.
-
-       - support for libgcrypt as a drop-in replacement for openssl.
-         Run configure --enable-cryptolib=gcrypt to link against
-         libgcrypt. The two crypto implementations are compatible to
-         each other, i.e. a para_client executable linked against
-         gcrypt can connect to para_server linked against libssl
-         and vice versa.
-       - Rewrite of the osx writer (output plugin for Mac OS).
-       - audiod: The format specifier for receivers, filters and
-         writers is now treated as a regular expression. This allows
-         to replace 5 lines in the config file (one for each audio
-         format) by one single line. See the manual for details.
-       - The *.cmdline.[ch] files are no longer contained in the released
-         tarballs. This reduces the size of the tarballs but requires
-         gengetopt to build the tarball.
-       - Compiles cleanly also with llvm/clang.
-       - Corrupt mp3 files are handled more gracefully.
-       - The alsa writer uses poll fds instead of computing timeouts.
-       - Cleanup of the generic writer API.
-       - sched: Optimized zero timeouts.
-       - vss timeout cleanups.
-       - oggdec fixes and improvements.
-
---------------------------------------
-0.4.7 (2011-06-01) "infinite rollback"
---------------------------------------
-
-The new ao writer, support for ssh RSA keys and a couple of other
-enhancements.
-
-       - Support for ESD, Pulseaudio, AIX, Solaris, IRIX and other
-         platforms through the libao audio library.
-       - Support for RSA keys generated with ssh-keygen.
-       - configure: improved options for ogg/vorbis/speex.
-       - The git version reported by --version always matches HEAD.
-       - The autogen script detects the number of processors and
-         runs a parallel make if possible.
-       - Major cleanup of the crypto API.
-       - Documentation updates.
-
-------------------------------------------
-0.4.6 (2011-03-31) "deterministic entropy"
-------------------------------------------
-
-Lots of ogg/vorbis improvements, the new test suite, enhancements
-for para_gui and a fair amount of other bug fixes.
-
-       - For DCCP/OGG streams the audio file header is only sent once
-         at the beginning of the stream rather than periodically
-         every five seconds. This reduces network traffic and the
-         FEC group size.
-       - The vorbis comment header is replaced by an empty dummy header
-         before the header is sent over the network. This also results in
-         less network traffic and smaller FEC groups.
-       - The new "test" make target allows to perform some sanity checks prior
-         to installing the package.
-       - ogg timing fixes and performance improvements
-       - Scheduler improvements
-       - Proper exit codes for para_write
-       - para_gui: New option --theme to select a startup theme. Several
-         other improvements and fixes.
-       - aacdec error message cleanups
-       - simplified color error handling
-
---------------------------------------------
-0.4.5 (2010-12-17) "symmetric randomization"
---------------------------------------------
-
-Bug fixes, internal cleanups and variable-sized FEC slices.
-
-       - Contains a fix for an invalid-free-bug in the ogg audio format
-         handler code.
-       - Switching off the DCCP sender works again.
-       - para_audiod handles crashes of para_server more robustly.
-       - Internal scheduler and writer cleanups.
-       - Reduced latency due to variable-sized FEC slices.
-       - Improved documentation and error diagnostics.
-       - The build of para_server is now optional, allowing the build
-         to succeed in case libosl is not installed.
-
-------------------------------------------
-0.4.4 (2010-08-06) "persistent regularity"
-------------------------------------------
-
-Support for yet another audio format, para_write improvements and
-bug fixes.
-
-       - Support for the speex codec.
-       - Support for sample formats other than 16 bit little endian.
-       - error2.h is now created by a perl script which speeds up configure
-         considerably.
-       - Fix a bug in the aac decoder which could lead to segfaults in
-         para_filter/para_audiod.
-       - Fixes for autoconf-2.66.
-
-----------------------------------------
-0.4.3 (2010-07-05) "imaginary radiation"
-----------------------------------------
-
-Many improvements for the DCCP and the UDP transport, the new user
-manual and the usual mix of bug fixes and internal improvements.
-
-       - FEC support for the DCCP sender (Gerrit Renker). The new
-         --dccp_max_slice_size, --dccp_data_slices_per_group and
-         --dccp_slices_per_group options can be used to set the FEC
-         parameters for the DCCP transport.
-       - DNS lookups for UDP targets (Gerrit Renker).
-       - The new user manual replaces the README, README.afs, REQUIREMENTS
-         and INSTALL documents.
-       - Fix an end-of-file detection bug in the oggdec filter.
-       - The new nonblock API.
-       - Both options of the oggdec filter have been removed.
-       - New debug mode for the internal scheduler.
-
-------------------------------------------
-0.4.2 (2010-04-23) "associative expansion"
-------------------------------------------
-
-It's been some time since the last release, but finally here is
-paraslash-0.4.2. The bulk of the changes comes from the new buffer
-tree API, but there are changes all over the tree. Mainly performance
-and usability improvements, but also quite some bug fixes.
-
-       - The new buffer tree API.
-       - DCCP: Support for CCID negotiation (Gerrit Renker).
-       - UDP robustness fixes.
-       - The --bufsize option for mp3dec is gone as it no longer makes sense
-         for the new buffer tree API.
-       - Fix audible buffer underruns for wma streams.
-       - The alsa writer no longer prints meaningless underrun durations.
-       - audiod: Defaults work also for udp streams. If no filter is
-         given for an audio format that is received via upd, fecdec is
-         automatically added as the first filter (along with the decoder).
-
----------------------------------------
-0.4.1 (2009-12-22) "concurrent horizon"
----------------------------------------
-
-Support for another audio format, minor feature enhancements and lots of bug
-fixes. All fixes that have been accumulated in the maint branch (in particular
-those mentionened in the 0.3.6 release notes) appear in this release as well.
-
-       - wma support.
-       - new afh option: --human to activate human-readable output.
-       - new server/audiod option: --log-timing to print timing information.
-       - build system improvements.
-       - source code documentation updates.
-
--------------------------------------
-0.3.6 (2009-12-07) "cubic continuity"
--------------------------------------
-
-Quite a few bugs have been found and fixed since 0.3.5, so here's
-another 0.3.x release. No new features.
-
-       - Always check return value of malloc().
-       - ogg vorbis/FEC: Do not write garbage after the audio file header.
-       - exit if root privileges could not be dropped.
-       - FEC: Fix computation of extra slices.
-       - oss: Fix check for empty input buffer.
-       - Avoid buffer underruns due to filter chain output buffer constraints.
-       - server: Fix assignment of afs_pid.
-       - Don't panic if the afs database contains unknown audio formats.
-       - http/dccp: Do not send the audio file header twice.
-       - FEC: Timing improvements.
-
-----------------------------------------------
-0.4.0 (2009-11-10) "simultaneous independence"
-----------------------------------------------
-
-Two significant changes which require the new version number: The
-improved authentication dialog and the fact that the database code
-has been moved to a library, libosl. To use the new version, you have
-to generate new RSA keys, see INSTALL for details. A shell script is
-provided for conversion of the 0.3 database to the new 0.4 format.
-
-       - stronger crypto for client authentication
-       - the database code has been moved to a library
-       - improved status item handling
-       - cleanup of the build system
-       - The "-V" option now also prints the git version
-       - the new parser-friendly listing mode for the ls and stat commands
-       - mandatory rc4 encryption
-       - major audio format handler cleanups
-       - (id3,...) tags are no longer stored as a combined string in the database
-       - new mood methods: artist_matches, title_matches, comment_matches,
-         album_matches, year_maches, year.
-
---------------------------------------------
-0.3.5 (2009-09-21) "symplectic separability"
---------------------------------------------
-
-Full client support for *BSD Unixes, complete re-write of the ogg
-vorbis audio format handler, various improvements all over the place
-and the usual mix of bugfixes. This release marks the end of the 0.3
-series if no serious problems show up.
-
-       - the new oss writer (supported on *BSD and Linux)
-       - rewrite of the ogg vorbis audio format handler. It's
-         recommended to replace the chunk tables of existing ogg
-         vorbis files in the afs database by re-adding these files
-         with "add -f".
-       - support for netmask subsets (Gerrit Renker)
-       - the new prebuffer filter
-       - improved signal handling
-       - variable fec output buffer size
-       - improved FEC timing fixes audible buffer underruns in UDP mode
-       - --log_color actually works
-       - new ls option: -d (print dates as seconds after the epoch)
-       - update to gengetopt 2.22.2
-       - support for RSA keys of size > 512 bits
-       - new option "mixer_channel" for para_fade
-
------------------------------------------
-0.3.4 (2009-05-07) "elliptic inheritance"
------------------------------------------
-
-The new udp sender, forward error correction, colored logs and various
-other improvements. As the udp sender does not depend on any special
-libraries, it is built unconditionally.
-
-       - The udp sender replaces the ortp sender. The new code uses forward
-         error correction to protect against packet losses. Many thanks to
-         Gerrit Renker for providing ipv6 support.
-       - The default port for udp streaming now defaults to 8000, like
-         for the http and the dccp senders/receivers.
-       - Loglevels are now specified as symbolic names, e.g.
-         "--loglevel info".
-       - improved ipv4 and ipv6 URI parser (Gerrit Renker).
-       - para_server/para_audiod: Color support for log messages.
-       - new options for mp3dec: --ignore-crc, --bufsize
-       - new audiod option: --config-file.
-       - gengetopt cleanups.
-       - Improved help/man pages: The documentation of para_audiod,
-         para_recv, para_filter and para_write now also contains
-         all options of the available receivers/filters/writers. The
-         man page of para_fade contains a description of the different
-         modes of operation.
-       - More source code documentation.
-       - vss timing fixes.
-
---------------------------------------------
-0.3.3 (2008-12-01) "axiomatic perspectivity"
---------------------------------------------
-
-Internal code cleanups, bug fixes, improved tag handling and the new
-amplification filter.
-
-       - para_server uses the generic scheduling code.
-       - overhaul of the virtual streaming system.
-       - mp3: id3 version 2 support via libid3tag (optional)
-       - ogg: vorbis comment support.
-       - aac meta info support.
-       - mp3 audio format handler cleanups.
-       - new filter: "amp" to amplify the amplitude of the audio stream
-       - new status item/database entry: amplification. It is
-         used by the amp filter to pre-amplify the audio stream.
-       - fix a close-without-open bug in para_write.
-       - fix a bug in com_init() which was introduced in 0.3.2.
-       - better error diagnostics for para_client.
-
------------------------------------------
-0.3.2 (2008-04-11) "probabilistic parity"
------------------------------------------
-
-The new para_afh executable, scheduling and documentation improvements.
-
-       - new ls option: -lc (list chunk table)
-       - new executable: para_afh, the stand-alone audio file handler tool
-       - afs commands can send output more than SHMMAX (32MB on Linux). This
-         also reduces the memory usage of commands that produce large amounts
-         of output.
-       - major scheduler and audiod cleanups.
-       - more detailed and much nicer man pages.
-
----------------------------------------
-0.3.1 (2008-02-23) "liquid interaction"
----------------------------------------
-
-A mix of cleanups, bug fixes, improvements, and some new features. No
-significant changes to the new database (osl) code, which is generally
-a good sign.
-
-       - Share some similar/duplicate code between the http and the
-         dccp sender.
-       - Generic access control lists for paraslash senders.
-       - dccp sender: Access control lists, connection limiting and support
-         for the allow,deny,on,off,help sender commands.
-       - The default dccp port changed from 5001 to 8000 (suggested by
-         Gerrit Renker).
-       - para_server starts even if not all public keys could be loaded.
-       - Audiod performance improvements.
-       - fix a bug in the "off" command of the http sender.
-       - fix some fd and memory leaks.
-       - Update to gengetopt-2.22.
-
--------------------------------------
-0.3.0 (2008-01-12) "solar saturation"
--------------------------------------
-
-paraslash.0.3.0 -- 'WWDBND --what would databases never do?'.
-
-
-Usually one might expect lots of new features AND a big increase in size
-for a major release like this.
-
-However, paraslash-0.3.0.tar.bz2 is the smallest paraslash tarball
-ever. The decrease in size is mostly due to the removal of some
-graphical tools (which were only quick hacks anyway). But also the
-fact that the mysql code is gone cuts down the size a bit.
-
-Being independent of mysql comes at a cost: The fact that paraslash
-now contains its own database (the object storage layer, osl) increases
-the (stripped) binary size of para_server by ~50K on i386.
-
-       - no more restrictions on unique basenames.
-       - independent of mysql: The new self-contained object
-         storage layer (osl) replaces the mysql database.
-       - New executable para_fsck: Check integrity of osl tables.
-       - Lyrics support.
-       - Reliable audio file move/rename detection.
-       - More portable than ever: Tested on Linux (x86_32, x86_64, sparc64),
-         MacOS (ppc32, x86_32), FreeBSD (x86_32), NetBSD (x86_32) and
-         Solaris (sparc64).
-       - the new osl-based audio file selector (afs) replaces the random,
-         the playlist and the mysql selector of paraslash-0.2.x.
-       - IPv6 support (thanks to Gerrit Renker).
-       - paraslash-0.2.x streams are now called "moods". Writing
-         0.3.x-mood definitions should be both easier and more
-         powerful than writing 0.2.x-stream definitions.
-       - para_krell, para_slider, para_para_sdl_gui, para_dbadm have
-         been removed. The world is a better place without them. However,
-         para_gui is still there.
-       - afs tracks audio file selection also in playlist mode.
-       - few easy-to-use afs commands replace the many not-so-easy-to-use
-         mysql commands (and are available also in playlist mode).
-       - Improved error subsystem.
-       - The earth-shaking new logo.
-
------------------------------------------
-0.2.17 (2007-11-20) "isotropic threshold"
------------------------------------------
-
-Mainly bugfixes and cleanups in this version which marks the end of
-the 0.2.x series if no serious bugs show up after the release.
-
-       - mysql_selector: fix a locking bug.
-       - universal chunk queueing.
-       - dccp sender uses chunk queueing if write() returns EAGAIN (thanks
-         to Gerrit Renker).
-       - be more carful wrt. signed vs. unsigned argument passing.
-       - cleanup error.h and fix some references to invalid error
-         codes.
-       - update to gengetopt-2.21.
-       - update to ortp-0.13.1.
-       - autoconf: extend checks for headers, library functions and
-         compiler characteristics.
-       - Fix streaming of large mp3 files.
-       - Fix an off-by-one bug in playlist handling.
-
---------------------------------------
-0.2.16 (2007-04-05) "neural discharge"
---------------------------------------
-
-The main change in this release is the major audio format handler
-cleanup which removes some similar/duplicate code and makes it easier
-to implement plugins for other audio formats. Of course, the usual mix
-of other improvements/changes/bugfixes also made it into the release.
-
-       - simplified audio format handlers (most of the handling functions
-         were moved one layer up to the virtual streaming system).
-       - para_server uses mmap to read audio files
-       - repositioning of mp3 streams is much faster, in particular for
-         jumping near the end of large mp3 files.
-       - permission flags DB_READ,DB_WRITE have been renamed to AFS_READ
-         and AFS_WRITE.
-       - fix a bug in para_filter that caused decoding of aac files
-         to start only after a few seconds.
-       - fix osx_writer hangs
-       - simplified dccp code (thanks to Gerrit Renker)
-       - the compress filter works also on big endian systems (ppc)
-
------------------------------------------
-0.2.15 (2007-02-16) "inductive resonance"
------------------------------------------
-
-Minor improvements, more documentation and a bunch of bug fixes.
-
-       - para_server: The server.users file is only read once on server
-         startup rather than for each connection
-       - mp3dec: Fix decoding of corrupt mp3 files
-       - afs (audio file sender) is now called vss (virtual streaming
-         system). Consequently, the permission flags specified in
-         ~/.paraslash/server.users have also changed: AFS_READ and AFS_WRITE
-         become VSS_READ and VSS_WRITE respectively.
-       - para_audiod/para_filter: Fix a bug that caused the last chunk
-         of audio data not being written under certain circumstances
-       - audiod: compute the difference of server time and local time
-         correctly
-       - para_server/para_audiod: Fix some memory leaks
-       - documentation improvements
-       - configure.ac: fix checks for para_krell
-       - new man pages
-
--------------------------------------------
-0.2.14 (2006-10-15) "transient singularity"
--------------------------------------------
-
-The only major enhancement of this version is the osx writer which completes
-the Mac OS Port and was originally planned already for 0.2.13 but had to wait
-until now for reasons beyond the scope of this changelog entry.
-
-       - new output plugin for Mac Os: the osx writer
-       - rename configure command line options from --enable-xxx-headers to
-         --with-xxx-headers and  --enable-xxx-libs to --with-xxx-libs
-       - configure: new command line options: --with-mad-headers,
-         --with-mad-libs, --with-oggvorbis-headers, and --with-oggvorbis-libs
-       - some robustness fixes
-       - dymamic audio format recognition for audiod
-       - para_server: new command line option: --autoplay_delay
-       - para_audiod: new command line option: --clock_diff_count
-
----------------------------------------
-0.2.13 (2006-07-14) "sonic convolution"
----------------------------------------
-
-A bunch of new features and core changes.
-
-       - the new paraslash scheduler, short and sweet.
-       - Support for m4a/mp4 files via the new aac audio format
-         handler/filter (requires libfaad).
-       - each writer has its own command line parser, just like
-         para_recv and para_filter.
-       - para_client and para_audioc use the error subsystem
-       - writers are integrated in para_audiod (currently linux-only)
-       - para_client is integrated in para_audiod
-       - random/playlist selector: improved info strings
-       - new audiod commands: tasks, kill
-       - update to libortp-0.10.1
-       - para_fade: wake time defaults to 8 hours from now
-       - update to autoconf-2.60
-
-------------------------------------------
-0.2.12 (2006-05-12) "oriented abstraction"
-------------------------------------------
-
-Many user-visible changes in this release and lots of new
-features:
-
-
-       - the new optional dccp sender/receiver. It uses the datagram
-         congestion control protocol. You'll need a fairly new kernel
-         for this.
-       - paraslash works on Mac OS X (thanks to Gerd Becker)
-       - para_play renamed to para_write
-       - modular output plugin design (writers) for para_write
-       - new file_writer output plugin for para_write
-       - compress filter speed improvements
-       - update to libortp-0.9.1
-       - update to gengetopt-2.17rc
-       - para_client no longer depends on libreadline (as the
-         code for the interactive mode was removed).
-       - gcc-2-95 is no longer a supported compiler. It may still
-         work, but it gets no more testing.
-       - the tarball no longer contains the screenshot images which
-         reduces its size quite a bit.
-       - configure: new command line options: --enable-mysql-headers
-         and --enable-mysql-libs
-
-------------------------------------
-0.2.11 (2006-03-11) "atomic duality"
-------------------------------------
-
-Here it is, the first paraslash release developed with git. There
-are fairly many user-visible changes in this release. As two out of
-the three "database tools" of paraslash don't use a database at all,
-they are now called "audio file selectors" instead.
-
-
-       - the cdt command (change database tool) becomes chs (change
-         selector)
-       - no more colon separators: The syntax of some options of
-         para_audiod and para_filter have changed. Use --help for
-         more info (and some examples).
-       - update to gengetopt-2.16 (thanks to Lorenzo Bettini)
-       - switch from cvs to git (should've done that earlier)
-       - the new ipc subsystem
-       - new audio file selector: playlist
-       - para_server: the dopey selector is now called "random",
-         and is the default selector. Use the --selector option to
-         choose another selector at startup, or the chs command to
-         change the selector at runtime.
-       - X86_64 fixes (thanks to Steffen Klassert)
-       - para_play fixes
-
---------------------------------------
-0.2.10 (2006-02-17) "cyclic attractor"
---------------------------------------
-
-Huge documentation update, a scrollable window for para_gui, ortp
-improvements, and of course many small fixes not mentioned here.
-The diffstat below is rather misleading as most insertions are due
-to the new source documentation.
-
-       - autoconf cleanup
-       - para_server also uses the new error subsystem
-       - lots of new documentation (UTSL)
-       - gui improvements:
-               - keysyms for cursor keys and for next/previous page keys
-               - scrollable output window
-               - new internal commands: scroll up/down, page up/down
-               - fix color of command output.
-       - ortp: the --chunk_time and --header flags are no longer needed
-       for para_recv/para_audiod as this information is now encoded in
-       each rtp packet sent by para_server.
-
--------------------------------------------
-0.2.9 (2006-01-24) "progressive turbulence"
--------------------------------------------
-
-Internal audiod receivers/filters, the new error subsystem and
-a lot of small improvements.
-
-       - para_recv and para_filter are integrated into the para_audiod
-         binary, i.e. audiod no longer spawns a new process for
-         each receiver/filter. As para_recv and para_filter might be
-         useful as standalone programs, they still get built (linked
-         against the same object files that are also used for audiod).
-       - further ortp timing improvements should reduce the CPU usage
-         of the ortp receiver.
-       - improved audio grabbing. The 'grab' command of para_audiod
-         has its own set of command line options. Read the output of
-         "para_audioc help grab" for more info.
-       - oggdec: configurable input prebuffer size.
-       - the new error subsystem gives better error diagnostics
-         and reduces code size.
-
------------------------------------------
-0.2.8 (2006-01-02) "dynamic accumulation"
------------------------------------------
-
-The new modular filter design and the para_play-hangs bugfix.
-
-       - new executable: para_filter. It combines para_mp3dec,
-         para_oggdec and para_compress. It also adds a further filter
-         type, wav, that just inserts a wave header at the desired point
-         of the filter chain. All 'piping' is done in-memory (i.e. no
-         read/write operations are used).
-       - para_play: fix a stupid bug that caused it to hang under
-         certain circumstances.
-
--------------------------------------------
-0.2.7 (2006-12-27) "transparent invariance"
--------------------------------------------
-
-Not many user-visible changes but a fair amount of internal improvements.
-
-
-       - The http sender buffers data if it can not be sent
-         out immediately (because the socket is not writable). This
-         should prevent para_server from shutting down the connection
-         too early on a loaded network.
-       - para_play also prebuffers data if it is told to start at a
-         future time by the --start_time option.
-       - The return of para_recv: It combines para_ortp_recv and
-         para_http_recv. Use the --receiver option to switch between
-         the two. para_recv builds without libortp, but contains
-         only the http receiver in this case.
-       - update to ortp 0.8.1. As this ortp release contains incompatible
-         changes, para_recv-0.2.7 won't link against older ortp libs.
-       - improved ortp timings.
-       - use of gcc-extensions that #define away for non-gcc and
-         gcc < 3.0.
-
--------------------------------------------
-0.2.6 (2005-10-29) "recursive compensation"
--------------------------------------------
-
-Transparent session encryption (uses openssl's Alleged RC4 cipher),
-the internal find command and several other improvements and cleanups.
-
-       - Encrypt the session if encryption is requested by the client
-         (default for para_client 0.2.6). This is backwards
-         compatible, so older clients can still connect to para_server
-         0.2.6. Use the new client option --plain to request an
-         uncrypted session (off by default, must be set to on in
-         order to connect to para_server 0.2.x with 0 <= x <= 5).
-       - para_server uses an internal function to locate audio files
-         rather than calling find(1). The server option
-         --mysql_audio_file_dir replaces --mysql_find_cmd.
-       - documentation update
-       - man pages
-       - header file cleanup
-       - para_client code cleanup
-       - para_gui: faster display of output of display commands
-
-------------------------------------------
-0.2.5 (2005-10-13) "aggressive resolution"
-------------------------------------------
-
-This release adds internal senders, i.e. no more external programs are
-spawned for sending out the audio data. There are two different senders
-available: The http sender and the ortp sender (former para_send which
-is no longer needed).
-
-The new sender code has a plugin-like design so it can be easily
-extended should there be be any future need for supporting another
-network streaming protocol. All senders are completely independent of
-each other. In particular, the http and the ortp sender can operate
-in parallel.
-
-       - new server command: sender to control senders at runtime.
-         Read the output of "para_server -h" and "para_client help
-         sender" for more information.
-       - para_recv renamed to para_ortp_recv
-       - new executable: para_http_recv, a simple command line
-         http receiver.
-       - major afs/mp3/ogg code simplifications due to internal
-         senders.
-       - ogg timing improvements
-       - fix several minor memory leaks (found by valgrind)
-       - empty stream definitions work again
-       - com_ne(): ignore errors on remove
-       - audiod: fix segfault on server restart
-
----------------------------------------
-0.2.4 (2005-09-21) "toxic anticipation"
----------------------------------------
-
-Several small improvements, fixes and the new grab command.
-
-       - audiod:
-               - new command: "grab" to grab the output of the stream reader
-                 or any filters. Read the output of "para_audioc help grab"
-                 for more information.
-               - fix memory leak
-               - code cleanup
-       - audioc: new command line option: --bufsize to specify a
-         buffer size different from the default size 8192.
-       - improved error diagnostics for para_play.
-       - new configure option: --enable-ssldir so search for openssl in
-         non-standard places
-       - sdl_gui: Make it look nice again for 1024x768
-       - server: report total size of memory allocated with sbrk by malloc,
-         new command line option: --announce_time
-
------------------------------------------
-0.2.3 (2005-09-01) "hydrophilic movement"
------------------------------------------
-
-Two new executables and major feature enhancements.
-
-       - audiod filters: It is now possible to specify arbitrary many
-         (including none) filters for each supported audio
-         format. This can be used e.g. for normalizing volume,
-         transforming or grabbing the audio stream, or for using
-         visualizers.  Read the output of "para_audiod -h" for the
-         syntax of the new --filter_cmd option.
-       - new executable: para_play, a tiny alsa player. It
-         can play wave files or raw pcm (16 bit little endian)
-         from stdin.
-       - new executable: para_compress, a dynamic range compressor
-         intended to keep audio output at a consistent volume. Derived
-         from AudioCompress, http://trikuare.cx/code/AudioCompress.html.
-       - audiod: New option: --stream_delay. This can be used in
-         a local network to syncronize the audio output of all
-         clients that play the same stream.
-
-------------------------------------------
-0.2.2 (2005-08-19) "tangential excitation"
-------------------------------------------
-
-Mostly internal changes in this release, but also some new commands
-for the mysql database tool.
-
-       - cleanup exec.c, fix para_exec bug
-       - compile time loglevel (log messages below the given level
-         won't be compiled in, which reduces the size of the
-         resulting binaries)
-       - new log macros that shorten the size of the source code.
-       - workaround a gcc-4.1 bug (?) that caused send_cred_buffer()
-         to send only zeros. With this workaround, para_audioc works
-         again.
-       - avoid gcc-4 warning: conflicting types for built-in function 'clog'
-       - new mysql commands: "rm" (remove entry), "mv" (rename entry) "ne"
-         (new entry), "snp" (set numplayed). Read the manual for more
-         information.
-
----------------------------------------
-0.2.1 (2005-08-15) "surreal experience"
----------------------------------------
-
-Here comes paraslash-0.2.1. It contains a couple of new features and,
-surprise, only minor bug fixes.
-
-       - kill noisy mp3 debug message
-       - cleanup of the build system
-       - para_server and para_client directly use the crypto routines
-         of the openssl library rather than invoking the openssl command
-         line utitlity
-       - server/audiod: new option --user to switch to the given user
-         when invoked as root. Read the output of "para_server -h" for
-         more information.
-       - gui/sdl_gui: new option --stat_cmd to be used to retrieve the
-         status. Default: "para_audioc stat"
-       - sdl_gui: new option --pic_cmd to be used to download the picture.
-         Default: "para_client pic"
-       - audiod: 5 slots ought to be enough for everybody
-       - audiod: new status item: Uptime, kill hup command
-
-------------------------------------------
-0.2.0 (2005-08-06) "distributed diffusion"
-------------------------------------------
-
-After several month of increased development activity, paraslash-0.2.0
-has arrived. It contains many new features and is much more
-self-contained than the old 0.1.x series. Enjoy!
-
-
-       - para_server: fix hang on song change and crash on sighup.
-         Speed up mysql queries. The DIR_LIKE macro is gone.
-       - new executables: para_audiod, the local audio daemon that
-         starts playback (uses SCM_CREDENTIALS socket magic) and
-         para_audioc, the corresponding client.
-       - new executables: para_mp3dec/para_oggdec, two really teensy
-         decoders. para_mp3dec is based on libmad, para_oggdec requires
-         libvorbisfile.
-       - ovsend/ovrecv are capable of streaming ogg as well as mp3, so
-          they are now called para_send and para_recv respectively.
-       - documentation updates
-       - para_gui is themable. For now there is the default theme that
-         looks as before and the simple theme: blue and easy.
-       - gui: audio streaming is now handled by audiod. Time display shows
-         playback time rather than streaming time
-       - slider: update to libzmw-0.2.0
-       - para_krell: fix crash on server shutdown
-       - switch from gzip to bzip2
-
-----------------------------------------
-0.1.7 (2005-04-18) "melting penetration"
-----------------------------------------
-
-The main change in this release is clearly the oggvorbis rewrite,
-but there are also lots of smaller changes. If you intend to use both
-the mp3 and the ogg plugin, it is recommended to use software mixing,
-e.g. the dmix plugin which is provided by ALSA.
-
-       - new executables: para_ovsend and para_ovrecv for sending/receiving
-         oggvorbis files via rtp. Requires the open rtp library. Get it at
-         http://www.linphone.org/ortp/
-       - rewrite of the ogg_vorbis core code
-       - configure detects libzmw and, if detected, includes
-          para_slider to the list of binaries to be built by make
-       - server stream writers read from their associated fifo rather
-         than from stdin
-       - slider: two new sliders, lastplayed and numplayed
-       - fix nasty double free bug which caused random segfaults in case of
-         mp3 files with invalid header information
-       - gui: new command line option: --stream_timeout=seconds  to
-         deactivate a slot if it is idle for that many seconds (default=`5')
-       - diffstats
-
----------------------------------------
-0.1.6 (2005-03-05) "asymptotic balance"
----------------------------------------
-
-Only little user-visible changes in this release. Mainly bugfixes and
-core code cleanup. This is probably the most stable version ever if you
-stick to mp3...
-
-       - fix several memory leaks
-       - rename default name of mysql database from "music" to "paraslash".
-         Use para_server's  --mysql_database option if you do not want to
-         rename your old database.
-       - rework ogg vorbis code
-       - make update command work on mysql servers with LOCAL_INFILE
-         disabled
-       - gui: improved stream I/O (slots)
-       - simplified audio format API
-       - para_pob_ogg is gone
-
-------------------------------------
-0.1.5 (2004-12-31) "opaque eternity"
-------------------------------------
-
-Let's slide gently into the new year.
-
-       - new: para_slider (not built automatically, type "make
-          para_slider" to build). A toy for those who always felt that
-          creating stream definitions is difficult. See screenshots,
-          README and FEATURES for more info.
-       - improved signal handling. Fixes server segfault on SIGHUP
-         for linux kernels newer than Aug 24 2004 and makes para_gui
-         race-free.
-       - reload database tool on SIGHUP
-       - improved help message for sl
-       - do not log "broken pipe" messages as errors. They are
-         perfectly ok.
-       - fix wrong error message on permission errors
-
------------------------------------------
-0.1.4 (2004-12-19) "tunneling transition"
------------------------------------------
-
-Bugfix release. As expected, 0.1.3 introduced a bunch of new bugs.
-Hopefully, most of them got wiped out with this release. Some
-enhancements went also in.
-
-       - improved error diagnostics for all commands
-       - stradd/picadd: overwrite previous contents if entry already
-          exists, rather than returning errors
-       - stradd: use current stream if invoked without args
-       - faster (and hopefully more stable) ogg-vorbis handling
-       - para_krell: reap children to avoid zombie-flooding in case
-         no server is running
-       - si: report also server pid
-       - server: don't busy-loop if dbtool reports only invalid files.
-       - gui: CTRL+C works again, fix stream_read command line option
-       - fix pic_add, hist
-       - fix mysql dbtool startup in case no database exists
-       - many small fixes and cleanups
-
----------------------------------------
-0.1.3: (2004-12-10) "vanishing inertia"
----------------------------------------
-
-Starting from this release, the database tools are integrated in the
-server binary. This decreases server startup time, reduces code size
-and speeds up database commands. However, the layout of the underlying
-mysql database changed only slightly and 0.1.3 should be backwards
-compatible in that respect.
-
-Visible changes:
-
-       - If mysql is not detected at compile time, or fails to init
-         at runtime, fall back to the dopey database tool which should
-         always work.
-       - para_dbtool and dbtool.conf are gone. All mysql specific
-         options are read from server.conf and are prefixed by 'mysql_'.
-       - new command: cdt (change database tool)
-       - new command line option: dbtool (choose startup database tool)
-       - The name of current stream is now stored in the database,
-         so paraslash remembers its current stream when restarted.
-       - new command: csp (change stream and play)
-       - para_gui also reports current database tool and server uptime
-
--------------------------------------------
-0.1.2: (2004-11-28) "spherical fluctuation"
--------------------------------------------
-
-Point release before the big dbtool changes go in.
-
-       - dbtool: rename ca to cam (copy all meta data). It now also
-         copies numplayed and lastplayed time as well as the picture
-         id.
-       - fix endless-loop-bug caused by mp3 files with invalid header
-
------------------------------------------
-0.1.1: (2004-11-05) "floating atmosphere"
------------------------------------------
-
-       - gkrellm plugin
-       - new dbtool command: mbox. Browse your sound-file collection
-         with your favorite mail reader.
-       - several small fixes
-
--------------------------------------
-0.1.0: (2004-10-22) "rotating cortex"
--------------------------------------
-
-       - fix logging bug for loglevel > VERBOSE
-       - fix skip command
-       - correct timings for vbr mp3s
-       - modular audio format support
-       - ogg-vorbis support (experimental)
-       - new server option: autoplay
-
------------------------------------------
-0.0.99: (2004-07-25) "harmonic deviation"
------------------------------------------
-
-       - rename projectname from icc to paraslash (play, archive, rate
-         and stream large audio sets happily)
-       - paraslash is no longer restricted to one particular audio
-         streaming software
-       - new dbtool commands (stradd, strq, strdel) for easy stream
-         managment w/o configuration file. That obsoletes stream_defs
-         file/config option for dbtool.
-       - picadd accepts jpeg data from stdin
-       - new server commands: ps (select previous stream), sc (song change)
-       - new default pictures for sdl_gui
-       - gui: new key_map option for binding commands and internal
-         functions to arbitrary keys, nice help screen, rip out
-         soundcard/linux specific stuff, avoid noise artefacts while jumping,
-         show silly logo on startup
-       - new executables: para_fade for fading volume, para_dbadm for
-         manipulating attributes
-       - cdb adds _all_ tables to mysql database
-       - revised and beautified documentation
-       - sample dbtool rewritten in C
-       - autoconf
-
----------------------------------------------
-0.0.98: (2003-12-26) "incremental smoothness"
----------------------------------------------
-
-       - kick icecast in favour of poc. That removes some races and reduces
-         core code considerably.
-       - cbr/vbr is displayed by stat and gui/sdl_gui. New status flags
-         give finer info on afs' status.
-       - gui can start decoder (see config options). Further new gui
-         commands: refresh (^L), jmp (F1-F10)
-        - gui rereads conf on SIGUSR1 instead of SIGHUP. SIGHUP
-          terminates gui. This fixes dead instances consuming memory
-          continuously.
-       - new dbtool command: verb for sending verbatim sql queries.
-       - fix pid_list races (by removing pid_list)
-       - codename funnies
-
---------------------
-0.0.97: (2003-10-26)
---------------------
-
-       - installation prefix now defaults to /usr/local
-       - new commands for gui: snozze, sleep and reread config
-       - config file for gui and sdl_gui
-       - fix problems with filenames containing funny characters
-         (reported by Thomas Forell)
-       - improved signal handling for gui, now it rereads conf on SIGHUP
-       - new dbtool command: cdb (create database)
-       - switch from argtable to gengetopt
-       - major code cleanup and speed improvements
-       - fix several potential buffer overflows
-       - many small fixes and cleanups
-
--------------------
-0.0.96 (2003-08-30)
--------------------
-
-       - easy stream_defs syntax
-       - sdl_gui can display images associated to the file being played
-       - Major feature enhancements for icc_gui including dynamic text
-         placement and the top/bottom window design
-       - vrfy/clean now also checks for NULL values in attributes as
-         well as for invalid picture pointers
-       - fix long outstanding case sensitivity bug
-       - many small fixes and cleanups
-
--------------------
-0.0.95 (2003-06-29)
--------------------
-
-       - sdl gui runs much faster
-       - new dbtool command: ca (copy attributes)
-       - count and display number of times the song has been played
-       - new feature: scoring
-       - command line options for sdl_gui
-       - simpler syntax of streams file
-       - decrease network traffic of stat
-       - fix zombie bug
-       - many small fixes and cleanups
-
--------------------
-0.0.94 (2003-05-04)
--------------------
-
-       - new server command: ns (next stream)
-       - new icc_gui command: c (change stream)
-       - internal mp3info
-       - stat shows also id3 tag info
-       - new sdl based gui
-       - log flodding bug fixed
-       - many small fixes and cleanups
-
--------------------
-0.0.93 (2003-03-28)
--------------------
-
-       - colors for icc_gui
-       - icc_gui sets volume directly (linux only)
-       - proper locking that fixes some races
-       - fix security bug that caused commands to be executed even
-         with unsufficient permissions
-       - new command: hup to make all servers reread their configuration file
-       - icecast meta data streaming
-       - many small fixes and cleanups
diff --git a/NEWS.md b/NEWS.md
new file mode 100644 (file)
index 0000000..b95cbb4
--- /dev/null
+++ b/NEWS.md
@@ -0,0 +1,1286 @@
+NEWS
+====
+
+------------------------------------------
+current master branch "cascading gradient"
+------------------------------------------
+
+The highlight of this release is the new -m flag for para_afh which
+lets it modify the meta tags of the given audio file(s). This feature
+is supported for all audio formats. Many small cleanups and bug fixes
+not mentioned here have accumulated and are also part of the release.
+
+- para_afh learned to modify meta tags of mp3 wma ogg spx
+  opus flac aac files.
+- afs commands propagate error codes to the client.
+- The check command now also checks the attribute table for
+  inconsistencies.
+- New -v flag for the version command (print verbose version string)
+- New option --priority for para_server and para_audiod.
+- New mood methods: image_id and lyrics_id.
+- The manual and this NEWS file have been converted to markdown.
+- Cleanup of the wma decoder and bitstream code.
+- Improved wide-character support and fixes related to signal handling.
+- para_gui no longer reports 100% playing time at the stream start.
+
+Download: [tarball](./releases/paraslash-git.tar.bz2)
+
+--------------------------------------
+0.5.5 (2015-09-20) "magnetic momentum"
+--------------------------------------
+
+Many new features and a lot of other improvements.
+
+- On Linux systems, local sockets are now created in the
+  abstract name space by default. This allows to get rid of
+  the socket specials in /var/paraslash.
+- The --user-allow option of para_audiod now accepts also
+  usernames rather than only user IDs.
+- New autoconf macros to avoid duplication in configure.ac.
+- Status items (as shown by para_gui) are updated correctly
+  when the meta information of the current audio changes.
+- para_server and para_audiod no longer refuse to start in
+  the background if no log file is given. Instead, all log
+  messages go to /dev/null in this case.
+- Web page cleanup.
+- New syntax for the -l and -s options of the ls command.
+  These options should now be specified as -l=v rather than
+  -lv, for example. The old syntax still works, but support
+  will be dropped in v0.6.0.
+
+Downloads:
+[tarball](./releases/paraslash-0.5.5.tar.bz2),
+[signature](./releases/paraslash-0.5.5.tar.bz2.asc)
+
+------------------------------------------
+0.5.4 (2015-01-23) "exponential alignment"
+------------------------------------------
+
+Another cleanup and bugfix release.
+
+- New server command: tasks.
+- Minor cleanups to daemon.c.
+- New URLs for home page and git services.
+- Improved error diagnostics for the mvblob commands.
+- New sender subcommand: status.
+- Improved help text for server and afs commands.
+- audiod memory leak fixes.
+- Miscellaneous improvements to the build system.
+- oss_writer improvements.
+- Improved handling of mp3 files with both id3v1 and id3v2 tags.
+
+Downloads:
+[tarball](./releases/paraslash-0.5.4.tar.bz2),
+[signature](./releases/paraslash-0.5.4.tar.bz2.asc)
+
+---------------------------------------------
+0.5.3 (2014-08-01) "symbolic synchronization"
+---------------------------------------------
+
+Not many new features, but lots of fixes and usability improvements.
+
+- para_gui has been converted to use the paraslash scheduler.
+- Various alsa-related fixes, mostly for the raspberry pi.
+- Many scheduler improvements and cleanups.
+- The test suite has been extended to include sanity checks
+  for the generated man pages.
+- ao_writer fixes. This writer was in a quite bad shape. Many
+  serious bugs have been fixed.
+- new audiod command: version.
+- Minor improvements to the bitstream API.
+- The cpsi command now prints a meaningful error message if
+  none of the given patterns matched any audio file.
+
+Downloads:
+[tarball](./releases/paraslash-0.5.3.tar.bz2),
+[signature](./releases/paraslash-0.5.3.tar.bz2.asc)
+
+----------------------------------------
+0.5.2 (2014-04-11) "orthogonal interior"
+----------------------------------------
+
+The new sync filter, the AES_CTR128 stream cipher and the overhauled
+network code are the highlights of this release. It also includes a
+fair number of smaller fixes and improvements not mentioned here.
+
+- The new sync filter synchronizes playback between multiple
+  clients.
+- Connections between para_server and para_client are now
+  encrypted by means of AES rather than RC4 if both sides
+  support it. RC4 is still available as a fallback. This
+  feature is fully transparent, i.e. no command line options
+  are necessary, and a client linked against openssl can
+  speak with a server linked against libgcrypt and vice versa.
+- Major cleanup of the networking subsystem.
+- Improvements to para_fade: the new set mode, multi-channel
+  initial volumes, better error logging.
+- The man pages of para_audiod, para_filter, para_recv, and
+  para_write contain the relevant options for receivers, filters,
+  writers. This broke in 0.5.0.
+- ogg/vorbis latency improvements.
+- Improved user manual.
+- Minor fixes to avoid clang warnings.
+
+Downloads:
+[tarball](./releases/paraslash-0.5.2.tar.bz2),
+[signature](./releases/paraslash-0.5.2.tar.bz2.asc)
+
+------------------------------------------
+0.5.1 (2013-12-20) "temporary implication"
+------------------------------------------
+
+Lots of fixes and improvements all over the place, and a major overhaul
+of the build system.
+
+- Audiod improvements and fixes.
+- Buffer tree robustness improvements.
+- Cleanup of the mood subsystem.
+- Fixes and cleanups for the flac decoder.
+- Latency improvements for the ogg/opus decoder.
+- Crypto support is now optional. On systems without
+  openssl/gcrypt, the build succeeds but para_server,
+  para_audiod, para_client won't be built.
+- The build system now works for cross-compile setups.
+- The dependency tree has been flattened, which speeds up
+  builds and avoids to recreate the man pages on every change.
+- The error code helper has been rewritten from perl to C,
+  which further improves build time.
+- Many small bugs in the build system have been identified
+  and fixed.
+
+Downloads:
+[tarball](./releases/paraslash-0.5.1.tar.bz2),
+[signature](./releases/paraslash-0.5.1.tar.bz2.asc)
+
+----------------------------------------
+0.5.0 (2013-08-23) "invertible validity"
+----------------------------------------
+
+Some API-breaking changes, one serious bug fix, and a lot of bike-shedding.
+
+- The sideband compatibility code has been removed, hence
+  sideband connections (introduced in 0.4.11) are now mandatory.
+- Addblob commands can produce output.
+- The stat command no longer sends garbage when para_server was
+  compiled against libgcrypt.
+- Dependencies for gengetopt files are computed automatically.
+  This eliminates a constant source of build bugs.
+- The setatt command now accepts file name patterns rather than only
+  path names.
+- overview.pdf is now based on dia, a simple diagram creation program.
+  The new version is much more detailed and contains descriptions of
+  the various programs of the paraslash package.
+- The separator of all multi-word options has been changed from
+  underscore to dash. For example --log_color becomes --log-color.
+- Overhauled web pages and the new logo.
+
+Downloads:
+[tarball](./releases/paraslash-0.5.0.tar.bz2),
+[signature](./releases/paraslash-0.5.0.tar.bz2.asc)
+
+--------------------------------------
+0.4.13 (2013-07-29) "spectral gravity"
+--------------------------------------
+
+One more 0.4.x release before the API-breaking changes for 0.5.0 go
+in. The main features of this release are the ogg/opus audio format,
+and UTF-8 support, but it includes also tons of other improvements
+and fixes all over the place.
+
+- New audio format: ogg/opus.
+- UTF8 support for para_gui and the mp3 audio format handler.
+- Scheduler improvements and fixes.
+- The obsolete gettimeofday() function has been replaced
+  by clock_gettime() on systems which support it.
+- Speed and usability improvements for para_gui.
+- para_client now restores the fd flags of stdin and stdout
+  on shutdown.
+- Improved manual pages.
+- Consistent version strings for all executables.
+- Reduced dependencies on generated files result in fewer
+  recompilations on changes.
+- Performance improvements for the compress filter.
+- Improved downloads web page.
+
+-----------------------------------------
+0.4.12 (2012-12-20) "volatile relativity"
+-----------------------------------------
+The new command line player, the resample filter, ALSA support for
+para_fade, and the improved build system are the highlights of this
+release which probably marks the end of the 0.4.x series.
+
+- The afh receiver and the para_play executable.
+- The resample filter: A sample rate converter based on
+  libsamplerate.
+- The "versions" directory has been removed from the master
+  branch. The tarballs of the old releases are now available
+  in the new "releases" branch.
+- Overhaul of the build system: All generated files are now
+  written to the "build" directory.
+- The modular mixer API and the alsa mixer.
+- Minor fixes for the osx writer.
+
+--------------------------------------
+0.4.11 (2012-07-20) "mutual diversity"
+--------------------------------------
+
+The major feature in this release is the new sideband API for
+client-server communication. This API will be used exclusively starting
+with 0.5.0, which breaks backward compatibility but allows to get rid
+of quite some compatibility code. Other noteworthy changes include
+decoder latency improvements and a long-standing bug fix for the
+ALSA writer.
+
+- Sideband connections: If both para_server and para_client
+  support this feature, data is sent as a multiplexed stream.
+- The --no_default_filters option of para_filter has been
+  removed.
+- Several fixes and latency improvements to various decoders.
+- The ALSA writer now limits the prebuffer time to 500ms.
+- Documentation improvements.
+- Overhaul of the command_util.sh script.
+- Fixes for some minor problems found by the clang analyzer.
+- Compiles (almost) without warnings on gcc-3.
+- Robustness improvements of the buffer tree code.
+
+------------------------------------------
+0.4.10 (2012-03-30) "heterogeneous vacuum"
+------------------------------------------
+
+Nothing earth-shaking in this release, but quite a few usability
+improvements and the usual mix of cleanups and fixes.
+
+- The --no_default_filters option of para_filter has been
+  deprecated. It still works but has no effect and will be
+  removed in the next version.
+- para_gui now prints also the stderr output of the executing
+  command in the bottom window.
+- Cleanup and consolidation of the various wrappers for
+  write(), writev(), send() and friends.
+- The obscure error messages on mmap() failures have been
+  replaced by meaningful messages. This affects mainly
+  para_afh.
+- para_audioc: Cleanups and memory leak fixes.
+- Test 0004-server no longer fails if para_server is not
+  being built.
+- New configure options: --with-id3tag-{headers,libs}.
+
+-------------------------------------
+0.4.9 (2011-12-06) "hybrid causality"
+-------------------------------------
+
+Support for another audio format, interactive mode for para_client
+and para_audiod and many small improvements/fixes all over the place.
+
+- Support for flac, the free lossless audio codec.
+- Fix for an endless loop in the mp3 decoder for certain
+  (corrupt) mp3 files.
+- When executed without specifying a command, para_client
+  and para_audioc start an interactive shell (requires
+  libreadline being installed). The interactive mode offers
+  full tab completion and command line history.
+- autogen.sh now detects a distcc setup and adjusts the
+  parameter for the -j option of make accordingly.
+- Shared memory areas are no longer restricted to 64K. We now
+  detect the maximal size of a shared memory area at runtime.
+- cleanup of the internal uptime API.
+- para_server prefaults the mmapped audio file to avoid
+  delays on slow media.
+- A new test for the test-suite that exercises the
+  communication between para_server and para_audiod.
+- The alsa writer eats up less CPU cycles when configured to
+  use the DMIX plugin.
+- Simplified and unified receiver code.
+- Makefile cleanups.
+- Commands which print a list of matching audio files now
+  emit a meaningful error message if no audio file matched the
+  given pattern(s).
+
+--------------------------------------
+0.4.8 (2011-08-19) "nested assignment"
+--------------------------------------
+
+Gcrypt support, the overhauled osx writer and regex format specifiers
+are the highlights of this release.
+
+- support for libgcrypt as a drop-in replacement for openssl.
+  Run configure --enable-cryptolib=gcrypt to link against
+  libgcrypt. The two crypto implementations are compatible to
+  each other, i.e. a para_client executable linked against
+  gcrypt can connect to para_server linked against libssl
+  and vice versa.
+- Rewrite of the osx writer (output plugin for Mac OS).
+- audiod: The format specifier for receivers, filters and
+  writers is now treated as a regular expression. This allows
+  to replace 5 lines in the config file (one for each audio
+  format) by one single line. See the manual for details.
+- The \*.cmdline.[ch] files are no longer contained in the released
+  tarballs. This reduces the size of the tarballs but requires
+  gengetopt to build the tarball.
+- Compiles cleanly also with llvm/clang.
+- Corrupt mp3 files are handled more gracefully.
+- The alsa writer uses poll fds instead of computing timeouts.
+- Cleanup of the generic writer API.
+- sched: Optimized zero timeouts.
+- vss timeout cleanups.
+- oggdec fixes and improvements.
+
+--------------------------------------
+0.4.7 (2011-06-01) "infinite rollback"
+--------------------------------------
+
+The new ao writer, support for ssh RSA keys and a couple of other
+enhancements.
+
+- Support for ESD, Pulseaudio, AIX, Solaris, IRIX and other
+  platforms through the libao audio library.
+- Support for RSA keys generated with ssh-keygen.
+- configure: improved options for ogg/vorbis/speex.
+- The git version reported by --version always matches HEAD.
+- The autogen script detects the number of processors and
+  runs a parallel make if possible.
+- Major cleanup of the crypto API.
+- Documentation updates.
+
+------------------------------------------
+0.4.6 (2011-03-31) "deterministic entropy"
+------------------------------------------
+
+Lots of ogg/vorbis improvements, the new test suite, enhancements
+for para_gui and a fair amount of other bug fixes.
+
+- For DCCP/OGG streams the audio file header is only sent once
+  at the beginning of the stream rather than periodically
+  every five seconds. This reduces network traffic and the
+  FEC group size.
+- The vorbis comment header is replaced by an empty dummy header
+  before the header is sent over the network. This also results in
+  less network traffic and smaller FEC groups.
+- The new "test" make target allows to perform some sanity checks prior
+  to installing the package.
+- ogg timing fixes and performance improvements
+- Scheduler improvements
+- Proper exit codes for para_write
+- para_gui: New option --theme to select a startup theme. Several
+  other improvements and fixes.
+- aacdec error message cleanups
+- simplified color error handling
+
+--------------------------------------------
+0.4.5 (2010-12-17) "symmetric randomization"
+--------------------------------------------
+
+Bug fixes, internal cleanups and variable-sized FEC slices.
+
+- Contains a fix for an invalid-free-bug in the ogg audio format
+  handler code.
+- Switching off the DCCP sender works again.
+- para_audiod handles crashes of para_server more robustly.
+- Internal scheduler and writer cleanups.
+- Reduced latency due to variable-sized FEC slices.
+- Improved documentation and error diagnostics.
+- The build of para_server is now optional, allowing the build
+  to succeed in case libosl is not installed.
+
+------------------------------------------
+0.4.4 (2010-08-06) "persistent regularity"
+------------------------------------------
+
+Support for yet another audio format, para_write improvements and
+bug fixes.
+
+- Support for the speex codec.
+- Support for sample formats other than 16 bit little endian.
+- error2.h is now created by a perl script which speeds up configure
+  considerably.
+- Fix a bug in the aac decoder which could lead to segfaults in
+  para_filter/para_audiod.
+- Fixes for autoconf-2.66.
+
+----------------------------------------
+0.4.3 (2010-07-05) "imaginary radiation"
+----------------------------------------
+
+Many improvements for the DCCP and the UDP transport, the new user
+manual and the usual mix of bug fixes and internal improvements.
+
+- FEC support for the DCCP sender (Gerrit Renker). The new
+  --dccp_max_slice_size, --dccp_data_slices_per_group and
+  --dccp_slices_per_group options can be used to set the FEC
+  parameters for the DCCP transport.
+- DNS lookups for UDP targets (Gerrit Renker).
+- The new user manual replaces the README, README.afs, REQUIREMENTS
+  and INSTALL documents.
+- Fix an end-of-file detection bug in the oggdec filter.
+- The new nonblock API.
+- Both options of the oggdec filter have been removed.
+- New debug mode for the internal scheduler.
+
+------------------------------------------
+0.4.2 (2010-04-23) "associative expansion"
+------------------------------------------
+
+It's been some time since the last release, but finally here is
+paraslash-0.4.2. The bulk of the changes comes from the new buffer
+tree API, but there are changes all over the tree. Mainly performance
+and usability improvements, but also quite some bug fixes.
+
+- The new buffer tree API.
+- DCCP: Support for CCID negotiation (Gerrit Renker).
+- UDP robustness fixes.
+- The --bufsize option for mp3dec is gone as it no longer makes sense
+  for the new buffer tree API.
+- Fix audible buffer underruns for wma streams.
+- The alsa writer no longer prints meaningless underrun durations.
+- audiod: Defaults work also for udp streams. If no filter is
+  given for an audio format that is received via upd, fecdec is
+  automatically added as the first filter (along with the decoder).
+
+---------------------------------------
+0.4.1 (2009-12-22) "concurrent horizon"
+---------------------------------------
+
+Support for another audio format, minor feature enhancements and lots of bug
+fixes. All fixes that have been accumulated in the maint branch (in particular
+those mentionened in the 0.3.6 release notes) appear in this release as well.
+
+- wma support.
+- new afh option: --human to activate human-readable output.
+- new server/audiod option: --log-timing to print timing information.
+- build system improvements.
+- source code documentation updates.
+
+-------------------------------------
+0.3.6 (2009-12-07) "cubic continuity"
+-------------------------------------
+
+Quite a few bugs have been found and fixed since 0.3.5, so here's
+another 0.3.x release. No new features.
+
+- Always check return value of malloc().
+- ogg vorbis/FEC: Do not write garbage after the audio file header.
+- exit if root privileges could not be dropped.
+- FEC: Fix computation of extra slices.
+- oss: Fix check for empty input buffer.
+- Avoid buffer underruns due to filter chain output buffer constraints.
+- server: Fix assignment of afs_pid.
+- Don't panic if the afs database contains unknown audio formats.
+- http/dccp: Do not send the audio file header twice.
+- FEC: Timing improvements.
+
+----------------------------------------------
+0.4.0 (2009-11-10) "simultaneous independence"
+----------------------------------------------
+
+Two significant changes which require the new version number: The
+improved authentication dialog and the fact that the database code
+has been moved to a library, libosl. To use the new version, you have
+to generate new RSA keys, see INSTALL for details. A shell script is
+provided for conversion of the 0.3 database to the new 0.4 format.
+
+- stronger crypto for client authentication
+- the database code has been moved to a library
+- improved status item handling
+- cleanup of the build system
+- The "-V" option now also prints the git version
+- the new parser-friendly listing mode for the ls and stat commands
+- mandatory rc4 encryption
+- major audio format handler cleanups
+- (id3,...) tags are no longer stored as a combined string in the database
+- new mood methods: artist_matches, title_matches, comment_matches,
+  album_matches, year_maches, year.
+
+--------------------------------------------
+0.3.5 (2009-09-21) "symplectic separability"
+--------------------------------------------
+
+Full client support for \*BSD Unixes, complete re-write of the ogg
+vorbis audio format handler, various improvements all over the place
+and the usual mix of bugfixes. This release marks the end of the 0.3
+series if no serious problems show up.
+
+- the new oss writer (supported on \*BSD and Linux)
+- rewrite of the ogg vorbis audio format handler. It's
+  recommended to replace the chunk tables of existing ogg
+  vorbis files in the afs database by re-adding these files
+  with "add -f".
+- support for netmask subsets (Gerrit Renker)
+- the new prebuffer filter
+- improved signal handling
+- variable fec output buffer size
+- improved FEC timing fixes audible buffer underruns in UDP mode
+- --log_color actually works
+- new ls option: -d (print dates as seconds after the epoch)
+- update to gengetopt 2.22.2
+- support for RSA keys of size > 512 bits
+- new option "mixer_channel" for para_fade
+
+-----------------------------------------
+0.3.4 (2009-05-07) "elliptic inheritance"
+-----------------------------------------
+
+The new udp sender, forward error correction, colored logs and various
+other improvements. As the udp sender does not depend on any special
+libraries, it is built unconditionally.
+
+- The udp sender replaces the ortp sender. The new code uses forward
+  error correction to protect against packet losses. Many thanks to
+  Gerrit Renker for providing ipv6 support.
+- The default port for udp streaming now defaults to 8000, like
+  for the http and the dccp senders/receivers.
+- Loglevels are now specified as symbolic names, e.g.
+  "--loglevel info".
+- improved ipv4 and ipv6 URI parser (Gerrit Renker).
+- para_server/para_audiod: Color support for log messages.
+- new options for mp3dec: --ignore-crc, --bufsize
+- new audiod option: --config-file.
+- gengetopt cleanups.
+- Improved help/man pages: The documentation of para_audiod,
+  para_recv, para_filter and para_write now also contains
+  all options of the available receivers/filters/writers. The
+  man page of para_fade contains a description of the different
+  modes of operation.
+- More source code documentation.
+- vss timing fixes.
+
+--------------------------------------------
+0.3.3 (2008-12-01) "axiomatic perspectivity"
+--------------------------------------------
+
+Internal code cleanups, bug fixes, improved tag handling and the new
+amplification filter.
+
+- para_server uses the generic scheduling code.
+- overhaul of the virtual streaming system.
+- mp3: id3 version 2 support via libid3tag (optional)
+- ogg: vorbis comment support.
+- aac meta info support.
+- mp3 audio format handler cleanups.
+- new filter: "amp" to amplify the amplitude of the audio stream
+- new status item/database entry: amplification. It is
+  used by the amp filter to pre-amplify the audio stream.
+- fix a close-without-open bug in para_write.
+- fix a bug in com_init() which was introduced in 0.3.2.
+- better error diagnostics for para_client.
+
+-----------------------------------------
+0.3.2 (2008-04-11) "probabilistic parity"
+-----------------------------------------
+
+The new para_afh executable, scheduling and documentation improvements.
+
+- new ls option: -lc (list chunk table)
+- new executable: para_afh, the stand-alone audio file handler tool
+- afs commands can send output more than SHMMAX (32MB on Linux). This
+  also reduces the memory usage of commands that produce large amounts
+  of output.
+- major scheduler and audiod cleanups.
+- more detailed and much nicer man pages.
+
+---------------------------------------
+0.3.1 (2008-02-23) "liquid interaction"
+---------------------------------------
+
+A mix of cleanups, bug fixes, improvements, and some new features. No
+significant changes to the new database (osl) code, which is generally
+a good sign.
+
+- Share some similar/duplicate code between the http and the
+  dccp sender.
+- Generic access control lists for paraslash senders.
+- dccp sender: Access control lists, connection limiting and support
+  for the allow,deny,on,off,help sender commands.
+- The default dccp port changed from 5001 to 8000 (suggested by
+  Gerrit Renker).
+- para_server starts even if not all public keys could be loaded.
+- Audiod performance improvements.
+- fix a bug in the "off" command of the http sender.
+- fix some fd and memory leaks.
+- Update to gengetopt-2.22.
+
+-------------------------------------
+0.3.0 (2008-01-12) "solar saturation"
+-------------------------------------
+
+paraslash.0.3.0 -- 'WWDBND --what would databases never do?'.
+
+
+Usually one might expect lots of new features AND a big increase in size
+for a major release like this.
+
+However, paraslash-0.3.0.tar.bz2 is the smallest paraslash tarball
+ever. The decrease in size is mostly due to the removal of some
+graphical tools (which were only quick hacks anyway). But also the
+fact that the mysql code is gone cuts down the size a bit.
+
+Being independent of mysql comes at a cost: The fact that paraslash
+now contains its own database (the object storage layer, osl) increases
+the (stripped) binary size of para_server by ~50K on i386.
+
+- no more restrictions on unique basenames.
+- independent of mysql: The new self-contained object
+  storage layer (osl) replaces the mysql database.
+- New executable para_fsck: Check integrity of osl tables.
+- Lyrics support.
+- Reliable audio file move/rename detection.
+- More portable than ever: Tested on Linux (x86_32, x86_64, sparc64),
+  MacOS (ppc32, x86_32), FreeBSD (x86_32), NetBSD (x86_32) and
+  Solaris (sparc64).
+- the new osl-based audio file selector (afs) replaces the random,
+  the playlist and the mysql selector of paraslash-0.2.x.
+- IPv6 support (thanks to Gerrit Renker).
+- paraslash-0.2.x streams are now called "moods". Writing
+  0.3.x-mood definitions should be both easier and more
+  powerful than writing 0.2.x-stream definitions.
+- para_krell, para_slider, para_para_sdl_gui, para_dbadm have
+  been removed. The world is a better place without them. However,
+  para_gui is still there.
+- afs tracks audio file selection also in playlist mode.
+- few easy-to-use afs commands replace the many not-so-easy-to-use
+  mysql commands (and are available also in playlist mode).
+- Improved error subsystem.
+- The earth-shaking new logo.
+
+-----------------------------------------
+0.2.17 (2007-11-20) "isotropic threshold"
+-----------------------------------------
+
+Mainly bugfixes and cleanups in this version which marks the end of
+the 0.2.x series if no serious bugs show up after the release.
+
+- mysql_selector: fix a locking bug.
+- universal chunk queueing.
+- dccp sender uses chunk queueing if write() returns EAGAIN (thanks
+  to Gerrit Renker).
+- be more carful wrt. signed vs. unsigned argument passing.
+- cleanup error.h and fix some references to invalid error
+  codes.
+- update to gengetopt-2.21.
+- update to ortp-0.13.1.
+- autoconf: extend checks for headers, library functions and
+  compiler characteristics.
+- Fix streaming of large mp3 files.
+- Fix an off-by-one bug in playlist handling.
+
+--------------------------------------
+0.2.16 (2007-04-05) "neural discharge"
+--------------------------------------
+
+The main change in this release is the major audio format handler
+cleanup which removes some similar/duplicate code and makes it easier
+to implement plugins for other audio formats. Of course, the usual mix
+of other improvements/changes/bugfixes also made it into the release.
+
+- simplified audio format handlers (most of the handling functions
+  were moved one layer up to the virtual streaming system).
+- para_server uses mmap to read audio files
+- repositioning of mp3 streams is much faster, in particular for
+  jumping near the end of large mp3 files.
+- permission flags DB_READ,DB_WRITE have been renamed to AFS_READ
+  and AFS_WRITE.
+- fix a bug in para_filter that caused decoding of aac files
+  to start only after a few seconds.
+- fix osx_writer hangs
+- simplified dccp code (thanks to Gerrit Renker)
+- the compress filter works also on big endian systems (ppc)
+
+-----------------------------------------
+0.2.15 (2007-02-16) "inductive resonance"
+-----------------------------------------
+
+Minor improvements, more documentation and a bunch of bug fixes.
+
+- para_server: The server.users file is only read once on server
+  startup rather than for each connection
+- mp3dec: Fix decoding of corrupt mp3 files
+- afs (audio file sender) is now called vss (virtual streaming
+  system). Consequently, the permission flags specified in
+  ~/.paraslash/server.users have also changed: AFS_READ and AFS_WRITE
+  become VSS_READ and VSS_WRITE respectively.
+- para_audiod/para_filter: Fix a bug that caused the last chunk
+  of audio data not being written under certain circumstances
+- audiod: compute the difference of server time and local time
+  correctly
+- para_server/para_audiod: Fix some memory leaks
+- documentation improvements
+- configure.ac: fix checks for para_krell
+- new man pages
+
+-------------------------------------------
+0.2.14 (2006-10-15) "transient singularity"
+-------------------------------------------
+
+The only major enhancement of this version is the osx writer which completes
+the Mac OS Port and was originally planned already for 0.2.13 but had to wait
+until now for reasons beyond the scope of this changelog entry.
+
+- new output plugin for Mac Os: the osx writer
+- rename configure command line options from --enable-xxx-headers to
+  --with-xxx-headers and  --enable-xxx-libs to --with-xxx-libs
+- configure: new command line options: --with-mad-headers,
+  --with-mad-libs, --with-oggvorbis-headers, and --with-oggvorbis-libs
+- some robustness fixes
+- dymamic audio format recognition for audiod
+- para_server: new command line option: --autoplay_delay
+- para_audiod: new command line option: --clock_diff_count
+
+---------------------------------------
+0.2.13 (2006-07-14) "sonic convolution"
+---------------------------------------
+
+A bunch of new features and core changes.
+
+- the new paraslash scheduler, short and sweet.
+- Support for m4a/mp4 files via the new aac audio format
+  handler/filter (requires libfaad).
+- each writer has its own command line parser, just like
+  para_recv and para_filter.
+- para_client and para_audioc use the error subsystem
+- writers are integrated in para_audiod (currently linux-only)
+- para_client is integrated in para_audiod
+- random/playlist selector: improved info strings
+- new audiod commands: tasks, kill
+- update to libortp-0.10.1
+- para_fade: wake time defaults to 8 hours from now
+- update to autoconf-2.60
+
+------------------------------------------
+0.2.12 (2006-05-12) "oriented abstraction"
+------------------------------------------
+
+Many user-visible changes in this release and lots of new
+features:
+
+- the new optional dccp sender/receiver. It uses the datagram
+  congestion control protocol. You'll need a fairly new kernel
+  for this.
+- paraslash works on Mac OS X (thanks to Gerd Becker)
+- para_play renamed to para_write
+- modular output plugin design (writers) for para_write
+- new file_writer output plugin for para_write
+- compress filter speed improvements
+- update to libortp-0.9.1
+- update to gengetopt-2.17rc
+- para_client no longer depends on libreadline (as the
+  code for the interactive mode was removed).
+- gcc-2-95 is no longer a supported compiler. It may still
+  work, but it gets no more testing.
+- the tarball no longer contains the screenshot images which
+  reduces its size quite a bit.
+- configure: new command line options: --enable-mysql-headers
+  and --enable-mysql-libs
+
+------------------------------------
+0.2.11 (2006-03-11) "atomic duality"
+------------------------------------
+
+Here it is, the first paraslash release developed with git. There
+are fairly many user-visible changes in this release. As two out of
+the three "database tools" of paraslash don't use a database at all,
+they are now called "audio file selectors" instead.
+
+- the cdt command (change database tool) becomes chs (change
+  selector)
+- no more colon separators: The syntax of some options of
+  para_audiod and para_filter have changed. Use --help for
+  more info (and some examples).
+- update to gengetopt-2.16 (thanks to Lorenzo Bettini)
+- switch from cvs to git (should've done that earlier)
+- the new ipc subsystem
+- new audio file selector: playlist
+- para_server: the dopey selector is now called "random",
+  and is the default selector. Use the --selector option to
+  choose another selector at startup, or the chs command to
+  change the selector at runtime.
+- X86_64 fixes (thanks to Steffen Klassert)
+- para_play fixes
+
+--------------------------------------
+0.2.10 (2006-02-17) "cyclic attractor"
+--------------------------------------
+
+Huge documentation update, a scrollable window for para_gui, ortp
+improvements, and of course many small fixes not mentioned here.
+The diffstat below is rather misleading as most insertions are due
+to the new source documentation.
+
+- autoconf cleanup
+- para_server also uses the new error subsystem
+- lots of new documentation (UTSL)
+- gui improvements:
+       - keysyms for cursor keys and for next/previous page keys
+       - scrollable output window
+       - new internal commands: scroll up/down, page up/down
+       - fix color of command output.
+- ortp: the --chunk_time and --header flags are no longer needed
+for para_recv/para_audiod as this information is now encoded in
+each rtp packet sent by para_server.
+
+-------------------------------------------
+0.2.9 (2006-01-24) "progressive turbulence"
+-------------------------------------------
+
+Internal audiod receivers/filters, the new error subsystem and
+a lot of small improvements.
+
+- para_recv and para_filter are integrated into the para_audiod
+  binary, i.e. audiod no longer spawns a new process for
+  each receiver/filter. As para_recv and para_filter might be
+  useful as standalone programs, they still get built (linked
+  against the same object files that are also used for audiod).
+- further ortp timing improvements should reduce the CPU usage
+  of the ortp receiver.
+- improved audio grabbing. The 'grab' command of para_audiod
+  has its own set of command line options. Read the output of
+  "para_audioc help grab" for more info.
+- oggdec: configurable input prebuffer size.
+- the new error subsystem gives better error diagnostics
+  and reduces code size.
+
+-----------------------------------------
+0.2.8 (2006-01-02) "dynamic accumulation"
+-----------------------------------------
+
+The new modular filter design and the para_play-hangs bugfix.
+
+- new executable: para_filter. It combines para_mp3dec,
+  para_oggdec and para_compress. It also adds a further filter
+  type, wav, that just inserts a wave header at the desired point
+  of the filter chain. All 'piping' is done in-memory (i.e. no
+  read/write operations are used).
+- para_play: fix a stupid bug that caused it to hang under
+  certain circumstances.
+
+-------------------------------------------
+0.2.7 (2006-12-27) "transparent invariance"
+-------------------------------------------
+
+Not many user-visible changes but a fair amount of internal improvements.
+
+- The http sender buffers data if it can not be sent
+  out immediately (because the socket is not writable). This
+  should prevent para_server from shutting down the connection
+  too early on a loaded network.
+- para_play also prebuffers data if it is told to start at a
+  future time by the --start_time option.
+- The return of para_recv: It combines para_ortp_recv and
+  para_http_recv. Use the --receiver option to switch between
+  the two. para_recv builds without libortp, but contains
+  only the http receiver in this case.
+- update to ortp 0.8.1. As this ortp release contains incompatible
+  changes, para_recv-0.2.7 won't link against older ortp libs.
+- improved ortp timings.
+- use of gcc-extensions that #define away for non-gcc and
+  gcc < 3.0.
+
+-------------------------------------------
+0.2.6 (2005-10-29) "recursive compensation"
+-------------------------------------------
+
+Transparent session encryption (uses openssl's Alleged RC4 cipher),
+the internal find command and several other improvements and cleanups.
+
+- Encrypt the session if encryption is requested by the client
+  (default for para_client 0.2.6). This is backwards
+  compatible, so older clients can still connect to para_server
+  0.2.6. Use the new client option --plain to request an
+  uncrypted session (off by default, must be set to on in
+  order to connect to para_server 0.2.x with 0 <= x <= 5).
+- para_server uses an internal function to locate audio files
+  rather than calling find(1). The server option
+  --mysql_audio_file_dir replaces --mysql_find_cmd.
+- documentation update
+- man pages
+- header file cleanup
+- para_client code cleanup
+- para_gui: faster display of output of display commands
+
+------------------------------------------
+0.2.5 (2005-10-13) "aggressive resolution"
+------------------------------------------
+
+This release adds internal senders, i.e. no more external programs are
+spawned for sending out the audio data. There are two different senders
+available: The http sender and the ortp sender (former para_send which
+is no longer needed).
+
+The new sender code has a plugin-like design so it can be easily
+extended should there be be any future need for supporting another
+network streaming protocol. All senders are completely independent of
+each other. In particular, the http and the ortp sender can operate
+in parallel.
+
+- new server command: sender to control senders at runtime.
+  Read the output of "para_server -h" and "para_client help
+  sender" for more information.
+- para_recv renamed to para_ortp_recv
+- new executable: para_http_recv, a simple command line
+  http receiver.
+- major afs/mp3/ogg code simplifications due to internal
+  senders.
+- ogg timing improvements
+- fix several minor memory leaks (found by valgrind)
+- empty stream definitions work again
+- com_ne(): ignore errors on remove
+- audiod: fix segfault on server restart
+
+---------------------------------------
+0.2.4 (2005-09-21) "toxic anticipation"
+---------------------------------------
+
+Several small improvements, fixes and the new grab command.
+
+- audiod:
+       - new command: "grab" to grab the output of the stream reader
+         or any filters. Read the output of "para_audioc help grab"
+         for more information.
+       - fix memory leak
+       - code cleanup
+- audioc: new command line option: --bufsize to specify a
+  buffer size different from the default size 8192.
+- improved error diagnostics for para_play.
+- new configure option: --enable-ssldir so search for openssl in
+  non-standard places
+- sdl_gui: Make it look nice again for 1024x768
+- server: report total size of memory allocated with sbrk by malloc,
+  new command line option: --announce_time
+
+-----------------------------------------
+0.2.3 (2005-09-01) "hydrophilic movement"
+-----------------------------------------
+
+Two new executables and major feature enhancements.
+
+- audiod filters: It is now possible to specify arbitrary many
+  (including none) filters for each supported audio
+  format. This can be used e.g. for normalizing volume,
+  transforming or grabbing the audio stream, or for using
+  visualizers. Read the output of "para_audiod -h" for the
+  syntax of the new --filter_cmd option.
+- new executable: para_play, a tiny alsa player. It
+  can play wave files or raw pcm (16 bit little endian)
+  from stdin.
+- new executable: para_compress, a dynamic range compressor
+  intended to keep audio output at a consistent volume. Derived
+  from [AudioCompress](http://trikuare.cx/code/AudioCompress.html).
+- audiod: New option: --stream_delay. This can be used in
+  a local network to syncronize the audio output of all
+  clients that play the same stream.
+
+------------------------------------------
+0.2.2 (2005-08-19) "tangential excitation"
+------------------------------------------
+
+Mostly internal changes in this release, but also some new commands
+for the mysql database tool.
+
+- cleanup exec.c, fix para_exec bug
+- compile time loglevel (log messages below the given level
+  won't be compiled in, which reduces the size of the
+  resulting binaries)
+- new log macros that shorten the size of the source code.
+- workaround a gcc-4.1 bug (?) that caused send_cred_buffer()
+  to send only zeros. With this workaround, para_audioc works
+  again.
+- avoid gcc-4 warning: conflicting types for built-in function 'clog'
+- new mysql commands: "rm" (remove entry), "mv" (rename entry) "ne"
+  (new entry), "snp" (set numplayed). Read the manual for more
+  information.
+
+---------------------------------------
+0.2.1 (2005-08-15) "surreal experience"
+---------------------------------------
+
+Here comes paraslash-0.2.1. It contains a couple of new features and,
+surprise, only minor bug fixes.
+
+- kill noisy mp3 debug message
+- cleanup of the build system
+- para_server and para_client directly use the crypto routines
+  of the openssl library rather than invoking the openssl command
+  line utitlity
+- server/audiod: new option --user to switch to the given user
+  when invoked as root. Read the output of "para_server -h" for
+  more information.
+- gui/sdl_gui: new option --stat_cmd to be used to retrieve the
+  status. Default: "para_audioc stat"
+- sdl_gui: new option --pic_cmd to be used to download the picture.
+  Default: "para_client pic"
+- audiod: 5 slots ought to be enough for everybody
+- audiod: new status item: Uptime, kill hup command
+
+------------------------------------------
+0.2.0 (2005-08-06) "distributed diffusion"
+------------------------------------------
+
+After several month of increased development activity, paraslash-0.2.0
+has arrived. It contains many new features and is much more
+self-contained than the old 0.1.x series. Enjoy!
+
+- para_server: fix hang on song change and crash on sighup.
+  Speed up mysql queries. The DIR_LIKE macro is gone.
+- new executables: para_audiod, the local audio daemon that
+  starts playback (uses SCM_CREDENTIALS socket magic) and
+  para_audioc, the corresponding client.
+- new executables: para_mp3dec/para_oggdec, two really teensy
+  decoders. para_mp3dec is based on libmad, para_oggdec requires
+  libvorbisfile.
+- ovsend/ovrecv are capable of streaming ogg as well as mp3, so
+  they are now called para_send and para_recv respectively.
+- documentation updates
+- para_gui is themable. For now there is the default theme that
+  looks as before and the simple theme: blue and easy.
+- gui: audio streaming is now handled by audiod. Time display shows
+  playback time rather than streaming time
+- slider: update to libzmw-0.2.0
+- para_krell: fix crash on server shutdown
+- switch from gzip to bzip2
+
+----------------------------------------
+0.1.7 (2005-04-18) "melting penetration"
+----------------------------------------
+
+The main change in this release is clearly the oggvorbis rewrite,
+but there are also lots of smaller changes. If you intend to use both
+the mp3 and the ogg plugin, it is recommended to use software mixing,
+e.g. the dmix plugin which is provided by ALSA.
+
+- new executables: para_ovsend and para_ovrecv for sending/receiving
+  oggvorbis files via rtp. Requires the open rtp library. Get it at
+  http://www.linphone.org/ortp/
+- rewrite of the ogg_vorbis core code
+- configure detects libzmw and, if detected, includes
+  para_slider to the list of binaries to be built by make
+- server stream writers read from their associated fifo rather
+  than from stdin
+- slider: two new sliders, lastplayed and numplayed
+- fix nasty double free bug which caused random segfaults in case of
+  mp3 files with invalid header information
+- gui: new command line option: --stream_timeout=seconds  to
+  deactivate a slot if it is idle for that many seconds (default=`5')
+- diffstats
+
+---------------------------------------
+0.1.6 (2005-03-05) "asymptotic balance"
+---------------------------------------
+
+Only little user-visible changes in this release. Mainly bugfixes and
+core code cleanup. This is probably the most stable version ever if you
+stick to mp3...
+
+- fix several memory leaks
+- rename default name of mysql database from "music" to "paraslash".
+  Use para_server's  --mysql_database option if you do not want to
+  rename your old database.
+- rework ogg vorbis code
+- make update command work on mysql servers with LOCAL_INFILE
+  disabled
+- gui: improved stream I/O (slots)
+- simplified audio format API
+- para_pob_ogg is gone
+
+------------------------------------
+0.1.5 (2004-12-31) "opaque eternity"
+------------------------------------
+
+Let's slide gently into the new year.
+
+- new: para_slider (not built automatically, type "make
+  para_slider" to build). A toy for those who always felt that
+  creating stream definitions is difficult. See screenshots,
+  README and FEATURES for more info.
+- improved signal handling. Fixes server segfault on SIGHUP
+  for linux kernels newer than Aug 24 2004 and makes para_gui
+  race-free.
+- reload database tool on SIGHUP
+- improved help message for sl
+- do not log "broken pipe" messages as errors. They are
+  perfectly ok.
+- fix wrong error message on permission errors
+
+-----------------------------------------
+0.1.4 (2004-12-19) "tunneling transition"
+-----------------------------------------
+
+Bugfix release. As expected, 0.1.3 introduced a bunch of new bugs.
+Hopefully, most of them got wiped out with this release. Some
+enhancements went also in.
+
+- improved error diagnostics for all commands
+- stradd/picadd: overwrite previous contents if entry already
+  exists, rather than returning errors
+- stradd: use current stream if invoked without args
+- faster (and hopefully more stable) ogg-vorbis handling
+- para_krell: reap children to avoid zombie-flooding in case
+  no server is running
+- si: report also server pid
+- server: don't busy-loop if dbtool reports only invalid files.
+- gui: CTRL+C works again, fix stream_read command line option
+- fix pic_add, hist
+- fix mysql dbtool startup in case no database exists
+- many small fixes and cleanups
+
+---------------------------------------
+0.1.3: (2004-12-10) "vanishing inertia"
+---------------------------------------
+
+Starting from this release, the database tools are integrated in the
+server binary. This decreases server startup time, reduces code size
+and speeds up database commands. However, the layout of the underlying
+mysql database changed only slightly and 0.1.3 should be backwards
+compatible in that respect.
+
+Visible changes:
+
+- If mysql is not detected at compile time, or fails to init
+  at runtime, fall back to the dopey database tool which should
+  always work.
+- para_dbtool and dbtool.conf are gone. All mysql specific
+  options are read from server.conf and are prefixed by 'mysql_'.
+- new command: cdt (change database tool)
+- new command line option: dbtool (choose startup database tool)
+- The name of current stream is now stored in the database,
+  so paraslash remembers its current stream when restarted.
+- new command: csp (change stream and play)
+- para_gui also reports current database tool and server uptime
+
+-------------------------------------------
+0.1.2: (2004-11-28) "spherical fluctuation"
+-------------------------------------------
+
+Point release before the big dbtool changes go in.
+
+- dbtool: rename ca to cam (copy all meta data). It now also
+  copies numplayed and lastplayed time as well as the picture
+  id.
+- fix endless-loop-bug caused by mp3 files with invalid header
+
+-----------------------------------------
+0.1.1: (2004-11-05) "floating atmosphere"
+-----------------------------------------
+
+- gkrellm plugin
+- new dbtool command: mbox. Browse your sound-file collection
+  with your favorite mail reader.
+- several small fixes
+
+-------------------------------------
+0.1.0: (2004-10-22) "rotating cortex"
+-------------------------------------
+
+- fix logging bug for loglevel > VERBOSE
+- fix skip command
+- correct timings for vbr mp3s
+- modular audio format support
+- ogg-vorbis support (experimental)
+- new server option: autoplay
+
+-----------------------------------------
+0.0.99: (2004-07-25) "harmonic deviation"
+-----------------------------------------
+
+- rename projectname from icc to paraslash (play, archive, rate
+  and stream large audio sets happily)
+- paraslash is no longer restricted to one particular audio
+  streaming software
+- new dbtool commands (stradd, strq, strdel) for easy stream
+  managment w/o configuration file. That obsoletes stream_defs
+  file/config option for dbtool.
+- picadd accepts jpeg data from stdin
+- new server commands: ps (select previous stream), sc (song change)
+- new default pictures for sdl_gui
+- gui: new key_map option for binding commands and internal
+  functions to arbitrary keys, nice help screen, rip out
+  soundcard/linux specific stuff, avoid noise artefacts while jumping,
+  show silly logo on startup
+- new executables: para_fade for fading volume, para_dbadm for
+  manipulating attributes
+- cdb adds _all_ tables to mysql database
+- revised and beautified documentation
+- sample dbtool rewritten in C
+- autoconf
+
+---------------------------------------------
+0.0.98: (2003-12-26) "incremental smoothness"
+---------------------------------------------
+
+- kick icecast in favour of poc. That removes some races and reduces
+  core code considerably.
+- cbr/vbr is displayed by stat and gui/sdl_gui. New status flags
+  give finer info on afs' status.
+- gui can start decoder (see config options). Further new gui
+  commands: refresh (^L), jmp (F1-F10)
+- gui rereads conf on SIGUSR1 instead of SIGHUP. SIGHUP
+  terminates gui. This fixes dead instances consuming memory
+  continuously.
+- new dbtool command: verb for sending verbatim sql queries.
+- fix pid_list races (by removing pid_list)
+- codename funnies
+
+--------------------
+0.0.97: (2003-10-26)
+--------------------
+
+- installation prefix now defaults to /usr/local
+- new commands for gui: snozze, sleep and reread config
+- config file for gui and sdl_gui
+- fix problems with filenames containing funny characters
+  (reported by Thomas Forell)
+- improved signal handling for gui, now it rereads conf on SIGHUP
+- new dbtool command: cdb (create database)
+- switch from argtable to gengetopt
+- major code cleanup and speed improvements
+- fix several potential buffer overflows
+- many small fixes and cleanups
+
+-------------------
+0.0.96 (2003-08-30)
+-------------------
+
+- easy stream_defs syntax
+- sdl_gui can display images associated to the file being played
+- Major feature enhancements for icc_gui including dynamic text
+  placement and the top/bottom window design
+- vrfy/clean now also checks for NULL values in attributes as
+  well as for invalid picture pointers
+- fix long outstanding case sensitivity bug
+- many small fixes and cleanups
+
+-------------------
+0.0.95 (2003-06-29)
+-------------------
+
+- sdl gui runs much faster
+- new dbtool command: ca (copy attributes)
+- count and display number of times the song has been played
+- new feature: scoring
+- command line options for sdl_gui
+- simpler syntax of streams file
+- decrease network traffic of stat
+- fix zombie bug
+- many small fixes and cleanups
+
+-------------------
+0.0.94 (2003-05-04)
+-------------------
+
+- new server command: ns (next stream)
+- new icc_gui command: c (change stream)
+- internal mp3info
+- stat shows also id3 tag info
+- new sdl based gui
+- log flodding bug fixed
+- many small fixes and cleanups
+
+-------------------
+0.0.93 (2003-03-28)
+-------------------
+
+- colors for icc_gui
+- icc_gui sets volume directly (linux only)
+- proper locking that fixes some races
+- fix security bug that caused commands to be executed even
+  with unsufficient permissions
+- new command: hup to make all servers reread their configuration file
+- icecast meta data streaming
+- many small fixes and cleanups
diff --git a/README b/README
index 0a0aae881bf6a766d449550c5ddc51152a4800bc..d8a545fc7abd744e6df57c51638dee607574e69e 100644 (file)
--- a/README
+++ b/README
@@ -6,7 +6,6 @@ Distribution of paraslash is covered by the GNU GPL, version 2 unless
 otherwise stated. See file COPYING.
 
 Web page:             http://people.tuebingen.mpg.de/maan/paraslash/
-Alternative web page: http://paraslash.systemlinux.org/
 Gitweb:               http://git.tuebingen.mpg.de/paraslash.git/
 Git URL:              git://git.tuebingen.mpg.de/paraslash.git
 Email:                Andre Noll <maan@tuebingen.mpg.de>
index d3e694548a3dbfaf08e40eb5cd8ba01bc10af7cf..c49f30dea858f05c627a820685fd6538b55eb07d 100644 (file)
--- a/aac_afh.c
+++ b/aac_afh.c
@@ -317,7 +317,7 @@ close:
        return ret;
 }
 
-static const char* aac_suffixes[] = {"m4a", "mp4", NULL};
+static const char * const aac_suffixes[] = {"m4a", "mp4", NULL};
 /**
  * the init function of the aac audio format handler
  *
diff --git a/afh.h b/afh.h
index 7a30947a637e43fbeccc9788b30c21f917a427df..dad67351a9ec6548dd464d691d9013afee0a0d6c 100644 (file)
--- a/afh.h
+++ b/afh.h
@@ -88,7 +88,7 @@ struct audio_format_handler {
         */
        void (*init)(struct audio_format_handler*);
        /** Typical file endings for files that can be handled by this afh. */
-       const char **suffixes;
+       const char * const *suffixes;
        /**
         * Check if this audio format handler can handle the file.
         *
diff --git a/afs.c b/afs.c
index d5afc6d9eb12eb731fecfdb8209bcd150e0e01cd..cc3fc020370821ff028a2543c354dab4acc08039 100644 (file)
--- a/afs.c
+++ b/afs.c
@@ -424,7 +424,7 @@ static int pass_afd(int fd, char *buf, size_t size)
 {
        struct msghdr msg = {.msg_iov = NULL};
        struct cmsghdr *cmsg;
-       char control[255];
+       char control[255] __a_aligned(8);
        int ret;
        struct iovec iov;
 
@@ -497,12 +497,11 @@ no_admissible_files:
 }
 
 /* Never fails if arg == NULL */
-static int activate_mood_or_playlist(char *arg, int *num_admissible)
+static int activate_mood_or_playlist(const char *arg, int *num_admissible)
 {
        enum play_mode mode;
        int ret;
 
-       PARA_INFO_LOG("new playlist: %s\n", arg);
        if (!arg) {
                ret = change_current_mood(NULL); /* always successful */
                mode = PLAY_MODE_MOOD;
@@ -591,7 +590,7 @@ static void flush_and_free_pb(struct para_buffer *pb)
 
 static int com_select_callback(struct afs_callback_arg *aca)
 {
-       char *arg = aca->query.data;
+       const char *arg = aca->query.data;
        int num_admissible, ret;
 
        ret = clear_score_table();
diff --git a/afs.h b/afs.h
index 25ff421d8b86d0f5708d4b4f3749f310f9c4a877..2f9d7e5fc40bdc9c1661336ffce20d7a7df76148 100644 (file)
--- a/afs.h
+++ b/afs.h
@@ -263,7 +263,7 @@ int audio_file_loop(void *private_data, osl_rbtree_loop_func *func);
 int aft_check_callback(struct afs_callback_arg *aca);
 
 /* playlist */
-int playlist_open(char *name);
+int playlist_open(const char *name);
 void playlist_close(void);
 int playlist_check_callback(struct afs_callback_arg *aca);
 
diff --git a/aft.c b/aft.c
index 261054df8fc4012236b42246158b87b77ce1623c..f14440e6fb903548e25ccfdf611f4c2f2881aa49 100644 (file)
--- a/aft.c
+++ b/aft.c
@@ -696,7 +696,13 @@ static int get_local_time(uint64_t *seconds, char *buf, size_t size,
                        return -E_STRFTIME;
                return 1;
        }
-       if (!strftime(buf, size, "%b %e %Y", tm))
+       /*
+        * If the given time is more than six month away from the current time,
+        * we print only the year. The additional space character in the format
+        * string below makes the formated date align nicely with dates that
+        * contain the time (those written by the above strftime() statement).
+        */
+       if (!strftime(buf, size, "%b %e  %Y", tm))
                return -E_STRFTIME;
        return 1;
 }
index f3f8ea7a45d0fb1136827cc19c8a715fdd3773a6..4cb2982860de78dd26b9fc55ad552c73a7ca1b9f 100644 (file)
@@ -437,13 +437,13 @@ err:
 
 static int att_logical_or(struct osl_row *row, void *data)
 {
-       uint64_t *att_mask = data;
+       uint64_t *att_mask = data, one = 1;
        struct osl_object bitnum_obj;
        int ret = osl_get_object(attribute_table, row, ATTCOL_BITNUM, &bitnum_obj);
 
        if (ret < 0)
                return ret;
-       *att_mask |= 1 << *(unsigned char *)bitnum_obj.data;
+       *att_mask |= one << *(unsigned char *)bitnum_obj.data;
        return 0;
 }
 
index 1593b99ee5bda9fe6f7e47b6ab63c445a10ad529..638d19a3579b02053bd281e29e7f39d2bf54495c 100644 (file)
@@ -166,29 +166,26 @@ void free_vlc(struct vlc *vlc)
  * \param gbc The getbit context structure.
  * \param table The vlc tables to use.
  * \param bits The number of bits which will be read at once.
- * \param max_depth The number of times \a bits bits must be read to completely
- * read the longest vlc code = (max_vlc_length + bits - 1) / bits.
  *
  * The \a bits parameter must be identical to the \a nb_bits value supplied to
  * \ref init_vlc().
  *
  * \return The vlc code.
  */
-int get_vlc(struct getbit_context *gbc, VLC_TYPE(*table)[2], int bits,
-               int max_depth)
+int get_vlc(struct getbit_context *gbc, VLC_TYPE(*table)[2], int bits)
 {
        int n, idx, nb_bits, code;
 
        idx = show_bits(gbc, bits);
        code = table[idx][0];
        n = table[idx][1];
-       if (max_depth > 1 && n < 0) {
+       if (n < 0) {
                skip_bits(gbc, bits);
                nb_bits = -n;
                idx = show_bits(gbc, nb_bits) + code;
                code = table[idx][0];
                n = table[idx][1];
-               if (max_depth > 2 && n < 0) {
+               if (n < 0) {
                        skip_bits(gbc, nb_bits);
                        nb_bits = -n;
                        idx = show_bits(gbc, nb_bits) + code;
index 5890d08c89d4033f7fefb9a19be525860a701d77..5875b0d090e6e8007d34766ee090950c819188dd 100644 (file)
@@ -37,7 +37,7 @@ static inline uint32_t show_bits(struct getbit_context *gbc, int num)
 {
        int idx = gbc->index;
        const uint8_t *p = gbc->buffer + (idx >> 3);
-       uint32_t x = ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
+       uint32_t x = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
        return (x << (idx & 7)) >> (32 - num);
 }
 
@@ -62,7 +62,7 @@ static inline unsigned int get_bits(struct getbit_context *gbc, int n)
 static inline unsigned int get_bit(struct getbit_context *gbc)
 {
        int idx = gbc->index++;
-       uint8_t tmp = gbc->buffer[idx >> 3], mask = (1 << (7 - (idx & 7)));
+       uint8_t tmp = gbc->buffer[idx >> 3], mask = 1 << (7 - (idx & 7));
        return !!(tmp & mask);
 }
 
@@ -88,5 +88,4 @@ static inline void init_get_bits(struct getbit_context *gbc,
 void init_vlc(struct vlc *vlc, int nb_bits, int nb_codes, const void *bits,
                const void *codes, int codes_size);
 void free_vlc(struct vlc *vlc);
-int get_vlc(struct getbit_context *gbc, VLC_TYPE(*table)[2], int bits,
-               int max_depth);
+int get_vlc(struct getbit_context *gbc, VLC_TYPE(*table)[2], int bits);
diff --git a/blob.c b/blob.c
index 2e0a4762bfd1e34d0f12c7a9b2d4de582c8316d4..ca39de0db5fc8fdb15009d0ed1c46ec14ca15087 100644 (file)
--- a/blob.c
+++ b/blob.c
@@ -496,6 +496,8 @@ static int blob_get_name_by_id(struct osl_table *table, uint32_t id,
        ret = osl(osl_get_object(table, row, BLOBCOL_NAME, &obj));
        if (ret < 0)
                return ret;
+       if (*(char *)obj.data == '\0')
+               return -E_DUMMY_ROW;
        *name = (char *)obj.data;
        return 1;
 }
index 34cc9189bb2a1768765be83a5edaf5c0e2be7f5d..31cfff09798b2089e2b815a544fd207464f0e76c 100644 (file)
--- a/client.c
+++ b/client.c
@@ -323,11 +323,7 @@ static void lsatt_completer(struct i9e_completion_info *ci,
                struct i9e_completion_result *cr)
 {
        char *opts[] = {"-i", "-l", "-r", NULL};
-
-       if (ci->word[0] == '-')
-               i9e_complete_option(opts, ci, cr);
-       else
-               complete_attributes(ci->word, &cr->matches);
+       i9e_complete_option(opts, ci, cr);
 }
 
 static void mvatt_completer(struct i9e_completion_info *ci,
index 5960b0871ec7fc720bef13a90d9af5a58dd75e10..2e4b42ceb064ada1fceda9cfbf88ac5f15685ea8 100644 (file)
@@ -71,6 +71,10 @@ AC_PATH_PROG([GENGETOPT], [gengetopt])
 test -z "$GENGETOPT" && AC_MSG_ERROR(
        [gengetopt is required to build this package])
 
+AC_PATH_PROG([M4], [m4])
+test -z "$M4" && AC_MSG_ERROR(
+       [The m4 macro processor is required to build this package])
+
 AC_PATH_PROG([HELP2MAN], [help2man])
 test -z "$HELP2MAN" && AC_MSG_ERROR(
        [help2man is required to build this package])
diff --git a/error.h b/error.h
index b735233339f1b64a89697e318db36436a907e091..830d0f8d186560522b93dd89d51065ee4d4119e2 100644 (file)
--- a/error.h
+++ b/error.h
@@ -246,7 +246,6 @@ extern const char **para_errlist[];
 
 #define MOOD_ERRORS \
        PARA_ERROR(NO_MOOD, "no mood available"), \
-       PARA_ERROR(DUMMY_ROW, "attempted to access blob dummy object"), \
 
 
 #define MM_ERRORS \
@@ -261,6 +260,7 @@ extern const char **para_errlist[];
 
 #define BLOB_ERRORS \
        PARA_ERROR(BLOB_SYNTAX, "blob syntax error"), \
+       PARA_ERROR(DUMMY_ROW, "attempted to access blob dummy object"), \
 
 
 #define PLAYLIST_ERRORS \
index 1ba12689b45d7b41d3e2a8b1a8c06464114211a6..9378e4695b6b113843d7d1b34a96ded4bdebd79e 100644 (file)
--- a/filter.c
+++ b/filter.c
@@ -58,7 +58,7 @@ __noreturn static void print_help_and_die(void)
 
        ggo_print_help(&h, d? GPH_STANDARD_FLAGS_DETAILED : GPH_STANDARD_FLAGS);
        print_filter_helps(d? GPH_MODULE_FLAGS_DETAILED : GPH_MODULE_FLAGS);
-       exit(0);
+       exit(EXIT_SUCCESS);
 }
 
 static int parse_config(void)
index 51c3c314bf9e265110e82eabae9e94918e1bc7e3..2e2842b183c91bfbe06ec2de0616fb52872ba4f4 100644 (file)
@@ -515,7 +515,7 @@ free_pfad:
        return ret;
 }
 
-static const char* flac_suffixes[] = {"flac", NULL};
+static const char * const flac_suffixes[] = {"flac", NULL};
 
 /**
  * The init function of the flac audio format handler.
diff --git a/gui.c b/gui.c
index 9d96e70f6949362b39b50fa1dc23e85327a9316a..b0eae64ae129999083263846d60a9bfd939aae2e 100644 (file)
--- a/gui.c
+++ b/gui.c
@@ -146,7 +146,7 @@ struct exec_task {
        unsigned flags[2]; /* passed to for_each_line() */
 };
 
-static int find_cmd_byname(char *name)
+static int find_cmd_byname(const char *name)
 {
        int i;
 
@@ -246,8 +246,8 @@ static char *km_keyname(int c)
 /* Print given number of spaces to curses window. */
 static void add_spaces(WINDOW* win, unsigned int num)
 {
-       char space[] = "                                ";
-       unsigned sz = sizeof(space) - 1; /* number of spaces */
+       const char space[] = "                                ";
+       const unsigned sz = sizeof(space) - 1; /* number of spaces */
 
        while (num >= sz)  {
                waddstr(win, space);
@@ -255,8 +255,7 @@ static void add_spaces(WINDOW* win, unsigned int num)
        }
        if (num > 0) {
                assert(num < sz);
-               space[num] = '\0';
-               waddstr(win, space);
+               waddstr(win, space + sz - num);
        }
 }
 
@@ -264,41 +263,35 @@ static void add_spaces(WINDOW* win, unsigned int num)
  * print aligned string to curses window. This function always prints
  * exactly len chars.
  */
-static int align_str(WINDOW* win, char *str, unsigned int len,
+static int align_str(WINDOW* win, const char *str, unsigned int len,
                unsigned int align)
 {
-       int ret, i, num; /* of spaces */
+       int ret, num; /* of spaces */
        size_t width;
+       char *sstr; /* sanitized string */
 
        if (!win || !str)
                return 0;
-       ret = strwidth(str, &width);
+       ret = sanitize_str(str, len, &sstr, &width);
        if (ret < 0) {
                PARA_ERROR_LOG("%s\n", para_strerror(-ret));
                width = 0;
-               str[0] = '\0';
+               sstr = para_strdup(NULL);
        }
+       assert(width <= len);
        num = len - width;
-       if (num < 0) {
-               str[len] = '\0';
-               num = 0;
-       }
-       /* replace control characters by spaces */
-       for (i = 0; i < len && str[i]; i++) {
-               if (str[i] == '\n' || str[i] == '\r' || str[i] == '\f')
-                       str[i] = ' ';
-       }
        if (align == LEFT) {
-               waddstr(win, str);
+               waddstr(win, sstr);
                add_spaces(win, num);
        } else if (align == RIGHT) {
                add_spaces(win, num);
-               waddstr(win, str);
+               waddstr(win, sstr);
        } else {
                add_spaces(win, num / 2);
-               waddstr(win, str);
+               waddstr(win, sstr);
                add_spaces(win, num - num / 2);
        }
+       free(sstr);
        return 1;
 }
 
@@ -505,9 +498,18 @@ static __printf_2_3 void curses_log(int ll, const char *fmt,...)
 /** The log function of para_gui, always set to curses_log(). */
 __printf_2_3 void (*para_log)(int, const char*, ...) = curses_log;
 
+/* Call endwin() to reset the terminal into non-visual mode. */
 static void shutdown_curses(void)
 {
-       def_prog_mode();
+       /*
+        * If para_gui received a terminating signal in external mode, the
+        * terminal can be in an unusable state at this point because the child
+        * process might not have caught the signal. In this case endwin() has
+        * already been called and must not be called again. So we first return
+        * to program mode, then call endwin().
+        */
+       if (!curses_active())
+               reset_prog_mode();
        endwin();
 }
 
@@ -516,13 +518,22 @@ __noreturn __printf_2_3 static void die(int exit_code, const char* fmt, ...)
 {
        va_list argp;
 
+       /* Kill every process in our process group. */
+       para_sigaction(SIGTERM, SIG_IGN);
+       kill(0, SIGTERM);
+       /* Wait up to two seconds for child processes to die. */
+       alarm(2);
+       while (waitpid(0, NULL, 0) >= 0)
+               ; /* nothing */
+       alarm(0);
+       /* mousemask() exists only in ncurses */
+#ifdef NCURSES_MOUSE_VERSION
+       mousemask(~(mmask_t)0, NULL); /* Avoid bad terminal state with xterm. */
+#endif
        shutdown_curses();
        va_start(argp, fmt);
        vfprintf(stderr, fmt, argp);
        va_end(argp);
-       /* kill every process in the process group and exit */
-       para_sigaction(SIGTERM, SIG_IGN);
-       kill(0, SIGTERM);
        exit(exit_code);
 }
 
@@ -924,12 +935,7 @@ static int signal_post_select(struct sched *s, __a_unused void *context)
        switch (ret) {
        case SIGTERM:
                die(EXIT_FAILURE, "only the good die young (caught SIGTERM)\n");
-               return 1;
        case SIGINT:
-               PARA_WARNING_LOG("caught SIGINT, reset\n");
-               /* Nothing to do. SIGINT killed our child which gets noticed
-                * by do_select and resets everything.
-                */
                return 1;
        case SIGUSR1:
                PARA_NOTICE_LOG("got SIGUSR1, rereading configuration\n");
@@ -1485,9 +1491,9 @@ static int setup_tasks_and_schedule(void)
  * The exec task is responsible for printing the output of the currently
  * running executable to the bottom window.
  *
- * The signal task performs suitable actions according to any signals received.
- * For example it refreshes all windows on terminal size changes and resets the
- * terminal on \p SIGTERM.
+ * The signal task performs various actions according to signals received. For
+ * example, it reloads the configuration file on SIGUSR1, and it shuts down the
+ * curses system on SIGTERM to restore the terminal settings before exit.
  *
  * The input task reads single key strokes from stdin. For each key pressed, it
  * executes the command handler associated with this key.
index 8e21356f3bb362b3aecccd6f4d19bbaea58c7ae2..a6b718ee958815fdadff3ff4cb7206626f46540b 100644 (file)
@@ -41,15 +41,13 @@ string typestr = "command"
 default = "para_audioc -- stat -p"
 optional
 details = "
-       In order to run para_gui on a host on which no para_audiod
-       is running (hence the default command does not work), the
-       command
+       On a host on which the para_audiod service is not is running, the
+       default command will fail. An alternative is
 
                para_client -- stat -p
 
-       may be used. This command prints less information though.
-       In particular, no timing information about the current audio
-       file is printed.
+       This command connects para_server instead of para_audiod. However,
+       no timing information about the current audio file is printed.
 "
 
 #---------------------------------
index 5130ddd1d7779790250ac52eb2e263503a1002c7..0db9d10e8a33d7fef84af8533fb7a6dbf545a421 100644 (file)
@@ -18,10 +18,10 @@ endif
 
 $(m4depdir)/%.m4d: $(m4_ggo_dir)/%.m4 | $(m4depdir)
        @[ -z "$(Q)" ] || echo 'M4D $<'
-       $(Q) m4 -I $(m4_ggo_dir) -s $< \
+       $(Q) $(M4) -I $(m4_ggo_dir) -s $< \
        | awk '{if ($$1 ~ /#line/) {gsub(/"/, "", $$3); if ($$3 != "$<") \
        print "$(ggo_dir)/$(*F).ggo: " $$3}}' | sort | uniq > $@
 
 $(ggo_dir)/%.ggo: $(m4_ggo_dir)/%.m4 $(m4_ggo_dir)/header.m4 | $(ggo_dir)
        @[ -z "$(Q)" ] || echo 'M4 $<'
-       $(Q) m4 -I $(m4_ggo_dir) $< > $@
+       $(Q) $(M4) -I $(m4_ggo_dir) $< > $@
diff --git a/mm.c b/mm.c
index d6f3573ce438564f0edbc4c0aafa1a9642470f3d..92856ec3ef903eb905b0379c6eaff605bf6f8d06 100644 (file)
--- a/mm.c
+++ b/mm.c
@@ -191,6 +191,22 @@ static int mm_channels_score_function(__a_unused const char *path,
        return mm_compare_num_score_function(afhi->channels, private);
 }
 
+static int mm_image_id_score_function(__a_unused const char *path,
+               const struct afs_info *afsi,
+               __a_unused const struct afh_info *afhi,
+               const void *private)
+{
+       return mm_compare_num_score_function(afsi->image_id, private);
+}
+
+static int mm_lyrics_id_score_function(__a_unused const char *path,
+               const struct afs_info *afsi,
+               __a_unused const struct afh_info *afhi,
+               const void *private)
+{
+       return mm_compare_num_score_function(afsi->lyrics_id, private);
+}
+
 static int mm_num_played_score_function(__a_unused const char *path,
                const struct afs_info *afsi,
                __a_unused const struct afh_info *afhi,
@@ -356,5 +372,7 @@ const struct mood_method mood_methods[] = {
        {DEFINE_COMPARE_NUM_MOOD_METHOD(frequency)},
        {DEFINE_COMPARE_NUM_MOOD_METHOD(channels)},
        {DEFINE_COMPARE_NUM_MOOD_METHOD(num_played)},
+       {DEFINE_COMPARE_NUM_MOOD_METHOD(image_id)},
+       {DEFINE_COMPARE_NUM_MOOD_METHOD(lyrics_id)},
        {.parser = NULL}
 };
diff --git a/mood.c b/mood.c
index d29c62c22b396ac685f140b9d936f041184ca5d3..83c3a574a53c5658afe43a296ae2de9f2c368873 100644 (file)
--- a/mood.c
+++ b/mood.c
@@ -446,7 +446,7 @@ static int64_t normalized_value(int64_t x, int64_t n, int64_t sum, int64_t qd)
 {
        if (!n || !qd)
                return 0;
-       return 100 * (n * x - sum) / (int64_t)int_sqrt(n * qd);
+       return 100 * (n * x - sum) / (int64_t)int_sqrt(n) / (int64_t)int_sqrt(qd);
 }
 
 static long compute_score(struct afs_info *afsi, long mood_score)
@@ -460,7 +460,7 @@ static long compute_score(struct afs_info *afsi, long mood_score)
 
 static int add_afs_statistics(const struct osl_row *row)
 {
-       uint64_t n, x, s;
+       uint64_t n, x, s, q;
        struct afs_info afsi;
        int ret;
 
@@ -470,14 +470,18 @@ static int add_afs_statistics(const struct osl_row *row)
        n = statistics.num;
        x = afsi.last_played;
        s = statistics.last_played_sum;
-       if (n > 0)
-               statistics.last_played_qd += (x - s / n) * (x - s / n) * n / (n + 1);
+       if (n > 0) {
+               q = (x > s / n)? x - s / n : s / n - x;
+               statistics.last_played_qd += q * q * n / (n + 1);
+       }
        statistics.last_played_sum += x;
 
        x = afsi.num_played;
        s = statistics.num_played_sum;
-       if (n > 0)
-               statistics.num_played_qd += (x - s / n) * (x - s / n) * n / (n + 1);
+       if (n > 0) {
+               q = (x > s / n)? x - s / n : s / n - x;
+               statistics.num_played_qd += q * q * n / (n + 1);
+       }
        statistics.num_played_sum += x;
        statistics.num++;
        return 1;
@@ -604,7 +608,8 @@ static int add_if_admissible(struct osl_row *aft_row, void *data)
  * the last number a_n was replaced by b) may be computed in O(1) time in terms
  * of n, q, a_n, b, and S as
  *
- *     q' = q + d * s - (2 * S + d) * d / n,
+ *     q' = q + d * s - (2 * S + d) * d / n
+ *        = q + d * (s - 2 * S / n - d /n),
  *
  * where d = b - a_n, and s = b + a_n.
  *
@@ -621,7 +626,7 @@ _static_inline_ int64_t update_quadratic_deviation(int64_t n, int64_t old_qd,
 {
        int64_t delta = new_val - old_val;
        int64_t sigma = new_val + old_val;
-       return old_qd + delta * sigma - (2 * old_sum + delta) * delta / n;
+       return old_qd + delta * (sigma - 2 * old_sum / n - delta / n);
 }
 
 static int update_afs_statistics(struct afs_info *old_afsi, struct afs_info *new_afsi)
@@ -790,7 +795,7 @@ void close_current_mood(void)
  * \sa struct admissible_file_info, struct admissible_array, struct
  * afs_info::last_played, mood_close().
  */
-int change_current_mood(char *mood_name)
+int change_current_mood(const char *mood_name)
 {
        int i, ret;
        struct admissible_array aa = {
@@ -802,7 +807,7 @@ int change_current_mood(char *mood_name)
                struct mood *m;
                struct osl_row *row;
                struct osl_object obj = {
-                       .data = mood_name,
+                       .data = (char *)mood_name,
                        .size = strlen(mood_name) + 1
                };
                ret = osl(osl_get_row(moods_table, BLOBCOL_NAME, &obj, &row));
diff --git a/mood.h b/mood.h
index 10e9319b2b2c8e7a7a094207609634a23a6b3a22..f7055753cf82fee8533f4f5fb0519ae4c86790d9 100644 (file)
--- a/mood.h
+++ b/mood.h
@@ -6,6 +6,6 @@
 
 /** \file mood.h Public functions of mood.c. */
 
-int change_current_mood(char *mood_name);
+int change_current_mood(const char *mood_name);
 void close_current_mood(void);
 int mood_check_callback(struct afs_callback_arg *aca);
index 73e744ec44088c4d8c92c1e19c1e6bed8b5076a0..74d65fff6750355fd4a62b296e0b0d4d2d70ff2b 100644 (file)
--- a/mp3_afh.c
+++ b/mp3_afh.c
@@ -684,7 +684,7 @@ static int mp3_get_file_info(char *map, size_t numbytes, int fd,
        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
diff --git a/net.c b/net.c
index 463033bb710a36036ca37907ecc59016fd6dd304..42418e5f20d9e168eb0af5c7da9c2d1ffa1c2127 100644 (file)
--- a/net.c
+++ b/net.c
@@ -1018,7 +1018,7 @@ static void dispose_fds(int *fds, unsigned num)
  */
 int recv_cred_buffer(int fd, char *buf, size_t size)
 {
-       char control[255];
+       char control[255] __a_aligned(8);
        struct msghdr msg;
        struct cmsghdr *cmsg;
        struct iovec iov;
index 32f8bc1beda6f10376db3d3842e0e3cfcaf02e96..29f08965077be97b6015208bb16cd8e8ef2d270c 100644 (file)
--- a/ogg_afh.c
+++ b/ogg_afh.c
@@ -171,8 +171,6 @@ fail:
        PARA_ERROR_LOG("%s\n", para_strerror(-ret));
 }
 
-static const char* ogg_suffixes[] = {"ogg", NULL};
-
 static int vorbis_make_meta_packet(struct taginfo *tags, ogg_packet *result)
 {
        vorbis_comment vc;
@@ -206,6 +204,9 @@ static int vorbis_rewrite_tags(const char *map, size_t mapsize,
        free(packet.packet);
        return ret;
 }
+
+static const char * const ogg_suffixes[] = {"ogg", NULL};
+
 /**
  * The init function of the ogg vorbis audio format handler.
  *
index ace83008d60db987cfa3350a13d5dc40d365819f..b1469b474d504e69bfe62ad95f6d1ee9043b65a5 100644 (file)
@@ -17,7 +17,7 @@
 #include "opus_common.h"
 #include "ogg_afh_common.h"
 
-static const char* opus_suffixes[] = {"opus", NULL};
+static const char * const opus_suffixes[] = {"opus", NULL};
 
 #define OPUS_COMMENT_HEADER "OpusTags"
 
@@ -96,7 +96,8 @@ static int opus_packet_callback(ogg_packet *packet, int packet_num,
                if (ret < 0)
                        return ret;
                afhi->channels = oh->channels;
-               afhi->techinfo = make_message("header version %d, input sample rate: %dHz",
+               afhi->techinfo = make_message(
+                       "header version %d, input sample rate: %" PRIu32 "Hz",
                        oh->version, oh->input_sample_rate);
                /*
                 * The input sample rate is irrelevant for afhi->frequency as
index 927df1f3c2f881fb036b13df50fbd49b43ec568d..67a8841e8b8ce7fe172043a144332cb1db4c577f 100644 (file)
@@ -104,7 +104,7 @@ int opus_parse_header(const char *packet, int len, struct opus_header *h)
        if (!read_chars(&p, &ch, 1))
                return -E_OPUS_HEADER;
        h->version = ch;
-       if((h->version & 240) != 0) /* Only major version 0 supported. */
+       if ((h->version & 240) != 0) /* Only major version 0 supported. */
                return -E_OPUS_HEADER;
 
        if (!read_chars(&p, &ch, 1))
diff --git a/play.c b/play.c
index 55c9ec1bbb635946fe8ec92eadb52fa0accc8bf6..e484427c87c1ed44d0585b67ef813b1c4da48521 100644 (file)
--- a/play.c
+++ b/play.c
@@ -277,7 +277,8 @@ static int eof_cleanup(struct play_task *pt)
        memset(&pt->wn, 0, sizeof(struct writer_node));
 
        task_reap(&pt->fn.task);
-       decoder->close(&pt->fn);
+       if (decoder->close)
+               decoder->close(&pt->fn);
        btr_remove_node(&pt->fn.btrn);
        free(pt->fn.conf);
        memset(&pt->fn, 0, sizeof(struct filter_node));
@@ -591,6 +592,28 @@ static char *get_key_map_seq(int key)
                get_internal_key_map_seq(key) : get_user_key_map_seq(key);
 }
 
+static char *get_key_map_seq_safe(int key)
+{
+       const char hex[] = "0123456789abcdef";
+       char *seq = get_key_map_seq(key), *sseq;
+       size_t n, len = strlen(seq);
+
+       if (len == 1 && isprint(*seq))
+               return seq;
+       sseq = para_malloc(2 + 2 * len + 1);
+       sseq[0] = '0';
+       sseq[1] = 'x';
+       for (n = 0; n < len; n++) {
+               uint8_t val = (seq[n] & 0xf0) >> 4;
+               sseq[2 + 2 * n] = hex[val];
+               val = seq[n] & 0xf;
+               sseq[2 + 2 * n + 1] = hex[val];
+       }
+       free(seq);
+       sseq[2 + 2 * n] = '\0';
+       return sseq;
+}
+
 static inline char *get_internal_key_map_cmd(int key)
 {
        return para_strdup(default_commands[get_internal_key_map_idx(key)]);
@@ -619,15 +642,8 @@ static char **get_mapped_keyseqs(void)
 
        result = para_malloc((NUM_MAPPED_KEYS + 1) * sizeof(char *));
        FOR_EACH_MAPPED_KEY(i) {
-               int idx = get_key_map_idx(i);
                char *seq = get_key_map_seq(i);
-               char *cmd = get_key_map_cmd(i);
-               bool internal = is_internal_key(i);
-               PARA_DEBUG_LOG("%s key sequence #%d: %s -> %s\n",
-                       internal? "internal" : "user-defined",
-                       idx, seq, cmd);
                result[i] = seq;
-               free(cmd);
        }
        result[i] = NULL;
        return result;
@@ -716,7 +732,7 @@ static int com_help(struct play_task *pt, int argc, char **argv)
                        FOR_EACH_MAPPED_KEY(i) {
                                bool internal = is_internal_key(i);
                                int idx = get_key_map_idx(i);
-                               char *seq = get_key_map_seq(i);
+                               char *seq = get_key_map_seq_safe(i);
                                char *cmd = get_key_map_cmd(i);
                                sz = xasprintf(&buf,
                                        "%s key #%d: %s -> %s\n",
index 9616ed0f0dd6dc9a215e4782375cd6fa081f187d..8ea1854bddfc004db52d6d0afe577d6601960b07 100644 (file)
@@ -159,13 +159,13 @@ void playlist_close(void)
  *
  * \return Standard.
  */
-int playlist_open(char *name)
+int playlist_open(const char *name)
 {
        struct osl_object obj;
        int ret;
        struct osl_row *row;
 
-       obj.data = name;
+       obj.data = (char *)name;
        obj.size = strlen(obj.data);
        ret = osl(osl_get_row(playlists_table, BLOBCOL_NAME, &obj, &row));
        if (ret < 0) {
@@ -191,8 +191,6 @@ static int handle_audio_file_event(enum afs_events event, void *data)
        char *new_path;
        const struct osl_row *row = data;
 
-       if (!current_playlist.name)
-               return 1;
        if (event == AUDIO_FILE_RENAME) {
                ret = row_belongs_to_score_table(row, NULL);
                if (ret < 0)
@@ -237,7 +235,9 @@ int playlists_event_handler(enum afs_events event,
        int ret;
        struct afsi_change_event_data *aced = data;
 
-       switch(event) {
+       if (!current_playlist.name)
+               return 1;
+       switch (event) {
        case AFSI_CHANGE:
                return playlist_update_audio_file(aced->aft_row);
        case AUDIO_FILE_RENAME:
index 108cfaa49c1acf2168858f1120357569379f9c71..b780635b383e8f95dd6f6df9f69cc09ce2c34d16 100644 (file)
--- a/spx_afh.c
+++ b/spx_afh.c
@@ -118,8 +118,6 @@ static int spx_get_comments(unsigned char *comments, int length,
        return 1;
 }
 
-static const char* speex_suffixes[] = {"spx", "speex", NULL};
-
 static int spx_packet_callback(ogg_packet *packet, int packet_num,
                __a_unused int serial, struct afh_info *afhi,
                void *private_data)
@@ -251,6 +249,8 @@ static int spx_rewrite_tags(const char *map, size_t mapsize,
        return ret;
 }
 
+static const char * const speex_suffixes[] = {"spx", "speex", NULL};
+
 /**
  * The init function of the ogg/speex audio format handler.
  *
index 701448e041cfa9ff86dc1a6cccf37cd088b76c20..e731bb496b4b0d0f2f5a7dac417cbbeab7b9f3f6 100644 (file)
--- a/string.c
+++ b/string.c
@@ -955,36 +955,24 @@ static bool utf8_mode(void)
        return have_utf8;
 }
 
-/*
- * glibc's wcswidth returns -1 if the string contains a tab character, which
- * makes the function next to useless. The two functions below are taken from
- * mutt.
- */
-
-#define IsWPrint(wc) (iswprint(wc) || wc >= 0xa0)
-
-static int mutt_wcwidth(wchar_t wc, size_t pos)
+static int xwcwidth(wchar_t wc, size_t pos)
 {
        int n;
 
+       /* special-case for tab */
        if (wc == 0x09) /* tab */
                return (pos | 7) + 1 - pos;
        n = wcwidth(wc);
-       if (IsWPrint(wc) && n > 0)
-               return n;
-       if (!(wc & ~0x7f))
-               return 2;
-       if (!(wc & ~0xffff))
-               return 6;
-       return 10;
+       /* wcswidth() returns -1 for non-printable characters */
+       return n >= 0? n : 1;
 }
 
-static size_t mutt_wcswidth(const wchar_t *s, size_t n)
+static size_t xwcswidth(const wchar_t *s, size_t n)
 {
        size_t w = 0;
 
        while (n--)
-               w += mutt_wcwidth(*s++, w);
+               w += xwcwidth(*s++, w);
        return w;
 }
 
@@ -1029,7 +1017,7 @@ int skip_cells(const char *s, size_t cells_to_skip, size_t *bytes_to_skip)
                if (mbret == (size_t)-1 || mbret == (size_t)-2)
                        return -ERRNO_TO_PARA_ERROR(EILSEQ);
                bytes_parsed += mbret;
-               cells_skipped += mutt_wcwidth(wc, cells_skipped);
+               cells_skipped += xwcwidth(wc, cells_skipped);
        }
        *bytes_to_skip = bytes_parsed;
        return 1;
@@ -1078,7 +1066,70 @@ __must_check int strwidth(const char *s, size_t *result)
        memset(&state, 0, sizeof(state));
        num_wchars = mbsrtowcs(dest, &src, num_wchars, &state);
        assert(num_wchars > 0 && num_wchars != (size_t)-1);
-       *result = mutt_wcswidth(dest, num_wchars);
+       *result = xwcswidth(dest, num_wchars);
        free(dest);
        return 1;
 }
+
+/**
+ * Truncate and sanitize a (wide character) string.
+ *
+ * This replaces all non-printable characters by spaces and makes sure that the
+ * modified string does not exceed the given maximal width.
+ *
+ * \param src The source string in multi-byte form.
+ * \param max_width The maximal number of cells the result may occupy.
+ * \param result Sanitized multi-byte string, must be freed by caller.
+ * \param width The width of the sanitized string, always <= max_width.
+ *
+ * The function is wide-character aware but falls back to C strings for
+ * non-UTF-8 locales.
+ *
+ * \return Standard. On success, *result points to a sanitized copy of the
+ * given string. This copy was allocated with malloc() and should hence be
+ * freed when the caller is no longer interested in the result.
+ *
+ * The function fails if the given string contains an invalid multibyte
+ * sequence. In this case, *result is set to NULL, and *width to zero.
+ */
+__must_check int sanitize_str(const char *src, size_t max_width,
+               char **result, size_t *width)
+{
+       mbstate_t state;
+       static wchar_t *wcs;
+       size_t num_wchars, n;
+
+       if (!utf8_mode()) {
+               *result = para_strdup(src);
+               /* replace non-printable characters by spaces */
+               for (n = 0; n < max_width && src[n]; n++) {
+                       if (!isprint((unsigned char)src[n]))
+                               (*result)[n] = ' ';
+               }
+               (*result)[n] = '\0';
+               *width = n;
+               return 0;
+       }
+       *result = NULL;
+       *width = 0;
+       memset(&state, 0, sizeof(state));
+       num_wchars = mbsrtowcs(NULL, &src, 0, &state);
+       if (num_wchars == (size_t)-1)
+               return -ERRNO_TO_PARA_ERROR(errno);
+       wcs = para_malloc((num_wchars + 1) * sizeof(*wcs));
+       memset(&state, 0, sizeof(state));
+       num_wchars = mbsrtowcs(wcs, &src, num_wchars + 1, &state);
+       assert(num_wchars != (size_t)-1);
+       for (n = 0; n < num_wchars && *width < max_width; n++) {
+               if (!iswprint(wcs[n]))
+                       wcs[n] = L' ';
+               *width += xwcwidth(wcs[n], *width);
+       }
+       wcs[n] = L'\0';
+       n = wcstombs(NULL, wcs, 0) + 1;
+       *result = para_malloc(n);
+       num_wchars = wcstombs(*result, wcs, n);
+       assert(num_wchars != (size_t)-1);
+       free(wcs);
+       return 1;
+}
index 61bb7c25b04998ed1c6616240f2e51f6627a5360..aa8292fdf4ec1f076294842e1b6cb02dbc4f23a6 100644 (file)
--- a/string.h
+++ b/string.h
@@ -101,3 +101,5 @@ char *safe_strdup(const char *src, size_t len);
 char *key_value_copy(const char *src, size_t len, const char *key);
 int skip_cells(const char *s, size_t cells_to_skip, size_t *result);
 __must_check int strwidth(const char *s, size_t *result);
+__must_check int sanitize_str(const char *src, size_t max_width,
+               char **result, size_t *width);
index 76128512bca28b7fba427cdb4b36b446629472cd..3cb37d4260cf21fb3ec83109642642cf67bc1f52 100755 (executable)
@@ -48,6 +48,30 @@ required_objects[$i]='ogg_afh'
 cmdline[$i]="ls -l=v ${oggs_base[@]}"
 good[$i]='^basename:'
 
+let i++
+commands[$i]='addatt'
+required_objects[$i]=''
+cmdline[$i]="addatt $(seq 64 | tr '\n' ' ')"
+bad[$i]='.'
+
+let i++
+commands[$i]='lsatt'
+required_objects[$i]=''
+cmdline[$i]="lsatt"
+good[$i]='^1$'
+
+let i++
+commands[$i]='setatt'
+required_objects[$i]='ogg_afh'
+cmdline[$i]="setatt 33+ ${oggs[@]}"
+bad[$i]='.'
+
+let i++
+commands[$i]="ls"
+required_objects[$i]='ogg_afh'
+cmdline[$i]="ls -l=v -p ${oggs[@]}"
+good[$i]='^attributes_txt: 33'
+
 let i++
 commands[$i]="term"
 cmdline[$i]="term"
index 0e702b53c9b4c4150418dc0e2a07e55949817b04..99e575d3b66d0f54e9746647eee1af4eba84fa2c 100644 (file)
@@ -272,7 +272,7 @@ fixup_dirs()
 {
        local wd=$(pwd)
 
-       test_dir="$wd/${0%/*}"
+       test_dir="$(realpath $wd/${0%/*})"
        test_audio_file_dir="$test_dir/audio_files"
 
        [[ -z "$o_results_dir" ]] && o_results_dir="$test_dir/test-results"
index bbc38f0117d796ac5211bf86821244daf17baf84..425118a135edfee7224f40256dc087a803115aaf 100644 (file)
@@ -46,6 +46,8 @@ struct udp_target {
        struct fec_client *fc;
        /** The FEC parameters for this target. */
        struct fec_client_parms fcp;
+       /** Whether we already sent the FEC eof packet to this target. */
+       bool sent_fec_eof;
 };
 
 static struct list_head targets;
@@ -54,15 +56,16 @@ static int sender_status;
 static void udp_close_target(struct sender_client *sc)
 {
        const char *buf;
-       size_t len = vss_get_fec_eof_packet(&buf);
-
-       /*
-        * Ignore the return value of write() since we are closing the target
-        * anyway. The sole purpose of the "do_nothing" statement is to silence
-        * gcc.
-        */
-       if (write(sc->fd, buf, len))
-               do_nothing;
+       size_t len;
+       struct udp_target *ut = sc->private_data;
+
+       if (ut->sent_fec_eof)
+               return;
+       PARA_NOTICE_LOG("sending FEC EOF\n");
+       len = vss_get_fec_eof_packet(&buf);
+       /* Ignore write() errors since we are closing the target anyway. */
+       if (write(sc->fd, buf, len) == len)
+               ut->sent_fec_eof = true;
 }
 
 static void udp_delete_target(struct sender_client *sc, const char *msg)
@@ -232,9 +235,11 @@ static int udp_com_delete(struct sender_command_data *scd)
 /** Initialize UDP session and set maximum payload size. */
 static int udp_init_fec(struct sender_client *sc)
 {
+       struct udp_target *ut = sc->private_data;
        int mps;
 
        PARA_NOTICE_LOG("sending to udp %s\n", sc->name);
+       ut->sent_fec_eof = false;
        mps = generic_max_transport_msg_size(sc->fd) - sizeof(struct udphdr);
        PARA_INFO_LOG("current MPS = %d bytes\n", mps);
        return mps;
diff --git a/vss.c b/vss.c
index cbc05d131b28550d8596cee1bb505a835ef81779..51db7686c6b008c2ac8704967d9cdfd7ea76e071 100644 (file)
--- a/vss.c
+++ b/vss.c
@@ -905,7 +905,7 @@ static void vss_pre_select(struct sched *s, void *context)
 
 static int recv_afs_msg(int afs_socket, int *fd, uint32_t *code, uint32_t *data)
 {
-       char control[255], buf[8];
+       char control[255] __a_aligned(8), buf[8];
        struct msghdr msg = {.msg_iov = NULL};
        struct cmsghdr *cmsg;
        struct iovec iov;
diff --git a/web/manual.m4 b/web/manual.m4
deleted file mode 100644 (file)
index d63b07e..0000000
+++ /dev/null
@@ -1,2236 +0,0 @@
-dnl To generate the html version, execute
-dnl m4 web/manual.m4 | grutatxt --toc
-
-define(`LOCAL_LINK_NAME', `translit(`$1', `A-Z 
-', `a-z__')')
-define(`REMOVE_NEWLINE', `translit(`$1',`
-', ` ')')
-
-define(`REFERENCE', ./``#''`LOCAL_LINK_NAME($1)' (`REMOVE_NEWLINE($2)'))
-define(`XREFERENCE', `$1' (`REMOVE_NEWLINE($2)'))
-define(`EMPH', ``_''`REMOVE_NEWLINE($1)'``_'')
-
-Paraslash user manual
-=====================
-
-This document describes how to install, configure and use the paraslash
-network audio streaming system.  Most chapters start with a chapter
-overview and conclude with an example section. We try to focus on
-general concepts and on the interaction of the various pieces of the
-paraslash package. Hence this user manual is not meant as a replacement
-for the manual pages that describe all command line options of each
-paraslash executable.
-
-------------
-Introduction
-------------
-
-In this chapter we give an REFERENCE(Overview, overview) of the
-interactions of the two main programs contained in the paraslash
-package, followed by REFERENCE(The paraslash executables, brief
-descriptions) of all executables.
-
-Overview
-~~~~~~~~
-
-The core functionality of the para suite is provided by two main
-executables, para_server and para_audiod. The former maintains a
-database of audio files and streams these files to para_audiod which
-receives and plays the stream.
-
-In a typical setting, both para_server and para_audiod act as
-background daemons whose functionality is controlled by client
-programs: the para_audioc client controls para_audiod over a local
-socket while the para_client program connects to para_server over a
-local or remote networking connection.
-
-Typically, these two daemons run on different hosts but a local setup
-is also possible.
-
-A simplified picture of a typical setup is as follows
-<<
-<pre>
- server_host                                  client_host
- ~~~~~~~~~~~                                  ~~~~~~~~~~~
- +-----------+         audio stream           +-----------+
- |para_server| -----------------------------> |para_audiod|
- +-----------+                                +-----------+
-      ^                                            ^
-      |                                            |
-      |                                            | connect
-      |                                            |
-      |                                            |
-      |                                       +-----------+
-      |                                       |para_audioc|
-      |                                       +-----------+
-      |
-      |
-      |                  connect              +-----------+
-      +-------------------------------------- |para_client|
-                                              +-----------+
-</pre>
->>
-
-The paraslash executables
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-*para_server*
-
-para_server streams binary audio data (MP3, ...) over local and/or
-remote networks. It listens on a TCP port and accepts commands such
-as play, stop, pause, next from authenticated clients. There are
-many more commands though, see the man page of para_server for a
-description of all commands.
-
-It supports three built-in network streaming protocols
-(senders/receivers): HTTP, DCCP, or UDP. This is explained in more
-detail in the section on REFERENCE(Networking, networking).
-
-The built-in audio file selector of paraslash is used to manage your
-audio files. It maintains statistics on the usage of all available
-audio files such as last-played time, and the number of times each
-file was selected.
-
-Additional information may be added to the database to allow
-fine-grained selection based on various properties of the audio file,
-including information found in (ID3) tags. However, old-fashioned
-playlists are also supported.
-
-It is also possible to store images (album covers) and lyrics in the
-database and associate these to the corresponding audio files.
-
-The section on the REFERENCE(The audio file selector, audio file
-selector) discusses this topic.
-
-
-*para_client*
-
-The client program to connect to para_server. paraslash commands
-are sent to para_server and the response is dumped to STDOUT. This
-can be used by any scripting language to produce user interfaces with
-little programming effort.
-
-All connections between para_server and para_client are encrypted
-with a symmetric session key. For each user of paraslash you must
-create a public/secret RSA key pair for authentication.
-
-If para_client is started without non-option arguments, an interactive
-session (shell) is started. Command history and command completion are
-supported through libreadline.
-
-*para_audiod*
-
-The local daemon that collects information from para_server.
-
-It runs on the client side and connects to para_server. As soon as
-para_server announces the availability of an audio stream, para_audiod
-starts an appropriate receiver, any number of filters and a paraslash
-writer to play the stream.
-
-Moreover, para_audiod listens on a local socket and sends status
-information about para_server and para_audiod to local clients on
-request. Access via this local socket may be restricted by using Unix
-socket credentials, if available.
-
-
-*para_audioc*
-
-The client program which talks to para_audiod. Used to control
-para_audiod, to receive status info, or to grab the stream at any
-point of the decoding process. Like para_client, para_audioc supports
-interactive sessions on systems with libreadline.
-
-*para_recv*
-
-A command line HTTP/DCCP/UDP stream grabber. The http mode is
-compatible with arbitrary HTTP streaming sources (e.g. icecast).
-In addition to the three network streaming modes, para_recv can also
-operate in local (afh) mode. In this mode it writes the content of
-an audio file on the local file system in complete chunks to stdout,
-optionally 'just in time'. This allows to cut an audio file without
-first decoding it, and it enables third-party software which is unaware
-of the particular audio format to send complete frames in real time.
-
-*para_filter*
-
-A filter program that reads from STDIN and writes to STDOUT.
-Like para_recv, this is an atomic building block which can be used to
-assemble higher-level audio receiving facilities. It combines several
-different functionalities in one tool: decoders for multiple audio
-formats and a number of processing filters, among these a normalizer
-for audio volume.
-
-*para_afh*
-
-A small stand-alone program that prints tech info about the given
-audio file to STDOUT. It can be instructed to print a "chunk table",
-an array of offsets within the audio file.
-
-*para_write*
-
-A modular audio stream writer. It supports a simple file writer
-output plug-in and optional WAV/raw players for ALSA (Linux) and for
-coreaudio (Mac OS). para_write can also be used as a stand-alone WAV
-or raw audio player.
-
-*para_play*
-
-A command line audio player.
-
-*para_gui*
-
-Curses-based gui that presents status information obtained in a curses
-window. Appearance can be customized via themes. para_gui provides
-key-bindings for the most common server commands and new key-bindings
-can be added easily.
-
-
-*para_fade*
-
-An alarm clock and volume-fader for OSS and ALSA.
-
------------
-Quick start
------------
-
-This chapter lists the REFERENCE(Requirements, necessary software)
-that must be installed to compile the paraslash package, describes
-how to REFERENCE(Installation, compile and install) the paraslash
-source code and the steps that have to be performed in order to
-REFERENCE(Quick start, set up) a typical server and client.
-
-Requirements
-~~~~~~~~~~~~
-For the impatient:
-
-       git clone git://git.tuebingen.mpg.de/osl
-       cd osl && make && sudo make install && sudo ldconfig
-       sudo apt-get install autoconf libssl-dev help2man gengetopt \
-              libmad0-dev libid3tag0-dev libasound2-dev libvorbis-dev \
-              libfaad-dev libspeex-dev libFLAC-dev libsamplerate-dev \
-              libasound2-dev libao-dev libreadline-dev libncurses-dev \
-              libopus-dev
-
-Detailed description: In any case you'll need
-
-       - XREFERENCE(http://people.tuebingen.mpg.de/maan/osl/, libosl).
-       The _object storage layer_ library is used by para_server. To
-       clone the source code repository, execute
-
-       git clone git://git.tuebingen.mpg.de/osl
-
-       - XREFERENCE(ftp://ftp.gnu.org/pub/gnu/gcc, gcc) or
-       XREFERENCE(http://clang.llvm.org, clang). All gcc versions
-       >= 3.3 are currently supported. Clang version 1.1 or newer
-       should work as well.
-
-       - XREFERENCE(ftp://ftp.gnu.org/pub/gnu/make, gnu make) is
-       also shipped with the disto. On BSD systems the gnu make
-       executable is often called gmake.
-
-       - XREFERENCE(ftp://ftp.gnu.org/pub/gnu/bash, bash). Some
-       scripts which run during compilation require the EMPH(Bourne
-       again shell).  It is most likely already installed.
-
-       - XREFERENCE(ftp://ftp.gnu.org/pub/gnu/gengetopt/, gengetopt)
-       is needed to generate the C code for the command line parsers
-       of all paraslash executables.
-
-       - XREFERENCE(ftp://ftp.gnu.org/pub/gnu/help2man, help2man)
-       is used to create the man pages.
-
-Optional:
-
-       - XREFERENCE(http://www.openssl.org/, openssl) or
-       XREFERENCE(ftp://ftp.gnupg.org/gcrypt/libgcrypt/, libgcrypt).
-       At least one of these two libraries is needed as the backend
-       for cryptographic routines on both the server and the client
-       side. Both openssl and libgcrypt are usually shipped with the
-       distro, but you might have to install the development package
-       (libssl-dev or libgcrypt-dev on debian systems) as well.
-
-       - XREFERENCE(http://www.underbit.com/products/mad/, libmad).
-       To compile in MP3 support for paraslash, the development
-       package must be installed. It is called libmad0-dev on
-       debian-based systems. Note that libmad is not necessary on
-       the server side, i.e. for sending MP3 files.
-
-       - XREFERENCE(http://www.underbit.com/products/mad/,
-       libid3tag). For version-2 ID3 tag support, you'll need
-       the libid3tag development package libid3tag0-dev. Without
-       libid3tag, only version-1 tags are recognized. The mp3 tagger
-       also needs this library for modifying (id3v1 and id3v2) tags.
-
-       - XREFERENCE(http://www.xiph.org/downloads/, ogg vorbis).
-       For ogg vorbis streams you'll need libogg, libvorbis,
-       libvorbisfile. The corresponding Debian packages are called
-       libogg-dev and libvorbis-dev.
-
-       - XREFERENCE(http://www.audiocoding.com/, libfaad).  For aac
-       files (m4a) you'll need libfaad (libfaad-dev).
-
-       - XREFERENCE(http://www.speex.org/, speex). In order to stream
-       or decode speex files, libspeex (libspeex-dev) is required.
-
-       - XREFERENCE(http://flac.sourceforge.net/, flac). To stream
-       or decode files encoded with the _Free Lossless Audio Codec_,
-       libFLAC (libFLAC-dev) must be installed.
-
-       - XREFERENCE(http://www.mega-nerd.com/SRC/index.html,
-       libsamplerate). The resample filter will only be compiled if
-       this library is installed. Debian package: libsamplerate-dev.
-
-       - XREFERENCE(ftp://ftp.alsa-project.org/pub/lib/, alsa-lib). On
-       Linux, you'll need to have ALSA's development package
-       libasound2-dev installed.
-
-       - XREFERENCE(http://downloads.xiph.org/releases/ao/,
-       libao). Needed to build the ao writer (ESD, PulseAudio,...).
-       Debian package: libao-dev.
-
-       - XREFERENCE(ftp://ftp.gnu.org/pub/gnu/ncurses, curses). Needed
-       for para_gui. Debian package: libncurses-dev.
-
-       - XREFERENCE(http://cnswww.cns.cwru.edu/php/chet/readline/rltop.html,
-       GNU Readline). If this library (libreadline-dev) is installed,
-       para_client, para_audioc and para_play support interactive
-       sessions.
-
-Installation
-~~~~~~~~~~~~
-To build the sources from a tarball, execute
-
-       ./configure && make
-
-To build from git or a gitweb snapshot, run this command instead:
-
-       ./autogen.sh
-
-There should be no errors but probably some warnings about missing
-packages which usually implies that not all audio formats will be
-supported. If headers or libs are installed at unusual locations you
-might need to tell the configure script where to find them. Try
-
-       ./configure --help
-
-to see a list of options. If the paraslash package was compiled
-successfully, execute (optionally)
-
-       make test
-
-to run the paraslash test suite. If all tests pass, execute as root
-
-       make install
-
-to install executables under /usr/local/bin and the man pages under
-/usr/local/man.
-
-Configuration
-~~~~~~~~~~~~~
-
-*Step 1*: Create a paraslash user
-
-In order to control para_server at runtime you must create a paraslash
-user. As authentication is based on the RSA crypto system you'll have
-to create an RSA key pair. If you already have a user and an RSA key
-pair, you may skip this step.
-
-In this section we'll assume a typical setup: You would like to run
-para_server on some host called server_host as user foo, and you want
-to connect to para_server from another machine called client_host as
-user bar.
-
-As foo@server_host, create ~/.paraslash/server.users by typing the
-following commands:
-
-       user=bar
-       target=~/.paraslash/server.users
-       key=~/.paraslash/id_rsa.pub.$user
-       perms=AFS_READ,AFS_WRITE,VSS_READ,VSS_WRITE
-       mkdir -p ~/.paraslash
-       echo "user $user $key $perms" >> $target
-
-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 '' -f $key
-
-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,
-para_client rejects private keys which are world-readable.
-
-para_server only needs to know the public key of the key pair just
-created. Copy this public key to server_host:
-
-       src=~/.ssh/id_rsa.pub
-       dest=.paraslash/id_rsa.pub.$LOGNAME
-       scp $src foo@server_host:$dest
-
-Finally, tell para_client to connect to server_host:
-
-       conf=~/.paraslash/client.conf
-       echo 'hostname server_host' > $conf
-
-
-*Step 2*: Start para_server
-
-For this first try, we'll use the info loglevel to make the output
-of para_server more verbose.
-
-       para_server -l info
-
-Now you can use para_client to connect to the server and issue
-commands. Open a new shell as bar@client_host and try
-
-       para_client help
-       para_client si
-
-to retrieve the list of available commands and some server info.
-Don't proceed if this doesn't work.
-
-*Step 3*: Create and populate the database
-
-An empty database is created with
-
-       para_client init
-
-This initializes a couple of empty tables under
-~/.paraslash/afs_database-0.4. You normally don't need to look at these
-tables, but it's good to know that you can start from scratch with
-
-       rm -rf ~/.paraslash/afs_database-0.4
-
-in case something went wrong.
-
-Next, you need to add some audio files to that database so that
-para_server knows about them. Choose an absolute path to a directory
-containing some audio files and add them to the audio file table:
-
-       para_client add /my/mp3/dir
-
-This might take a while, so it is a good idea to start with a directory
-containing not too many files. Note that the table only contains data
-about the audio files found, not the files themselves.
-
-You may print the list of all known audio files with
-
-       para_client ls
-
-*Step 4*: Configure para_audiod
-
-We will have to tell para_audiod that it should receive the audio
-stream from server_host via http:
-
-       para_audiod -l info -r '.:http -i server_host'
-
-You should now be able to listen to the audio stream once para_server
-starts streaming. To activate streaming, execute
-
-       para_client play
-
-Since no playlist has been specified yet, the "dummy" mode which
-selects all known audio files is activated automatically. See the
-section on the REFERENCE(The audio file selector, audio file selector)
-for how to use playlists and moods to specify which files should be
-streamed in which order.
-
-*Troubleshooting*
-
-If you receive a socket related error on server or audiod startup,
-make sure you have write permissions to the /var/paraslash directory:
-
-       sudo chown $LOGNAME /var/paraslash
-
-Alternatively, use the --afs-socket (para_server) or --socket
-(para_audiod) option to specify a different socket pathname.
-
-To identify streaming problems try to receive, decode and play the
-stream manually using para_recv, para_filter and para_write as follows.
-For simplicity we assume that you're running Linux/ALSA and that only
-MP3 files have been added to the database.
-
-       para_recv -r 'http -i server_host' > file.mp3
-       # (interrupt with CTRL+C after a few seconds)
-       ls -l file.mp3 # should not be empty
-       para_filter -f mp3dec -f wav < file.mp3 > file.wav
-       ls -l file.wav # should be much bigger than file.mp3
-       para_write -w alsa < file.wav
-
-Double check what is logged by para_server and use the --loglevel
-option of para_recv, para_filter and para_write to increase verbosity.
-
----------------
-User management
----------------
-
-para_server uses a challenge-response mechanism to authenticate
-requests from incoming connections, similar to ssh's public key
-authentication method. Authenticated connections are encrypted using
-a stream cipher, either RC4 or AES in integer counter mode.
-
-In this chapter we briefly describe RSA, RC4 and AES, and sketch the
-REFERENCE(Client-server authentication, authentication handshake)
-between para_client and para_server. User management is discussed
-in the section on REFERENCE(The user_list file, the user_list file).
-These sections are all about communication between the client and the
-server. Connecting para_audiod is a different matter and is described
-in a REFERENCE(Connecting para_audiod, separate section).
-
-
-
-RSA, RC4, AES
-~~~~~~~~~~~~~
-
-RSA is an asymmetric block cipher which is used in many applications,
-including ssh and gpg. An RSA key consists in fact of two keys,
-called the public key and the private key. A message can be encrypted
-with either key and only the counterpart of that key can decrypt
-the message. While RSA can be used for both signing and encrypting
-a message, paraslash uses RSA only for the latter purpose. The
-RSA public key encryption and signatures algorithms are defined in
-detail in RFC 2437.
-
-RC4 is a stream cipher, i.e. the input is XORed with a pseudo-random
-key stream to produce the output. Decryption uses the same function
-calls as encryption. While RC4 supports variable key lengths,
-paraslash uses a fixed length of 256 bits, which is considered a
-strong encryption by today's standards. Since the same key must never
-be used twice, a different, randomly-generated key is used for every
-new connection.
-
-AES, the advanced encryption standard, is a well-known symmetric block
-cipher, i.e. a transformation operating on fixed-length blocks which
-is determined by a single key for both encryption and decryption. Any
-block cipher can be turned into a stream cipher by generating
-a pseudo-random key stream by encrypting successive values of a
-counter. The AES_CTR128 stream cipher used in paraslash is obtained
-in this way from the AES block cipher with a 128 bit block size.
-
-
-Client-server authentication
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The authentication handshake between para_client and para_server goes
-as follows:
-
-       - para_client connects to para_server and sends an
-       authentication request for a user. It does so by connecting
-       to TCP port 2990 of the server host. This port is called the
-       para_server _control port_.
-
-       - para_server accepts the connection and forks a child process
-       which handles the incoming request. The parent process keeps
-       listening on the control port while the child process (also
-       called para_server below) continues as follows.
-
-       - para_server loads the RSA public key of that user, fills a
-       fixed-length buffer with random bytes, encrypts that buffer
-       using the public key and sends the encrypted buffer to the
-       client. The first part of the buffer is the challenge which
-       is used for authentication while the second part is the
-       session key.
-
-       - para_client receives the encrypted buffer and decrypts it
-       with the user's private key, thereby obtaining the challenge
-       buffer and the session key. It sends the SHA1 hash value of
-       the challenge back to para_server and stores the session key
-       for further use.
-
-       - para_server also computes the SHA1 hash of the challenge
-       and compares it against what was sent back by the client.
-
-       - If the two hashes do not match, the authentication has
-       failed and para_server closes the connection.
-
-       - Otherwise the user is considered authenticated and the client
-       is allowed to proceed by sending a command to be executed. From
-       this point on the communication is encrypted using the stream
-       cipher with the session key known to both peers.
-
-paraslash relies on the quality of the pseudo-random bytes provided
-by the crypto library (openssl or libgcrypt), on the security of
-the implementation of the RSA, RC4 and AES crypto routines and on the
-infeasibility to invert the SHA1 function.
-
-Neither para_server or para_client create RSA keys on their own. This
-has to be done once for each user as sketched in REFERENCE(Quick start,
-Quick start) and discussed in more detail REFERENCE(The user_list
-file, below).
-
-The user_list file
-~~~~~~~~~~~~~~~~~~
-
-At startup para_server reads the user list file which contains one
-line per user. The default location of the user list file may be
-changed with the --user-list option.
-
-There should be at least one user in this file. Each user must have
-an RSA key pair. The public part of the key is needed by para_server
-while the private key is needed by para_client. Each line of the
-user list file must be of the form
-
-       user <username> <key> <perms>
-
-where _username_ is an arbitrary string (usually the user's login
-name), _key_ is the full path to that user's public RSA key, and
-_perms_ is a comma-separated list of zero or more of the following
-permission bits:
-
-       +---------------------------------------------------------+
-       | AFS_READ  | read the contents of the databases          |
-       +-----------+---------------------------------------------+
-       | AFS_WRITE | change database contents                    |
-       +-----------+---------------------------------------------+
-       | VSS_READ  | obtain information about the current stream |
-       +-----------+---------------------------------------------+
-       | VSS_WRITE | change the current stream                   |
-       +---------------------------------------------------------+
-
-The permission bits specify which commands the user is allowed to
-execute. The output of
-
-       para_client help
-
-contains in the third column the permissions needed to execute the
-command.
-
-It is possible to make para_server reread the user_list file by
-executing the paraslash "hup" command or by sending SIGHUP to the
-PID of para_server.
-
-
-Connecting para_audiod
-~~~~~~~~~~~~~~~~~~~~~~
-
-para_audiod listens on a Unix domain socket. Those sockets are
-for local communication only, so only local users can connect to
-para_audiod. The default is to let any user connect but this can be
-restricted on platforms that support UNIX socket credentials which
-allow para_audiod to obtain the Unix credentials of the connecting
-process.
-
-Use para_audiod's --user-allow option to allow connections only for
-a limited set of users.
-
------------------------
-The audio file selector
------------------------
-
-paraslash comes with a sophisticated audio file selector (AFS),
-whose main task is to determine which file to stream next, based on
-information on the audio files stored in a database. It communicates
-also with para_client whenever an AFS command is executed, for example
-to answer a database query.
-
-Besides the traditional playlists, AFS supports audio file selection
-based on _moods_ which act as a filter that limits the set of all
-known audio files to those which satisfy certain criteria.  It also
-maintains tables containing images (e.g. album cover art) and lyrics
-that can be associated with one or more audio files.
-
-AFS uses XREFERENCE(http://people.tuebingen.mpg.de/maan/osl/, libosl), the
-object storage layer library, as the backend library for storing
-information on audio files, playlists, etc. This library offers
-functionality similar to a relational database, but is much more
-lightweight than a full database backend.
-
-In this chapter we sketch the setup of the REFERENCE(The AFS process,
-AFS process) during server startup and proceed with the description
-of the REFERENCE(Database layout, layout) of the various database
-tables. The section on REFERENCE(Playlists and moods, playlists
-and moods) explains these two audio file selection mechanisms
-in detail and contains pratical examples. The way REFERENCE(File
-renames and content changes, file renames and content changes) are
-detected is discussed briefly before the REFERENCE(Troubleshooting,
-Troubleshooting) section concludes the chapter.
-
-The AFS process
-~~~~~~~~~~~~~~~
-
-On startup, para_server forks to create the AFS process which opens
-the OSL database tables. The server process communicates with the
-AFS process via pipes and shared memory. Usually, the AFS process
-awakes only briefly whenever the current audio file changes. The AFS
-process determines the next audio file, opens it, verifies it has
-not been changed since it was added to the database and passes the
-open file descriptor to the server process, along with audio file
-meta-data such as file name, duration, audio format and so on. The
-server process then starts to stream the audio file.
-
-The AFS process also accepts connections from local clients via
-a well-known socket. However, only child processes of para_server
-may connect through this socket. All server commands that have the
-AFS_READ or AFS_WRITE permission bits use this mechanism to query or
-change the database.
-
-Database layout
-~~~~~~~~~~~~~~~
-
-*The audio file table*
-
-This is the most important and usually also the largest table of the
-AFS database. It contains the information needed to stream each audio
-file. In particular the following data is stored for each audio file.
-
-       - SHA1 hash value of the audio file contents. This is computed
-       once when the file is added to the database. Whenever AFS
-       selects this audio file for streaming the hash value is
-       recomputed and checked against the value stored in the
-       database to detect content changes.
-
-       - The time when this audio file was last played.
-
-       - The number of times the file has been played so far.
-
-       - The attribute bitmask.
-
-       - The image id which describes the image associated with this
-       audio file.
-
-       - The lyrics id which describes the lyrics associated with
-       this audio file.
-
-       - The audio format id (MP3, OGG, ...).
-
-       - An amplification value that can be used by the amplification
-       filter to pre-amplify the decoded audio stream.
-
-       - The chunk table. It describes the location and the timing
-       of the building blocks of the audio file. This is used by
-       para_server to send chunks of the file at appropriate times.
-
-       - The duration of the audio file.
-
-       - Tag information contained in the audio file (ID3 tags,
-       Vorbis comments, ...).
-
-       - The number of channels
-
-       - The encoding bitrate.
-
-       - The sampling frequency.
-
-To add or refresh the data contained in the audio file table, the _add_
-command is used. It takes the full path of either an audio file or a
-directory. In the latter case, the directory is traversed recursively
-and all files which are recognized as valid audio files are added to
-the database.
-
-*The attribute table*
-
-The attribute table contains two columns, _name_ and _bitnum_. An
-attribute is simply a name for a certain bit number in the attribute
-bitmask of the audio file table.
-
-Each of the 64 bits of the attribute bitmask can be set for each
-audio file individually. Hence up to 64  different attributes may be
-defined. For example, "pop", "rock", "blues", "jazz", "instrumental",
-"german_lyrics", "speech", whatever. You are free to choose as
-many attributes as you like and there are no naming restrictions
-for attributes.
-
-A new attribute "test" is created by
-
-       para_client addatt test
-and
-       para_client lsatt
-
-lists all available attributes. You can set the "test" attribute for
-an audio file by executing
-
-       para_client setatt test+ /path/to/the/audio/file
-
-Similarly, the "test" bit can be removed from an audio file with
-
-       para_client setatt test- /path/to/the/audio/file
-
-Instead of a path you may use a shell wildcard pattern. The attribute
-is applied to all audio files matching this pattern:
-
-       para_client setatt test+ '/test/directory/*'
-
-The command
-
-       para_client -- ls -l=v
-
-gives you a verbose listing of your audio files also showing which
-attributes are set.
-
-In case you wonder why the double-dash in the above command is needed:
-It tells para_client to not interpret the options after the dashes. If
-you find this annoying, just say
-
-       alias para='para_client --'
-
-and be happy. In what follows we shall use this alias.
-
-The "test" attribute can be dropped from the database with
-
-       para rmatt test
-
-Read the output of
-
-       para help ls
-       para help setatt
-
-for more information and a complete list of command line options to
-these commands.
-
-*Blob tables*
-
-The image, lyrics, moods and playlists tables are all blob tables.
-Blob tables consist of three columns each: The identifier which is
-a positive non-negative number that is auto-incremented, the name
-(an arbitrary string) and the content (the blob).
-
-All blob tables support the same set of actions: cat, ls, mv, rm
-and add. Of course, _add_ is used for adding new blobs to the table
-while the other actions have the same meaning as the corresponding
-Unix commands. The paraslash commands to perform these actions are
-constructed as the concatenation of the table name and the action. For
-example addimg, catimg, lsimg, mvimg, rmimg are the commands that
-manipulate or query the image table.
-
-The add variant of these commands is special as these commands read
-the blob contents from stdin. To add an image to the image table the
-command
-
-       para addimg image_name < file.jpg
-
-can be used.
-
-Note that the images and lyrics are not interpreted at all, and also
-the playlist and the mood blobs are only investigated when the mood
-or playlist is activated with the select command.
-
-*The score table*
-
-Unlike all other tables the contents of the score table remain in
-memory and are never stored on disk. The score table contains two
-columns: The SHA1 hash value (of an audio file) and its current
-score.
-
-However, only those files which are admissible for the current mood
-or playlist are contained in the score table. The audio file selector
-always chooses the row with the highest score as the file to stream
-next. While doing so, it computes the new score and updates the
-last_played and the num_played fields in the audio file table.
-
-The score table is recomputed by the select command which loads a
-mood or playlist. Audio files are chosen for streaming from the rows
-of the score table on a highest-score-first basis.
-
-
-Playlists and moods
-~~~~~~~~~~~~~~~~~~~
-
-Playlists and moods offer two different ways of specifying the set of
-admissible files. A playlist in itself describes a set of admissible
-files. A mood, in contrast, describes the set of admissible files in
-terms of attributes and other type of information available in the
-audio file table. As an example, a mood can define a filename pattern,
-which is then matched against the names of audio files in the table.
-
-*Playlists*
-
-Playlists are accommodated in the playlist table of the afs database,
-using the aforementioned blob format for tables. A new playlist is
-created with the addpl command by specifying the full (absolute)
-paths of all desired audio files, separated by newlines. Example:
-
-       find /my/mp3/dir -name "*.mp3" | para addpl my_playlist
-
-If _my_playlist_ already exists it is overwritten. To activate the
-new playlist, execute
-
-       para select p/my_playlist
-
-The audio file selector will assign scores to each entry of the list,
-in descending order so that files will be selected in order. If a
-file could not be opened for streaming, its entry is removed from
-the score table (but not from the playlist).
-
-*Moods*
-
-A mood consists of a unique name and its *mood definition*, which is
-a set of *mood lines* containing expressions in terms of attributes
-and other data contained in the database.
-
-At any time at most one mood can be *active* which means that
-para_server is going to select only files from that subset of
-admissible files.
-
-So in order to create a mood definition one has to write a set of
-mood lines. Mood lines come in three flavours: Accept lines, deny
-lines and score lines.
-
-The general syntax of the three types of mood lines is
-
-
-       accept [with score <score>] [if] [not] <mood_method> [options]
-       deny [with score <score>] [if] [not] <mood_method> [options]
-       score <score>  [if] [not] <mood_method> [options]
-
-
-Here <score> is either an integer or the string "random" which assigns
-a random score to all matching files. The score value changes the
-order in which admissible files are going to be selected, but is of
-minor importance for this introduction.
-
-So we concentrate on the first two forms, i.e. accept and deny
-lines. As usual, everything in square brackets is optional, i.e.
-accept/deny lines take the following form when ignoring scores:
-
-       accept [if] [not] <mood_method> [options]
-
-and analogously for the deny case. The "if" keyword is only syntactic
-sugar and has no function. The "not" keyword just inverts the result,
-so the essence of a mood line is the mood method part and the options
-following thereafter.
-
-A *mood method* is realized as a function which takes an audio file
-and computes a number from the data contained in the database.
-If this number is non-negative, we say the file *matches* the mood
-method. The file matches the full mood line if it either
-
-       - matches the mood method and the "not" keyword is not given,
-or
-       - does not match the mood method, but the "not" keyword is given.
-
-The set of admissible files for the whole mood is now defined as those
-files which match at least one accept mood line, but no deny mood line.
-More formally, an audio file F is admissible if and only if
-
-       (F ~ AL1 or F ~ AL2...) and not (F ~ DL1 or F ~ DN2 ...)
-
-where AL1, AL2... are the accept lines, DL1, DL2... are the deny
-lines and "~" means "matches".
-
-The cases where no mood lines of accept/deny type are defined need
-special treatment:
-
-       - Neither accept nor deny lines: This treats all files as
-       admissible (in fact, that is the definition of the dummy mood
-       which is activated automatically if no moods are available).
-
-       - Only accept lines: A file is admissible iff it matches at
-       least one accept line:
-
-               F ~ AL1 or F ~ AL2 or ...
-
-       - Only deny lines: A file is admissible iff it matches no
-       deny line:
-
-               not (F ~ DL1 or F ~ DN2 ...)
-
-
-
-*List of mood_methods*
-
-       no_attributes_set
-
-Takes no arguments and matches an audio file if and only if no
-attributes are set.
-
-       is_set <attribute_name>
-
-Takes the name of an attribute and matches iff that attribute is set.
-
-       path_matches <pattern>
-
-Takes a filename pattern and matches iff the path of the audio file
-matches the pattern.
-
-       artist_matches <pattern>
-       album_matches <pattern>
-       title_matches <pattern>
-       comment_matches <pattern>
-
-Takes an extended regular expression and matches iff the text of the
-corresponding tag of the audio file matches the pattern. If the tag
-is not set, the empty string is matched against the pattern.
-
-       year ~ <num>
-       bitrate ~ <num>
-       frequency ~ <num>
-       channels ~ <num>
-       num_played ~ <num>
-
-Takes a comparator ~ of the set {<, =, <=, >, >=, !=} and a number
-<num>. Matches an audio file iff the condition <val> ~ <num> is
-satisfied where val is the corresponding value of the audio file
-(value of the year tag, bitrate in kbit/s, frequency in Hz, channel
-count, play count).
-
-The year tag is special as its value is undefined if the audio file
-has no year tag or the content of the year tag is not a number. Such
-audio files never match. Another difference is the special treatment
-if the year tag is a two-digit number. In this case either 1900 or
-2000 is added to the tag value, depending on whether the number is
-greater than 2000 plus the current year.
-
-
-*Mood usage*
-
-To create a new mood called "my_mood", write its definition into
-some temporary file, say "tmpfile", and add it to the mood table
-by executing
-
-       para addmood my_mood < tmpfile
-
-If the mood definition is really short, you may just pipe it to the
-client instead of using temporary files. Like this:
-
-       echo "$MOOD_DEFINITION" | para addmood my_mood
-
-There is no need to keep the temporary file since you can always use
-the catmood command to get it back:
-
-       para catmood my_mood
-
-A mood can be activated by executing
-
-       para select m/my_mood
-
-Once active, the list of admissible files is shown by the ls command
-if the "-a" switch is given:
-
-       para ls -a
-
-
-*Example mood definition*
-
-Suppose you have defined attributes "punk" and "rock" and want to define
-a mood containing only Punk-Rock songs. That is, an audio file should be
-admissible if and only if both attributes are set. Since
-
-       punk and rock
-
-is obviously the same as
-
-       not (not punk or not rock)
-
-(de Morgan's rule), a mood definition that selects only Punk-Rock
-songs is
-
-       deny if not is_set punk
-       deny if not is_set rock
-
-
-
-File renames and content changes
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Since the audio file selector knows the SHA1 of each audio file that
-has been added to the afs database, it recognizes if the content of
-a file has changed, e.g. because an ID3 tag was added or modified.
-Also, if a file has been renamed or moved to a different location,
-afs will detect that an entry with the same hash value already exists
-in the audio file table.
-
-In both cases it is enough to just re-add the new file. In the
-first case (file content changed), the audio table is updated, while
-metadata such as the num_played and last_played fields, as well as
-the attributes, remain unchanged. In the other case, when the file
-is moved or renamed, only the path information is updated, all other
-data remains as before.
-
-It is possible to change the behaviour of the add command by using the
-"-l" (lazy add) or the "-f" (force add) option.
-
-Troubleshooting
-~~~~~~~~~~~~~~~
-
-Use the debug loglevel (-l debug) to show debugging info. All paraslash
-executables have a brief online help which is displayed when -h is
-given. The --detailed-help option prints the full help text.
-
-If para_server crashed or was killed by SIGKILL (signal 9), it
-may refuse to start again because of "dirty osl tables". In this
-case you'll have to run the oslfsck program of libosl to fix your
-database:
-
-       oslfsck -fd ~/.paraslash/afs_database-0.4
-
-However, make sure para_server isn't running before executing oslfsck.
-
-If you don't mind to recreate your database you can start
-from scratch by removing the entire database directory, i.e.
-
-       rm -rf ~/.paraslash/afs_database-0.4
-
-Be aware that this removes all attribute definitions, all playlists
-and all mood definitions and requires to re-initialize the tables.
-
-Although oslfsck fixes inconsistencies in database tables it doesn't
-care about the table contents. To check for invalid table contents, use
-
-       para_client check
-
-This prints out references to missing audio files as well as invalid
-playlists and mood definitions.
-
-Similarly, para_audiod refuses to start if its socket file exists, since
-this indicates that another instance of para_audiod is running. After
-a crash a stale socket file might remain and you must run
-
-       para_audiod --force
-
-once to fix it up.
-
----------------------------------------
-Audio formats and audio format handlers
----------------------------------------
-
-Audio formats
-~~~~~~~~~~~~~
-
-The following audio formats are supported by paraslash:
-
-*MP3*
-
-Mp3, MPEG-1 Audio Layer 3, is a common audio format for audio storage,
-designed as part of its MPEG-1 standard.  An MP3 file is made up of
-multiple MP3 frames, which consist of a header and a data block. The
-size of an MP3 frame depends on the bit rate and on the number
-of channels. For a typical CD-audio file (sample rate of 44.1 kHz
-stereo), encoded with a bit rate of 128 kbit, an MP3 frame is about
-400 bytes large.
-
-*OGG/Vorbis*
-
-OGG is a standardized audio container format, while Vorbis is an
-open source codec for lossy audio compression. Since Vorbis is most
-commonly made available via the OGG container format, it is often
-referred to as OGG/Vorbis. The OGG container format divides data into
-chunks called OGG pages. A typical OGG page is about 4KB large. The
-Vorbis codec creates variable-bitrate (VBR) data, where the bitrate
-may vary considerably.
-
-*OGG/Speex*
-
-Speex is an open-source speech codec that is based on CELP (Code
-Excited Linear Prediction) coding. It is designed for voice
-over IP applications, has modest complexity and a small memory
-footprint. Wideband and narrowband (telephone quality) speech are
-supported. As for Vorbis audio, Speex bit-streams are often stored
-in OGG files. As of 2012 this codec is considered obsolete since the
-Oppus codec, described below, surpasses its performance in all areas.
-
-*OGG/Opus*
-
-Opus is a lossy audio compression format standardized through RFC
-6716 in 2012. It combines the speech-oriented SILK codec and the
-low-latency CELT (Constrained Energy Lapped Transform) codec. Like
-OGG/Vorbis and OGG/Speex, Opus data is usually encapsulated in OGG
-containers. All known software patents which cover Opus are licensed
-under royalty-free terms.
-
-*AAC*
-
-Advanced Audio Coding (AAC) is a standardized, lossy compression
-and encoding scheme for digital audio which is the default audio
-format for Apple's iPhone, iPod, iTunes. Usually MPEG-4 is used as
-the container format and audio files encoded with AAC have the .m4a
-extension. A typical AAC frame is about 700 bytes large.
-
-*WMA*
-
-Windows Media Audio (WMA) is an audio data compression technology
-developed by Microsoft. A WMA file is usually encapsulated in the
-Advanced Systems Format (ASF) container format, which also specifies
-how meta data about the file is to be encoded. The bit stream of WMA
-is composed of superframes, each containing one or more frames of
-2048 samples. For 16 bit stereo a WMA superframe is about 8K large.
-
-*FLAC*
-
-The Free Lossless Audio Codec (FLAC) compresses audio without quality
-loss. It gives better compression ratios than a general purpose
-compressor like zip or bzip2 because FLAC is designed specifically
-for audio. A FLAC-encoded file consists of frames of varying size, up
-to 16K. Each frame starts with a header that contains all information
-necessary to decode the frame.
-
-Meta data
-~~~~~~~~~
-
-Unfortunately, each audio format has its own conventions how meta
-data is added as tags to the audio file.
-
-For MP3 files, ID3, version 1 and 2 are widely used. ID3 version 1
-is rather simple but also very limited as it supports only artist,
-title, album, year and comment tags. Each of these can only be at most
-32 characters long. ID3, version 2 is much more flexible but requires
-a separate library being installed for paraslash to support it.
-
-Ogg vorbis, ogg speex and flac files contain meta data as Vorbis
-comments, which are typically implemented as strings of the form
-"[TAG]=[VALUE]". Unlike ID3 version 1 tags, one may use whichever
-tags are appropriate for the content.
-
-AAC files usually use the MPEG-4 container format for storing meta
-data while WMA files wrap meta data as special objects within the
-ASF container format.
-
-paraslash only tracks the most common tags that are supported by
-all tag variants: artist, title, year, album, comment. When a file
-is added to the AFS database, the meta data of the file is extracted
-and stored in the audio file table.
-
-Chunks and chunk tables
-~~~~~~~~~~~~~~~~~~~~~~~
-
-paraslash uses the word "chunk" as common term for the building blocks
-of an audio file. For MP3 files, a chunk is the same as an MP3 frame,
-while for OGG files a chunk is an OGG page, etc.  Therefore the chunk
-size varies considerably between audio formats, from a few hundred
-bytes (MP3) up to 16K (FLAC).
-
-The chunk table contains the offsets within the audio file that
-correspond to the chunk boundaries of the file. Like the meta data,
-the chunk table is computed and stored in the database whenever an
-audio file is added.
-
-The paraslash senders (see below) always send complete chunks. The
-granularity for seeking is therefore determined by the chunk size.
-
-Audio format handlers
-~~~~~~~~~~~~~~~~~~~~~
-
-For each audio format paraslash contains an audio format handler whose
-first task is to tell whether a given file is a valid audio file of
-this type. If so, the audio file handler extracts some technical data
-(duration, sampling rate, number of channels etc.), computes the
-chunk table and reads the meta data.
-
-The audio format handler code is linked into para_server and executed
-via the _add_ command. The same code is also available as a stand-alone
-tool, para_afh, which prints the technical data, the chunk table
-and the meta data of a file. Moreover, all audio format handlers are
-combined in the afh receiver which is part of para_recv and para_play.
-
-----------
-Networking
-----------
-
-Paraslash uses different network connections for control and data.
-para_client communicates with para_server over a dedicated TCP control
-connection. To transport audio data, separate data connections are
-used. For these data connections, a variety of transports (UDP, DCCP,
-HTTP) can be chosen.
-
-The chapter starts with the REFERENCE(The paraslash control
-service, control service), followed by a section on the various
-REFERENCE(Streaming protocols, streaming protocols) in which the data
-connections are described. The way audio file headers are embedded into
-the stream is discussed REFERENCE(Streams with headers and headerless
-streams, briefly) before the REFERENCE(Networking examples, example
-section) which illustrates typical commands for real-life scenarios.
-
-Both IPv4 and IPv6 are supported.
-
-The paraslash control service
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-para_server is controlled at runtime via the paraslash control
-connection. This connection is used for server commands (play, stop,
-...) as well as for afs commands (ls, select, ...).
-
-The server listens on a TCP port and accepts connections from clients
-that connect the open port. Each connection causes the server to fork
-off a client process which inherits the connection and deals with that
-client only. In this classical accept/fork approach the server process
-is unaffected if the child dies or goes crazy for whatever reason. In
-fact, the child process can not change address space of server process.
-
-The section on REFERENCE(Client-server authentication, client-server
-authentication) above described the early connection establishment
-from the crypto point of view. Here it is described what happens
-after the connection (including crypto setup) has been established.
-There are four processes involved during command dispatch as sketched
-in the following diagram.
-
-<<
-<pre>
- server_host                                   client_host
- ~~~~~~~~~~~                                   ~~~~~~~~~~~
-
- +-----------+             connect            +-----------+
- |para_server|<------------------------------ |para_client|
- +-----------+                                +-----------+
-      |                                             ^
-      |     fork   +---+                            |
-      +----------> |AFS|                            |
-      |            +---+                            |
-      |              ^                              |
-      |              |                              |
-      |              | connect (cookie)             |
-      |              |                              |
-      |              |                              |
-      |    fork   +-----+    inherited connection   |
-      +---------->|child|<--------------------------+
-                  +-----+
-</pre>
->>
-
-Note that the child process is not a child of the afs process,
-so communication of these two processes has to happen via local
-sockets. In order to avoid abuse of the local socket by unrelated
-processes, a magic cookie is created once at server startup time just
-before the server process forks off the AFS process. This cookie is
-known to the server, AFS and the child, but not to unrelated processes.
-
-There are two different kinds of commands: First there are commands
-that cause the server to respond with some answer such as the list
-of all audio files. All but the addblob commands (addimg, addlyr,
-addpl, addmood) are of this kind. The addblob commands add contents
-to the database, so they need to transfer data the other way round,
-from the client to the server.
-
-There is no knowledge about the server commands built into para_client,
-so it does not know about addblob commands. Instead, the server sends
-a special "awaiting data" packet for these commands. If the client
-receives this packet, it sends STDIN to the server, otherwise it
-dumps data from the server to STDOUT.
-
-Streaming protocols
-~~~~~~~~~~~~~~~~~~~
-
-A network (audio) stream usually consists of one streaming source,
-the _sender_, and one or more _receivers_ which read data over the
-network from the streaming source.
-
-Senders are thus part of para_server while receivers are part of
-para_audiod. Moreover, there is the stand-alone tool para_recv which
-can be used to manually download a stream, either from para_server
-or from a web-based audio streaming service.
-
-The following three streaming protocols are supported by paraslash:
-
-       - HTTP. Recommended for public streams that can be played by
-       any player like mpg123, xmms, itunes, winamp, etc. The HTTP
-       sender is supported on all operating systems and all platforms.
-
-       - DCCP. Recommended for LAN streaming. DCCP is currently
-       available only for Linux.
-
-       - UDP. Recommended for multicast LAN streaming.
-
-See the Appendix on REFERENCE(Network protocols, network protocols)
-for brief descriptions of the various protocols relevant for network
-audio streaming with paraslash.
-
-It is possible to activate more than one sender simultaneously.
-Senders can be controlled at run time and via config file and command
-line options.
-
-Note that audio connections are _not_ encrypted. Transport or Internet
-layer encryption should be used if encrypted data connections are
-needed.
-
-Since DCCP and TCP are both connection-oriented protocols, connection
-establishment/teardown and access control are very similar between
-these two streaming protocols. UDP is the most lightweight option,
-since in contrast to TCP/DCCP it is connectionless. It is also the
-only protocol supporting IP multicast.
-
-The HTTP and the DCCP sender listen on a (TCP/DCCP) port waiting for
-clients to connect and establish a connection via some protocol-defined
-handshake mechanism. Both senders maintain two linked lists each:
-The list of all clients which are currently connected, and the list
-of access control entries which determines who is allowed to connect.
-IP-based access control may be configured through config file and
-command line options and via the "allow" and "deny" sender subcommands.
-
-Upon receiving a GET request from the client, the HTTP sender sends
-back a status line and a message. The body of this message is the
-audio stream. This is common practice and is supported by many popular
-clients which can thus be used to play a stream offered by para_server.
-For DCCP things are a bit simpler: No messages are exchanged between
-the receiver and sender. The client simply connects and the sender
-starts to stream.
-
-DCCP is an experimental protocol which offers a number of new features
-not available for TCP. Both ends can negotiate these features using
-a built-in negotiation mechanism. In contrast to TCP/HTTP, DCCP is
-datagram-based (no retransmissions) and thus should not be used over
-lossy media (e.g. WiFi networks). One useful feature offered by DCCP
-is access to a variety of different congestion-control mechanisms
-called CCIDs. Two different CCIDs are available per default on Linux:
-
-
-       - _CCID 2_. A Congestion Control mechanism similar to that
-       of TCP. The sender maintains a congestion window and halves
-       this window in response to congestion.
-
-
-       - _CCID-3_. Designed to be fair when competing for bandwidth.
-       It has lower variation of throughput over time compared with
-       TCP, which makes it suitable for streaming media.
-
-Unlike the HTTP and DCCP senders, the UDP sender maintains only a
-single list, the _target list_. This list describes the set of clients
-to which the stream is sent. There is no list for access control and
-no "allow" and "deny" commands for the UDP sender. Instead, the "add"
-and "delete" commands can be used to modify the target list.
-
-Since both UDP and DCCP offer an unreliable datagram-based transport,
-additional measures are necessary to guard against disruptions over
-networks that are lossy or which may be subject to interference (as
-is for instance the case with WiFi). Paraslash uses FEC (Forward
-Error Correction) to guard against packet losses and reordering. The
-stream is FEC-encoded before it is sent through the UDP socket and
-must be decoded accordingly on the receiver side.
-
-The packet size and the amount of redundancy introduced by FEC can
-be configured via the FEC parameters which are dictated by server
-and may also be configured through the "sender" command.  The FEC
-parameters are encoded in the header of each network packet, so no
-configuration is necessary on the receiver side. See the section on
-REFERENCE(Forward error correction, FEC) below.
-
-Streams with headers and headerless streams
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-For OGG/Vorbis, OGG/Speex and wma streams, some of the information
-needed to decode the stream is only contained in the audio file
-header of the container format but not in each data chunk. Clients
-must be able to obtain this information in case streaming starts in
-the middle of the file or if para_audiod is started while para_server
-is already sending a stream.
-
-This is accomplished in different ways, depending on the streaming
-protocol. For connection-oriented streams (HTTP, DCCP) the audio file
-header is sent prior to audio file data. This technique however does
-not work for the connectionless UDP transport. Hence the audio file
-header is periodically being embedded into the UDP audio data stream.
-By default, the header is resent after five seconds. The receiver has
-to wait until the next header arrives before it can start decoding
-the stream.
-
-Examples
-~~~~~~~~
-
-The "si" (server info) command lists some information about the
-currently running server process.
-
--> Show PIDs, number of connected clients, uptime, and more:
-
-       para_client si
-
-The sender command of para_server prints information about senders,
-like the various access control lists, and it allows to (de-)activate
-senders and to change the access permissions at runtime.
-
--> List all senders
-
-       para_client sender
-
--> Obtain general help for the sender command:
-
-       para_client help sender
-
--> Get help for a specific sender (contains further examples):
-
-       s=http # or dccp or udp
-       para_client sender $s help
-
--> Show status of the http sender
-
-       para_client sender http status
-
-By default para_server activates both the HTTP and th DCCP sender on
-startup. This can be changed via command line options or para_server's
-config file.
-
--> List config file options for senders:
-
-       para_server -h
-
-All senders share the "on" and "off" commands, so senders may be
-activated and deactivated independently of each other.
-
--> Switch off the http sender:
-
-       para_client sender http off
-
--> Receive a DCCP stream using CCID2 and write the output into a file:
-
-       host=foo.org; ccid=2; filename=bar
-       para_recv --receiver "dccp --host $host --ccid $ccid" > $filename
-
-Note the quotes around the arguments for the dccp receiver. Each
-receiver has its own set of command line options and its own command
-line parser, so arguments for the dccp receiver must be protected
-from being interpreted by para_recv.
-
--> Start UDP multicast, using the default multicast address:
-
-       para_client sender udp add 224.0.1.38
-
--> Receive FEC-encoded multicast stream and write the output into a file:
-
-       filename=foo
-       para_recv -r udp > $filename
-
--> Add an UDP unicast for a client to the target list of the UDP sender:
-
-       t=client.foo.org
-       para_client sender udp add $t
-
--> Receive this (FEC-encoded) unicast stream:
-
-       filename=foo
-       para_recv -r 'udp -i 0.0.0.0' > $filename
-
--> Create a minimal config for para_audiod for HTTP streams:
-
-       c=$HOME/.paraslash/audiod.conf.min; s=server.foo.com
-       echo receiver \".:http -i $s\" > $c
-       para_audiod --config $c
-
--------
-Filters
--------
-
-A paraslash filter is a module which transforms an input stream into
-an output stream. Filters are included in the para_audiod executable
-and in the stand-alone tool para_filter which usually contains the
-same modules.
-
-While para_filter reads its input stream from STDIN and writes
-the output to STDOUT, the filter modules of para_audiod are always
-connected to a receiver which produces the input stream and a writer
-which absorbs the output stream.
-
-Some filters depend on a specific library and are not compiled in
-if this library was not found at compile time. To see the list of
-supported filters, run para_filter and para_audiod with the --help
-option. The output looks similar to the following:
-
-       Available filters:
-               compress wav amp fecdec wmadec prebuffer oggdec aacdec mp3dec
-
-Out of these filter modules, a chain of filters can be constructed,
-much in the way Unix pipes can be chained, and analogous to the use
-of modules in gstreamer: The output of the first filter becomes the
-input of the second filter. There is no limitation on the number of
-filters and the same filter may occur more than once.
-
-Like receivers, each filter has its own command line options which
-must be quoted to protect them from the command line options of
-the driving application (para_audiod or para_filter). Example:
-
-       para_filter -f 'mp3dec --ignore-crc' -f 'compress --damp 1'
-
-For para_audiod, each audio format has its own set of filters. The
-name of the audio format for which the filter should be applied can
-be used as the prefix for the filter option. Example:
-
-       para_audiod -f 'mp3:prebuffer --duration 300'
-
-The "mp3" prefix above is actually interpreted as a POSIX extended
-regular expression. Therefore
-
-       para_audiod -f '.:prebuffer --duration 300'
-
-activates the prebuffer filter for all supported audio formats (because
-"." matches all audio formats) while
-
-       para_audiod -f 'wma|ogg:prebuffer --duration 300'
-
-activates it only for wma and ogg streams.
-
-Decoders
-~~~~~~~~
-
-For each supported audio format there is a corresponding filter
-which decodes audio data in this format to 16 bit PCM data which
-can be directly sent to the sound device or any other software that
-operates on undecoded PCM data (visualizers, equalizers etc.). Such
-filters are called _decoders_ in general, and xxxdec is the name of
-the paraslash decoder for the audio format xxx. For example, the mp3
-decoder is called mp3dec.
-
-Note that the output of the decoder is about 10 times larger than
-its input. This means that filters that operate on the decoded audio
-stream have to deal with much more data than filters that transform
-the audio stream before it is fed to the decoder.
-
-Paraslash relies on external libraries for most decoders, so these
-libraries must be installed for the decoder to be included in the
-executables. For example, the mp3dec filter depends on the mad library.
-
-Forward error correction
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-As already mentioned REFERENCE(Streaming protocols, earlier),
-paraslash uses forward error correction (FEC) for the unreliable UDP
-and DCCP transports. FEC is a technique which was invented already
-in 1960 by Reed and Solomon and which is widely used for the parity
-calculations of storage devices (RAID arrays). It is based on the
-algebraic concept of finite fields, today called Galois fields, in
-honour of the mathematician Galois (1811-1832). The FEC implementation
-of paraslash is based on code by Luigi Rizzo.
-
-Although the details require a sound knowledge of the underlying
-mathematics, the basic idea is not hard to understand: For positive
-integers k and n with k < n it is possible to compute for any k given
-data bytes d_1, ..., d_k the corresponding r := n -k parity bytes p_1,
-..., p_r such that all data bytes can be reconstructed from *any*
-k bytes of the set
-
-       {d_1, ..., d_k, p_1, ..., p_r}.
-
-FEC-encoding for unreliable network transports boils down to slicing
-the audio stream into groups of k suitably sized pieces called _slices_
-and computing the r corresponding parity slices. This step is performed
-in para_server which then sends both the data and the parity slices
-over the unreliable network connection. If the client was able
-to receive at least k of the n = k + r slices, it can reconstruct
-(FEC-decode) the original audio stream.
-
-From these observations it is clear that there are three different
-FEC parameters: The slice size, the number of data slices k, and the
-total number of slices n. It is crucial to choose the slice size
-such that no fragmentation of network packets takes place because
-FEC only guards against losses and reordering but fails if slices are
-received partially.
-
-FEC decoding in paralash is performed through the fecdec filter which
-usually is the first filter (there can be other filters before fecdec
-if these do not alter the audio stream).
-
-
-Volume adjustment (amp and compress)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The amp and the compress filter both adjust the volume of the audio
-stream. These filters operate on uncompressed audio samples. Hence
-they are usually placed directly after the decoding filter. Each
-sample is multiplied with a scaling factor (>= 1) which makes amp
-and compress quite expensive in terms of computing power.
-
-*amp*
-
-The amp filter amplifies the audio stream by a fixed scaling factor
-that must be known in advance. For para_audiod this factor is derived
-from the amplification field of the audio file's entry in the audio
-file table while para_filter uses the value given at the command line.
-
-The optimal scaling factor F for an audio file is the largest real
-number F >= 1 such that after multiplication with F all samples still
-fit into the sample interval [-32768, 32767]. One can use para_filter
-in combination with the sox utility to compute F:
-
-       para_filter -f mp3dec -f wav < file.mp3 | sox -t wav - -e stat -v
-
-The amplification value V which is stored in the audio file table,
-however, is an integer between 0 and 255 which is connected to F
-through the formula
-
-       V = (F - 1) * 64.
-
-To store V in the audio file table, the command
-
-       para_client -- touch -a=V file.mp3
-
-is used. The reader is encouraged to write a script that performs
-these computations :)
-
-*compress*
-
-Unlike the amplification filter, the compress filter adjusts the volume
-of the audio stream dynamically without prior knowledge about the peak
-value. It maintains the maximal volume of the last n samples of the
-audio stream and computes a suitable amplification factor based on that
-value and the various configuration options. It tries to chose this
-factor such that the adjusted volume meets the desired target level.
-
-Note that it makes sense to combine amp and compress.
-
-Misc filters (wav and prebuffer)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-These filters are rather simple and do not modify the audio stream at
-all. The wav filter is only useful with para_filter and in connection
-with a decoder. It asks the decoder for the number of channels and the
-sample rate of the stream and adds a Microsoft wave header containing
-this information at the beginning. This allows to write wav files
-rather than raw PCM files (which do not contain any information about
-the number of channels and the sample rate).
-
-The prebuffer filter simply delays the output until the given time has
-passed (starting from the time the first byte was available in its
-input queue) or until the given amount of data has accumulated. It
-is mainly useful for para_audiod if the standard parameters result
-in buffer underruns.
-
-Both filters require almost no additional computing time, even when
-operating on uncompressed audio streams, since data buffers are simply
-"pushed down" rather than copied.
-
-Examples
-~~~~~~~~
-
--> Decode an mp3 file to wav format:
-
-       para_filter -f mp3dec -f wav < file.mp3 > file.wav
-
--> Amplify a raw audio file by a factor of 1.5:
-
-       para_filter -f amp --amp 32 < foo.raw > bar.raw
-
-------
-Output
-------
-
-Once an audio stream has been received and decoded to PCM format,
-it can be sent to a sound device for playback. This part is performed
-by paraslash _writers_ which are described in this chapter.
-
-Writers
-~~~~~~~
-
-A paraslash writer acts as a data sink that consumes but does not
-produce audio data. Paraslash writers operate on the client side and
-are contained in para_audiod and in the stand-alone tool para_write.
-
-The para_write program reads uncompressed audio data from STDIN. If
-this data starts with a wav header, sample rate, sample format and
-channel count are read from the header. Otherwise CD audio (44.1KHz
-16 bit little endian, stereo) is assumed but this can be overridden
-by command line options. para_audiod, on the other hand, obtains
-the sample rate and the number of channels from the decoder.
-
-Like receivers and filters, each writer has an individual set of
-command line options, and for para_audiod writers can be configured
-per audio format separately. It is possible to activate more than
-one writer for the same stream simultaneously.
-
-OS-dependent APIs
-~~~~~~~~~~~~~~~~~
-
-Unfortunately, the various flavours of Unix on which paraslash
-runs on have different APIs for opening a sound device and starting
-playback. Hence for each such API there is a paraslash writer that
-can play the audio stream via this API.
-
-*ALSA*. The _Advanced Linux Sound Architecture_ is only available on
-Linux systems. Although there are several mid-layer APIs in use by
-the various Linux distributions (ESD, Jack, PulseAudio), paraslash
-currently supports only the low-level ALSA API which is not supposed
-to be change. ALSA is very feature-rich, in particular it supports
-software mixing via its DMIX plugin. ALSA is the default writer on
-Linux systems.
-
-*OSS*. The _Open Sound System_ is the only API on *BSD Unixes and
-is also available on Linux systems, usually provided by ALSA as an
-emulation for backwards compatibility. This API is rather simple but
-also limited. For example only one application can open the device
-at any time. The OSS writer is activated by default on BSD Systems.
-
-*OSX*. Mac OS X has yet another API called CoreAudio. The OSX writer
-for this API is only compiled in on such systems and is of course
-the default there.
-
-*FILE*. The file writer allows to capture the audio stream and
-write the PCM data to a file on the file system rather than playing
-it through a sound device. It is supported on all platforms and is
-always compiled in.
-
-*AO*. _Libao_ is a cross-platform audio library which supports a wide
-variety of platforms including PulseAudio (gnome), ESD (Enlightened
-Sound Daemon), AIX, Solaris and IRIX.  The ao writer plays audio
-through an output plugin of libao.
-
-Examples
-~~~~~~~~
-
--> Use the OSS writer to play a wav file:
-
-       para_write --writer oss < file.wav
-
--> Enable ALSA software mixing for mp3 streams
-
-       para_audiod --writer 'mp3:alsa -d plug:swmix'
-
-
----
-Gui
----
-
-para_gui executes an arbitrary command which is supposed to print
-status information to STDOUT. It then displays this information in
-a curses window. By default the command
-
-       para_audioc -- stat -p
-
-is executed, but this can be customized via the --stat-cmd option. In
-particular it possible to use
-
-       para_client -- stat -p
-
-to make para_gui work on systems on which para_audiod is not running.
-
-Key bindings
-~~~~~~~~~~~~
-
-It is possible to bind keys to arbitrary commands via custom
-key-bindings. Besides the internal keys which can not be changed (help,
-quit, loglevel, version...), the following flavours of key-bindings
-are supported:
-
-       - external: Shutdown curses before launching the given command.
-       Useful for starting other ncurses programs from within
-       para_gui, e.g. aumix or dialog scripts. Or, use the mbox
-       output format to write a mailbox containing one mail for each
-       (admissible) file the audio file selector knows about. Then
-       start mutt from within para_gui to browse your collection!
-
-       - display: Launch the command and display its stdout in
-       para_gui's bottom window.
-
-       - para: Like display, but start "para_client <specified
-       command>" instead of "<specified command>".
-
-The general form of a key binding is
-
-       key_map k:m:c
-
-which maps key k to command c using mode m. Mode may be x, d or p
-for external, display and paraslash commands, respectively.
-
-Themes
-~~~~~~
-
-Currently there are only two themes for para_gui. It is easy, however,
-to add more themes. To create a new theme one has to define the
-position, color and geometry for for each status item that should be
-shown by this theme. See gui_theme.c for examples.
-
-The "." and "," keys are used to switch between themes.
-
-Examples
-~~~~~~~~
-
--> Show server info:
-
-       key_map "i:p:si"
-
--> Jump to the middle of the current audio file by pressing F5:
-
-       key_map "<F5>:p:jmp 50"
-
--> vi-like bindings for jumping around:
-
-       key_map "l:p:ff 10"
-       key_map "h:p:ff 10-"
-       key_map "w:p:ff 60"
-       key_map "b:p:ff 60-"
-
--> Print the current date and time:
-
-       key_map "D:d:date"
-
--> Call other curses programs:
-
-       key_map "U:x:aumix"
-       key_map "!:x:/bin/bash"
-       key_map "^E:x:/bin/sh -c 'vi ~/.paraslash/gui.conf'"
-
------------
-Development
------------
-
-Tools
-~~~~~
-
-In order to compile the sources from the git repository (rather than
-from tar balls) and for contributing non-trivial changes to the
-paraslash project, some additional tools should be installed on a
-developer machine.
-
-http://git.or.cz/ (git). As described in more detail REFERENCE(Git
-branches, below), the git source code management tool is used for
-paraslash development. It is necessary for cloning the git repository
-and for getting updates.
-
-ftp://ftp.gnu.org/pub/gnu/m4/ (m4). Some input files for gengetopt
-are generated from templates by the m4 macro processor.
-
-ftp://ftp.gnu.org/pub/gnu/autoconf/ (autoconf) GNU autoconf creates
-the configure file which is shipped in the tarballs but has to be
-generated when compiling from git.
-
-http://www.triptico.com/software/grutatxt.html (grutatxt). The
-HTML version of this manual and some of the paraslash web pages are
-generated by the grutatxt plain text to HTML converter. If changes
-are made to these text files the grutatxt package must be installed
-to regenerate the HTML files.
-
-http://www.stack.nl/~dimitri/doxygen/ (doxygen). The documentation
-of paraslash's C sources uses the doxygen documentation system. The
-conventions for documenting the source code is described in the
-REFERENCE(Doxygen, Doxygen section).
-
-ftp://ftp.gnu.org/pub/gnu/global (global). This is used to generate
-browsable HTML from the C sources. It is needed by doxygen.
-
-Git branches
-~~~~~~~~~~~~
-
-Paraslash has been developed using the git source code management
-tool since 2006. Development is organized roughly in the same spirit
-as the git development itself, as described below.
-
-The following text passage is based on "A note from the maintainer",
-written by Junio C Hamano, the maintainer of git.
-
-There are four branches in the paraslash repository that track the
-source tree: "master", "maint", "next", and "pu".
-
-The "master" branch is meant to contain what is well tested and
-ready to be used in a production setting. There could occasionally be
-minor breakages or brown paper bag bugs but they are not expected to
-be anything major, and more importantly quickly and easily fixable.
-Every now and then, a "feature release" is cut from the tip of this
-branch, named with three dotted decimal digits, like 0.4.2.
-
-Whenever changes are about to be included that will eventually lead to
-a new major release (e.g. 0.5.0), a "maint" branch is forked off from
-"master" at that point. Obvious, safe and urgent fixes after the major
-release are applied to this branch and maintenance releases are cut
-from it. New features never go to this branch. This branch is also
-merged into "master" to propagate the fixes forward.
-
-A trivial and safe enhancement goes directly on top of "master".
-New development does not usually happen on "master", however.
-Instead, a separate topic branch is forked from the tip of "master",
-and it first is tested in isolation; Usually there are a handful such
-topic branches that are running ahead of "master". The tip of these
-branches is not published in the public repository to keep the number
-of branches that downstream developers need to worry about low.
-
-The quality of topic branches varies widely. Some of them start out as
-"good idea but obviously is broken in some areas" and then with some
-more work become "more or less done and can now be tested by wider
-audience". Luckily, most of them start out in the latter, better shape.
-
-The "next" branch is to merge and test topic branches in the latter
-category.  In general, this branch always contains the tip of "master".
-It might not be quite rock-solid production ready, but is expected to
-work more or less without major breakage. The maintainer usually uses
-the "next" version of paraslash for his own pleasure, so it cannot
-be _that_ broken. The "next" branch is where new and exciting things
-take place.
-
-The two branches "master" and "maint" are never rewound, and "next"
-usually will not be either (this automatically means the topics that
-have been merged into "next" are usually not rebased, and you can find
-the tip of topic branches you are interested in from the output of
-"git log next"). You should be able to safely build on top of them.
-
-However, at times "next" will be rebuilt from the tip of "master" to
-get rid of merge commits that will never be in "master". The commit
-that replaces "next" will usually have the identical tree, but it
-will have different ancestry from the tip of "master".
-
-The "pu" (proposed updates) branch bundles the remainder of the
-topic branches.  The "pu" branch, and topic branches that are only in
-"pu", are subject to rebasing in general.  By the above definition
-of how "next" works, you can tell that this branch will contain quite
-experimental and obviously broken stuff.
-
-When a topic that was in "pu" proves to be in testable shape, it
-graduates to "next".  This is done with
-
-        git checkout next
-       git merge that-topic-branch
-
-Sometimes, an idea that looked promising turns out to be not so good
-and the topic can be dropped from "pu" in such a case.
-
-A topic that is in "next" is expected to be polished to perfection
-before it is merged to "master".  Similar to the above, this is
-done with
-
-        git checkout master
-       git merge that-topic-branch
-       git branch -d that-topic-branch
-
-Note that being in "next" is not a guarantee to appear in the next
-release (being in "master" is such a guarantee, unless it is later
-found seriously broken and reverted), nor even in any future release.
-
-Coding Style
-~~~~~~~~~~~~
-
-The preferred coding style for paraslash coincides more or less
-with the style of the Linux kernel. So rather than repeating what is
-written XREFERENCE(http://www.kernel.org/doc/Documentation/CodingStyle,
-there), here are the most important points.
-
-       - Burn the GNU coding standards.
-       - Never use spaces for indentation.
-       - Tabs are 8 characters, and thus indentations are also 8 characters.
-       - Don't put multiple assignments on a single line.
-       - Avoid tricky expressions.
-       - Don't leave whitespace at the end of lines.
-       - The limit on the length of lines is 80 columns.
-       - Use K&R style for placing braces and spaces:
-
-               if (x is true) {
-                       we do y
-               }
-
-       - Use a space after (most) keywords.
-       - Do not add spaces around (inside) parenthesized expressions.
-       - Use one space around (on each side of) most binary and ternary operators.
-       - Do not use cute names like ThisVariableIsATemporaryCounter, call it tmp.
-       - Mixed-case names are frowned upon.
-       - Descriptive names for global variables are a must.
-       - Avoid typedefs.
-       - Functions should be short and sweet, and do just one thing.
-       - The number of local variables shouldn't exceed 10.
-       - Gotos are fine if they improve readability and reduce nesting.
-       - Don't use C99-style "// ..." comments.
-       - Names of macros defining constants and labels in enums are capitalized.
-       - Enums are preferred when defining several related constants.
-       - Always use the paraslash wrappers for allocating memory.
-       - If the name of a function is an action or an imperative.
-         command, the function should return an error-code integer
-         (<0 means error, >=0 means success). If the name is a
-         predicate, the function should return a "succeeded" boolean.
-
-
-Doxygen
-~~~~~~~
-
-Doxygen is a documentation system for various programming
-languages. The API reference on the paraslash web page is generated
-by doxygen.
-
-It is more illustrative to look at the source code for examples than
-to describe the conventions in this manual, so we only describe which
-parts of the code need doxygen comments, but leave out details on
-documentation conventions.
-
-As a rule, only the public part of the C source is documented with
-Doxygen. This includes structures, defines and enumerations in header
-files as well as public (non-static) C functions.  These should be
-documented completely. For example, each parameter and the return
-value of a public function should get a descriptive doxygen comment.
-
-No doxygen comments are necessary for static functions and for
-structures and enumerations in C files (which are used only within
-this file). This does not mean, however, that those entities need
-no documentation at all. Instead, common sense should be applied to
-document what is not obvious from reading the code.
-
---------
-Appendix
---------
-
-Network protocols
-~~~~~~~~~~~~~~~~~
-
-*IP*. The _Internet Protocol_ is the primary networking protocol
-used for the Internet. All protocols described below use IP as the
-underlying layer. Both the prevalent IPv4 and the next-generation
-IPv6 variant are being deployed actively worldwide.
-
-*Connection-oriented and connectionless protocols*. Connectionless
-protocols differ from connection-oriented ones in that state
-associated with the sending/receiving endpoints is treated
-implicitly. Connectionless protocols maintain no internal knowledge
-about the state of the connection. Hence they are not capable of
-reacting to state changes, such as sudden loss or congestion on the
-connection medium. Connection-oriented protocols, in contrast, make
-this knowledge explicit. The connection is established only after
-a bidirectional handshake which requires both endpoints to agree
-on the state of the connection, and may also involve negotiating
-specific parameters for the particular connection. Maintaining an
-up-to-date internal state of the connection also in general means
-that the sending endpoints perform congestion control, adapting to
-qualitative changes of the connection medium.
-
-*Reliability*. In IP networking, packets can be lost, duplicated,
-or delivered out of order, and different network protocols handle
-these problems in different ways. We call a transport-layer protocol
-_reliable_, if it turns the unreliable IP delivery into an ordered,
-duplicate- and loss-free delivery of packets. Sequence numbers
-are used to discard duplicates and re-arrange packets delivered
-out-of-order. Retransmission is used to guarantee loss-free
-delivery. Unreliable protocols, in contrast, do not guarantee ordering
-or data integrity.
-
-*Classification*. With these definitions the protocols which are used
-by paraslash for steaming audio data may be classified as follows.
-
-       - HTTP/TCP: connection-oriented, reliable,
-       - UDP: connectionless, unreliable,
-       - DCCP: connection-oriented, unreliable.
-
-Below we give a short descriptions of these protocols.
-
-*TCP*. The _Transmission Control Protocol_ provides reliable,
-ordered delivery of a stream and a classic window-based congestion
-control. In contrast to UDP and DCCP (see below), TCP does not have
-record-oriented or datagram-based syntax, i.e. it provides a stream
-which is unaware and independent of any record (packet) boundaries.
-TCP is used extensively by many application layers. Besides HTTP (the
-Hypertext Transfer Protocol), also FTP (the File Transfer protocol),
-SMTP (Simple Mail Transfer Protocol), SSH (Secure Shell) all sit on
-top of TCP.
-
-*UDP*. The _User Datagram Protocol_ is the simplest transport-layer
-protocol, built as a thin layer directly on top of IP. For this reason,
-it offers the same best-effort service as IP itself, i.e. there is no
-detection of duplicate or reordered packets. Being a connectionless
-protocol, only minimal internal state about the connection is
-maintained, which means that there is no protection against packet
-loss or network congestion. Error checking and correction (if at all)
-are performed in the application.
-
-*DCCP*. The _Datagram Congestion Control Protocol_ combines the
-connection-oriented state maintenance known from TCP with the
-unreliable, datagram-based transport of UDP. This means that it
-is capable of reacting to changes in the connection by performing
-congestion control, offering multiple alternative approaches. But it
-is bound to datagram boundaries (the maximum packet size supported
-by a medium), and like UDP it lacks retransmission to protect
-against loss. Due to the use of sequence numbers, it is however
-able to react to loss (interpreted as a congestion indication) and
-to ignore out-of-order and duplicate packets. Unlike TCP it allows
-to negotiate specific, binding features for a connection, such as
-the choice of congestion control: classic, window-based congestion
-control known from TCP is available as CCID-2, rate-based, "smooth"
-congestion control is offered as CCID-3.
-
-*HTTP*. _The Hypertext Transfer Protocol_ is an application layer
-protocol on top of TCP. It is spoken by web servers and is most often
-used for web services.  However, as can be seen by the many Internet
-radio stations and YouTube/Flash videos, http is by far not limited to
-the delivery of web pages only. Being a simple request/response based
-protocol, the semantics of the protocol also allow the delivery of
-multimedia content, such as audio over http.
-
-*Multicast*. IP multicast is not really a protocol but a technique
-for one-to-many communication over an IP network. The challenge is to
-deliver information to a group of destinations simultaneously using
-the most efficient strategy to send the messages over each link of
-the network only once. This has benefits for streaming multimedia:
-the standard one-to-one unicast offered by TCP/DCCP means that
-n clients listening to the same stream also consume n-times the
-resources, whereas multicast requires to send the stream just once,
-irrespective of the number of receivers.  Since it would be costly to
-maintain state for each listening receiver, multicast often implies
-connectionless transport, which is the reason that it is currently
-only available via UDP.
-
-Abstract socket namespace
-~~~~~~~~~~~~~~~~~~~~~~~~~
-UNIX domain sockets are a traditional way to communicate between
-processes on the same machine. They are always reliable (see above)
-and don't reorder datagrams. Unlike TCP and UDP, UNIX domain sockets
-support passing open file descriptors or process credentials to
-other processes.
-
-The usual way to set up a UNIX domain socket (as obtained from
-socket(2)) for listening is to first bind the socket to a file system
-pathname and then call listen(2), then accept(2). Such sockets are
-called _pathname sockets_ because bind(2) creates a special socket
-file at the specified path. Pathname sockets allow unrelated processes
-to communicate with the listening process by binding to the same path
-and calling connect(2).
-
-There are two problems with pathname sockets:
-
-       * The listing process must be able to (safely) create the
-       socket special in a directory which is also accessible to
-       the connecting process.
-
-       * After an unclean shutdown of the listening process, a stale
-       socket special may reside on the file system.
-
-The abstract socket namespace is a non-portable Linux feature which
-avoids these problems. Abstract sockets are still bound to a name,
-but the name has no connection with file system pathnames.
-
-License
-~~~~~~~
-
-Paraslash is licensed under the GPL, version 2. Most of the code
-base has been written from scratch, and those parts are GPL V2
-throughout. Notable exceptions are FEC and the WMA decoder. See the
-corresponding source files for licencing details for these parts. Some
-code sniplets of several other third party software packages have
-been incorporated into the paraslash sources, for example log message
-coloring was taken from the git sources. These third party software
-packages are all published under the GPL or some other license
-compatible to the GPL.
-
-Acknowledgements
-~~~~~~~~~~~~~~~~
-
-Many thanks to Gerrit Renker who read an early draft of this manual
-and contributed significant improvements.
-
-----------
-References
-----------
-
-Articles
-~~~~~~~~
-       - Reed, Irving S.; Solomon, Gustave (1960),
-       XREFERENCE(http://kom.aau.dk/~heb/kurser/NOTER/KOFA01.PDF,
-       Polynomial Codes over Certain Finite Fields), Journal of the
-       Society for Industrial and Applied Mathematics (SIAM) 8 (2):
-       300-304, doi:10.1137/0108018)
-
-RFCs
-~~~~
-
-       - XREFERENCE(http://www.ietf.org/rfc/rfc768.txt, RFC 768) (1980):
-       User Datagram Protocol
-       - XREFERENCE(http://www.ietf.org/rfc/rfc791.txt, RFC 791) (1981):
-       Internet Protocol
-       - XREFERENCE(http://www.ietf.org/rfc/rfc2437.txt, RFC 2437) (1998):
-       RSA Cryptography Specifications
-       - XREFERENCE(http://www.ietf.org/rfc/rfc4340.txt, RFC 4340)
-       (2006): Datagram Congestion Control Protocol (DCCP)
-       - XREFERENCE(http://www.ietf.org/rfc/rfc4341.txt, RFC 4341) (2006):
-       Congestion Control ID 2: TCP-like Congestion Control
-       - XREFERENCE(http://www.ietf.org/rfc/rfc4342.txt, RFC 4342) (2006):
-       Congestion Control ID 3: TCP-Friendly Rate Control (TFRC)
-       - XREFERENCE(http://www.ietf.org/rfc/rfc6716.txt, RFC 6716) (2012):
-       Definition of the Opus Audio Codec
-
-Application web pages
-~~~~~~~~~~~~~~~~~~~~~
-
-       - XREFERENCE(http://people.tuebingen.mpg.de/maan/paraslash/, paraslash)
-       - XREFERENCE(http://paraslash.systemlinux.org/, paraslash (alternative page))
-       - XREFERENCE(http://xmms2.org/wiki/Main_Page, xmms)
-       - XREFERENCE(http://www.mpg123.de/, mpg123)
-       - XREFERENCE(http://gstreamer.freedesktop.org/, gstreamer)
-       - XREFERENCE(http://www.icecast.org/, icecast)
-       - XREFERENCE(http://beesbuzz.biz/code/audiocompress.php, Audio Compress)
-
-External documentation
-~~~~~~~~~~~~~~~~~~~~~~
-
-       - XREFERENCE(http://kernel.org/pub/linux/kernel/people/hpa/raid6.pdf,
-       H. Peter Anvin: The mathematics of Raid6)
-       - XREFERENCE(http://info.iet.unipi.it/~luigi/fec_ccr.ps.gz,
-       Luigi Rizzo: Effective Erasure Codes for reliable Computer
-       Communication Protocols)
-
-Code
-~~~~
-       - XREFERENCE(http://info.iet.unipi.it/~luigi/vdm.tar.gz,
-       Original FEC implementation by Luigi Rizzo)
-
diff --git a/web/manual.md b/web/manual.md
new file mode 100644 (file)
index 0000000..b154b39
--- /dev/null
@@ -0,0 +1,2221 @@
+**Paraslash user manual**
+
+This document describes how to install, configure and use the paraslash
+network audio streaming system.  Most chapters start with a chapter
+overview and conclude with an example section. We try to focus on
+general concepts and on the interaction of the various pieces of the
+paraslash package. Hence this user manual is not meant as a replacement
+for the manual pages that describe all command line options of each
+paraslash executable.
+
+============
+Introduction
+============
+
+In this chapter we give an [overview](#Overview) of the interactions of
+the two main programs contained in the paraslash package, followed by
+[brief descriptions](#The.paraslash.executables) of all executables.
+
+Overview
+--------
+
+The core functionality of the para suite is provided by two main
+executables, para_server and para_audiod. The former maintains a
+database of audio files and streams these files to para_audiod which
+receives and plays the stream.
+
+In a typical setting, both para_server and para_audiod act as
+background daemons whose functionality is controlled by client
+programs: the para_audioc client controls para_audiod over a local
+socket while the para_client program connects to para_server over a
+local or remote networking connection.
+
+Typically, these two daemons run on different hosts but a local setup
+is also possible.
+
+A simplified picture of a typical setup is as follows
+
+       server_host                                  client_host
+       ~~~~~~~~~~~                                  ~~~~~~~~~~~
+
+       +-----------+         audio stream           +-----------+
+       |para_server| -----------------------------> |para_audiod|
+       +-----------+                                +-----------+
+            ^                                            ^
+            |                                            |
+            |                                            | connect
+            |                                            |
+            |                                            |
+            |                                       +-----------+
+            |                                       |para_audioc|
+            |                                       +-----------+
+            |
+            |
+            |                  connect              +-----------+
+            +-------------------------------------- |para_client|
+                                                    +-----------+
+The paraslash executables
+-------------------------
+
+### para_server ###
+
+para_server streams binary audio data (MP3, ...) over local and/or
+remote networks. It listens on a TCP port and accepts commands such
+as play, stop, pause, next from authenticated clients. There are
+many more commands though, see the man page of para_server for a
+description of all commands.
+
+It supports three built-in network streaming protocols
+(senders/receivers): HTTP, DCCP, or UDP. This is explained in more
+detail in the section on [networking](#Networking).
+
+The built-in audio file selector of paraslash is used to manage your
+audio files. It maintains statistics on the usage of all available
+audio files such as last-played time, and the number of times each
+file was selected.
+
+Additional information may be added to the database to allow
+fine-grained selection based on various properties of the audio file,
+including information found in (ID3) tags. However, old-fashioned
+playlists are also supported.
+
+It is also possible to store images (album covers) and lyrics in the
+database and associate these to the corresponding audio files.
+
+The section on the [audio file selector](#The.audio.file.selector)
+discusses this topic.
+
+
+### para_client ###
+
+The client program to connect to para_server. paraslash commands
+are sent to para_server and the response is dumped to STDOUT. This
+can be used by any scripting language to produce user interfaces with
+little programming effort.
+
+All connections between para_server and para_client are encrypted
+with a symmetric session key. For each user of paraslash you must
+create a public/secret RSA key pair for authentication.
+
+If para_client is started without non-option arguments, an interactive
+session (shell) is started. Command history and command completion are
+supported through libreadline.
+
+### para_audiod ###
+
+The local daemon that collects information from para_server.
+
+It runs on the client side and connects to para_server. As soon as
+para_server announces the availability of an audio stream, para_audiod
+starts an appropriate receiver, any number of filters and a paraslash
+writer to play the stream.
+
+Moreover, para_audiod listens on a local socket and sends status
+information about para_server and para_audiod to local clients on
+request. Access via this local socket may be restricted by using Unix
+socket credentials, if available.
+
+
+### para_audioc ###
+
+The client program which talks to para_audiod. Used to control
+para_audiod, to receive status info, or to grab the stream at any
+point of the decoding process. Like para_client, para_audioc supports
+interactive sessions on systems with libreadline.
+
+### para_recv ###
+
+A command line HTTP/DCCP/UDP stream grabber. The http mode is
+compatible with arbitrary HTTP streaming sources (e.g. icecast).
+In addition to the three network streaming modes, para_recv can also
+operate in local (afh) mode. In this mode it writes the content of
+an audio file on the local file system in complete chunks to stdout,
+optionally 'just in time'. This allows to cut an audio file without
+first decoding it, and it enables third-party software which is unaware
+of the particular audio format to send complete frames in real time.
+
+### para_filter ###
+
+A filter program that reads from STDIN and writes to STDOUT.
+Like para_recv, this is an atomic building block which can be used to
+assemble higher-level audio receiving facilities. It combines several
+different functionalities in one tool: decoders for multiple audio
+formats and a number of processing filters, among these a normalizer
+for audio volume.
+
+### para_afh ###
+
+A small stand-alone program that prints tech info about the given
+audio file to STDOUT. It can be instructed to print a "chunk table",
+an array of offsets within the audio file.
+
+### para_write ###
+
+A modular audio stream writer. It supports a simple file writer
+output plug-in and optional WAV/raw players for ALSA (Linux) and for
+coreaudio (Mac OS). para_write can also be used as a stand-alone WAV
+or raw audio player.
+
+### para_play ###
+
+A command line audio player.
+
+### para_gui ###
+
+Curses-based gui that presents status information obtained in a curses
+window. Appearance can be customized via themes. para_gui provides
+key-bindings for the most common server commands and new key-bindings
+can be added easily.
+
+### para_fade ###
+
+An alarm clock and volume-fader for OSS and ALSA.
+
+===========
+Quick start
+===========
+
+This chapter lists the [necessary software](#Requirements)
+that must be installed to compile the paraslash package, describes
+how to [compile and install](#Installation) the paraslash
+source code and the steps that have to be performed in order to
+[set up](#Configuration) a typical server and client.
+
+Requirements
+------------
+### For the impatient ###
+
+       git clone git://git.tuebingen.mpg.de/osl
+       cd osl && make && sudo make install && sudo ldconfig
+       sudo apt-get install autoconf libssl-dev help2man gengetopt m4 \
+              libmad0-dev libid3tag0-dev libasound2-dev libvorbis-dev \
+              libfaad-dev libspeex-dev libFLAC-dev libsamplerate-dev realpath \
+              libasound2-dev libao-dev libreadline-dev libncurses-dev \
+              libopus-dev
+
+### Detailed description ###
+
+In any case you will need
+
+- [libosl](http://people.tuebingen.mpg.de/maan/osl/). The _object
+storage layer_ library is used by para_server. To clone the source
+code repository, execute
+
+               git clone git://git.tuebingen.mpg.de/osl
+
+- [gcc](ftp://ftp.gnu.org/pub/gnu/gcc) or
+[clang](http://clang.llvm.org). All gcc versions >= 4.2 are currently
+supported. Clang version 1.1 or newer should work as well.
+
+- [gnu make](ftp://ftp.gnu.org/pub/gnu/make) is also shipped with the
+disto. On BSD systems the gnu make executable is often called gmake.
+
+- [bash](ftp://ftp.gnu.org/pub/gnu/bash). Some scripts which run
+during compilation require the _Bourne again shell_.  It is most
+likely already installed.
+
+- [gengetopt](ftp://ftp.gnu.org/pub/gnu/gengetopt/) is needed to
+generate the C code for the command line parsers of all paraslash
+executables.
+
+- [help2man](ftp://ftp.gnu.org/pub/gnu/help2man) is used to create
+the man pages.
+
+- [m4](ftp://ftp.gnu.org/pub/gnu/m4/). Some source files are generated
+from templates by the m4 macro processor.
+
+Optional:
+
+- [openssl](http://www.openssl.org/) or
+[libgcrypt](ftp://ftp.gnupg.org/gcrypt/libgcrypt/).  At least one
+of these two libraries is needed as the backend for cryptographic
+routines on both the server and the client side. Both openssl and
+libgcrypt are usually shipped with the distro, but you might have
+to install the development package (`libssl-dev` or `libgcrypt-dev`
+on debian systems) as well.
+
+- [libmad](http://www.underbit.com/products/mad/). To compile in MP3
+support for paraslash, the development package must be installed. It
+is called `libmad0-dev` on debian-based systems. Note that libmad is
+not necessary on the server side, i.e., for sending MP3 files.
+
+- [libid3tag](http://www.underbit.com/products/mad/). For version-2
+ID3 tag support, you willl need the libid3tag development package
+`libid3tag0-dev`. Without libid3tag, only version-1 tags are
+recognized. The mp3 tagger also needs this library for modifying
+(id3v1 and id3v2) tags.
+
+- [ogg vorbis](http://www.xiph.org/downloads/). For ogg vorbis streams
+you need libogg, libvorbis, libvorbisfile. The corresponding Debian
+packages are called `libogg-dev` and `libvorbis-dev`.
+
+- [libfaad](http://www.audiocoding.com/). For aac files (m4a) you
+need libfaad (`libfaad-dev`).
+
+- [speex](http://www.speex.org/). In order to stream or decode speex
+files, libspeex (`libspeex-dev`) is required.
+
+- [flac](http://flac.sourceforge.net/). To stream or decode files
+encoded with the _Free Lossless Audio Codec_, libFLAC (`libFLAC-dev`)
+must be installed.
+
+- [libsamplerate](http://www.mega-nerd.com/SRC/index.html). The
+resample filter will only be compiled if this library is
+installed. Debian package: `libsamplerate-dev`.
+
+- [alsa-lib](ftp://ftp.alsa-project.org/pub/lib/). On Linux, you will
+need to have the ALSA development package `libasound2-dev` installed.
+
+- [libao](http://downloads.xiph.org/releases/ao/). Needed to build
+the ao writer (ESD, PulseAudio,...).  Debian package: `libao-dev`.
+
+- [curses](ftp://ftp.gnu.org/pub/gnu/ncurses). Needed for
+para_gui. Debian package: `libncurses-dev`.
+
+- [GNU
+Readline](http://cnswww.cns.cwru.edu/php/chet/readline/rltop.html). If
+this library (`libreadline-dev`) is installed, para_client, para_audioc
+and para_play support interactive sessions.
+
+Installation
+------------
+To build the sources from a tarball, execute
+
+       ./configure && make
+
+To build from git or a gitweb snapshot, run this command instead:
+
+       ./autogen.sh
+
+There should be no errors but probably some warnings about missing
+packages which usually implies that not all audio formats will be
+supported. If headers or libs are installed at unusual locations you
+might need to tell the configure script where to find them. Try
+
+       ./configure --help
+
+to see a list of options. If the paraslash package was compiled
+successfully, execute (optionally)
+
+       make test
+
+to run the paraslash test suite. If all tests pass, execute as root
+
+       make install
+
+to install executables under /usr/local/bin and the man pages under
+/usr/local/man.
+
+Configuration
+-------------
+
+### Create a paraslash user ###
+
+In order to control para_server at runtime you must create a paraslash
+user. As authentication is based on the RSA crypto system you'll have
+to create an RSA key pair. If you already have a user and an RSA key
+pair, you may skip this step.
+
+In this section we'll assume a typical setup: You would like to run
+para_server on some host called server_host as user foo, and you want
+to connect to para_server from another machine called client_host as
+user bar.
+
+As foo@server_host, create ~/.paraslash/server.users by typing the
+following commands:
+
+       user=bar
+       target=~/.paraslash/server.users
+       key=~/.paraslash/id_rsa.pub.$user
+       perms=AFS_READ,AFS_WRITE,VSS_READ,VSS_WRITE
+       mkdir -p ~/.paraslash
+       echo "user $user $key $perms" >> $target
+
+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 '' -f $key
+
+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,
+para_client rejects private keys which are world-readable.
+
+para_server only needs to know the public key of the key pair just
+created. Copy this public key to server_host:
+
+       src=~/.ssh/id_rsa.pub
+       dest=.paraslash/id_rsa.pub.$LOGNAME
+       scp $src foo@server_host:$dest
+
+Finally, tell para_client to connect to server_host:
+
+       conf=~/.paraslash/client.conf
+       echo 'hostname server_host' > $conf
+
+
+### Start para_server ###
+
+For this first try, we'll use the info loglevel to make the output
+of para_server more verbose.
+
+       para_server -l info
+
+Now you can use para_client to connect to the server and issue
+commands. Open a new shell as bar@client_host and try
+
+       para_client help
+       para_client si
+
+to retrieve the list of available commands and some server info.
+Don't proceed if this doesn't work.
+
+### Create and populate the database ###
+
+An empty database is created with
+
+       para_client init
+
+This initializes a couple of empty tables under
+~/.paraslash/afs_database-0.4. You normally don't need to look at these
+tables, but it's good to know that you can start from scratch with
+
+       rm -rf ~/.paraslash/afs_database-0.4
+
+in case something went wrong.
+
+Next, you need to add some audio files to that database so that
+para_server knows about them. Choose an absolute path to a directory
+containing some audio files and add them to the audio file table:
+
+       para_client add /my/mp3/dir
+
+This might take a while, so it is a good idea to start with a directory
+containing not too many files. Note that the table only contains data
+about the audio files found, not the files themselves.
+
+You may print the list of all known audio files with
+
+       para_client ls
+
+### Configure para_audiod ###
+
+We will have to tell para_audiod that it should receive the audio
+stream from server_host via http:
+
+       para_audiod -l info -r '.:http -i server_host'
+
+You should now be able to listen to the audio stream once para_server
+starts streaming. To activate streaming, execute
+
+       para_client play
+
+Since no playlist has been specified yet, the "dummy" mode which
+selects all known audio files is activated automatically. See the
+section on the [audio file selector](#The.audio.file.selector) for how
+to use playlists and moods to specify which files should be streamed
+in which order.
+
+Troubleshooting
+---------------
+
+If you receive a socket related error on server or audiod startup,
+make sure you have write permissions to the /var/paraslash directory:
+
+       sudo chown $LOGNAME /var/paraslash
+
+Alternatively, use the --afs-socket (para_server) or --socket
+(para_audiod) option to specify a different socket pathname.
+
+To identify streaming problems try to receive, decode and play the
+stream manually using para_recv, para_filter and para_write as follows.
+For simplicity we assume that you're running Linux/ALSA and that only
+MP3 files have been added to the database.
+
+       para_recv -r 'http -i server_host' > file.mp3
+       # (interrupt with CTRL+C after a few seconds)
+       ls -l file.mp3 # should not be empty
+       para_filter -f mp3dec -f wav < file.mp3 > file.wav
+       ls -l file.wav # should be much bigger than file.mp3
+       para_write -w alsa < file.wav
+
+Double check what is logged by para_server and use the --loglevel
+option of para_recv, para_filter and para_write to increase verbosity.
+
+===============
+User management
+===============
+
+para_server uses a challenge-response mechanism to authenticate
+requests from incoming connections, similar to ssh's public key
+authentication method. Authenticated connections are encrypted using
+a stream cipher, either RC4 or AES in integer counter mode.
+
+In this chapter we briefly describe RSA, RC4 and AES, and sketch the
+[authentication handshake](#Client-server.authentication)
+between para_client and para_server. User management is discussed
+in the section on [the user_list file](#The.user_list.file).
+These sections are all about communication between the client and the
+server. Connecting para_audiod is a different matter and is described
+in a [separate section](#Connecting.para_audiod).
+
+RSA, RC4, AES
+-------------
+
+RSA is an asymmetric block cipher which is used in many applications,
+including ssh and gpg. An RSA key consists in fact of two keys,
+called the public key and the private key. A message can be encrypted
+with either key and only the counterpart of that key can decrypt
+the message. While RSA can be used for both signing and encrypting
+a message, paraslash uses RSA only for the latter purpose. The
+RSA public key encryption and signatures algorithms are defined in
+detail in RFC 2437.
+
+RC4 is a stream cipher, i.e. the input is XORed with a pseudo-random
+key stream to produce the output. Decryption uses the same function
+calls as encryption. While RC4 supports variable key lengths,
+paraslash uses a fixed length of 256 bits, which is considered a
+strong encryption by today's standards. Since the same key must never
+be used twice, a different, randomly-generated key is used for every
+new connection.
+
+AES, the advanced encryption standard, is a well-known symmetric block
+cipher, i.e. a transformation operating on fixed-length blocks which
+is determined by a single key for both encryption and decryption. Any
+block cipher can be turned into a stream cipher by generating
+a pseudo-random key stream by encrypting successive values of a
+counter. The AES_CTR128 stream cipher used in paraslash is obtained
+in this way from the AES block cipher with a 128 bit block size.
+
+Client-server authentication
+----------------------------
+
+The authentication handshake between para_client and para_server goes
+as follows:
+
+- para_client connects to para_server and sends an authentication
+request for a user. It does so by connecting to TCP port 2990 of the
+server host. This port is called the para_server _control port_.
+
+- para_server accepts the connection and forks a child process which
+handles the incoming request. The parent process keeps listening on the
+control port while the child process (also called para_server below)
+continues as follows.
+
+- para_server loads the RSA public key of that user, fills a
+fixed-length buffer with random bytes, encrypts that buffer using the
+public key and sends the encrypted buffer to the client. The first
+part of the buffer is the challenge which is used for authentication
+while the second part is the session key.
+
+- para_client receives the encrypted buffer and decrypts it with the
+user's private key, thereby obtaining the challenge buffer and the
+session key. It sends the SHA1 hash value of the challenge back to
+para_server and stores the session key for further use.
+
+- para_server also computes the SHA1 hash of the challenge and compares
+it against what was sent back by the client.
+
+- If the two hashes do not match, the authentication has failed and
+para_server closes the connection.
+
+- Otherwise the user is considered authenticated and the client is
+allowed to proceed by sending a command to be executed. From this
+point on the communication is encrypted using the stream cipher with
+the session key known to both peers.
+
+paraslash relies on the quality of the pseudo-random bytes provided
+by the crypto library (openssl or libgcrypt), on the security of the
+implementation of the RSA, RC4 and AES crypto routines and on the
+infeasibility to invert the SHA1 function.
+
+Neither para_server or para_client create RSA keys on their
+own. This has to be done once for each user as sketched in
+[Quick start](#Quick.start) and discussed in more detail
+[below](#The.user_list.file).
+
+The user_list file
+------------------
+
+At startup para_server reads the user list file which contains one
+line per user. The default location of the user list file may be
+changed with the --user-list option.
+
+There should be at least one user in this file. Each user must have
+an RSA key pair. The public part of the key is needed by para_server
+while the private key is needed by para_client. Each line of the
+user list file must be of the form
+
+       user <username> <key> <perms>
+
+where _username_ is an arbitrary string (usually the user's login
+name), _key_ is the full path to that user's public RSA key, and
+_perms_ is a comma-separated list of zero or more of the following
+permission bits:
+
+       +---------------------------------------------------------+
+       | AFS_READ  | read the contents of the databases          |
+       +-----------+---------------------------------------------+
+       | AFS_WRITE | change database contents                    |
+       +-----------+---------------------------------------------+
+       | VSS_READ  | obtain information about the current stream |
+       +-----------+---------------------------------------------+
+       | VSS_WRITE | change the current stream                   |
+       +---------------------------------------------------------+
+
+The permission bits specify which commands the user is allowed to
+execute. The output of
+
+       para_client help
+
+contains in the third column the permissions needed to execute the
+command.
+
+It is possible to make para_server reread the user_list file by
+executing the paraslash "hup" command or by sending SIGHUP to the
+PID of para_server.
+
+Connecting para_audiod
+----------------------
+
+para_audiod listens on a Unix domain socket. Those sockets are
+for local communication only, so only local users can connect to
+para_audiod. The default is to let any user connect but this can be
+restricted on platforms that support UNIX socket credentials which
+allow para_audiod to obtain the Unix credentials of the connecting
+process.
+
+Use para_audiod's --user-allow option to allow connections only for
+a limited set of users.
+
+=======================
+The audio file selector
+=======================
+
+paraslash comes with a sophisticated audio file selector (AFS),
+whose main task is to determine which file to stream next, based on
+information on the audio files stored in a database. It communicates
+also with para_client whenever an AFS command is executed, for example
+to answer a database query.
+
+Besides the traditional playlists, AFS supports audio file selection
+based on _moods_ which act as a filter that limits the set of all
+known audio files to those which satisfy certain criteria.  It also
+maintains tables containing images (e.g. album cover art) and lyrics
+that can be associated with one or more audio files.
+
+AFS employs [libosl](http://people.tuebingen.mpg.de/maan/osl/), the
+object storage layer library, as the backend library for storing
+information on audio files, playlists, etc. This library offers
+functionality similar to a relational database, but is much more
+lightweight than a full database backend.
+
+In this chapter we sketch the setup of the [AFS
+process](#The.AFS.process) during server startup and proceed with the
+description of the [layout](#Database.layout) of the various database
+tables. The section on [playlists and moods](#Playlists.and.moods)
+explains these two audio file selection mechanisms in detail
+and contains pratical examples. The way [file renames and content
+changes](#File.renames.and.content.changes) are detected is discussed
+briefly before the [Troubleshooting](#Troubleshooting) section
+concludes the chapter.
+
+The AFS process
+---------------
+
+On startup, para_server forks to create the AFS process which opens
+the OSL database tables. The server process communicates with the
+AFS process via pipes and shared memory. Usually, the AFS process
+awakes only briefly whenever the current audio file changes. The AFS
+process determines the next audio file, opens it, verifies it has
+not been changed since it was added to the database and passes the
+open file descriptor to the server process, along with audio file
+meta-data such as file name, duration, audio format and so on. The
+server process then starts to stream the audio file.
+
+The AFS process also accepts connections from local clients via
+a well-known socket. However, only child processes of para_server
+may connect through this socket. All server commands that have the
+AFS_READ or AFS_WRITE permission bits use this mechanism to query or
+change the database.
+
+Database layout
+---------------
+
+### The audio file table ###
+
+This is the most important and usually also the largest table of the
+AFS database. It contains the information needed to stream each audio
+file. In particular the following data is stored for each audio file.
+
+- SHA1 hash value of the audio file contents. This is computed once
+when the file is added to the database. Whenever AFS selects this
+audio file for streaming the hash value is recomputed and checked
+against the value stored in the database to detect content changes.
+
+- The time when this audio file was last played.
+
+- The number of times the file has been played so far.
+
+- The attribute bitmask.
+
+- The image id which describes the image associated with this audio
+file.
+
+- The lyrics id which describes the lyrics associated with this
+audio file.
+
+- The audio format id (MP3, OGG, ...).
+
+- An amplification value that can be used by the amplification filter
+to pre-amplify the decoded audio stream.
+
+- The chunk table. It describes the location and the timing of the
+building blocks of the audio file. This is used by para_server to
+send chunks of the file at appropriate times.
+
+- The duration of the audio file.
+
+- Tag information contained in the audio file (ID3 tags, Vorbis
+comments, ...).
+
+- The number of channels
+
+- The encoding bitrate.
+
+- The sampling frequency.
+
+To add or refresh the data contained in the audio file table, the _add_
+command is used. It takes the full path of either an audio file or a
+directory. In the latter case, the directory is traversed recursively
+and all files which are recognized as valid audio files are added to
+the database.
+
+### The attribute table ###
+
+The attribute table contains two columns, _name_ and _bitnum_. An
+attribute is simply a name for a certain bit number in the attribute
+bitmask of the audio file table.
+
+Each of the 64 bits of the attribute bitmask can be set for each
+audio file individually. Hence up to 64  different attributes may be
+defined. For example, "pop", "rock", "blues", "jazz", "instrumental",
+"german_lyrics", "speech", whatever. You are free to choose as
+many attributes as you like and there are no naming restrictions
+for attributes.
+
+A new attribute "test" is created by
+
+       para_client addatt test
+and
+       para_client lsatt
+
+lists all available attributes. You can set the "test" attribute for
+an audio file by executing
+
+       para_client setatt test+ /path/to/the/audio/file
+
+Similarly, the "test" bit can be removed from an audio file with
+
+       para_client setatt test- /path/to/the/audio/file
+
+Instead of a path you may use a shell wildcard pattern. The attribute
+is applied to all audio files matching this pattern:
+
+       para_client setatt test+ '/test/directory/*'
+
+The command
+
+       para_client -- ls -l=v
+
+gives you a verbose listing of your audio files also showing which
+attributes are set.
+
+In case you wonder why the double-dash in the above command is needed:
+It tells para_client to not interpret the options after the dashes. If
+you find this annoying, just say
+
+       alias para='para_client --'
+
+and be happy. In what follows we shall use this alias.
+
+The "test" attribute can be dropped from the database with
+
+       para rmatt test
+
+Read the output of
+
+       para help ls
+       para help setatt
+
+for more information and a complete list of command line options to
+these commands.
+
+### Blob tables ###
+
+The image, lyrics, moods and playlists tables are all blob tables.
+Blob tables consist of three columns each: The identifier which is
+a positive non-negative number that is auto-incremented, the name
+(an arbitrary string) and the content (the blob).
+
+All blob tables support the same set of actions: cat, ls, mv, rm
+and add. Of course, _add_ is used for adding new blobs to the table
+while the other actions have the same meaning as the corresponding
+Unix commands. The paraslash commands to perform these actions are
+constructed as the concatenation of the table name and the action. For
+example addimg, catimg, lsimg, mvimg, rmimg are the commands that
+manipulate or query the image table.
+
+The add variant of these commands is special as these commands read
+the blob contents from stdin. To add an image to the image table the
+command
+
+       para addimg image_name < file.jpg
+
+can be used.
+
+Note that the images and lyrics are not interpreted at all, and also
+the playlist and the mood blobs are only investigated when the mood
+or playlist is activated with the select command.
+
+### The score table ###
+
+The score table describes those audio files which are admissible for
+the current mood or playlist (see below). The table has two columns:
+a pointer to a row of the audio file table and a score value.
+
+Unlike all other tables of the database, the score table remains in
+memory and is never stored on disk. It is initialized at startup and
+recomputed when the select command loads a new mood or playlist.
+
+When the audio file selector is asked to open the next audio file,
+it picks the row with the highest score, opens the corresponding
+file and passes the file descriptor to the virtual streaming system.
+At this point the last_played and the num_played fields of the selected
+file are updated and the score is recomputed.
+
+Playlists and moods
+-------------------
+
+Playlists and moods offer two different ways of specifying the set of
+admissible files. A playlist in itself describes a set of admissible
+files. A mood, in contrast, describes the set of admissible files in
+terms of attributes and other type of information available in the
+audio file table. As an example, a mood can define a filename pattern,
+which is then matched against the names of audio files in the table.
+
+### Playlists ###
+
+Playlists are accommodated in the playlist table of the afs database,
+using the aforementioned blob format for tables. A new playlist is
+created with the addpl command by specifying the full (absolute)
+paths of all desired audio files, separated by newlines. Example:
+
+       find /my/mp3/dir -name "*.mp3" | para addpl my_playlist
+
+If _my_playlist_ already exists it is overwritten. To activate the
+new playlist, execute
+
+       para select p/my_playlist
+
+The audio file selector will assign scores to each entry of the list,
+in descending order so that files will be selected in order. If a
+file could not be opened for streaming, its entry is removed from
+the score table (but not from the playlist).
+
+### Moods ###
+
+A mood consists of a unique name and its *mood definition*, which is
+a set of *mood lines* containing expressions in terms of attributes
+and other data contained in the database.
+
+At any time at most one mood can be *active* which means that
+para_server is going to select only files from that subset of
+admissible files.
+
+So in order to create a mood definition one has to write a set of
+mood lines. Mood lines come in three flavours: Accept lines, deny
+lines and score lines.
+
+The general syntax of the three types of mood lines is
+
+
+       accept [with score <score>] [if] [not] <mood_method> [options]
+       deny [with score <score>] [if] [not] <mood_method> [options]
+       score <score>  [if] [not] <mood_method> [options]
+
+
+Here <score> is either an integer or the string "random" which assigns
+a random score to all matching files. The score value changes the
+order in which admissible files are going to be selected, but is of
+minor importance for this introduction.
+
+So we concentrate on the first two forms, i.e. accept and deny
+lines. As usual, everything in square brackets is optional, i.e.
+accept/deny lines take the following form when ignoring scores:
+
+       accept [if] [not] <mood_method> [options]
+
+and analogously for the deny case. The "if" keyword is only syntactic
+sugar and has no function. The "not" keyword just inverts the result,
+so the essence of a mood line is the mood method part and the options
+following thereafter.
+
+A *mood method* is realized as a function which takes an audio file
+and computes a number from the data contained in the database.
+If this number is non-negative, we say the file *matches* the mood
+method. The file matches the full mood line if it either
+
+       - matches the mood method and the "not" keyword is not given,
+or
+       - does not match the mood method, but the "not" keyword is given.
+
+The set of admissible files for the whole mood is now defined as those
+files which match at least one accept mood line, but no deny mood line.
+More formally, an audio file F is admissible if and only if
+
+       (F ~ AL1 or F ~ AL2...) and not (F ~ DL1 or F ~ DN2 ...)
+
+where AL1, AL2... are the accept lines, DL1, DL2... are the deny
+lines and "~" means "matches".
+
+The cases where no mood lines of accept/deny type are defined need
+special treatment:
+
+       - Neither accept nor deny lines: This treats all files as
+       admissible (in fact, that is the definition of the dummy mood
+       which is activated automatically if no moods are available).
+
+       - Only accept lines: A file is admissible iff it matches at
+       least one accept line:
+
+               F ~ AL1 or F ~ AL2 or ...
+
+       - Only deny lines: A file is admissible iff it matches no
+       deny line:
+
+               not (F ~ DL1 or F ~ DN2 ...)
+
+
+
+### List of mood_methods ###
+
+       no_attributes_set
+
+Takes no arguments and matches an audio file if and only if no
+attributes are set.
+
+       is_set <attribute_name>
+
+Takes the name of an attribute and matches iff that attribute is set.
+
+       path_matches <pattern>
+
+Takes a filename pattern and matches iff the path of the audio file
+matches the pattern.
+
+       artist_matches <pattern>
+       album_matches <pattern>
+       title_matches <pattern>
+       comment_matches <pattern>
+
+Takes an extended regular expression and matches iff the text of the
+corresponding tag of the audio file matches the pattern. If the tag
+is not set, the empty string is matched against the pattern.
+
+       year ~ <num>
+       bitrate ~ <num>
+       frequency ~ <num>
+       channels ~ <num>
+       num_played ~ <num>
+       image_id ~ <num>
+       lyrics_id ~ <num>
+
+Takes a comparator ~ of the set {<, =, <=, >, >=, !=} and a number
+<num>. Matches an audio file iff the condition <val> ~ <num> is
+satisfied where val is the corresponding value of the audio file
+(value of the year tag, bitrate in kbit/s, etc.).
+
+The year tag is special as its value is undefined if the audio file
+has no year tag or the content of the year tag is not a number. Such
+audio files never match. Another difference is the special treatment
+if the year tag is a two-digit number. In this case either 1900 or
+2000 is added to the tag value, depending on whether the number is
+greater than 2000 plus the current year.
+
+
+### Mood usage ###
+
+To create a new mood called "my_mood", write its definition into
+some temporary file, say "tmpfile", and add it to the mood table
+by executing
+
+       para addmood my_mood < tmpfile
+
+If the mood definition is really short, you may just pipe it to the
+client instead of using temporary files. Like this:
+
+       echo "$MOOD_DEFINITION" | para addmood my_mood
+
+There is no need to keep the temporary file since you can always use
+the catmood command to get it back:
+
+       para catmood my_mood
+
+A mood can be activated by executing
+
+       para select m/my_mood
+
+Once active, the list of admissible files is shown by the ls command
+if the "-a" switch is given:
+
+       para ls -a
+
+
+### Example mood definition ###
+
+Suppose you have defined attributes "punk" and "rock" and want to define
+a mood containing only Punk-Rock songs. That is, an audio file should be
+admissible if and only if both attributes are set. Since
+
+       punk and rock
+
+is obviously the same as
+
+       not (not punk or not rock)
+
+(de Morgan's rule), a mood definition that selects only Punk-Rock
+songs is
+
+       deny if not is_set punk
+       deny if not is_set rock
+
+
+
+File renames and content changes
+--------------------------------
+
+Since the audio file selector knows the SHA1 of each audio file that
+has been added to the afs database, it recognizes if the content of
+a file has changed, e.g. because an ID3 tag was added or modified.
+Also, if a file has been renamed or moved to a different location,
+afs will detect that an entry with the same hash value already exists
+in the audio file table.
+
+In both cases it is enough to just re-add the new file. In the
+first case (file content changed), the audio table is updated, while
+metadata such as the num_played and last_played fields, as well as
+the attributes, remain unchanged. In the other case, when the file
+is moved or renamed, only the path information is updated, all other
+data remains as before.
+
+It is possible to change the behaviour of the add command by using the
+"-l" (lazy add) or the "-f" (force add) option.
+
+Troubleshooting
+---------------
+
+Use the debug loglevel (-l debug) to show debugging info. All paraslash
+executables have a brief online help which is displayed when -h is
+given. The --detailed-help option prints the full help text.
+
+If para_server crashed or was killed by SIGKILL (signal 9), it
+may refuse to start again because of "dirty osl tables". In this
+case you'll have to run the oslfsck program of libosl to fix your
+database:
+
+       oslfsck -fd ~/.paraslash/afs_database-0.4
+
+However, make sure para_server isn't running before executing oslfsck.
+
+If you don't mind to recreate your database you can start
+from scratch by removing the entire database directory, i.e.
+
+       rm -rf ~/.paraslash/afs_database-0.4
+
+Be aware that this removes all attribute definitions, all playlists
+and all mood definitions and requires to re-initialize the tables.
+
+Although oslfsck fixes inconsistencies in database tables it doesn't
+care about the table contents. To check for invalid table contents, use
+
+       para_client check
+
+This prints out references to missing audio files as well as invalid
+playlists and mood definitions.
+
+Similarly, para_audiod refuses to start if its socket file exists, since
+this indicates that another instance of para_audiod is running. After
+a crash a stale socket file might remain and you must run
+
+       para_audiod --force
+
+once to fix it up.
+
+=======================================
+Audio formats and audio format handlers
+=======================================
+
+Audio formats
+-------------
+
+The following audio formats are supported by paraslash:
+
+### MP3 ###
+
+Mp3, MPEG-1 Audio Layer 3, is a common audio format for audio storage,
+designed as part of its MPEG-1 standard.  An MP3 file is made up of
+multiple MP3 frames, which consist of a header and a data block. The
+size of an MP3 frame depends on the bit rate and on the number
+of channels. For a typical CD-audio file (sample rate of 44.1 kHz
+stereo), encoded with a bit rate of 128 kbit, an MP3 frame is about
+400 bytes large.
+
+### OGG/Vorbis ###
+
+OGG is a standardized audio container format, while Vorbis is an
+open source codec for lossy audio compression. Since Vorbis is most
+commonly made available via the OGG container format, it is often
+referred to as OGG/Vorbis. The OGG container format divides data into
+chunks called OGG pages. A typical OGG page is about 4KB large. The
+Vorbis codec creates variable-bitrate (VBR) data, where the bitrate
+may vary considerably.
+
+### OGG/Speex ###
+
+Speex is an open-source speech codec that is based on CELP (Code
+Excited Linear Prediction) coding. It is designed for voice
+over IP applications, has modest complexity and a small memory
+footprint. Wideband and narrowband (telephone quality) speech are
+supported. As for Vorbis audio, Speex bit-streams are often stored
+in OGG files. As of 2012 this codec is considered obsolete since the
+Oppus codec, described below, surpasses its performance in all areas.
+
+### OGG/Opus ###
+
+Opus is a lossy audio compression format standardized through RFC
+6716 in 2012. It combines the speech-oriented SILK codec and the
+low-latency CELT (Constrained Energy Lapped Transform) codec. Like
+OGG/Vorbis and OGG/Speex, Opus data is usually encapsulated in OGG
+containers. All known software patents which cover Opus are licensed
+under royalty-free terms.
+
+### AAC ###
+
+Advanced Audio Coding (AAC) is a standardized, lossy compression
+and encoding scheme for digital audio which is the default audio
+format for Apple's iPhone, iPod, iTunes. Usually MPEG-4 is used as
+the container format and audio files encoded with AAC have the .m4a
+extension. A typical AAC frame is about 700 bytes large.
+
+### WMA ###
+
+Windows Media Audio (WMA) is an audio data compression technology
+developed by Microsoft. A WMA file is usually encapsulated in the
+Advanced Systems Format (ASF) container format, which also specifies
+how meta data about the file is to be encoded. The bit stream of WMA
+is composed of superframes, each containing one or more frames of
+2048 samples. For 16 bit stereo a WMA superframe is about 8K large.
+
+### FLAC ###
+
+The Free Lossless Audio Codec (FLAC) compresses audio without quality
+loss. It gives better compression ratios than a general purpose
+compressor like zip or bzip2 because FLAC is designed specifically
+for audio. A FLAC-encoded file consists of frames of varying size, up
+to 16K. Each frame starts with a header that contains all information
+necessary to decode the frame.
+
+Meta data
+---------
+
+Unfortunately, each audio format has its own conventions how meta
+data is added as tags to the audio file.
+
+For MP3 files, ID3, version 1 and 2 are widely used. ID3 version 1
+is rather simple but also very limited as it supports only artist,
+title, album, year and comment tags. Each of these can only be at most
+32 characters long. ID3, version 2 is much more flexible but requires
+a separate library being installed for paraslash to support it.
+
+Ogg vorbis, ogg speex and flac files contain meta data as Vorbis
+comments, which are typically implemented as strings of the form
+"[TAG]=[VALUE]". Unlike ID3 version 1 tags, one may use whichever
+tags are appropriate for the content.
+
+AAC files usually use the MPEG-4 container format for storing meta
+data while WMA files wrap meta data as special objects within the
+ASF container format.
+
+paraslash only tracks the most common tags that are supported by
+all tag variants: artist, title, year, album, comment. When a file
+is added to the AFS database, the meta data of the file is extracted
+and stored in the audio file table.
+
+Chunks and chunk tables
+-----------------------
+
+paraslash uses the word "chunk" as common term for the building blocks
+of an audio file. For MP3 files, a chunk is the same as an MP3 frame,
+while for OGG files a chunk is an OGG page, etc.  Therefore the chunk
+size varies considerably between audio formats, from a few hundred
+bytes (MP3) up to 16K (FLAC).
+
+The chunk table contains the offsets within the audio file that
+correspond to the chunk boundaries of the file. Like the meta data,
+the chunk table is computed and stored in the database whenever an
+audio file is added.
+
+The paraslash senders (see below) always send complete chunks. The
+granularity for seeking is therefore determined by the chunk size.
+
+Audio format handlers
+---------------------
+
+For each audio format paraslash contains an audio format handler whose
+first task is to tell whether a given file is a valid audio file of
+this type. If so, the audio file handler extracts some technical data
+(duration, sampling rate, number of channels etc.), computes the
+chunk table and reads the meta data.
+
+The audio format handler code is linked into para_server and executed
+via the _add_ command. The same code is also available as a stand-alone
+tool, para_afh, which prints the technical data, the chunk table
+and the meta data of a file. Moreover, all audio format handlers are
+combined in the afh receiver which is part of para_recv and para_play.
+
+==========
+Networking
+==========
+
+Paraslash uses different network connections for control and data.
+para_client communicates with para_server over a dedicated TCP control
+connection. To transport audio data, separate data connections are
+used. For these data connections, a variety of transports (UDP, DCCP,
+HTTP) can be chosen.
+
+The chapter starts with the [control
+service](#The.paraslash.control.service), followed by a section
+on the various [streaming protocols](#Streaming.protocols)
+in which the data connections are described. The way
+audio file headers are embedded into the stream is discussed
+[briefly](#Streams.with.headers.and.headerless.streams) before the
+[example section](#Networking.examples) which illustrates typical
+commands for real-life scenarios.
+
+Both IPv4 and IPv6 are supported.
+
+The paraslash control service
+-----------------------------
+
+para_server is controlled at runtime via the paraslash control
+connection. This connection is used for server commands (play, stop,
+...) as well as for afs commands (ls, select, ...).
+
+The server listens on a TCP port and accepts connections from clients
+that connect the open port. Each connection causes the server to fork
+off a client process which inherits the connection and deals with that
+client only. In this classical accept/fork approach the server process
+is unaffected if the child dies or goes crazy for whatever reason. In
+fact, the child process can not change address space of server process.
+
+The section on [client-server
+authentication](#Client-server.authentication) above described the
+early connection establishment from the crypto point of view. Here
+it is described what happens after the connection (including crypto
+setup) has been established.  There are four processes involved during
+command dispatch as sketched in the following diagram.
+
+       server_host                                   client_host
+       ~~~~~~~~~~~                                   ~~~~~~~~~~~
+
+       +-----------+             connect            +-----------+
+       |para_server|<------------------------------ |para_client|
+       +-----------+                                +-----------+
+            |                                             ^
+            |     fork   +---+                            |
+            +----------> |AFS|                            |
+            |            +---+                            |
+            |              ^                              |
+            |              |                              |
+            |              | connect (cookie)             |
+            |              |                              |
+            |              |                              |
+            |    fork   +-----+    inherited connection   |
+            +---------->|child|<--------------------------+
+                        +-----+
+
+Note that the child process is not a child of the afs process,
+so communication of these two processes has to happen via local
+sockets. In order to avoid abuse of the local socket by unrelated
+processes, a magic cookie is created once at server startup time just
+before the server process forks off the AFS process. This cookie is
+known to the server, AFS and the child, but not to unrelated processes.
+
+There are two different kinds of commands: First there are commands
+that cause the server to respond with some answer such as the list
+of all audio files. All but the addblob commands (addimg, addlyr,
+addpl, addmood) are of this kind. The addblob commands add contents
+to the database, so they need to transfer data the other way round,
+from the client to the server.
+
+There is no knowledge about the server commands built into para_client,
+so it does not know about addblob commands. Instead, the server sends
+a special "awaiting data" packet for these commands. If the client
+receives this packet, it sends STDIN to the server, otherwise it
+dumps data from the server to STDOUT.
+
+Streaming protocols
+-------------------
+
+A network (audio) stream usually consists of one streaming source,
+the _sender_, and one or more _receivers_ which read data over the
+network from the streaming source.
+
+Senders are thus part of para_server while receivers are part of
+para_audiod. Moreover, there is the stand-alone tool para_recv which
+can be used to manually download a stream, either from para_server
+or from a web-based audio streaming service.
+
+The following three streaming protocols are supported by paraslash:
+
+- HTTP. Recommended for public streams that can be played by any
+player like mpg123, xmms, itunes, winamp, etc. The HTTP sender is
+supported on all operating systems and all platforms.
+
+- DCCP. Recommended for LAN streaming. DCCP is currently available
+only for Linux.
+
+- UDP. Recommended for multicast LAN streaming.
+
+See the Appendix on [network protocols](/#Network.protocols)
+for brief descriptions of the various protocols relevant for network
+audio streaming with paraslash.
+
+It is possible to activate more than one sender simultaneously.
+Senders can be controlled at run time and via config file and command
+line options.
+
+Note that audio connections are _not_ encrypted. Transport or Internet
+layer encryption should be used if encrypted data connections are
+needed.
+
+Since DCCP and TCP are both connection-oriented protocols, connection
+establishment/teardown and access control are very similar between
+these two streaming protocols. UDP is the most lightweight option,
+since in contrast to TCP/DCCP it is connectionless. It is also the
+only protocol supporting IP multicast.
+
+The HTTP and the DCCP sender listen on a (TCP/DCCP) port waiting for
+clients to connect and establish a connection via some protocol-defined
+handshake mechanism. Both senders maintain two linked lists each:
+The list of all clients which are currently connected, and the list
+of access control entries which determines who is allowed to connect.
+IP-based access control may be configured through config file and
+command line options and via the "allow" and "deny" sender subcommands.
+
+Upon receiving a GET request from the client, the HTTP sender sends
+back a status line and a message. The body of this message is the
+audio stream. This is common practice and is supported by many popular
+clients which can thus be used to play a stream offered by para_server.
+For DCCP things are a bit simpler: No messages are exchanged between
+the receiver and sender. The client simply connects and the sender
+starts to stream.
+
+DCCP is an experimental protocol which offers a number of new features
+not available for TCP. Both ends can negotiate these features using
+a built-in negotiation mechanism. In contrast to TCP/HTTP, DCCP is
+datagram-based (no retransmissions) and thus should not be used over
+lossy media (e.g. WiFi networks). One useful feature offered by DCCP
+is access to a variety of different congestion-control mechanisms
+called CCIDs. Two different CCIDs are available per default on Linux:
+
+
+- _CCID 2_. A Congestion Control mechanism similar to that of TCP. The
+sender maintains a congestion window and halves this window in response
+to congestion.
+
+
+- _CCID-3_. Designed to be fair when competing for bandwidth.
+It has lower variation of throughput over time compared with TCP,
+which makes it suitable for streaming media.
+
+Unlike the HTTP and DCCP senders, the UDP sender maintains only a
+single list, the _target list_. This list describes the set of clients
+to which the stream is sent. There is no list for access control and
+no "allow" and "deny" commands for the UDP sender. Instead, the "add"
+and "delete" commands can be used to modify the target list.
+
+Since both UDP and DCCP offer an unreliable datagram-based transport,
+additional measures are necessary to guard against disruptions over
+networks that are lossy or which may be subject to interference (as
+is for instance the case with WiFi). Paraslash uses FEC (Forward
+Error Correction) to guard against packet losses and reordering. The
+stream is FEC-encoded before it is sent through the UDP socket and
+must be decoded accordingly on the receiver side.
+
+The packet size and the amount of redundancy introduced by FEC can
+be configured via the FEC parameters which are dictated by server
+and may also be configured through the "sender" command.  The FEC
+parameters are encoded in the header of each network packet, so no
+configuration is necessary on the receiver side. See the section on
+[FEC](#Forward.error.correction) below.
+
+Streams with headers and headerless streams
+-------------------------------------------
+
+For OGG/Vorbis, OGG/Speex and wma streams, some of the information
+needed to decode the stream is only contained in the audio file
+header of the container format but not in each data chunk. Clients
+must be able to obtain this information in case streaming starts in
+the middle of the file or if para_audiod is started while para_server
+is already sending a stream.
+
+This is accomplished in different ways, depending on the streaming
+protocol. For connection-oriented streams (HTTP, DCCP) the audio file
+header is sent prior to audio file data. This technique however does
+not work for the connectionless UDP transport. Hence the audio file
+header is periodically being embedded into the UDP audio data stream.
+By default, the header is resent after five seconds. The receiver has
+to wait until the next header arrives before it can start decoding
+the stream.
+
+Networking examples
+-------------------
+
+The "si" (server info) command lists some information about the
+currently running server process.
+
+-> Show PIDs, number of connected clients, uptime, and more:
+
+       para_client si
+
+The sender command of para_server prints information about senders,
+like the various access control lists, and it allows to (de-)activate
+senders and to change the access permissions at runtime.
+
+-> List all senders
+
+       para_client sender
+
+-> Obtain general help for the sender command:
+
+       para_client help sender
+
+-> Get help for a specific sender (contains further examples):
+
+       s=http # or dccp or udp
+       para_client sender $s help
+
+-> Show status of the http sender
+
+       para_client sender http status
+
+By default para_server activates both the HTTP and th DCCP sender on
+startup. This can be changed via command line options or para_server's
+config file.
+
+-> List config file options for senders:
+
+       para_server -h
+
+All senders share the "on" and "off" commands, so senders may be
+activated and deactivated independently of each other.
+
+-> Switch off the http sender:
+
+       para_client sender http off
+
+-> Receive a DCCP stream using CCID2 and write the output into a file:
+
+       host=foo.org; ccid=2; filename=bar
+       para_recv --receiver "dccp --host $host --ccid $ccid" > $filename
+
+Note the quotes around the arguments for the dccp receiver. Each
+receiver has its own set of command line options and its own command
+line parser, so arguments for the dccp receiver must be protected
+from being interpreted by para_recv.
+
+-> Start UDP multicast, using the default multicast address:
+
+       para_client sender udp add 224.0.1.38
+
+-> Receive FEC-encoded multicast stream and write the output into a file:
+
+       filename=foo
+       para_recv -r udp > $filename
+
+-> Add an UDP unicast for a client to the target list of the UDP sender:
+
+       t=client.foo.org
+       para_client sender udp add $t
+
+-> Receive this (FEC-encoded) unicast stream:
+
+       filename=foo
+       para_recv -r 'udp -i 0.0.0.0' > $filename
+
+-> Create a minimal config for para_audiod for HTTP streams:
+
+       c=$HOME/.paraslash/audiod.conf.min; s=server.foo.com
+       echo receiver \".:http -i $s\" > $c
+       para_audiod --config $c
+
+=======
+Filters
+=======
+
+A paraslash filter is a module which transforms an input stream into
+an output stream. Filters are included in the para_audiod executable
+and in the stand-alone tool para_filter which usually contains the
+same modules.
+
+While para_filter reads its input stream from STDIN and writes
+the output to STDOUT, the filter modules of para_audiod are always
+connected to a receiver which produces the input stream and a writer
+which absorbs the output stream.
+
+Some filters depend on a specific library and are not compiled in
+if this library was not found at compile time. To see the list of
+supported filters, run para_filter and para_audiod with the --help
+option. The output looks similar to the following:
+
+       Available filters:
+               compress wav amp fecdec wmadec prebuffer oggdec aacdec mp3dec
+
+Out of these filter modules, a chain of filters can be constructed,
+much in the way Unix pipes can be chained, and analogous to the use
+of modules in gstreamer: The output of the first filter becomes the
+input of the second filter. There is no limitation on the number of
+filters and the same filter may occur more than once.
+
+Like receivers, each filter has its own command line options which
+must be quoted to protect them from the command line options of
+the driving application (para_audiod or para_filter). Example:
+
+       para_filter -f 'mp3dec --ignore-crc' -f 'compress --damp 1'
+
+For para_audiod, each audio format has its own set of filters. The
+name of the audio format for which the filter should be applied can
+be used as the prefix for the filter option. Example:
+
+       para_audiod -f 'mp3:prebuffer --duration 300'
+
+The "mp3" prefix above is actually interpreted as a POSIX extended
+regular expression. Therefore
+
+       para_audiod -f '.:prebuffer --duration 300'
+
+activates the prebuffer filter for all supported audio formats (because
+"." matches all audio formats) while
+
+       para_audiod -f 'wma|ogg:prebuffer --duration 300'
+
+activates it only for wma and ogg streams.
+
+Decoders
+--------
+
+For each supported audio format there is a corresponding filter
+which decodes audio data in this format to 16 bit PCM data which
+can be directly sent to the sound device or any other software that
+operates on undecoded PCM data (visualizers, equalizers etc.). Such
+filters are called _decoders_ in general, and xxxdec is the name of
+the paraslash decoder for the audio format xxx. For example, the mp3
+decoder is called mp3dec.
+
+Note that the output of the decoder is about 10 times larger than
+its input. This means that filters that operate on the decoded audio
+stream have to deal with much more data than filters that transform
+the audio stream before it is fed to the decoder.
+
+Paraslash relies on external libraries for most decoders, so these
+libraries must be installed for the decoder to be included in the
+executables. For example, the mp3dec filter depends on the mad library.
+
+Forward error correction
+------------------------
+
+As already mentioned [earlier](#Streaming.protocols), paraslash
+uses forward error correction (FEC) for the unreliable UDP and
+DCCP transports. FEC is a technique which was invented already in
+1960 by Reed and Solomon and which is widely used for the parity
+calculations of storage devices (RAID arrays). It is based on the
+algebraic concept of finite fields, today called Galois fields, in
+honour of the mathematician Galois (1811-1832). The FEC implementation
+of paraslash is based on code by Luigi Rizzo.
+
+Although the details require a sound knowledge of the underlying
+mathematics, the basic idea is not hard to understand: For positive
+integers k and n with k < n it is possible to compute for any k given
+data bytes d_1, ..., d_k the corresponding r := n -k parity bytes p_1,
+..., p_r such that all data bytes can be reconstructed from *any*
+k bytes of the set
+
+       {d_1, ..., d_k, p_1, ..., p_r}.
+
+FEC-encoding for unreliable network transports boils down to slicing
+the audio stream into groups of k suitably sized pieces called _slices_
+and computing the r corresponding parity slices. This step is performed
+in para_server which then sends both the data and the parity slices
+over the unreliable network connection. If the client was able
+to receive at least k of the n = k + r slices, it can reconstruct
+(FEC-decode) the original audio stream.
+
+From these observations it is clear that there are three different
+FEC parameters: The slice size, the number of data slices k, and the
+total number of slices n. It is crucial to choose the slice size
+such that no fragmentation of network packets takes place because
+FEC only guards against losses and reordering but fails if slices are
+received partially.
+
+FEC decoding in paralash is performed through the fecdec filter which
+usually is the first filter (there can be other filters before fecdec
+if these do not alter the audio stream).
+
+Volume adjustment (amp and compress)
+------------------------------------
+
+The amp and the compress filter both adjust the volume of the audio
+stream. These filters operate on uncompressed audio samples. Hence
+they are usually placed directly after the decoding filter. Each
+sample is multiplied with a scaling factor (>= 1) which makes amp
+and compress quite expensive in terms of computing power.
+
+### amp ###
+
+The amp filter amplifies the audio stream by a fixed scaling factor
+that must be known in advance. For para_audiod this factor is derived
+from the amplification field of the audio file's entry in the audio
+file table while para_filter uses the value given at the command line.
+
+The optimal scaling factor F for an audio file is the largest real
+number F >= 1 such that after multiplication with F all samples still
+fit into the sample interval [-32768, 32767]. One can use para_filter
+in combination with the sox utility to compute F:
+
+       para_filter -f mp3dec -f wav < file.mp3 | sox -t wav - -e stat -v
+
+The amplification value V which is stored in the audio file table,
+however, is an integer between 0 and 255 which is connected to F
+through the formula
+
+       V = (F - 1) * 64.
+
+To store V in the audio file table, the command
+
+       para_client -- touch -a=V file.mp3
+
+is used. The reader is encouraged to write a script that performs
+these computations :)
+
+### compress ###
+
+Unlike the amplification filter, the compress filter adjusts the volume
+of the audio stream dynamically without prior knowledge about the peak
+value. It maintains the maximal volume of the last n samples of the
+audio stream and computes a suitable amplification factor based on that
+value and the various configuration options. It tries to chose this
+factor such that the adjusted volume meets the desired target level.
+
+Note that it makes sense to combine amp and compress.
+
+Misc filters (wav and prebuffer)
+--------------------------------
+
+These filters are rather simple and do not modify the audio stream at
+all. The wav filter is only useful with para_filter and in connection
+with a decoder. It asks the decoder for the number of channels and the
+sample rate of the stream and adds a Microsoft wave header containing
+this information at the beginning. This allows to write wav files
+rather than raw PCM files (which do not contain any information about
+the number of channels and the sample rate).
+
+The prebuffer filter simply delays the output until the given time has
+passed (starting from the time the first byte was available in its
+input queue) or until the given amount of data has accumulated. It
+is mainly useful for para_audiod if the standard parameters result
+in buffer underruns.
+
+Both filters require almost no additional computing time, even when
+operating on uncompressed audio streams, since data buffers are simply
+"pushed down" rather than copied.
+
+Examples
+--------
+
+-> Decode an mp3 file to wav format:
+
+       para_filter -f mp3dec -f wav < file.mp3 > file.wav
+
+-> Amplify a raw audio file by a factor of 1.5:
+
+       para_filter -f amp --amp 32 < foo.raw > bar.raw
+
+======
+Output
+======
+
+Once an audio stream has been received and decoded to PCM format,
+it can be sent to a sound device for playback. This part is performed
+by paraslash _writers_ which are described in this chapter.
+
+Writers
+-------
+
+A paraslash writer acts as a data sink that consumes but does not
+produce audio data. Paraslash writers operate on the client side and
+are contained in para_audiod and in the stand-alone tool para_write.
+
+The para_write program reads uncompressed audio data from STDIN. If
+this data starts with a wav header, sample rate, sample format and
+channel count are read from the header. Otherwise CD audio (44.1KHz
+16 bit little endian, stereo) is assumed but this can be overridden
+by command line options. para_audiod, on the other hand, obtains
+the sample rate and the number of channels from the decoder.
+
+Like receivers and filters, each writer has an individual set of
+command line options, and for para_audiod writers can be configured
+per audio format separately. It is possible to activate more than
+one writer for the same stream simultaneously.
+
+OS-dependent APIs
+-----------------
+
+Unfortunately, the various flavours of Unix on which paraslash
+runs on have different APIs for opening a sound device and starting
+playback. Hence for each such API there is a paraslash writer that
+can play the audio stream via this API.
+
+- *ALSA*. The _Advanced Linux Sound Architecture_ is only available on
+Linux systems. Although there are several mid-layer APIs in use by
+the various Linux distributions (ESD, Jack, PulseAudio), paraslash
+currently supports only the low-level ALSA API which is not supposed
+to be change. ALSA is very feature-rich, in particular it supports
+software mixing via its DMIX plugin. ALSA is the default writer on
+Linux systems.
+
+- *OSS*. The _Open Sound System_ is the only API on \*BSD Unixes and
+is also available on Linux systems, usually provided by ALSA as an
+emulation for backwards compatibility. This API is rather simple but
+also limited. For example only one application can open the device
+at any time. The OSS writer is activated by default on BSD Systems.
+
+- *OSX*. Mac OS X has yet another API called CoreAudio. The OSX writer
+for this API is only compiled in on such systems and is of course
+the default there.
+
+- *FILE*. The file writer allows to capture the audio stream and
+write the PCM data to a file on the file system rather than playing
+it through a sound device. It is supported on all platforms and is
+always compiled in.
+
+- *AO*. _Libao_ is a cross-platform audio library which supports a wide
+variety of platforms including PulseAudio (gnome), ESD (Enlightened
+Sound Daemon), AIX, Solaris and IRIX.  The ao writer plays audio
+through an output plugin of libao.
+
+Examples
+--------
+
+-> Use the OSS writer to play a wav file:
+
+       para_write --writer oss < file.wav
+
+-> Enable ALSA software mixing for mp3 streams:
+
+       para_audiod --writer 'mp3:alsa -d plug:swmix'
+
+
+===
+Gui
+===
+
+para_gui executes an arbitrary command which is supposed to print
+status information to STDOUT. It then displays this information in
+a curses window. By default the command
+
+       para_audioc -- stat -p
+
+is executed, but this can be customized via the --stat-cmd option. In
+particular it possible to use
+
+       para_client -- stat -p
+
+to make para_gui work on systems on which para_audiod is not running.
+
+Key bindings
+------------
+
+It is possible to bind keys to arbitrary commands via custom
+key-bindings. Besides the internal keys which can not be changed (help,
+quit, loglevel, version...), the following flavours of key-bindings
+are supported:
+
+- external: Shutdown curses before launching the given command.
+Useful for starting other ncurses programs from within para_gui,
+e.g. aumix or dialog scripts. Or, use the mbox output format to write
+a mailbox containing one mail for each (admissible) file the audio
+file selector knows about. Then start mutt from within para_gui to
+browse your collection!
+
+- display: Launch the command and display its stdout in para_gui's
+bottom window.
+
+- para: Like display, but start "para_client <specified command>"
+instead of "<specified command>".
+
+The general form of a key binding is
+
+       key_map k:m:c
+
+which maps key k to command c using mode m. Mode may be x, d or p
+for external, display and paraslash commands, respectively.
+
+Themes
+------
+
+Currently there are only two themes for para_gui. It is easy, however,
+to add more themes. To create a new theme one has to define the
+position, color and geometry for for each status item that should be
+shown by this theme. See gui_theme.c for examples.
+
+The "." and "," keys are used to switch between themes.
+
+Examples
+--------
+
+-> Show server info:
+
+       key_map "i:p:si"
+
+-> Jump to the middle of the current audio file by pressing F5:
+
+       key_map "<F5>:p:jmp 50"
+
+-> vi-like bindings for jumping around:
+
+       key_map "l:p:ff 10"
+       key_map "h:p:ff 10-"
+       key_map "w:p:ff 60"
+       key_map "b:p:ff 60-"
+
+-> Print the current date and time:
+
+       key_map "D:d:date"
+
+-> Call other curses programs:
+
+       key_map "U:x:aumix"
+       key_map "!:x:/bin/bash"
+       key_map "^E:x:/bin/sh -c 'vi ~/.paraslash/gui.conf'"
+
+===========
+Development
+===========
+
+Tools
+-----
+
+In order to compile the sources from the git repository (rather than
+from tar balls) and for contributing non-trivial changes to the
+paraslash project, some additional tools should be installed on a
+developer machine.
+
+- [git](http://git.or.cz/). As described in more detail
+[below](#Git.branches), the git source code management tool is used for
+paraslash development. It is necessary for cloning the git repository
+and for getting updates.
+
+- [autoconf](ftp://ftp.gnu.org/pub/gnu/autoconf/) GNU autoconf creates
+the configure file which is shipped in the tarballs but has to be
+generated when compiling from git.
+
+- [discount](http://www.pell.portland.or.us/~orc/Code/discount). The
+HTML version of this manual and some of the paraslash web pages are
+written in the Markdown markup language and are translated into html
+with the converter of the *Discount* package.
+
+- [doxygen](http://www.stack.nl/~dimitri/doxygen/). The documentation
+of paraslash's C sources uses the doxygen documentation system. The
+conventions for documenting the source code is described in the
+[Doxygen section](#Doxygen).
+
+- [global](ftp://ftp.gnu.org/pub/gnu/global). This is used to generate
+browsable HTML from the C sources. It is needed by doxygen.
+
+Git branches
+------------
+
+Paraslash has been developed using the git source code management
+tool since 2006. Development is organized roughly in the same spirit
+as the git development itself, as described below.
+
+The following text passage is based on "A note from the maintainer",
+written by Junio C Hamano, the maintainer of git.
+
+There are four branches in the paraslash repository that track the
+source tree: "master", "maint", "next", and "pu".
+
+The "master" branch is meant to contain what is well tested and
+ready to be used in a production setting. There could occasionally be
+minor breakages or brown paper bag bugs but they are not expected to
+be anything major, and more importantly quickly and easily fixable.
+Every now and then, a "feature release" is cut from the tip of this
+branch, named with three dotted decimal digits, like 0.4.2.
+
+Whenever changes are about to be included that will eventually lead to
+a new major release (e.g. 0.5.0), a "maint" branch is forked off from
+"master" at that point. Obvious, safe and urgent fixes after the major
+release are applied to this branch and maintenance releases are cut
+from it. New features never go to this branch. This branch is also
+merged into "master" to propagate the fixes forward.
+
+A trivial and safe enhancement goes directly on top of "master".
+New development does not usually happen on "master", however.
+Instead, a separate topic branch is forked from the tip of "master",
+and it first is tested in isolation; Usually there are a handful such
+topic branches that are running ahead of "master". The tip of these
+branches is not published in the public repository to keep the number
+of branches that downstream developers need to worry about low.
+
+The quality of topic branches varies widely. Some of them start out as
+"good idea but obviously is broken in some areas" and then with some
+more work become "more or less done and can now be tested by wider
+audience". Luckily, most of them start out in the latter, better shape.
+
+The "next" branch is to merge and test topic branches in the latter
+category.  In general, this branch always contains the tip of "master".
+It might not be quite rock-solid production ready, but is expected to
+work more or less without major breakage. The maintainer usually uses
+the "next" version of paraslash for his own pleasure, so it cannot
+be _that_ broken. The "next" branch is where new and exciting things
+take place.
+
+The two branches "master" and "maint" are never rewound, and "next"
+usually will not be either (this automatically means the topics that
+have been merged into "next" are usually not rebased, and you can find
+the tip of topic branches you are interested in from the output of
+"git log next"). You should be able to safely build on top of them.
+
+However, at times "next" will be rebuilt from the tip of "master" to
+get rid of merge commits that will never be in "master". The commit
+that replaces "next" will usually have the identical tree, but it
+will have different ancestry from the tip of "master".
+
+The "pu" (proposed updates) branch bundles the remainder of the
+topic branches.  The "pu" branch, and topic branches that are only in
+"pu", are subject to rebasing in general.  By the above definition
+of how "next" works, you can tell that this branch will contain quite
+experimental and obviously broken stuff.
+
+When a topic that was in "pu" proves to be in testable shape, it
+graduates to "next".  This is done with
+
+               git checkout next
+               git merge that-topic-branch
+
+Sometimes, an idea that looked promising turns out to be not so good
+and the topic can be dropped from "pu" in such a case.
+
+A topic that is in "next" is expected to be polished to perfection
+before it is merged to "master".  Similar to the above, this is
+done with
+
+               git checkout master
+               git merge that-topic-branch
+               git branch -d that-topic-branch
+
+Note that being in "next" is not a guarantee to appear in the next
+release (being in "master" is such a guarantee, unless it is later
+found seriously broken and reverted), nor even in any future release.
+
+Coding Style
+------------
+
+The preferred coding style for paraslash coincides more or less
+with the style of the Linux kernel. So rather than repeating what is
+written [there](http://www.kernel.org/doc/Documentation/CodingStyle),
+here are the most important points.
+
+- Burn the GNU coding standards.
+- Never use spaces for indentation.
+- Tabs are 8 characters, and thus indentations are also 8 characters.
+- Don't put multiple assignments on a single line.
+- Avoid tricky expressions.
+- Don't leave whitespace at the end of lines.
+- The limit on the length of lines is 80 columns.
+- Use K&R style for placing braces and spaces:
+
+               if (x is true) {
+                       we do y
+               }
+
+- Use a space after (most) keywords.
+- Do not add spaces around (inside) parenthesized expressions.
+- Use one space around (on each side of) most binary and ternary operators.
+- Do not use cute names like ThisVariableIsATemporaryCounter, call it tmp.
+- Mixed-case names are frowned upon.
+- Descriptive names for global variables are a must.
+- Avoid typedefs.
+- Functions should be short and sweet, and do just one thing.
+- The number of local variables shouldn't exceed 10.
+- Gotos are fine if they improve readability and reduce nesting.
+- Don't use C99-style "// ..." comments.
+- Names of macros defining constants and labels in enums are capitalized.
+- Enums are preferred when defining several related constants.
+- Always use the paraslash wrappers for allocating memory.
+- If the name of a function is an action or an imperative.
+  command, the function should return an error-code integer
+  (<0 means error, >=0 means success). If the name is a
+  predicate, the function should return a "succeeded" boolean.
+
+Doxygen
+-------
+
+Doxygen is a documentation system for various programming
+languages. The API reference on the paraslash web page is generated
+by doxygen.
+
+It is more illustrative to look at the source code for examples than
+to describe the conventions in this manual, so we only describe which
+parts of the code need doxygen comments, but leave out details on
+documentation conventions.
+
+As a rule, only the public part of the C source is documented with
+Doxygen. This includes structures, defines and enumerations in header
+files as well as public (non-static) C functions.  These should be
+documented completely. For example, each parameter and the return
+value of a public function should get a descriptive doxygen comment.
+
+No doxygen comments are necessary for static functions and for
+structures and enumerations in C files (which are used only within
+this file). This does not mean, however, that those entities need
+no documentation at all. Instead, common sense should be applied to
+document what is not obvious from reading the code.
+
+========
+Appendix
+========
+
+Network protocols
+-----------------
+
+### IP ###
+
+The _Internet Protocol_ is the primary networking protocol used for
+the Internet. All protocols described below use IP as the underlying
+layer. Both the prevalent IPv4 and the next-generation IPv6 variant
+are being deployed actively worldwide.
+
+### Connection-oriented and connectionless protocols ###
+
+Connectionless protocols differ from connection-oriented ones in
+that state associated with the sending/receiving endpoints is treated
+implicitly. Connectionless protocols maintain no internal knowledge
+about the state of the connection. Hence they are not capable of
+reacting to state changes, such as sudden loss or congestion on the
+connection medium. Connection-oriented protocols, in contrast, make
+this knowledge explicit. The connection is established only after
+a bidirectional handshake which requires both endpoints to agree
+on the state of the connection, and may also involve negotiating
+specific parameters for the particular connection. Maintaining an
+up-to-date internal state of the connection also in general means
+that the sending endpoints perform congestion control, adapting to
+qualitative changes of the connection medium.
+
+### Reliability ###
+
+In IP networking, packets can be lost, duplicated, or delivered
+out of order, and different network protocols handle these
+problems in different ways. We call a transport-layer protocol
+_reliable_, if it turns the unreliable IP delivery into an ordered,
+duplicate- and loss-free delivery of packets. Sequence numbers
+are used to discard duplicates and re-arrange packets delivered
+out-of-order. Retransmission is used to guarantee loss-free
+delivery. Unreliable protocols, in contrast, do not guarantee ordering
+or data integrity.
+
+### Classification ###
+
+With these definitions the protocols which are used by paraslash for
+steaming audio data may be classified as follows.
+
+       - HTTP/TCP: connection-oriented, reliable,
+       - UDP: connectionless, unreliable,
+       - DCCP: connection-oriented, unreliable.
+
+Below we give a short descriptions of these protocols.
+
+### TCP ###
+
+The _Transmission Control Protocol_ provides reliable, ordered delivery
+of a stream and a classic window-based congestion control. In contrast
+to UDP and DCCP (see below), TCP does not have record-oriented or
+datagram-based syntax, i.e. it provides a stream which is unaware
+and independent of any record (packet) boundaries.  TCP is used
+extensively by many application layers. Besides HTTP (the Hypertext
+Transfer Protocol), also FTP (the File Transfer protocol), SMTP (Simple
+Mail Transfer Protocol), SSH (Secure Shell) all sit on top of TCP.
+
+### UDP ###
+
+The _User Datagram Protocol_ is the simplest transport-layer protocol,
+built as a thin layer directly on top of IP. For this reason, it offers
+the same best-effort service as IP itself, i.e. there is no detection
+of duplicate or reordered packets. Being a connectionless protocol,
+only minimal internal state about the connection is maintained, which
+means that there is no protection against packet loss or network
+congestion. Error checking and correction (if at all) are performed
+in the application.
+
+### DCCP ###
+
+The _Datagram Congestion Control Protocol_ combines the
+connection-oriented state maintenance known from TCP with the
+unreliable, datagram-based transport of UDP. This means that it
+is capable of reacting to changes in the connection by performing
+congestion control, offering multiple alternative approaches. But it
+is bound to datagram boundaries (the maximum packet size supported
+by a medium), and like UDP it lacks retransmission to protect
+against loss. Due to the use of sequence numbers, it is however
+able to react to loss (interpreted as a congestion indication) and
+to ignore out-of-order and duplicate packets. Unlike TCP it allows
+to negotiate specific, binding features for a connection, such as
+the choice of congestion control: classic, window-based congestion
+control known from TCP is available as CCID-2, rate-based, "smooth"
+congestion control is offered as CCID-3.
+
+### HTTP ###
+
+The _Hypertext Transfer Protocol_ is an application layer protocol
+on top of TCP. It is spoken by web servers and is most often used
+for web services.  However, as can be seen by the many Internet radio
+stations and YouTube/Flash videos, http is by far not limited to the
+delivery of web pages only. Being a simple request/response based
+protocol, the semantics of the protocol also allow the delivery of
+multimedia content, such as audio over http.
+
+### Multicast ###
+
+IP multicast is not really a protocol but a technique for one-to-many
+communication over an IP network. The challenge is to deliver
+information to a group of destinations simultaneously using the
+most efficient strategy to send the messages over each link of the
+network only once. This has benefits for streaming multimedia: the
+standard one-to-one unicast offered by TCP/DCCP means that n clients
+listening to the same stream also consume n-times the resources,
+whereas multicast requires to send the stream just once, irrespective
+of the number of receivers.  Since it would be costly to maintain state
+for each listening receiver, multicast often implies connectionless
+transport, which is the reason that it is currently only available
+via UDP.
+
+Abstract socket namespace
+-------------------------
+UNIX domain sockets are a traditional way to communicate between
+processes on the same machine. They are always reliable (see above)
+and don't reorder datagrams. Unlike TCP and UDP, UNIX domain sockets
+support passing open file descriptors or process credentials to
+other processes.
+
+The usual way to set up a UNIX domain socket (as obtained from
+socket(2)) for listening is to first bind the socket to a file system
+pathname and then call listen(2), then accept(2). Such sockets are
+called _pathname sockets_ because bind(2) creates a special socket
+file at the specified path. Pathname sockets allow unrelated processes
+to communicate with the listening process by binding to the same path
+and calling connect(2).
+
+There are two problems with pathname sockets:
+
+       * The listing process must be able to (safely) create the
+       socket special in a directory which is also accessible to
+       the connecting process.
+
+       * After an unclean shutdown of the listening process, a stale
+       socket special may reside on the file system.
+
+The abstract socket namespace is a non-portable Linux feature which
+avoids these problems. Abstract sockets are still bound to a name,
+but the name has no connection with file system pathnames.
+
+License
+-------
+
+Paraslash is licensed under the GPL, version 2. Most of the code
+base has been written from scratch, and those parts are GPL V2
+throughout. Notable exceptions are FEC and the WMA decoder. See the
+corresponding source files for licencing details for these parts. Some
+code sniplets of several other third party software packages have
+been incorporated into the paraslash sources, for example log message
+coloring was taken from the git sources. These third party software
+packages are all published under the GPL or some other license
+compatible to the GPL.
+
+Acknowledgements
+----------------
+
+Many thanks to Gerrit Renker who read an early draft of this manual
+and contributed significant improvements.
+
+==========
+References
+==========
+
+Articles
+--------
+- [Polynomial Codes over Certain Finite
+Fields](http://kom.aau.dk/~heb/kurser/NOTER/KOFA01.PDF) by Reed, Irving
+S.; Solomon, Gustave (1960), Journal of the Society for Industrial
+and Applied Mathematics (SIAM) 8 (2): 300-304, doi:10.1137/0108018)
+
+RFCs
+----
+
+- [RFC 768](http://www.ietf.org/rfc/rfc768.txt) (1980): User Datagram
+Protocol
+
+- [RFC 791](http://www.ietf.org/rfc/rfc791.txt) (1981): Internet
+Protocol
+
+- [RFC 2437](http://www.ietf.org/rfc/rfc2437.txt) (1998): RSA
+Cryptography Specifications
+
+- [RFC 4340](http://www.ietf.org/rfc/rfc4340.txt) (2006): Datagram
+Congestion Control Protocol (DCCP)
+
+- [RFC 4341](http://www.ietf.org/rfc/rfc4341.txt) (2006): Congestion
+Control ID 2: TCP-like Congestion Control
+
+- [RFC 4342](http://www.ietf.org/rfc/rfc4342.txt) (2006): Congestion
+Control ID 3: TCP-Friendly Rate Control (TFRC)
+
+- [RFC 6716](http://www.ietf.org/rfc/rfc6716.txt) (2012): Definition
+of the Opus Audio Codec
+
+Application web pages
+---------------------
+
+- [paraslash](http://people.tuebingen.mpg.de/maan/paraslash/)
+- [xmms](http://xmms2.org/wiki/Main_Page)
+- [mpg123](http://www.mpg123.de/)
+- [gstreamer](http://gstreamer.freedesktop.org/)
+- [icecast](http://www.icecast.org/)
+- [Audio Compress](http://beesbuzz.biz/code/audiocompress.php)
+
+External documentation
+----------------------
+
+- [The mathematics of
+Raid6](http://kernel.org/pub/linux/kernel/people/hpa/raid6.pdf)
+by H. Peter Anvin
+
+- [Effective Erasure Codes for reliable Computer Communication
+Protocols](http://info.iet.unipi.it/~luigi/fec_ccr.ps.gz) by Luigi
+Rizzo
+
+Code
+----
+- [Original FEC
+implementation](http://info.iet.unipi.it/~luigi/vdm.tar.gz) by
+Luigi Rizzo)
index 0b6081cfdb9ea919537532d19dadab004a5fa825..929e732b8cb03bd84d6b382e05508fc2f81cf49d 100644 (file)
--- a/wma_afh.c
+++ b/wma_afh.c
@@ -642,7 +642,7 @@ out:
        return ret;
 }
 
-static const char* wma_suffixes[] = {"wma", NULL};
+static const char * const wma_suffixes[] = {"wma", NULL};
 
 /**
  * The init function of the wma audio format handler.
index 6b7251ee06338d1c1b50b4cd5eb674a6958ee0c0..0dff2b7914a0e1f1e18afc412bbd331bfe32f648 100644 (file)
@@ -88,8 +88,8 @@ struct private_wmadec_data {
        int frame_len_bits;
        /** Number of block sizes, one if !ahi->use_variable_block_len. */
        int nb_block_sizes;
-       /* block info */
-       int reset_block_lengths;
+       /* Whether to update block lengths from getbit context. */
+       bool reset_block_lengths;
        /** log2 of current block length. */
        int block_len_bits;
        /** log2 of next block length. */
@@ -131,13 +131,8 @@ struct private_wmadec_data {
 };
 
 #define EXPVLCBITS 8
-#define EXPMAX DIV_ROUND_UP(19, EXPVLCBITS)
-
 #define HGAINVLCBITS 9
-#define HGAINMAX DIV_ROUND_UP(13, HGAINVLCBITS)
-
 #define VLCBITS 9
-#define VLCMAX DIV_ROUND_UP(22, VLCBITS)
 
 /** \cond sine_winows */
 
@@ -396,7 +391,7 @@ static int wma_init(struct private_wmadec_data *pwd)
                pwd->windows[i] = sine_windows[pwd->frame_len_bits - i - 7];
        }
 
-       pwd->reset_block_lengths = 1;
+       pwd->reset_block_lengths = true;
 
        if (pwd->use_noise_coding) {
                /* init the noise generator */
@@ -434,13 +429,13 @@ static int wma_init(struct private_wmadec_data *pwd)
        return 0;
 }
 
-static void wma_lsp_to_curve_init(struct private_wmadec_data *pwd, int frame_len)
+static void wma_lsp_to_curve_init(struct private_wmadec_data *pwd)
 {
        float wdel, a, b;
        int i, e, m;
 
-       wdel = M_PI / frame_len;
-       for (i = 0; i < frame_len; i++)
+       wdel = M_PI / pwd->frame_len;
+       for (i = 0; i < pwd->frame_len; i++)
                pwd->lsp_cos_table[i] = 2.0f * cos(wdel * i);
 
        /* tables for x^-0.25 computation */
@@ -496,7 +491,7 @@ static int wma_decode_init(char *initial_buf, int len, struct private_wmadec_dat
                        wma_scale_huffbits, wma_scale_huffcodes, 4);
        } else {
                PARA_INFO_LOG("using curve\n");
-               wma_lsp_to_curve_init(pwd, pwd->frame_len);
+               wma_lsp_to_curve_init(pwd);
        }
        *result = pwd;
        return pwd->ahi.header_len;
@@ -586,7 +581,7 @@ static int decode_exp_vlc(struct private_wmadec_data *pwd, int ch)
        last_exp = 36;
 
        while (q < q_end) {
-               code = get_vlc(&pwd->gb, pwd->exp_vlc.table, EXPVLCBITS, EXPMAX);
+               code = get_vlc(&pwd->gb, pwd->exp_vlc.table, EXPVLCBITS);
                if (code < 0)
                        return code;
                /* NOTE: this offset is the same as MPEG4 AAC ! */
@@ -714,8 +709,7 @@ static int compute_high_band_values(struct private_wmadec_data *pwd,
                                val = get_bits(&pwd->gb, 7) - 19;
                        else {
                                int code = get_vlc(&pwd->gb,
-                                       pwd->hgain_vlc.table, HGAINVLCBITS,
-                                       HGAINMAX);
+                                       pwd->hgain_vlc.table, HGAINVLCBITS);
                                if (code < 0)
                                        return code;
                                val += code - 18;
@@ -816,7 +810,7 @@ static void compute_mdct_coefficients(struct private_wmadec_data *pwd,
                }
                /* very high freqs: noise */
                n = pwd->block_len - pwd->coefs_end[bsize];
-               mult1 = mult * exponents[((-1 << bsize)) >> esize];
+               mult1 = mult * exponents[(-(1 << bsize)) >> esize];
                for (i = 0; i < n; i++) {
                        *coefs++ = pwd->noise_table[pwd->noise_index] * mult1;
                        pwd->noise_index = (pwd->noise_index + 1)
@@ -840,7 +834,7 @@ static int wma_decode_block(struct private_wmadec_data *pwd)
                n = wma_log2(pwd->nb_block_sizes - 1) + 1;
 
                if (pwd->reset_block_lengths) {
-                       pwd->reset_block_lengths = 0;
+                       pwd->reset_block_lengths = false;
                        v = get_bits(&pwd->gb, n);
                        if (v >= pwd->nb_block_sizes)
                                return -E_WMA_BLOCK_SIZE;
@@ -946,8 +940,7 @@ static int wma_decode_block(struct private_wmadec_data *pwd)
                eptr = ptr + nb_coefs[ch];
                memset(ptr, 0, pwd->block_len * sizeof(int16_t));
                for (;;) {
-                       code = get_vlc(&pwd->gb, coef_vlc->table,
-                               VLCBITS, VLCMAX);
+                       code = get_vlc(&pwd->gb, coef_vlc->table, VLCBITS);
                        if (code < 0)
                                return code;
                        if (code == 1) /* EOB */
@@ -1136,7 +1129,7 @@ static int wma_decode_superframe(struct private_wmadec_data *pwd, void *data,
                if (len > 0)
                        skip_bits(&pwd->gb, len);
 
-               pwd->reset_block_lengths = 1;
+               pwd->reset_block_lengths = true;
                for (i = 0; i < nb_frames; i++) {
                        ret = wma_decode_frame(pwd, samples);
                        if (ret < 0)