The afh_receiver, infrastructure.
authorAndre Noll <maan@systemlinux.org>
Tue, 23 Aug 2011 16:11:38 +0000 (18:11 +0200)
committerAndre Noll <maan@systemlinux.org>
Sun, 18 Nov 2012 19:28:28 +0000 (20:28 +0100)
This adds a dummy implementation of the new afh_receiver which will
replace the streaming mode of para_afh.

It "receives" its input data from a local audio file rather than from
a network socket, but supports the same API as all other receivers. In
particular it provides a buffer tree node which feeds the chunks of
the audio file to any filter which is connected to that node. This
mechanism will be used by the para_play executable.

The afh receiver is not needed for para_audiod, so we link afh_recv.o
only to para_recv.

afh_recv.c [new file with mode: 0644]
audiod.c
configure.ac
error.h
m4/gengetopt/afh_recv.m4 [new file with mode: 0644]
recv.c
recv.h
recv_common.c

diff --git a/afh_recv.c b/afh_recv.c
new file mode 100644 (file)
index 0000000..550ca42
--- /dev/null
@@ -0,0 +1,41 @@
+#include <regex.h>
+#include <sys/types.h>
+#include <stdbool.h>
+
+#include "para.h"
+#include "error.h"
+#include "list.h"
+#include "sched.h"
+#include "ggo.h"
+#include "buffer_tree.h"
+#include "recv.h"
+#include "afh_recv.cmdline.h"
+#include "string.h"
+#include "fd.h"
+
+/**
+ * The init function of the afh receiver.
+ *
+ * \param r Pointer to the receiver struct to initialize.
+ *
+ * This initializes all function pointers of \a r.
+ */
+void afh_recv_init(struct receiver *r)
+{
+       struct afh_recv_args_info dummy;
+
+       afh_recv_cmdline_parser_init(&dummy);
+#if 0
+       r->open = afh_recv_open;
+       r->close = afh_recv_close;
+       r->pre_select = afh_recv_pre_select;
+       r->post_select = afh_recv_post_select;
+       r->parse_config = afh_recv_parse_config;
+       r->free_config = afh_recv_free_config;
+#endif
+       r->help = (struct ggo_help) {
+               .short_help = afh_recv_args_info_help,
+               .detailed_help = afh_recv_args_info_detailed_help
+       };
+       afh_recv_cmdline_parser_free(&dummy);
+}
index 791432c..4dfd5d5 100644 (file)
--- a/audiod.c
+++ b/audiod.c
@@ -38,6 +38,8 @@ INIT_AUDIOD_ERRLISTS;
 /** define the array containing all supported audio formats */
 const char *audio_formats[] = {AUDIOD_AUDIO_FORMAT_ARRAY NULL};
 
+DEFINE_RECEIVER_ARRAY;
+
 /** Defines how audiod handles one supported audio format. */
 struct audio_format_info {
        /** pointer to the receiver for this audio format */
index 32ad846..2df7339 100644 (file)
@@ -102,14 +102,17 @@ 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"
-
+       gui gui_theme sideband afh_recv"
 executables="recv filter audioc write client afh audiod"
 
-recv_cmdline_objs="add_cmdline(recv http_recv dccp_recv udp_recv)"
+recv_cmdline_objs="add_cmdline(recv http_recv dccp_recv udp_recv afh_recv)"
+
+recv_errlist_objs="
+       http_recv recv_common recv time string net dccp_recv fd
+       sched stdout ggo udp_recv buffer_tree afh_recv afh_common
+       wma_afh wma_common mp3_afh
+"
 
-recv_errlist_objs="http_recv recv_common recv time string net dccp_recv
-       fd sched stdout ggo udp_recv buffer_tree"
 recv_ldflags=""
 
 filter_cmdline_objs="add_cmdline(filter compress_filter amp_filter prebuffer_filter)"
@@ -590,8 +593,10 @@ if test "$have_vorbis" = "yes" || test "$have_speex" = "yes"; then
        filter_ldflags="$filter_ldflags $ogg_libs"
        audiod_ldflags="$audiod_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"
 fi
 if test "$have_vorbis" = "yes"; then
@@ -603,11 +608,13 @@ if test "$have_vorbis" = "yes"; then
        filter_ldflags="$filter_ldflags $vorbis_libs"
        audiod_ldflags="$audiod_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"
        afh_errlist_objs="$afh_errlist_objs ogg_afh"
+       recv_errlist_objs="$recv_errlist_objs ogg_afh"
 
        audiod_audio_formats="$audiod_audio_formats ogg"
        server_audio_formats="$server_audio_formats ogg"
@@ -623,11 +630,13 @@ if test "$have_speex" = "yes"; then
        filter_ldflags="$filter_ldflags $speex_libs"
        audiod_ldflags="$audiod_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"
        afh_errlist_objs="$afh_errlist_objs spx_afh spx_common"
+       recv_errlist_objs="$recv_errlist_objs spx_afh spx_common"
 
        audiod_audio_formats="$audiod_audio_formats spx"
        server_audio_formats="$server_audio_formats spx"
@@ -663,10 +672,14 @@ if test "$have_faad" = "yes"; then
        afh_errlist_objs="$afh_errlist_objs aac_common aac_afh"
        audiod_errlist_objs="$audiod_errlist_objs aacdec_filter 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"
        afh_ldflags="$afh_ldflags $faad_libs -lfaad"
+       recv_ldflags="$afh_ldflags $faad_libs -lfaad"
+
        audiod_audio_formats="$audiod_audio_formats aac"
        server_audio_formats="$server_audio_formats aac"
        filters="$filters aacdec"
@@ -750,6 +763,7 @@ 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"
+       recv_ldflags="$recv_ldflags $id3tag_libs -lid3tag"
        AC_SUBST(id3tag_cppflags)
 else
        AC_MSG_WARN([no support for id3v2 tags])
@@ -784,10 +798,12 @@ if test "$have_flac" = "yes"; then
        audiod_errlist_objs="$audiod_errlist_objs flacdec_filter"
        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"
        server_ldflags="$server_ldflags $flac_libs -lFLAC"
        afh_ldflags="$afh_ldflags $flac_libs -lFLAC"
+       recv_ldflags="$afh_ldflags $flac_libs -lFLAC"
        filters="$filters flacdec"
        server_audio_formats="$server_audio_formats flac"
        audiod_audio_formats="$audiod_audio_formats flac"
diff --git a/error.h b/error.h
index 8579bd8..1e62466 100644 (file)
--- a/error.h
+++ b/error.h
@@ -33,6 +33,7 @@ DEFINE_ERRLIST_OBJECT_ENUM;
 #define FILE_WRITE_ERRORS
 #define STDIN_ERRORS
 #define WRITE_ERRORS
+#define AFH_RECV_ERRORS
 
 extern const char **para_errlist[];
 
diff --git a/m4/gengetopt/afh_recv.m4 b/m4/gengetopt/afh_recv.m4
new file mode 100644 (file)
index 0000000..4995e77
--- /dev/null
@@ -0,0 +1,71 @@
+include(header.m4)
+<qu>
+text "
+       The afh (audio format handler) receiver can be used to write
+       selected parts of the given audio file without decoding
+       the data.
+
+       The selected parts of the content of the audio file are passed
+       to the child nodes of the buffer tree. Only complete chunks
+       with respect of the underlying audio format are passed.
+
+"
+
+option "filename" f
+#~~~~~~~~~~~~~~~~~~
+"file to open"
+string typestr = "filename"
+required
+
+option "begin-chunk" b
+#~~~~~~~~~~~~~~~~~~~~~
+"skip a number of chunks"
+int typestr = "chunk_num"
+default = "0"
+optional
+details = "
+       The chunk_num argument must be between -num_chunks and
+       num_chunks - 1 inclusively where num_chunks is the total number
+       of chunks which is printed when using the --info option. If
+       chunk_num is negative, the given number of chunks are counted
+       backwards from the end of the file. For example --begin_chunk
+       -100 instructs para_afh to start output at chunk num_chunks
+       - 100. This is mainly useful for cutting off the end of an
+       audio file.
+"
+
+option "end-chunk" e
+#~~~~~~~~~~~~~~~~~~~
+"only write up to chunk chunk_num"
+int typestr = "chunk_num"
+optional
+details = "
+       For the chunk_num argument the same rules as for --begin_chunk
+       apply. The default is to write up to the last chunk.
+"
+
+option "just-in-time" j
+#~~~~~~~~~~~~~~~~~~~~~~
+"use timed writes"
+flag off
+details = "
+       Write the specified chunks of data 'just in time', i.e. the
+       write of each chunk is delayed until the time it is needed
+       by the decoder/player in order to guarantee an uninterrupted
+       audio stream. This may be useful for third-party software
+       that is capable of reading from stdin.
+"
+
+option "no-header" H
+#~~~~~~~~~~~~~~~~~~~
+"do not write an audio file header"
+flag off
+details = "
+       If an audio format needs information about the audio file
+       in a format-specific header in order to be understood by
+       the decoding software, a suitable header is automatically
+       send. This option changes the default behaviour, i.e. no
+       header is written.
+"
+
+</qu>
diff --git a/recv.c b/recv.c
index 3d5049b..a37e4d0 100644 (file)
--- a/recv.c
+++ b/recv.c
 #include "stdout.h"
 #include "version.h"
 
+extern void afh_recv_init(struct receiver *r);
+#undef AFH_RECEIVER
+#define AFH_RECEIVER {.name = "afh", .init = afh_recv_init},
+DEFINE_RECEIVER_ARRAY;
+
 /** The gengetopt args info struct. */
 static struct recv_args_info conf;
 
diff --git a/recv.h b/recv.h
index 322ac57..1f3ecfc 100644 (file)
--- a/recv.h
+++ b/recv.h
@@ -133,6 +133,7 @@ struct receiver {
        HTTP_RECEIVER \
        DCCP_RECEIVER \
        UDP_RECEIVER \
+       AFH_RECEIVER \
        {.name = NULL}};
 
 /** Iterate over all available receivers. */
@@ -150,6 +151,7 @@ extern void dccp_recv_init(struct receiver *r);
 #define DCCP_RECEIVER {.name = "dccp", .init = dccp_recv_init},
 extern void udp_recv_init(struct receiver *r);
 #define UDP_RECEIVER {.name = "udp", .init = udp_recv_init},
+#define AFH_RECEIVER /* not active by default */
 
 extern struct receiver receivers[];
 /** \endcond receiver */
index f0321df..20b6783 100644 (file)
@@ -16,8 +16,6 @@
 #include "recv.h"
 #include "string.h"
 
-DEFINE_RECEIVER_ARRAY;
-
 /**
  * Call the init function of each paraslash receiver.
  */