para_play, infrastructure.
authorAndre Noll <maan@systemlinux.org>
Mon, 25 Jun 2012 23:48:04 +0000 (01:48 +0200)
committerAndre Noll <maan@systemlinux.org>
Sun, 18 Nov 2012 19:28:28 +0000 (20:28 +0100)
Now that the preparatory changes to the interactive subsystem
(single key mode, status bar, signal handling) and the writer nodes
(notifications) and receiver nodes (btr exec mechanism) are in place,
we can move on to the para_play executable.

This patch adds only the necessary changes to the build system and
provides a dummy implementation of para_play. The real implementation
will be provided as as a separate patch in the next commit.

Makefile.in
configure.ac
error.h
m4/gengetopt/makefile
m4/gengetopt/play.m4 [new file with mode: 0644]
play.c [new file with mode: 0644]
play.cmd [new file with mode: 0644]
server.c
web/manual.m4

index 3755e59..4d1c232 100644 (file)
@@ -141,6 +141,10 @@ $(man_dir)/para_audiod.1: para_audiod audiod_command_list.man | $(man_dir)
        @[ -z "$(Q)" ] || echo 'MAN $<'
        $(Q) $(HELP2MAN) -h --detailed-help -N -i audiod_command_list.man ./para_audiod > $@
 
+$(man_dir)/para_play.1: para_play play_command_list.man | $(man_dir)
+       @[ -z "$(Q)" ] || echo 'MAN $<'
+       $(Q) $(HELP2MAN) -h --detailed-help -N -i play_command_list.man ./para_play > $@
+
 $(man_dir)/%.1: % | $(man_dir)
        @[ -z "$(Q)" ] || echo 'MAN $<'
        $(Q) $(HELP2MAN) -h --detailed-help -N ./$< > $@
@@ -219,7 +223,7 @@ $(dep_dir)/%.d: %.c | $(dep_dir)
 
 all_objs := @recv_objs@ @filter_objs@ @client_objs@ @gui_objs@ \
        @audiod_objs@ @audioc_objs@ @fade_objs@ @server_objs@ \
-       @write_objs@ @afh_objs@
+       @write_objs@ @afh_objs@ @play_objs@
 deps := $(addprefix $(dep_dir)/, $(all_objs:.o=.d))
 
 recv_objs := $(addprefix $(object_dir)/, @recv_objs@)
@@ -232,6 +236,7 @@ fade_objs := $(addprefix $(object_dir)/, @fade_objs@)
 server_objs := $(addprefix $(object_dir)/, @server_objs@)
 write_objs := $(addprefix $(object_dir)/, @write_objs@)
 afh_objs := $(addprefix $(object_dir)/, @afh_objs@)
+play_objs := $(addprefix $(object_dir)/, @play_objs@)
 
 ifeq ($(findstring clean, $(MAKECMDGOALS)),)
 -include $(deps)
@@ -277,6 +282,10 @@ para_afh: $(afh_objs)
        @[ -z "$(Q)" ] || echo 'LD $@'
        $(Q) $(CC) $(LDFLAGS) -o $@ $(afh_objs) @afh_ldflags@
 
+para_play: $(play_objs)
+       @[ -z "$(Q)" ] || echo 'LD $@'
+       $(Q) $(CC) $(LDFLAGS) -o $@ $(play_objs) @play_ldflags@
+
 clean:
        @[ -z "$(Q)" ] || echo 'CLEAN'
        $(Q) rm -f @executables@
index 2df7339..661081c 100644 (file)
@@ -102,8 +102,9 @@ all_errlist_objs="mp3_afh afh_common net string signal time daemon
        exec send_common ggo udp_recv color fec fecdec_filter
        prebuffer_filter bitstream imdct
        wma_afh wma_common wmadec_filter buffer_tree crypt_common
-       gui gui_theme sideband afh_recv"
-executables="recv filter audioc write client afh audiod"
+       gui gui_theme sideband afh_recv play"
+
+executables="recv filter audioc write client afh audiod play"
 
 recv_cmdline_objs="add_cmdline(recv http_recv dccp_recv udp_recv afh_recv)"
 
@@ -154,6 +155,17 @@ client_ldflags=""
 gui_cmdline_objs="add_cmdline(gui)"
 gui_errlist_objs="exec signal string stat ringbuffer fd gui gui_theme"
 gui_objs="$gui_cmdline_objs $gui_errlist_objs"
+play_errlist_objs="play fd sched ggo buffer_tree time string net
+       afh_recv afh_common
+       wma_afh wma_common mp3_afh
+       recv_common udp_recv http_recv dccp_recv
+       filter_common fec bitstream imdct
+       wav_filter compress_filter amp_filter prebuffer_filter fecdec_filter
+               wmadec_filter
+       write_common file_write
+"
+play_cmdline_objs="add_cmdline(http_recv dccp_recv udp_recv afh_recv compress_filter amp_filter prebuffer_filter file_write play)"
+play_ldflags="-lm"
 ########################################################################### snprintf
 # ===========================================================================
 #        http://www.nongnu.org/autoconf-archive/ax_func_snprintf.html
@@ -514,6 +526,10 @@ if test ${have_core_audio} = yes; then
        audiod_cmdline_objs="$audiod_cmdline_objs osx_write.cmdline"
        audiod_ldflags="$audiod_ldflags $f"
 
+       play_errlist_objs="$play_errlist_objs osx_write ipc"
+       play_cmdline_objs="$play_cmdline_objs osx_write.cmdline"
+       play_ldflags="$play_ldflags $f"
+
        write_errlist_objs="$write_errlist_objs osx_write ipc"
        write_cmdline_objs="$write_cmdline_objs osx_write.cmdline"
        write_ldflags="$write_ldflags $f"
@@ -592,12 +608,14 @@ if test "$have_vorbis" = "yes" || test "$have_speex" = "yes"; then
        server_ldflags="$server_ldflags $ogg_libs"
        filter_ldflags="$filter_ldflags $ogg_libs"
        audiod_ldflags="$audiod_ldflags $ogg_libs"
+       play_ldflags="$play_ldflags $ogg_libs"
        afh_ldflags="$afh_ldflags $ogg_libs"
        recv_ldflags="$recv_ldflags $ogg_libs"
        all_errlist_objs="$all_errlist_objs ogg_afh_common"
        afh_errlist_objs="$afh_errlist_objs ogg_afh_common"
        recv_errlist_objs="$recv_errlist_objs ogg_afh_common"
        server_errlist_objs="$server_errlist_objs ogg_afh_common"
+       play_errlist_objs="$play_errlist_objs ogg_afh_common"
 fi
 if test "$have_vorbis" = "yes"; then
        all_errlist_objs="$all_errlist_objs oggdec_filter ogg_afh"
@@ -607,12 +625,14 @@ if test "$have_vorbis" = "yes"; then
        server_ldflags="$server_ldflags $vorbis_libs"
        filter_ldflags="$filter_ldflags $vorbis_libs"
        audiod_ldflags="$audiod_ldflags $vorbis_libs"
+       play_ldflags="$play_ldflags $vorbis_libs"
        afh_ldflags="$afh_ldflags $vorbis_libs"
        recv_ldflags="$recv_ldflags $vorbis_libs"
 
        server_errlist_objs="$server_errlist_objs ogg_afh"
        filter_errlist_objs="$filter_errlist_objs oggdec_filter"
        audiod_errlist_objs="$audiod_errlist_objs oggdec_filter"
+       play_errlist_objs="$play_errlist_objs oggdec_filter ogg_afh"
        afh_errlist_objs="$afh_errlist_objs ogg_afh"
        recv_errlist_objs="$recv_errlist_objs ogg_afh"
 
@@ -629,12 +649,14 @@ if test "$have_speex" = "yes"; then
        server_ldflags="$server_ldflags $speex_libs"
        filter_ldflags="$filter_ldflags $speex_libs"
        audiod_ldflags="$audiod_ldflags $speex_libs"
+       play_ldflags="$play_ldflags $speex_libs"
        afh_ldflags="$afh_ldflags $speex_libs"
        recv_ldflags="$recv_ldflags $speex_libs"
 
        server_errlist_objs="$server_errlist_objs spx_afh spx_common"
        filter_errlist_objs="$filter_errlist_objs spxdec_filter spx_common"
        audiod_errlist_objs="$audiod_errlist_objs spxdec_filter spx_common"
+       play_errlist_objs="$play_errlist_objs spxdec_filter spx_afh spx_common"
        afh_errlist_objs="$afh_errlist_objs spx_afh spx_common"
        recv_errlist_objs="$recv_errlist_objs spx_afh spx_common"
 
@@ -671,12 +693,14 @@ if test "$have_faad" = "yes"; then
        filter_errlist_objs="$filter_errlist_objs aacdec_filter aac_common"
        afh_errlist_objs="$afh_errlist_objs aac_common aac_afh"
        audiod_errlist_objs="$audiod_errlist_objs aacdec_filter aac_common"
+       play_errlist_objs="$play_errlist_objs aacdec_filter aac_afh aac_common"
        server_errlist_objs="$server_errlist_objs aac_afh aac_common"
        recv_errlist_objs="$recv_errlist_objs aac_afh aac_common"
 
        server_ldflags="$server_ldflags $faad_libs -lfaad"
        filter_ldflags="$filter_ldflags $faad_libs -lfaad"
        audiod_ldflags="$audiod_ldflags $faad_libs -lfaad"
+       play_ldflags="$play_ldflags $faad_libs -lfaad"
        afh_ldflags="$afh_ldflags $faad_libs -lfaad"
        recv_ldflags="$afh_ldflags $faad_libs -lfaad"
 
@@ -718,11 +742,14 @@ if test "$have_mad" = "yes"; then
        AC_DEFINE(HAVE_MAD, 1, define to 1 if you want to build the mp3dec filter)
        filter_cmdline_objs="$filter_cmdline_objs add_cmdline(mp3dec_filter)"
        audiod_cmdline_objs="$audiod_cmdline_objs add_cmdline(mp3dec_filter)"
+       play_cmdline_objs="$play_cmdline_objs add_cmdline(mp3dec_filter)"
        all_errlist_objs="$all_errlist_objs mp3dec_filter"
        filter_errlist_objs="$filter_errlist_objs mp3dec_filter"
        audiod_errlist_objs="$audiod_errlist_objs mp3dec_filter"
+       play_errlist_objs="$play_errlist_objs mp3dec_filter"
        filter_ldflags="$filter_ldflags $mad_libs -lmad"
        audiod_ldflags="$audiod_ldflags $mad_libs -lmad"
+       play_ldflags="$play_ldflags $mad_libs -lmad"
        audiod_audio_formats="$audiod_audio_formats mp3"
        filters="$filters mp3dec"
        AC_SUBST(mad_cppflags)
@@ -763,7 +790,9 @@ if test ${have_libid3tag} = yes; then
        AC_DEFINE(HAVE_LIBID3TAG, 1, define to 1 you have libid3tag)
        server_ldflags="$server_ldflags $id3tag_libs -lid3tag -lz"
        afh_ldflags="$afh_ldflags $id3tag_libs -lid3tag -lz"
+       play_ldflags="$play_ldflags -lz"
        recv_ldflags="$recv_ldflags $id3tag_libs -lid3tag"
+       play_ldflags="$play_ldflags $id3tag_libs -lid3tag"
        AC_SUBST(id3tag_cppflags)
 else
        AC_MSG_WARN([no support for id3v2 tags])
@@ -796,11 +825,13 @@ if test "$have_flac" = "yes"; then
        all_errlist_objs="$all_errlist_objs flacdec_filter flac_afh"
        filter_errlist_objs="$filter_errlist_objs flacdec_filter"
        audiod_errlist_objs="$audiod_errlist_objs flacdec_filter"
+       play_errlist_objs="$play_errlist_objs flacdec_filter flac_afh"
        afh_errlist_objs="$afh_errlist_objs flac_afh"
        server_errlist_objs="$server_errlist_objs flac_afh"
        recv_errlist_objs="$recv_errlist_objs flac_afh"
        filter_ldflags="$filter_ldflags $flac_libs -lFLAC"
        audiod_ldflags="$audiod_ldflags $flac_libs -lFLAC"
+       play_ldflags="$play_ldflags $flac_libs -lFLAC"
        server_ldflags="$server_ldflags $flac_libs -lFLAC"
        afh_ldflags="$afh_ldflags $flac_libs -lFLAC"
        recv_ldflags="$afh_ldflags $flac_libs -lFLAC"
@@ -824,7 +855,10 @@ msg="=> will not build oss writer"
 
 AC_CHECK_HEADER(sys/soundcard.h, [
        audiod_errlist_objs="$audiod_errlist_objs oss_write"
+       play_errlist_objs="$play_errlist_objs oss_write"
        audiod_cmdline_objs="$audiod_cmdline_objs add_cmdline(oss_write)"
+       play_cmdline_objs="$play_cmdline_objs add_cmdline(oss_write)"
+
        write_errlist_objs="$write_errlist_objs oss_write"
        write_cmdline_objs="$write_cmdline_objs add_cmdline(oss_write)"
        fade_errlist_objs="$fade_errlist_objs oss_mix"
@@ -837,6 +871,7 @@ AC_CHECK_HEADER(sys/soundcard.h, [
 
        AC_CHECK_LIB(ossaudio, _oss_ioctl, [
                        audiod_ldflags="$audiod_ldflags -lossaudio"
+                       play_ldflags="$play_ldflags -lossaudio"
                        write_ldflags="$write_ldflags -lossaudio"
                        fade_ldflags="$fade_ldflags -lossaudio"
                ]
@@ -880,6 +915,10 @@ if test "$have_alsa" = "yes"; then
        audiod_errlist_objs="$audiod_errlist_objs alsa_write"
        audiod_cmdline_objs="$audiod_cmdline_objs add_cmdline(alsa_write)"
        audiod_ldflags="$audiod_ldflags -lasound"
+       play_errlist_objs="$play_errlist_objs alsa_write"
+       play_cmdline_objs="$play_cmdline_objs add_cmdline(alsa_write)"
+       play_ldflags="$play_ldflags -lasound"
+
        write_errlist_objs="$write_errlist_objs alsa_write"
        write_cmdline_objs="$write_cmdline_objs add_cmdline(alsa_write)"
        write_ldflags="$write_ldflags -lasound"
@@ -983,6 +1022,10 @@ if test "$have_ao" = "yes"; then
        audiod_cmdline_objs="$audiod_cmdline_objs add_cmdline(ao_write)"
        audiod_ldflags="$audiod_ldflags -lao -lpthread"
 
+       play_errlist_objs="$play_errlist_objs ao_write"
+       play_cmdline_objs="$play_cmdline_objs add_cmdline(ao_write)"
+       play_ldflags="$play_ldflags -lao -lpthread"
+
        write_errlist_objs="$write_errlist_objs ao_write"
        write_cmdline_objs="$write_cmdline_objs add_cmdline(ao_write)"
        write_ldflags="$write_ldflags $ao_libs -lao -lpthread"
@@ -1020,12 +1063,12 @@ AC_CHECK_HEADERS([readline/readline.h], [
 ])
 if test "$have_readline" = "yes"; then
        readline_libs="$readline_libs -lreadline"
-       AC_SEARCH_LIBS([rl_replace_line], [readline], [], [have_readline="no"])
+       AC_SEARCH_LIBS([rl_free_keymap], [readline], [], [have_readline="no"])
        if test "$have_readline" = "no"; then # try with -lcurses
                 # clear cache
                AC_MSG_NOTICE([trying again with -lcurses])
-                unset ac_cv_search_rl_replace_line 2> /dev/null
-               AC_SEARCH_LIBS([rl_replace_line], [readline], [
+                unset ac_cv_search_rl_free_keymap 2> /dev/null
+               AC_SEARCH_LIBS([rl_free_keymap], [readline], [
                        have_readline=yes
                        readline_libs="$readline_libs -lcurses"
                ], [], [-lcurses])
@@ -1033,8 +1076,8 @@ if test "$have_readline" = "yes"; then
        if test "$have_readline" = "no"; then # try with -ltermcap
                 # clear cache
                AC_MSG_NOTICE([trying again with -ltermcap])
-                unset ac_cv_search_rl_replace_line 2> /dev/null
-               AC_SEARCH_LIBS([rl_replace_line], [readline], [
+                unset ac_cv_search_rl_free_keymap 2> /dev/null
+               AC_SEARCH_LIBS([rl_free_keymap], [readline], [
                        have_readline=yes
                        readline_libs="$readline_libs -ltermcap"
                ], [], [-ltermcap])
@@ -1047,6 +1090,8 @@ if test "$have_readline" = "yes"; then
        client_ldflags="$client_ldflags $readline_libs"
        audioc_errlist_objs="$audioc_errlist_objs buffer_tree interactive sched time"
        audioc_ldflags="$audioc_ldflags $readline_libs"
+       play_errlist_objs="$play_errlist_objs interactive"
+       play_ldflags="$play_ldflags $readline_libs"
        AC_SUBST(readline_cppflags)
        AC_DEFINE(HAVE_READLINE, 1, define to 1 to turn on readline support)
 else
@@ -1106,6 +1151,8 @@ write_objs="$write_cmdline_objs $write_errlist_objs"
 client_objs="$client_cmdline_objs $client_errlist_objs"
 audioc_objs="$audioc_cmdline_objs $audioc_errlist_objs"
 afh_objs="$afh_cmdline_objs $afh_errlist_objs"
+play_objs="$play_cmdline_objs $play_errlist_objs"
+
 
 AC_SUBST(recv_objs, add_dot_o($recv_objs))
 AC_SUBST(recv_ldflags, $recv_ldflags)
@@ -1151,6 +1198,13 @@ AC_SUBST(gui_objs, add_dot_o($gui_objs))
 AC_DEFINE_UNQUOTED(INIT_GUI_ERRLISTS,
        objlist_to_errlist($gui_errlist_objs), errors used by para_gui)
 
+AC_SUBST(play_objs, add_dot_o($play_objs))
+AC_SUBST(play_ldflags, $play_ldflags)
+AC_DEFINE_UNQUOTED(INIT_PLAY_ERRLISTS,
+       objlist_to_errlist($play_errlist_objs), errors used by para_play)
+
+AC_MSG_NOTICE(play objs: $play_objs)
+
 enum="$(for i in $filters; do printf "${i}_FILTER, " | tr '[a-z]' '[A-Z]'; done)"
 AC_DEFINE_UNQUOTED(FILTER_ENUM, $enum NUM_SUPPORTED_FILTERS,
        enum of supported filters)
diff --git a/error.h b/error.h
index 8b1ae34..fd2e01a 100644 (file)
--- a/error.h
+++ b/error.h
@@ -50,6 +50,10 @@ extern const char **para_errlist[];
        PARA_ERROR(SB_PACKET_SIZE, "invalid sideband packet size or protocol error"), \
 
 
+#define PLAY_ERRORS \
+       PARA_ERROR(PLAY_SYNTAX, "play syntax error"), \
+
+
 #define FLACDEC_FILTER_ERRORS \
        PARA_ERROR(FLACDEC_DECODER_ALLOC, "could not allocate stream decoder"), \
        PARA_ERROR(FLACDEC_DECODER_INIT, "could not init stream decoder"), \
index c81eda4..c88dfd9 100644 (file)
@@ -34,6 +34,7 @@ $(ggo_dir)/client.ggo: \
        $(m4_ggo_dir)/history_file.m4 \
        $(m4_ggo_dir)/complete.m4
 $(ggo_dir)/fade.ggo: $(m4_ggo_dir)/loglevel.m4 $(m4_ggo_dir)/config_file.m4
+$(ggo_dir)/play.ggo: $(m4_ggo_dir)/loglevel.m4 $(m4_ggo_dir)/config_file.m4
 
 $(ggo_dir)/%.ggo: $(m4_ggo_dir)/%.m4 $(m4_ggo_dir)/header.m4 | $(ggo_dir)
        @[ -z "$(Q)" ] || echo 'M4 $<'
diff --git a/m4/gengetopt/play.m4 b/m4/gengetopt/play.m4
new file mode 100644 (file)
index 0000000..9bdc767
--- /dev/null
@@ -0,0 +1,11 @@
+args "--unamed-opts=audio_file --no-handle-version --conf-parser --no-handle-help"
+include(header.m4)
+define(CURRENT_PROGRAM,para_play)
+define(DEFAULT_CONFIG_FILE,~/.paraslash/play.conf)
+<qu>
+#########################
+section "General options"
+#########################
+</qu>
+include(loglevel.m4)
+include(config_file.m4)
diff --git a/play.c b/play.c
new file mode 100644 (file)
index 0000000..fc33f68
--- /dev/null
+++ b/play.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2012 Andre Noll <maan@systemlinux.org>
+ *
+ * Licensed under the GPL v2. For licencing details see COPYING.
+ */
+
+/** \file play.c Paraslash's standalone player. */
+
+#include <regex.h>
+
+#include "para.h"
+#include "list.h"
+#include "play.cmdline.h"
+#include "filter.cmdline.h"
+#include "error.h"
+#include "ggo.h"
+#include "buffer_tree.h"
+#include "version.h"
+#include "string.h"
+#include "sched.h"
+#include "filter.h"
+#include "afh.h"
+#include "recv.h"
+#include "write.h"
+#include "write_common.h"
+#include "fd.h"
+
+static struct play_args_info conf;
+
+/** Initialize the array of errors for para_play. */
+INIT_PLAY_ERRLISTS;
+
+/* Activate the afh receiver. */
+extern void afh_recv_init(struct receiver *r);
+#undef AFH_RECEIVER
+#define AFH_RECEIVER {.name = "afh", .init = afh_recv_init},
+DEFINE_RECEIVER_ARRAY;
+
+/* FIXME: This is needed by the amp filter. */
+char *stat_item_values[NUM_STAT_ITEMS] = {NULL};
+
+static int loglevel = LL_WARNING;
+INIT_STDERR_LOGGING(loglevel);
+
+__noreturn static void print_help_and_die(void)
+{
+       int d = conf.detailed_help_given;
+       const char **p = d? play_args_info_detailed_help
+               : play_args_info_help;
+
+       printf_or_die("%s\n\n", PLAY_CMDLINE_PARSER_PACKAGE "-"
+               PLAY_CMDLINE_PARSER_VERSION);
+       printf_or_die("%s\n\n", play_args_info_usage);
+       for (; *p; p++)
+               printf_or_die("%s\n", *p);
+       print_filter_helps(d);
+       print_writer_helps(d);
+       exit(0);
+}
+
+static void parse_config_or_die(int argc, char *argv[])
+{
+       int ret;
+       char *config_file;
+       struct play_cmdline_parser_params params = {
+               .override = 0,
+               .initialize = 1,
+               .check_required = 0,
+               .check_ambiguity = 0,
+               .print_errors = 1
+       };
+
+       if (play_cmdline_parser_ext(argc, argv, &conf, &params))
+               exit(EXIT_FAILURE);
+       HANDLE_VERSION_FLAG("play", conf);
+       if (conf.help_given || conf.detailed_help_given)
+               print_help_and_die();
+       loglevel = get_loglevel_by_name(conf.loglevel_arg);
+       if (conf.config_file_given)
+               config_file = para_strdup(conf.config_file_arg);
+       else {
+               char *home = para_homedir();
+               config_file = make_message("%s/.paraslash/play.conf", home);
+               free(home);
+       }
+       ret = file_exists(config_file);
+       if (conf.config_file_given && !ret) {
+               PARA_EMERG_LOG("can not read config file %s\n", config_file);
+               goto err;
+       }
+       if (ret) {
+               params.initialize = 0;
+               params.check_required = 1;
+               play_cmdline_parser_config_file(config_file, &conf, &params);
+       }
+       free(config_file);
+       return;
+err:
+       free(config_file);
+       exit(EXIT_FAILURE);
+}
+
+int main(int argc, char *argv[])
+{
+       /* needed this early to make help work */
+       recv_init();
+       filter_init();
+       writer_init();
+
+       parse_config_or_die(argc, argv);
+       return 0;
+}
diff --git a/play.cmd b/play.cmd
new file mode 100644 (file)
index 0000000..c0e8d7f
--- /dev/null
+++ b/play.cmd
@@ -0,0 +1,8 @@
+BN: play
+SF: play.c
+SN: list of commands
+---
+N: quit
+D: Exit para_play.
+U: quit
+H: Pressing CTRL+D causes EOF on stdin which also exits para_play.
index 8e8cb5f..5d4a9fe 100644 (file)
--- a/server.c
+++ b/server.c
@@ -14,7 +14,7 @@
  *
  *
  *     - The main programs: \ref server.c, \ref audiod.c, \ref client.c,
- *       \ref audioc.c, \ref afh.c
+ *       \ref audioc.c, \ref afh.c, \ref play.c,
  *     - Server: \ref server_command, \ref sender,
  *     - Audio file selector: \ref audio_format_handler, \ref afs_table,
  *     - Client: \ref receiver, \ref receiver_node, \ref filter,
index 5ceeac0..3ebeb6b 100644 (file)
@@ -174,6 +174,9 @@ 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*
 
@@ -274,7 +277,8 @@ Optional:
 
        - XREFERENCE(http://cnswww.cns.cwru.edu/php/chet/readline/rltop.html,
        GNU Readline). If this library (libreadline-dev) is installed,
-       para_client and para_audioc support interactive sessions.
+       para_client, para_audioc and para_play support interactive
+       sessions.
 
 Installation
 ~~~~~~~~~~~~